diff options
-rw-r--r-- | CMakeLists.txt | 12 | ||||
-rw-r--r-- | layers.json.split | 56 | ||||
-rw-r--r-- | src/CMakeLists.txt | 17 | ||||
-rw-r--r-- | src/json_helper.cpp | 12 | ||||
-rw-r--r-- | src/json_helper.hpp | 1 | ||||
-rw-r--r-- | src/main.cpp | 12 | ||||
-rw-r--r-- | src/pm_wrapper.cpp | 261 | ||||
-rw-r--r-- | src/pm_wrapper.hpp | 75 | ||||
-rw-r--r-- | src/policy_manager/CMakeLists.txt | 65 | ||||
-rw-r--r-- | src/policy_manager/db/layouts.db | 152 | ||||
-rw-r--r-- | src/policy_manager/db/roles.db | 44 | ||||
-rw-r--r-- | src/policy_manager/db/roles.db.split | 51 | ||||
-rw-r--r-- | src/policy_manager/policy_manager.cpp | 1341 | ||||
-rw-r--r-- | src/policy_manager/policy_manager.hpp | 144 | ||||
-rw-r--r-- | src/policy_manager/stm/stub/src/CMakeLists.txt | 53 | ||||
-rw-r--r-- | src/policy_manager/stm/stub/src/include/stm.h | 170 | ||||
-rw-r--r-- | src/policy_manager/stm/stub/src/stm.c | 237 | ||||
-rw-r--r-- | src/window_manager.cpp | 504 | ||||
-rw-r--r-- | src/window_manager.hpp | 12 |
19 files changed, 451 insertions, 2768 deletions
diff --git a/CMakeLists.txt b/CMakeLists.txt index 92ee691..4ed6d6d 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -79,16 +79,4 @@ set(SANITIZER_MODE "none" CACHE STRING "Build using a specific sanitizer (e.g. ' set(LINK_LIBCXX OFF CACHE BOOL "Link against LLVMs libc++") -# Set name of PolicyManager and STM -set(PLUGIN_PM policy_manager) -set(USE_STM_NAME stub) - -# Add STM -add_subdirectory(src/${PLUGIN_PM}/stm/${USE_STM_NAME}/src) -include_directories(src/${PLUGIN_PM}/stm/${USE_STM_NAME}/src) - -# Add PolicyManager as plugin -add_subdirectory(src/${PLUGIN_PM}) -include_directories(src/${PLUGIN_PM}) - add_subdirectory(src) diff --git a/layers.json.split b/layers.json.split new file mode 100644 index 0000000..641e2f4 --- /dev/null +++ b/layers.json.split @@ -0,0 +1,56 @@ +{ + "comment": "Surface ID to Layer ID mapping", + + "main_surface": { + "surface_role": "HomeScreen", + "comment": "This surface should never be made invisible (The HomeScreen)" + }, + + "mappings": [ + { + "role": "BackGroundLayer", + "name": "BackGroundLayer", + "layer_id": 999, + "comment": "Single BackGround layer map for the map, radio, music and video" + }, + { + "role": "homescreen", + "name": "FarHomeScreen", + "layer_id": 1000, + "comment": "FarHomeScreen is the part of HomeScreen. The z order of this layer is lower than NearHomeScreen" + }, + { + "role": "music|video|browser|radio|phone|map|hvac|settings|dashboard|poi|mixer|sdl|launcher|fallback", + "name": "Apps", + "layer_id": 1001, + "comment": "Range of IDs that will always be placed on layer 1001", + + "split_layouts": [ + { + "name": "map", + "main_match": "map", + "sub_match": "hvac|music", + "priority": 1000 + } + ] + }, + { + "role": "software_keyboard", + "name": "NearHomeScreen", + "layer_id": 1002, + "comment": "NearHomeScreen is the part of HomeScreen. The z order of this layer is upper than FarHomeScreen" + }, + { + "role": "restriction", + "name": "Restriction", + "layer_id": 1003, + "comment": "This layer is for restriction notification. This is used by restriction role" + }, + { + "role": "^on_screen.*", + "name": "OnScreen", + "layer_id": 9999, + "comment": "Range of IDs that will always be placed on the OnScreen layer, that gets a very high 'dummy' id of 9999" + } + ] +} diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 6155ef3..ee398e0 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -38,23 +38,20 @@ add_library(${TARGETS_WM} MODULE wm_error.cpp wm_config.cpp applist.cpp - request.cpp - pm_wrapper.cpp) + request.cpp) target_include_directories(${TARGETS_WM} PRIVATE ${AFB_INCLUDE_DIRS} ${SD_INCLUDE_DIRS} ../include - ../src - ../src/${PLUGIN_PM}) + ../src) target_link_libraries(${TARGETS_WM} PRIVATE ${AFB_LIBRARIES} ${WLC_LIBRARIES} - ${SD_LIBRARIES} - ${CMAKE_BINARY_DIR}/src/${PLUGIN_PM}/lib${PLUGIN_PM}.so) + ${SD_LIBRARIES}) target_compile_definitions(${TARGETS_WM} PRIVATE @@ -86,12 +83,12 @@ set_target_properties(${TARGETS_WM} C_STANDARD 99 C_STANDARD_REQUIRED ON - LINK_FLAGS "-Wl,--version-script=${CMAKE_CURRENT_SOURCE_DIR}/../export.map -Wl,-rpath,'$ORIGIN'") + LINK_FLAGS "-Wl,--version-script=${CMAKE_CURRENT_SOURCE_DIR}/../export.map") if (LINK_LIBCXX) set_target_properties(${TARGETS_WM} PROPERTIES - LINK_FLAGS "-Wl,--version-script=${CMAKE_CURRENT_SOURCE_DIR}/../export.map -lc++ -Wl,-rpath,'$ORIGIN'") + LINK_FLAGS "-Wl,--version-script=${CMAKE_CURRENT_SOURCE_DIR}/../export.map -lc++") endif() if (NOT ${SANITIZER_MODE} STREQUAL "none" AND NOT ${SANITIZER_MODE} STREQUAL "") @@ -117,10 +114,6 @@ add_custom_command(TARGET ${TARGETS_WM} POST_BUILD COMMAND cp -f ${PROJECT_SOURCE_DIR}/src/db/old_roles.db ${PROJECT_BINARY_DIR}/package/root/etc COMMAND cp -f ${PROJECT_SOURCE_DIR}/src/db/areas.db ${PROJECT_BINARY_DIR}/package/root/etc COMMAND cp -f ${PROJECT_SOURCE_DIR}/conf/setting.json ${PROJECT_BINARY_DIR}/package/root/etc - COMMAND cp -f ${PROJECT_SOURCE_DIR}/src/${PLUGIN_PM}/db/layouts.db ${PROJECT_BINARY_DIR}/package/root/etc - COMMAND cp -f ${PROJECT_SOURCE_DIR}/src/${PLUGIN_PM}/db/roles.db ${PROJECT_BINARY_DIR}/package/root/etc - COMMAND cp -f ${PROJECT_BINARY_DIR}/src/${PLUGIN_PM}/lib${PLUGIN_PM}.so ${PROJECT_BINARY_DIR}/package/root/lib - COMMAND cp -f ${PROJECT_BINARY_DIR}/src/${PLUGIN_PM}/stm/${USE_STM_NAME}/src/libstm.so ${PROJECT_BINARY_DIR}/package/root/lib ) add_custom_target(package DEPENDS ${PROJECT_BINARY_DIR}/package/root diff --git a/src/json_helper.cpp b/src/json_helper.cpp index b97f21d..c2f4173 100644 --- a/src/json_helper.cpp +++ b/src/json_helper.cpp @@ -136,18 +136,6 @@ int getIntFromJson(json_object *obj, const char *key) return json_object_get_int(tmp); } -json_bool getBoolFromJson(json_object *obj, const char *key) -{ - json_object *tmp; - if (!json_object_object_get_ex(obj, key, &tmp)) - { - HMI_DEBUG("wm:jh", "Not found key \"%s\"", key); - return FALSE; - } - - return json_object_get_boolean(tmp); -} - int inputJsonFilie(const char* file, json_object** obj) { const int input_size = 128; diff --git a/src/json_helper.hpp b/src/json_helper.hpp index 5333130..2f6b817 100644 --- a/src/json_helper.hpp +++ b/src/json_helper.hpp @@ -30,7 +30,6 @@ json_object *to_json(std::vector<uint32_t> const &v); namespace jh { const char* getStringFromJson(json_object* obj, const char* key); int getIntFromJson(json_object *obj, const char *key); -json_bool getBoolFromJson(json_object *obj, const char *key); int inputJsonFilie(const char* file, json_object** obj); } // namespace jh diff --git a/src/main.cpp b/src/main.cpp index e982337..6521c6c 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -195,6 +195,18 @@ static void cbRemoveClientCtxt(void *data) if (pSid) { auto sid = *pSid; + auto o_state = *g_afb_instance->wmgr.layers.get_layout_state(sid); + if (o_state != nullptr) + { + if (o_state->main == sid) + { + o_state->main = -1; + } + else if (o_state->sub == sid) + { + o_state->sub = -1; + } + } g_afb_instance->wmgr.id_alloc.remove_id(sid); g_afb_instance->wmgr.layers.remove_surface(sid); g_afb_instance->wmgr.controller->sprops.erase(sid); diff --git a/src/pm_wrapper.cpp b/src/pm_wrapper.cpp deleted file mode 100644 index 1454bf9..0000000 --- a/src/pm_wrapper.cpp +++ /dev/null @@ -1,261 +0,0 @@ -/* - * Copyright (c) 2018 TOYOTA MOTOR CORPORATION - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#include "pm_wrapper.hpp" -#include "json_helper.hpp" -#include "hmi-debug.h" - -namespace wm -{ - -static PMWrapper *g_context; - -namespace -{ - -static void onStateTransitioned(json_object *json_out) -{ - g_context->updateStates(json_out); -} - -static void onError(json_object *json_out) -{ - HMI_DEBUG("wm", "error message from PolicyManager:%s", - json_object_get_string(json_out)); - - g_context->processError(); -} - -} // namespace - -PMWrapper::PMWrapper() {} - -int PMWrapper::initialize() -{ - int ret = 0; - - ret = this->pm.initialize(); - if (0 > ret) - { - HMI_ERROR("wm:pmw", "Faild to initialize PolicyManager"); - } - - g_context = this; - - return ret; -} - -void PMWrapper::registerCallback(StateTransitionHandler on_state_transitioned, - ErrorHandler on_error) -{ - this->on_state_transitioned = on_state_transitioned; - this->on_error = on_error; - - PolicyManager::CallbackTable my_callback; - my_callback.onStateTransitioned = onStateTransitioned; - my_callback.onError = onError; - this->pm.registerCallback(my_callback); -} - -int PMWrapper::setInputEventData(Task task, std::string role, std::string area) -{ - const char* event; - if (Task::TASK_ALLOCATE == task) - { - event = "activate"; - } - else if (Task::TASK_RELEASE == task) - { - event = "deactivate"; - } - else - { - event = ""; - } - - json_object *json_in = json_object_new_object(); - json_object_object_add(json_in, "event", json_object_new_string(event)); - json_object_object_add(json_in, "role", json_object_new_string(role.c_str())); - json_object_object_add(json_in, "area", json_object_new_string(area.c_str())); - - int ret; - ret = this->pm.setInputEventData(json_in); - if (0 > ret) - { - HMI_ERROR("wm:pmw", "Faild to set input event data to PolicyManager"); - } - json_object_put(json_in); - - return ret; -} - -int PMWrapper::executeStateTransition() -{ - int ret; - ret = this->pm.executeStateTransition(); - if (0 > ret) - { - HMI_ERROR("wm:pmw", "Failed to execute state transition for PolicyManager"); - } - - return ret; -} - -void PMWrapper::undoState() -{ - this->pm.undoState(); - - this->crrlayer2rolestate = this->prvlayer2rolestate; -} - -void PMWrapper::updateStates(json_object *json_out) -{ - std::vector<WMAction> actions; - - HMI_DEBUG("wm", "json_out dump:%s", json_object_get_string(json_out)); - - this->createLayoutChangeAction(json_out, actions); - - this->on_state_transitioned(actions); -} - -void PMWrapper::createLayoutChangeAction(json_object *json_out, std::vector<WMAction> &actions) -{ - // Get displayed roles from previous layout - json_object *json_layers; - if (!json_object_object_get_ex(json_out, "layers", &json_layers)) - { - HMI_DEBUG("wm", "Not found key \"layers\""); - return; - } - - int len = json_object_array_length(json_layers); - HMI_DEBUG("wm", "json_layers len:%d", len); - - for (int i = 0; i < len; i++) - { - json_object *json_tmp = json_object_array_get_idx(json_layers, i); - - std::string layer_name = jh::getStringFromJson(json_tmp, "name"); - json_bool changed = jh::getBoolFromJson(json_tmp, "changed"); - HMI_DEBUG("wm", "layer:%s changed:%d", layer_name.c_str(), changed); - - if (changed) - { - json_object *json_areas; - if (!json_object_object_get_ex(json_tmp, "areas", &json_areas)) - { - HMI_DEBUG("wm", "Not found key \"areas\""); - return; - } - - int len = json_object_array_length(json_areas); - HMI_DEBUG("wm", "json_layers len:%d", len); - - // Store previous role state in this layer - this->prvlayer2rolestate[layer_name] = this->crrlayer2rolestate[layer_name]; - - RoleState crr_roles; - RoleState prv_roles = this->prvlayer2rolestate[layer_name]; - for (int j = 0; j < len; j++) - { - json_object *json_tmp2 = json_object_array_get_idx(json_areas, j); - - std::string area_name = jh::getStringFromJson(json_tmp2, "name"); - std::string role_name = jh::getStringFromJson(json_tmp2, "role"); - - crr_roles[role_name] = area_name; - - auto i_prv = prv_roles.find(role_name); - HMI_DEBUG("wm", "current role:%s area:%s", - role_name.c_str(), area_name.c_str()); - - // If current role does not exist in previous - if (prv_roles.end() == i_prv) - { - HMI_DEBUG("wm", "current role does not exist in previous"); - - // Set activate action - bool end_draw_finished = false; - WMAction act - { - "", - role_name, - area_name, - TaskVisible::VISIBLE, - end_draw_finished - }; - actions.push_back(act); - } - else - { - HMI_DEBUG("wm", "previous role:%s area:%s", - i_prv->first.c_str(), i_prv->second.c_str()); - - // If current role exists in previous and area is different with previous - if (area_name != i_prv->second) - { - HMI_DEBUG("wm", "current role exists in previous and area is different with previous"); - - // Set activate action - bool end_draw_finished = false; - WMAction act - { - "", - role_name, - area_name, - TaskVisible::VISIBLE, - end_draw_finished - }; - actions.push_back(act); - } - - // Remove role which exist in current list from previous list - prv_roles.erase(i_prv); - } - } - - // Deactivate roles which remains in previous list - // because these are not displayed in current layout - for (auto i_prv : prv_roles) - { - HMI_DEBUG("wm", "Deactivate role:%s", i_prv.first.c_str()); - - // Set deactivate action - bool end_draw_finished = true; - WMAction act - { - "", - i_prv.first, - "", - TaskVisible::INVISIBLE, - end_draw_finished - }; - actions.push_back(act); - } - - // Update previous role list - this->crrlayer2rolestate[layer_name] = crr_roles; - } - } -} - -void PMWrapper::processError() -{ - this->on_error(); -} - -} // namespace wm diff --git a/src/pm_wrapper.hpp b/src/pm_wrapper.hpp deleted file mode 100644 index 31ec002..0000000 --- a/src/pm_wrapper.hpp +++ /dev/null @@ -1,75 +0,0 @@ -/* - * Copyright (c) 2018 TOYOTA MOTOR CORPORATION - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#ifndef TMCAGLWM_PM_WRAPPER_HPP -#define TMCAGLWM_PM_WRAPPER_HPP - -#include <functional> -#include <vector> -#include <string> -#include <map> -#include "policy_manager.hpp" -#include "request.hpp" - -struct json_object; -struct sd_event; -struct sd_event_source; -struct StmState; - -namespace wm -{ - -class PMWrapper -{ - public: - explicit PMWrapper(); - ~PMWrapper() = default; - - using StateTransitionHandler = std::function<void(std::vector<WMAction>)>; - using ErrorHandler = std::function<void(void)>; - - int initialize(); - void registerCallback(StateTransitionHandler on_state_transitioned, - ErrorHandler on_error); - int setInputEventData(Task task, std::string role, std::string area); - int executeStateTransition(); - void undoState(); - - // Do not use these functions - void updateStates(json_object *json_out); - void processError(); - - private: - // Disable copy and move - PMWrapper(PMWrapper const &) = delete; - PMWrapper &operator=(PMWrapper const &) = delete; - PMWrapper(PMWrapper &&) = delete; - PMWrapper &operator=(PMWrapper &&) = delete; - - typedef std::map<std::string, std::string> RoleState; - - PolicyManager pm; - StateTransitionHandler on_state_transitioned; - ErrorHandler on_error; - std::map<std::string, RoleState> prvlayer2rolestate; - std::map<std::string, RoleState> crrlayer2rolestate; - - void createLayoutChangeAction(json_object *json_out, std::vector<WMAction> &actions); -}; - -} // namespace wm - -#endif // TMCAGLWM_PM_WRAPPER_HPP diff --git a/src/policy_manager/CMakeLists.txt b/src/policy_manager/CMakeLists.txt deleted file mode 100644 index 62e5ee9..0000000 --- a/src/policy_manager/CMakeLists.txt +++ /dev/null @@ -1,65 +0,0 @@ -# -# Copyright (c) 2017 TOYOTA MOTOR CORPORATION -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# - -include(FindPkgConfig) - -# We do not want a prefix for our module -set(CMAKE_SHARED_MODULE_PREFIX "") - -set(TARGETS_PM lib${PLUGIN_PM}) - -add_library(${TARGETS_PM} MODULE - policy_manager.cpp -) - -target_include_directories(${TARGETS_PM} - PRIVATE - ../../include - ../ - ./ - ./stm/${USE_STM_NAME}/src/include -) - -target_link_libraries(${TARGETS_PM} - PRIVATE - ${CMAKE_BINARY_DIR}/src/${PLUGIN_PM}/stm/${USE_STM_NAME}/src/libstm.so -) - -target_compile_definitions(${TARGETS_PM} - PRIVATE - _GNU_SOURCE -) - -target_compile_options(${TARGETS_PM} - PRIVATE - -Wall -Wextra -Wno-unused-parameter -Wno-comment) - -set_target_properties(${TARGETS_PM} - PROPERTIES - CXX_EXTENSIONS OFF - CXX_STANDARD 14 - CXX_STANDARD_REQUIRED ON - - C_EXTENSIONS OFF - C_STANDARD 99 - C_STANDARD_REQUIRED ON -) - -install( - TARGETS ${TARGET_PM} - DESTINATION ${CMAKE_INSTALL_LIBDIR} - COMPONENT "runtime" -) diff --git a/src/policy_manager/db/layouts.db b/src/policy_manager/db/layouts.db deleted file mode 100644 index da78b31..0000000 --- a/src/policy_manager/db/layouts.db +++ /dev/null @@ -1,152 +0,0 @@ -{ - "layouts": [ - { - "name": "homescreen", - "layer": "far_homescreen", - "areas": [ - { - "name": "fullscreen", - "category": "homescreen" - } - ] - }, - { - "name": "map.normal", - "layer": "apps", - "areas": [ - { - "name": "normal.full", - "category": "map" - } - ] - }, - { - "name": "map.split", - "layer": "apps", - "areas": [ - { - "name": "split.main", - "category": "map" - }, - { - "name": "split.sub", - "category": "splitable" - } - ] - }, - { - "name": "map.fullscreen", - "layer": "apps", - "areas": [ - { - "name": "fullscreen", - "category": "map" - } - ] - }, - { - "name": "splitable.normal", - "layer": "apps", - "areas": [ - { - "name": "normal.full", - "category": "splitable" - } - ] - }, - { - "name": "splitable.split", - "layer": "apps", - "areas": [ - { - "name": "split.main", - "category": "splitable" - }, - { - "name": "split.sub", - "category": "splitable" - } - ] - }, - { - "name": "general.normal", - "layer": "apps", - "areas": [ - { - "name": "normal.full", - "category": "general" - } - ] - }, - { - "name": "system.normal", - "layer": "apps", - "areas": [ - { - "name": "normal.full", - "category": "system" - } - ] - }, - { - "name": "software_keyboard", - "layer": "near_homescreen", - "areas": [ - { - "name": "software_keyboard", - "category": "software_keyboard" - } - ] - }, - { - "name": "restriction.normal", - "layer": "restriction", - "areas": [ - { - "name": "restriction.normal", - "category": "restriction" - } - ] - }, - { - "name": "restriction.split.main", - "layer": "restriction", - "areas": [ - { - "name": "restriction.split.main", - "category": "restriction" - } - ] - }, - { - "name": "restriction.split.sub", - "layer": "restriction", - "areas": [ - { - "name": "restriction.split.sub", - "category": "restriction" - } - ] - }, - { - "name": "pop_up", - "layer": "on_screen", - "areas": [ - { - "name": "on_screen", - "category": "pop_up" - } - ] - }, - { - "name": "system_alert", - "layer": "on_screen", - "areas": [ - { - "name": "on_screen", - "category": "system_alert" - } - ] - } - ] -} diff --git a/src/policy_manager/db/roles.db b/src/policy_manager/db/roles.db deleted file mode 100644 index d0d911a..0000000 --- a/src/policy_manager/db/roles.db +++ /dev/null @@ -1,44 +0,0 @@ -{ - "roles":[ - { - "category": "homescreen", - "role": "homescreen", - "area": "fullscreen", - }, - { - "category": "map", - "role": "map", - "area": "normal.full | split.main", - }, - { - "category": "general", - "role": "launcher | poi | browser | sdl | mixer | radio | hvac | debug | phone | video | music | fallback", - "area": "normal.full", - }, - { - "category": "system", - "role": "settings | dashboard", - "area": "normal.full", - }, - { - "category": "software_keyboard", - "role": "software_keyboard", - "area": "software_keyboard", - }, - { - "category": "restriction", - "role": "restriction", - "area": "restriction.normal | restriction.split.main | restriction.split.sub", - }, - { - "category": "pop_up", - "role": "on_screen | on_screen_phone", - "area": "on_screen", - }, - { - "category": "system_alert", - "role": "system_alert", - "area": "on_screen", - } - ] -} diff --git a/src/policy_manager/db/roles.db.split b/src/policy_manager/db/roles.db.split deleted file mode 100644 index 2776ce5..0000000 --- a/src/policy_manager/db/roles.db.split +++ /dev/null @@ -1,51 +0,0 @@ -{ - "roles":[ - { - "category": "homescreen", - "role": "homescreen", - "area": "fullscreen", - }, - { - "category": "map", - "role": "map", - "area": "normal.full | split.main", - }, - { - "category": "general", - "role": "launcher | poi | browser | sdl | mixer | radio | hvac | debug | phone | fallback", - "area": "normal.full", - "description": "For split test, video and music are moved to category:splitable", - }, - { - "category": "system", - "role": "settings | dashboard", - "area": "normal.full", - }, - { - "category": "splitable", - "role": "video | music", - "area": "normal.full | split.main | split.sub", - "description": "For split test, video and music are included here", - }, - { - "category": "software_keyboard", - "role": "software_keyboard", - "area": "software_keyboard", - }, - { - "category": "restriction", - "role": "restriction", - "area": "restriction.normal | restriction.split.main | restriction.split.sub", - }, - { - "category": "pop_up", - "role": "on_screen | on_screen_phone", - "area": "on_screen", - }, - { - "category": "system_alert", - "role": "system_alert", - "area": "on_screen", - } - ] -} diff --git a/src/policy_manager/policy_manager.cpp b/src/policy_manager/policy_manager.cpp deleted file mode 100644 index f994281..0000000 --- a/src/policy_manager/policy_manager.cpp +++ /dev/null @@ -1,1341 +0,0 @@ -/* - * Copyright (c) 2018 TOYOTA MOTOR CORPORATION - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#include <fstream> -#include <sstream> -#include <istream> -#include <thread> -#include <map> -#include <algorithm> -#include <systemd/sd-event.h> -#include <json-c/json.h> -#include "policy_manager.hpp" -#include "hmi-debug.h" - -extern "C" -{ -#define AFB_BINDING_VERSION 2 -#include <afb/afb-binding.h> -#include "stm.h" -} - -namespace pm -{ -static PolicyManager *g_context; - -static int transitionStateWrapper(sd_event_source *source, void *data) -{ - int ret = g_context->transitionState(source, data); - return ret; -} - -static int timerEventWrapper(sd_event_source *source, uint64_t usec, void *data) -{ - int ret = g_context->timerEvent(source, usec, data); - return ret; -} - -} // namespace pm - -PolicyManager::PolicyManager() - : eventname2no(), - categoryname2no(), - areaname2no(), - role2category(), - category2role(), - role2defaultarea() -{} - -int PolicyManager::initialize() -{ - int ret = 0; - - // Create convert map - for (int i = StmEvtNoMin; i <= StmEvtNoMax; i++) - { - HMI_DEBUG("wm:pm", "event name:%s no:%d", kStmEventName[i], i); - this->eventname2no[kStmEventName[i]] = i; - } - - for (int i = StmCtgNoMin; i <= StmCtgNoMax; i++) - { - HMI_DEBUG("wm:pm", "category name:%s no:%d", kStmCategoryName[i], i); - this->categoryname2no[kStmCategoryName[i]] = i; - } - - for (int i = StmAreaNoMin; i <= StmAreaNoMax; i++) - { - HMI_DEBUG("wm:pm", "area name:%s no:%d", kStmAreaName[i], i); - this->areaname2no[kStmAreaName[i]] = i; - } - - // Load roles.db - ret = this->loadRoleDb(); - if (0 > ret) - { - HMI_ERROR("wm:pm", "Load roles.db Error!!"); - return ret; - } - - // Load layouts.db - ret = this->loadLayoutDb(); - if (0 > ret) - { - HMI_ERROR("wm:pm", "Load layouts.db Error!!"); - return ret; - } - - // Initialize state which is managed by PolicyManager - this->initializeState(); - - // Initialize StateTransitioner - stmInitialize(); - - // Store instance - pm::g_context = this; - - return ret; -} - -void PolicyManager::registerCallback(CallbackTable callback) -{ - this->callback.onStateTransitioned = callback.onStateTransitioned; - this->callback.onError = callback.onError; -} - -int PolicyManager::setInputEventData(json_object *json_in) -{ - // Check arguments - if (nullptr == json_in) - { - HMI_ERROR("wm:pm", "Argument is NULL!!"); - return -1; - } - - // Get event from json_object - const char *event = this->getStringFromJson(json_in, "event"); - int event_no = StmEvtNoNone; - if (nullptr != event) - { - // Convert name to number - auto itr = this->eventname2no.find(event); - if (this->eventname2no.end() != itr) - { - event_no = this->eventname2no[event]; - HMI_DEBUG("wm:pm", "event(%s:%d)", event, event_no); - } - else - { - HMI_ERROR("wm:pm", "Invalid event name!!"); - return -1; - } - } - else - { - HMI_ERROR("wm:pm", "Event is not set!!"); - return -1; - } - - // Get role from json_object - const char *role = this->getStringFromJson(json_in, "role"); - int category_no = StmCtgNoNone; - if (nullptr != role) - { - HMI_DEBUG("wm:pm", "role(%s)", role); - - // Convert role to category - std::string category = ""; - auto itr = this->role2category.find(role); - if (this->role2category.end() != itr) - { - category = this->role2category[role]; - } - else - { - itr = this->role2category.find("fallback"); - if (this->role2category.end() != itr) - { - HMI_DEBUG("wm:pm", "Role:%s is not registered in roles.db, fallback as normal app", role); - category = this->role2category["fallback"]; - } - } - - if ("" != category) - { - // Convert name to number - category_no = categoryname2no[category]; - HMI_DEBUG("wm:pm", "category(%s:%d)", category.c_str(), category_no); - } - } - - if (StmCtgNoNone == category_no) - { - role = ""; - } - - // Get areat from json_object - const char *area = this->getStringFromJson(json_in, "area"); - int area_no = StmAreaNoNone; - if (nullptr != area) - { - auto itr = this->areaname2no.find(area); - if (this->areaname2no.end() != itr) - { - area_no = this->areaname2no[area]; - HMI_DEBUG("wm:pm", "area(%s:%d)", area, area_no); - } - } - - // If role is set and area is not set, use default area - if ((StmAreaNoNone == area_no) && (StmCtgNoNone != category_no)) - { - std::string def_area = this->role2defaultarea[role]; - area_no = this->areaname2no[def_area]; - HMI_DEBUG("wm:pm", "area(%s:%d)", def_area.c_str(), area_no); - } - - // Set event info to the queue - EventInfo event_info; - int event_id = STM_CREATE_EVENT_ID(event_no, category_no, area_no); - event_info.event = event_id; - event_info.role = std::string(role); - event_info.delay = 0; - this->event_info_queue.push(event_info); - - return 0; -} - -int PolicyManager::executeStateTransition() -{ - int ret; - EventInfo event_info; - - while (!this->event_info_queue.empty()) - { - // Get event info from queue and delete - event_info = this->event_info_queue.front(); - this->event_info_queue.pop(); - - // Set event info for checking policy - ret = this->setStateTransitionProcessToSystemd(event_info.event, event_info.delay, event_info.role); - } - return ret; -} - -void PolicyManager::undoState() -{ - HMI_DEBUG("wm:pm", "Undo State !!!"); - - // Undo state of STM - stmUndoState(); - - HMI_DEBUG("wm:pm", ">>>>>>>>>> BEFORE UNDO"); - this->dumpLayerState(this->crr_layers); - - this->crr_layers = this->prv_layers; - - HMI_DEBUG("wm:pm", ">>>>>>>>>> AFTER UNDO"); - this->dumpLayerState(this->crr_layers); -} - -void PolicyManager::initializeState() -{ - this->initializeLayerState(); -} - -void PolicyManager::initializeLayerState() -{ - AreaState init_area; - LayoutState init_layout; - init_area.name = kStmAreaName[StmAreaNoNone]; - init_area.category = kStmCategoryName[StmCtgNoNone]; - init_area.role = ""; - init_layout.name = kStmLayoutName[StmLayoutNoNone]; - init_layout.area_list.push_back(init_area); - - for (int i = StmLayerNoMin; i <= StmLayerNoMax; i++) - { - const char *layer_name = kStmLayerName[i]; - this->crr_layers[layer_name].name = layer_name; - this->crr_layers[layer_name].layout_state = init_layout; - this->crr_layers[layer_name].changed = false; - } - - this->prv_layers = this->crr_layers; -} - -void PolicyManager::addStateToJson(const char *name, bool changed, - std::string state, json_object **json_out) -{ - if ((nullptr == name) || (nullptr == json_out)) - { - HMI_ERROR("wm:pm", "Invalid argument!!!"); - return; - } - - json_object_object_add(*json_out, "name", json_object_new_string(name)); - json_object_object_add(*json_out, "state", json_object_new_string(state.c_str())); - json_object_object_add(*json_out, "changed", json_object_new_boolean(changed)); -} - -void PolicyManager::addStateToJson(const char *layer_name, bool changed, - AreaList area_list, json_object **json_out) -{ - if ((nullptr == layer_name) || (nullptr == json_out)) - { - HMI_ERROR("wm:pm", "Invalid argument!!!"); - return; - } - - json_object *json_areas = json_object_new_array(); - json_object *json_tmp; - for (const auto &as : area_list) - { - json_tmp = json_object_new_object(); - json_object_object_add(json_tmp, "name", json_object_new_string(as.name.c_str())); - json_object_object_add(json_tmp, "role", json_object_new_string(as.role.c_str())); - json_object_array_add(json_areas, json_tmp); - } - - json_object_object_add(*json_out, "name", json_object_new_string(layer_name)); - json_object_object_add(*json_out, "changed", json_object_new_boolean(changed)); - json_object_object_add(*json_out, "areas", json_areas); -} - -void PolicyManager::updateState(int event_id, StmState crr_state) -{ - this->updateLayerState(event_id, crr_state); -} - -void PolicyManager::updateLayerState(int event_id, StmState crr_state) -{ - int event_no, category_no, area_no; - - for (int layer_no = StmLayerNoMin; - layer_no <= StmLayerNoMax; layer_no++) - { - HMI_DEBUG("wm:pm", ">>> LAYER:%s CHANGED:%d LAYOUT:%s", - kStmLayerName[layer_no], crr_state.layer[layer_no].changed, - kStmLayoutName[crr_state.layer[layer_no].state]); - } - - event_no = STM_GET_EVENT_FROM_ID(event_id); - category_no = STM_GET_CATEGORY_FROM_ID(event_id); - area_no = STM_GET_AREA_FROM_ID(event_id); - - std::string req_evt = kStmEventName[event_no]; - std::string req_ctg = kStmCategoryName[category_no]; - std::string req_area = kStmAreaName[area_no]; - std::string req_role = this->req_role_list[event_id]; - - // Store previous layers - this->prv_layers = this->crr_layers; - - // Update layers - for (int layer_no = StmLayerNoMin; - layer_no <= StmLayerNoMax; layer_no++) - { - const char *layer_name = kStmLayerName[layer_no]; - - // This layer is changed? - int changed = crr_state.layer[layer_no].changed; - if (changed) - { - HMI_DEBUG("wm:pm", ">>>>>>>>>> Update layer:%s", layer_name); - - // Get previous layout name of this layer - LayoutState prv_layout_state = this->prv_layers[layer_name].layout_state; - std::string prv_layout_name = prv_layout_state.name; - - // Get current layout name of this layer - int crr_layout_state_no = crr_state.layer[layer_no].state; - std::string crr_layout_name = std::string(kStmLayoutName[crr_layout_state_no]); - - LayoutState crr_layout_state; - if ((prv_layout_name == crr_layout_name) && - (kStmAreaName[StmAreaNoNone] == crr_layout_name)) - { - // Copy previous layout state for current - crr_layout_state = prv_layout_state; - changed = 0; - } - else - { - // Copy previous layout state for current - crr_layout_state = prv_layout_state; - - HMI_DEBUG("wm:pm", "-- layout name previous:%s current:%s", - prv_layout_name.c_str(), crr_layout_name.c_str()); - if (prv_layout_name == crr_layout_name) - { - HMI_DEBUG("wm:pm", "---- Previous layout is same with current"); - } - else - { - // If previous layout is NOT same with current, - // current areas is set with default value - HMI_DEBUG("wm:pm", "---- Previous layout is NOT same with current"); - crr_layout_state.name = this->default_layouts[crr_layout_name].name; - crr_layout_state.category_num = this->default_layouts[crr_layout_name].category_num; - crr_layout_state.area_list = this->default_layouts[crr_layout_name].area_list; - } - - // Create candidate list - std::map<std::string, AreaList> cand_list; - for (int ctg_no = StmCtgNoMin; - ctg_no <= StmCtgNoMax; ctg_no++) - { - if (ctg_no == StmCtgNoNone) - { - continue; - } - - const char *ctg = kStmCategoryName[ctg_no]; - HMI_DEBUG("wm:pm", "-- Create candidate list for ctg:%s", ctg); - - AreaList tmp_cand_list; - int candidate_num = 0; - int blank_num = crr_layout_state.category_num[ctg]; - - // If requested event is "activate" - // and there are requested category and area, - // update area with requested role in current layout. - bool request_for_this_layer = false; - std::string used_role = ""; - if ((ctg == req_ctg) && ("activate" == req_evt)) - { - HMI_DEBUG("wm:pm", "---- Requested event is activate"); - for (AreaState &as : crr_layout_state.area_list) - { - if (as.category == req_ctg) - { - request_for_this_layer = true; - - if (as.name == req_area) - { - as.role = req_role; - used_role = req_role; - blank_num--; - HMI_DEBUG("wm:pm", "------ Update current layout: area:%s category:%s role:%s", - as.name.c_str(), as.category.c_str(), as.role.c_str()); - break; - } - } - } - } - - // Create candidate list for category from the previous displayed categories - for (AreaState area_state : prv_layout_state.area_list) - { - if ((std::string(ctg) == area_state.category) && - (used_role != area_state.role)) - { - // If there is the category - // which is same with new category and not used for updating yet, - // push it to list - HMI_DEBUG("wm:pm", "---- Push previous(category:%s role:%s) to candidate list", - area_state.category.c_str(), area_state.role.c_str()); - tmp_cand_list.push_back(area_state); - candidate_num++; - } - } - - // If NOT updated by requested area: - // there is not requested area in new layout, - // so push requested role to candidate list - if (request_for_this_layer && ("" == used_role)) - { - HMI_DEBUG("wm:pm", "---- Push request(area:%s category:%s role:%s) to candidate list", - req_area.c_str(), req_ctg.c_str(), req_role.c_str()); - AreaState area_state; - area_state.name = req_area; - area_state.category = req_ctg; - area_state.role = req_role; - tmp_cand_list.push_back(area_state); - candidate_num++; - } - - HMI_DEBUG("wm:pm", "---- blank_num:%d candidate_num:%d", blank_num, candidate_num); - - // Compare number of candidate/blank, - // And remove role in order of the oldest as necessary - if (candidate_num < blank_num) - { - // Refer history stack - // and add to the top of tmp_cand_list in order to the newest - while (candidate_num != blank_num) - { - AreaState area_state; - area_state.name = kStmAreaName[StmAreaNoNone]; - area_state.category = ctg; - area_state.role = this->popRoleHistory(ctg); - if ("" == area_state.role) - { - HMI_ERROR("wm:pm", "There is no role in history stack!!"); - } - tmp_cand_list.push_back(area_state); - HMI_DEBUG("wm:pm", "------ Add role:%s to candidate list", - area_state.role.c_str()); - candidate_num++; - } - } - else if (candidate_num > blank_num) - { - // Remove the oldest role from candidate list - while (candidate_num != blank_num) - { - std::string removed_role = tmp_cand_list.begin()->role; - HMI_DEBUG("wm:pm", "------ Remove the oldest role:%s from candidate list", - removed_role.c_str()); - tmp_cand_list.erase(tmp_cand_list.begin()); - candidate_num--; - - // Push removed data to history stack - this->pushRoleHistory(ctg, removed_role); - - // Remove from current layout - for (AreaState &as : crr_layout_state.area_list) - { - if (as.role == removed_role) - { - as.role = ""; - } - } - } - } - else - { // (candidate_num == blank_num) - // nop - } - - cand_list[ctg] = tmp_cand_list; - } - - // Update areas - HMI_DEBUG("wm:pm", "-- Update areas by using candidate list"); - for (AreaState &as : crr_layout_state.area_list) - { - HMI_DEBUG("wm:pm", "---- Check area:%s category:%s role:%s", - as.name.c_str(), as.category.c_str(), as.role.c_str()); - if ("" == as.role) - { - HMI_DEBUG("wm:pm", "------ Update this area with role:%s", - cand_list[as.category].begin()->role.c_str()); - as.role = cand_list[as.category].begin()->role; - cand_list[as.category].erase(cand_list[as.category].begin()); - } - } - } - // Update current layout of this layer - this->crr_layers[layer_name].layout_state = crr_layout_state; - } - // Update changed flag - this->crr_layers[layer_name].changed = (changed) ? true : false; - } - - // Erase role for the event_id from list - this->req_role_list.erase(event_id); - - HMI_DEBUG("wm:pm", ">>>>>>>>>> DUMP LAYERS (BEFORE)"); - this->dumpLayerState(this->prv_layers); - - HMI_DEBUG("wm:pm", ">>>>>>>>>> DUMP LAYERS (AFTER)"); - this->dumpLayerState(this->crr_layers); - - this->dumpRoleHistory(); -} - -void PolicyManager::createOutputInformation(StmState crr_state, json_object **json_out) -{ - json_object *json_tmp; - - // Create layout information - // - // "layers": [ - // { - // "homescreen": { - // "changed": <bool>, - // "areas": [ - // { - // "name":<const char*>, - // "role":<const char*> - // }. - // ... - // ] - // } - // }, - // ... - json_object *json_layer = json_object_new_array(); - const char *layer_name; - for (int layer_no = StmLayerNoMin; - layer_no <= StmLayerNoMax; layer_no++) - { - layer_name = kStmLayerName[layer_no]; - json_tmp = json_object_new_object(); - this->addStateToJson(layer_name, - this->crr_layers[layer_name].changed, - this->crr_layers[layer_name].layout_state.area_list, - &json_tmp); - json_object_array_add(json_layer, json_tmp); - } - json_object_object_add(*json_out, "layers", json_layer); -} - -int PolicyManager::transitionState(sd_event_source *source, void *data) -{ - HMI_DEBUG("wm:pm", ">>>>>>>>>> START STATE TRANSITION"); - - int event_id = *((int *)data); - - int event_no, category_no, area_no; - event_no = STM_GET_EVENT_FROM_ID(event_id); - category_no = STM_GET_CATEGORY_FROM_ID(event_id); - area_no = STM_GET_AREA_FROM_ID(event_id); - HMI_DEBUG("wm:pm", ">>>>>>>>>> EVENT:%s CATEGORY:%s AREA:%s", - kStmEventName[event_no], - kStmCategoryName[category_no], - kStmAreaName[area_no]); - - // Transition state - StmState crr_state; - int ret = stmTransitionState(event_id, &crr_state); - if (0 > ret) - { - HMI_ERROR("wm:pm", "Failed transition state"); - if (nullptr != this->callback.onError) - { - json_object *json_out = json_object_new_object(); - json_object_object_add(json_out, "message", - json_object_new_string("Failed to transition state")); - json_object_object_add(json_out, "event", - json_object_new_string(kStmEventName[event_no])); - json_object_object_add(json_out, "role", - json_object_new_string(this->req_role_list[event_id].c_str())); - json_object_object_add(json_out, "area", - json_object_new_string(kStmAreaName[area_no])); - this->callback.onError(json_out); - json_object_put(json_out); - } - return -1; - } - - // Update state which is managed by PolicyManager - this->updateState(event_id, crr_state); - - // Create output information for ResourceManager - json_object *json_out = json_object_new_object(); - this->createOutputInformation(crr_state, &json_out); - - // Notify changed state - if (nullptr != this->callback.onStateTransitioned) - { - this->callback.onStateTransitioned(json_out); - } - - // Release json_object - json_object_put(json_out); - - // Release data - delete (int *)data; - - // Destroy sd_event_source object - sd_event_source_unref(source); - - // Remove event source from list - if (this->event_source_list.find(event_id) != this->event_source_list.end()) - { - this->event_source_list.erase(event_id); - } - - HMI_DEBUG("wm:pm", ">>>>>>>>>> FINISH STATE TRANSITION"); - return 0; -} - -int PolicyManager::timerEvent(sd_event_source *source, uint64_t usec, void *data) -{ - HMI_DEBUG("wm:pm", "Call"); - - int ret = this->transitionState(source, data); - return ret; -} - -int PolicyManager::setStateTransitionProcessToSystemd(int event_id, uint64_t delay_ms, std::string role) -{ - HMI_DEBUG("wm:pm", "event_id:0x%x delay:%d role:%s", event_id, delay_ms, role.c_str()); - - // Store requested role - this->req_role_list[event_id] = role; - - if (0 == delay_ms) - { - int ret = sd_event_add_defer(afb_daemon_get_event_loop(), NULL, - &pm::transitionStateWrapper, new int(event_id)); - if (0 > ret) - { - HMI_ERROR("wm:pm", "Faild to sd_event_add_defer: errno:%d", ret); - this->req_role_list.erase(event_id); - return -1; - } - } - else - { - // Get current time - struct timespec time_spec; - clock_gettime(CLOCK_MONOTONIC, &time_spec); - - // Calculate timer fired time - uint64_t usec = (time_spec.tv_sec * 1000000) + (time_spec.tv_nsec / 1000) + (delay_ms * 1000); - - // Set timer - struct sd_event_source *event_source; - int ret = sd_event_add_time(afb_daemon_get_event_loop(), &event_source, - CLOCK_MONOTONIC, usec, 1, - &pm::timerEventWrapper, new int(event_id)); - if (0 > ret) - { - HMI_ERROR("wm:pm", "Faild to sd_event_add_time: errno:%d", ret); - this->req_role_list.erase(event_id); - return -1; - } - - // Store event source - this->event_source_list[event_id] = event_source; - } - - return 0; -} - -int PolicyManager::loadRoleDb() -{ - std::string file_name; - - // Get afm application installed dir - char const *afm_app_install_dir = getenv("AFM_APP_INSTALL_DIR"); - HMI_DEBUG("wm:pm", "afm_app_install_dir:%s", afm_app_install_dir); - - if (!afm_app_install_dir) - { - HMI_ERROR("wm:pm", "AFM_APP_INSTALL_DIR is not defined"); - } - else - { - file_name = std::string(afm_app_install_dir) + std::string("/etc/roles.db"); - } - - // Load roles.db - json_object *json_obj; - int ret = this->inputJsonFilie(file_name.c_str(), &json_obj); - if (0 > ret) - { - HMI_ERROR("wm:pm", "Could not open roles.db, so use default role information"); - json_obj = json_tokener_parse(kDefaultRoleDb); - } - HMI_DEBUG("wm:pm", "json_obj dump:%s", json_object_get_string(json_obj)); - - json_object *json_roles; - if (!json_object_object_get_ex(json_obj, "roles", &json_roles)) - { - HMI_ERROR("wm:pm", "Parse Error!!"); - return -1; - } - - int len = json_object_array_length(json_roles); - HMI_DEBUG("wm:pm", "json_cfg len:%d", len); - HMI_DEBUG("wm:pm", "json_cfg dump:%s", json_object_get_string(json_roles)); - - json_object *json_tmp; - const char *category; - const char *roles; - const char *areas; - for (int i = 0; i < len; i++) - { - json_tmp = json_object_array_get_idx(json_roles, i); - - category = this->getStringFromJson(json_tmp, "category"); - roles = this->getStringFromJson(json_tmp, "role"); - areas = this->getStringFromJson(json_tmp, "area"); - - if ((nullptr == category) || (nullptr == roles) || (nullptr == areas)) - { - HMI_ERROR("wm:pm", "Parse Error!!"); - return -1; - } - - // Parse roles by '|' - std::vector<std::string> vct_roles; - vct_roles = this->parseString(std::string(roles), '|'); - - // Parse areas by '|' - std::vector<std::string> vct_areas; - vct_areas = this->parseString(std::string(areas), '|'); - - // Set role, category, default area - for (auto itr = vct_roles.begin(); itr != vct_roles.end(); ++itr) - { - // Delete space from role and area name - std::string role = this->deleteSpace(*itr); - std::string area = this->deleteSpace(vct_areas[0]); - - this->role2category[role] = std::string(category); - this->role2defaultarea[role] = area; - } - - this->category2role[std::string(category)] = std::string(roles); - } - - // Check - HMI_DEBUG("wm:pm", "Check role2category"); - for (const auto &x : this->role2category) - { - HMI_DEBUG("wm:pm", "key:%s, val:%s", x.first.c_str(), x.second.c_str()); - } - - HMI_DEBUG("wm:pm", "Check role2defaultarea"); - for (const auto &x : this->role2defaultarea) - { - HMI_DEBUG("wm:pm", "key:%s, val:%s", x.first.c_str(), x.second.c_str()); - } - - HMI_DEBUG("wm:pm", "Check category2role"); - for (const auto &x : this->category2role) - { - HMI_DEBUG("wm:pm", "key:%s, val:%s", x.first.c_str(), x.second.c_str()); - } - - return 0; -} - -int PolicyManager::loadLayoutDb() -{ - HMI_DEBUG("wm:pm", "Call"); - - // Get afm application installed dir - char const *afm_app_install_dir = getenv("AFM_APP_INSTALL_DIR"); - HMI_DEBUG("wm:pm", "afm_app_install_dir:%s", afm_app_install_dir); - - std::string file_name; - if (!afm_app_install_dir) - { - HMI_ERROR("wm:pm", "AFM_APP_INSTALL_DIR is not defined"); - } - else - { - file_name = std::string(afm_app_install_dir) + std::string("/etc/layouts.db"); - } - - // Load layouts.db - json_object *json_obj; - int ret = this->inputJsonFilie(file_name.c_str(), &json_obj); - if (0 > ret) - { - HMI_DEBUG("wm:pm", "Could not open layouts.db, so use default layout information"); - json_obj = json_tokener_parse(kDefaultLayoutDb); - } - HMI_DEBUG("wm:pm", "json_obj dump:%s", json_object_get_string(json_obj)); - - // Perse layouts - HMI_DEBUG("wm:pm", "Perse layouts"); - json_object *json_cfg; - if (!json_object_object_get_ex(json_obj, "layouts", &json_cfg)) - { - HMI_ERROR("wm:pm", "Parse Error!!"); - return -1; - } - - int len = json_object_array_length(json_cfg); - HMI_DEBUG("wm:pm", "json_cfg len:%d", len); - HMI_DEBUG("wm:pm", "json_cfg dump:%s", json_object_get_string(json_cfg)); - - const char *layout; - const char *role; - const char *category; - for (int i = 0; i < len; i++) - { - json_object *json_tmp = json_object_array_get_idx(json_cfg, i); - - layout = this->getStringFromJson(json_tmp, "name"); - if (nullptr == layout) - { - HMI_ERROR("wm:pm", "Parse Error!!"); - return -1; - } - HMI_DEBUG("wm:pm", "> layout:%s", layout); - - json_object *json_area_array; - if (!json_object_object_get_ex(json_tmp, "areas", &json_area_array)) - { - HMI_ERROR("wm:pm", "Parse Error!!"); - return -1; - } - - int len_area = json_object_array_length(json_area_array); - HMI_DEBUG("wm:pm", "json_area_array len:%d", len_area); - HMI_DEBUG("wm:pm", "json_area_array dump:%s", json_object_get_string(json_area_array)); - - LayoutState layout_state; - AreaState area_state; - std::map<std::string, int> category_num; - for (int ctg_no = StmCtgNoMin; - ctg_no <= StmCtgNoMax; ctg_no++) - { - const char *ctg_name = kStmCategoryName[ctg_no]; - category_num[ctg_name] = 0; - } - - for (int j = 0; j < len_area; j++) - { - json_object *json_area = json_object_array_get_idx(json_area_array, j); - - // Get area name - const char *area = this->getStringFromJson(json_area, "name"); - if (nullptr == area) - { - HMI_ERROR("wm:pm", "Parse Error!!"); - return -1; - } - area_state.name = std::string(area); - HMI_DEBUG("wm:pm", ">> area:%s", area); - - // Get app attribute of the area - category = this->getStringFromJson(json_area, "category"); - if (nullptr == category) - { - HMI_ERROR("wm:pm", "Parse Error!!"); - return -1; - } - area_state.category = std::string(category); - category_num[category]++; - HMI_DEBUG("wm:pm", ">>> category:%s", category); - - role = this->getStringFromJson(json_area, "role"); - if (nullptr != role) - { - // Role is NOT essential here - area_state.role = std::string(role); - } - else - { - area_state.role = std::string(""); - } - HMI_DEBUG("wm:pm", ">>> role:%s", role); - - layout_state.area_list.push_back(area_state); - } - - layout_state.name = layout; - layout_state.category_num = category_num; - this->default_layouts[layout] = layout_state; - } - - // initialize for none layout - LayoutState none_layout_state; - memset(&none_layout_state, 0, sizeof(none_layout_state)); - none_layout_state.name = "none"; - this->default_layouts["none"] = none_layout_state; - - // Check - for (auto itr_layout = this->default_layouts.begin(); - itr_layout != this->default_layouts.end(); ++itr_layout) - { - HMI_DEBUG("wm:pm", ">>> layout:%s", itr_layout->first.c_str()); - - for (auto itr_area = itr_layout->second.area_list.begin(); - itr_area != itr_layout->second.area_list.end(); ++itr_area) - { - HMI_DEBUG("wm:pm", ">>> >>> area :%s", itr_area->name.c_str()); - HMI_DEBUG("wm:pm", ">>> >>> category:%s", itr_area->category.c_str()); - HMI_DEBUG("wm:pm", ">>> >>> role :%s", itr_area->role.c_str()); - } - } - - // Release json_object - json_object_put(json_obj); - - return 0; -} - -static const int kHistoryNum = 5; -void PolicyManager::pushRoleHistory(std::string category, std::string role) -{ - auto i = std::remove_if(this->role_history[category].begin(), - this->role_history[category].end(), - [role](std::string x) { return (role == x); }); - - if (this->role_history[category].end() != i) - { - this->role_history[category].erase(i); - } - - this->role_history[category].push_back(role); - - if (kHistoryNum < role_history[category].size()) - { - this->role_history[category].erase( - this->role_history[category].begin()); - } -} - -std::string PolicyManager::popRoleHistory(std::string category) -{ - std::string role; - if (role_history[category].empty()) - { - role = ""; - } - else - { - role = this->role_history[category].back(); - this->role_history[category].pop_back(); - } - return role; -} - -const char *PolicyManager::getStringFromJson(json_object *obj, const char *key) -{ - json_object *tmp; - if (!json_object_object_get_ex(obj, key, &tmp)) - { - HMI_DEBUG("wm:pm", "Not found key \"%s\"", key); - return nullptr; - } - - return json_object_get_string(tmp); -} - -int PolicyManager::inputJsonFilie(const char *file, json_object **obj) -{ - const int input_size = 128; - int ret = -1; - - HMI_DEBUG("wm:pm", "Input file: %s", file); - - // Open json file - FILE *fp = fopen(file, "rb"); - if (nullptr == fp) - { - HMI_ERROR("wm:pm", "Could not open file"); - return ret; - } - - // Parse file data - struct json_tokener *tokener = json_tokener_new(); - enum json_tokener_error json_error; - char buffer[input_size]; - int block_cnt = 1; - while (1) - { - size_t len = fread(buffer, sizeof(char), input_size, fp); - *obj = json_tokener_parse_ex(tokener, buffer, len); - if (nullptr != *obj) - { - HMI_DEBUG("wm:pm", "File input is success"); - ret = 0; - break; - } - - json_error = json_tokener_get_error(tokener); - if ((json_tokener_continue != json_error) || (input_size > len)) - { - HMI_ERROR("wm:pm", "Failed to parse file (byte:%d err:%s)", - (input_size * block_cnt), json_tokener_error_desc(json_error)); - HMI_ERROR("wm:pm", "\n%s", buffer); - *obj = nullptr; - break; - } - block_cnt++; - } - - // Close json file - fclose(fp); - - // Free json_tokener - json_tokener_free(tokener); - - return ret; -} - -void PolicyManager::dumpLayerState(std::unordered_map<std::string, LayerState> &layers) -{ - HMI_DEBUG("wm:pm", "-------------------------------------------------------------------------------------------------------"); - HMI_DEBUG("wm:pm", "|%-15s|%s|%-20s|%-20s|%-20s|%-20s|", - "LAYER", "C", "LAYOUT", "AREA", "CATEGORY", "ROLE"); - for (const auto &itr : layers) - { - LayerState ls = itr.second; - const char* layer = ls.name.c_str(); - const char* changed = (ls.changed) ? "T" : "f"; - const char* layout = ls.layout_state.name.c_str(); - bool first = true; - for (const auto &as : ls.layout_state.area_list) - { - if (first) - { - first = false; - HMI_DEBUG("wm:pm", "|%-15s|%1s|%-20s|%-20s|%-20s|%-20s|", - layer, changed, layout, - as.name.c_str(), as.category.c_str(), as.role.c_str()); - } - else - HMI_DEBUG("wm:pm", "|%-15s|%1s|%-20s|%-20s|%-20s|%-20s|", - "", "", "", as.name.c_str(), as.category.c_str(), as.role.c_str()); - } - } - HMI_DEBUG("wm:pm", "-------------------------------------------------------------------------------------------------------"); -} - -void PolicyManager::dumpRoleHistory() -{ - HMI_DEBUG("wm:pm", ">>>>>>>>>> DUMP ROLE HISTORY ( category [older > newer] )"); - for (int ctg_no = StmCtgNoMin; ctg_no <= StmCtgNoMax; ctg_no++) - { - if (ctg_no == StmCtgNoNone) - continue; - - std::string category = std::string(kStmCategoryName[ctg_no]); - - std::string str = category + " [ "; - for (const auto &i : this->role_history[category]) - str += (i + " > "); - - str += "]"; - HMI_DEBUG("wm:pm", "%s", str.c_str()); - } -} - -std::vector<std::string> PolicyManager::parseString(std::string str, char delimiter) -{ - // Parse string by delimiter - std::vector<std::string> vct; - std::stringstream ss{str}; - std::string buf; - while (std::getline(ss, buf, delimiter)) - { - if (!buf.empty()) - { - vct.push_back(buf); - } - } - return vct; -} - -std::string PolicyManager::deleteSpace(std::string str) -{ - std::string ret = str; - size_t pos; - while ((pos = ret.find_first_of(" ")) != std::string::npos) - { - ret.erase(pos, 1); - } - return ret; -} - -const char *PolicyManager::kDefaultRoleDb = "{ \ - \"roles\":[ \ - { \ - \"category\": \"homescreen\", \ - \"role\": \"homescreen\", \ - \"area\": \"fullscreen\", \ - }, \ - { \ - \"category\": \"map\", \ - \"role\": \"map\", \ - \"area\": \"normal.full | split.main\", \ - }, \ - { \ - \"category\": \"general\", \ - \"role\": \"launcher | poi | browser | sdl | mixer | radio | hvac | debug | phone | video | music\", \ - \"area\": \"normal.full\", \ - }, \ - { \ - \"category\": \"system\", \ - \"role\": \"settings | dashboard\", \ - \"area\": \"normal.full\", \ - }, \ - { \ - \"category\": \"software_keyboard\", \ - \"role\": \"software_keyboard\", \ - \"area\": \"software_keyboard\", \ - }, \ - { \ - \"category\": \"restriction\", \ - \"role\": \"restriction\", \ - \"area\": \"restriction.normal | restriction.split.main | restriction.split.sub\", \ - }, \ - { \ - \"category\": \"pop_up\", \ - \"role\": \"pop_up\", \ - \"area\": \"on_screen\", \ - }, \ - { \ - \"category\": \"system_alert\", \ - \"role\": \"system_alert\", \ - \"area\": \"on_screen\", \ - } \ - ] \ -}"; - -const char *PolicyManager::kDefaultLayoutDb = "{ \ - \"layouts\": [ \ - { \ - \"name\": \"homescreen\", \ - \"layer\": \"far_homescreen\", \ - \"areas\": [ \ - { \ - \"name\": \"fullscreen\", \ - \"category\": \"homescreen\" \ - } \ - ] \ - }, \ - { \ - \"name\": \"map.normal\", \ - \"layer\": \"apps\", \ - \"areas\": [ \ - { \ - \"name\": \"normal.full\", \ - \"category\": \"map\" \ - } \ - ] \ - }, \ - { \ - \"name\": \"map.split\", \ - \"layer\": \"apps\", \ - \"areas\": [ \ - { \ - \"name\": \"split.main\", \ - \"category\": \"map\" \ - }, \ - { \ - \"name\": \"split.sub\", \ - \"category\": \"splitable\" \ - } \ - ] \ - }, \ - { \ - \"name\": \"map.fullscreen\", \ - \"layer\": \"apps\", \ - \"areas\": [ \ - { \ - \"name\": \"fullscreen\", \ - \"category\": \"map\" \ - } \ - ] \ - }, \ - { \ - \"name\": \"splitable.normal\", \ - \"layer\": \"apps\", \ - \"areas\": [ \ - { \ - \"name\": \"normal.full\", \ - \"category\": \"splitable\" \ - } \ - ] \ - }, \ - { \ - \"name\": \"splitable.split\", \ - \"layer\": \"apps\", \ - \"areas\": [ \ - { \ - \"name\": \"split.main\", \ - \"category\": \"splitable\" \ - }, \ - { \ - \"name\": \"split.sub\", \ - \"category\": \"splitable\" \ - } \ - ] \ - }, \ - { \ - \"name\": \"general.normal\", \ - \"layer\": \"apps\", \ - \"areas\": [ \ - { \ - \"name\": \"normal.full\", \ - \"category\": \"general\" \ - } \ - ] \ - }, \ - { \ - \"name\": \"system.normal\", \ - \"layer\": \"apps\", \ - \"areas\": [ \ - { \ - \"name\": \"normal.full\", \ - \"category\": \"system\" \ - } \ - ] \ - }, \ - { \ - \"name\": \"software_keyboard\", \ - \"layer\": \"near_homescreen\", \ - \"areas\": [ \ - { \ - \"name\": \"software_keyboard\", \ - \"category\": \"software_keyboard\" \ - } \ - ] \ - }, \ - { \ - \"name\": \"restriction.normal\", \ - \"layer\": \"restriction\", \ - \"areas\": [ \ - { \ - \"name\": \"restriction.normal\", \ - \"category\": \"restriction\" \ - } \ - ] \ - }, \ - { \ - \"name\": \"restriction.split.main\", \ - \"layer\": \"restriction\", \ - \"areas\": [ \ - { \ - \"name\": \"restriction.split.main\", \ - \"category\": \"restriction\" \ - } \ - ] \ - }, \ - { \ - \"name\": \"restriction.split.sub\", \ - \"layer\": \"restriction\", \ - \"areas\": [ \ - { \ - \"name\": \"restriction.split.sub\", \ - \"category\": \"restriction\" \ - } \ - ] \ - }, \ - { \ - \"name\": \"pop_up\", \ - \"layer\": \"on_screen\", \ - \"areas\": [ \ - { \ - \"name\": \"on_screen\", \ - \"category\": \"pop_up\" \ - } \ - ] \ - }, \ - { \ - \"name\": \"system_alert\", \ - \"layer\": \"on_screen\", \ - \"areas\": [ \ - { \ - \"name\": \"on_screen\", \ - \"category\": \"system_alert\" \ - } \ - ] \ - } \ - ] \ -}"; diff --git a/src/policy_manager/policy_manager.hpp b/src/policy_manager/policy_manager.hpp deleted file mode 100644 index 1f69474..0000000 --- a/src/policy_manager/policy_manager.hpp +++ /dev/null @@ -1,144 +0,0 @@ -/* - * Copyright (c) 2018 TOYOTA MOTOR CORPORATION - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#ifndef TMCAGLWM_POLICY_MANAGER_HPP -#define TMCAGLWM_POLICY_MANAGER_HPP - -#include <functional> -#include <unordered_map> -#include <vector> -#include <queue> - -struct json_object; -struct sd_event; -struct sd_event_source; -struct StmState; - -class PolicyManager -{ - - public: - explicit PolicyManager(); - ~PolicyManager() = default; - - using Handler = std::function<void(json_object *)>; - - typedef struct - { - Handler onStateTransitioned; - Handler onError; - } CallbackTable; - - int initialize(); - void registerCallback(CallbackTable callback_table); - int setInputEventData(json_object *json_in); - int executeStateTransition(); - void undoState(); - - // Do not use these functions - int transitionState(sd_event_source *source, void *data); - int timerEvent(sd_event_source *source, uint64_t usec, void *data); - - private: - // Disable copy and move - PolicyManager(PolicyManager const &) = delete; - PolicyManager &operator=(PolicyManager const &) = delete; - PolicyManager(PolicyManager &&) = delete; - PolicyManager &operator=(PolicyManager &&) = delete; - - typedef struct EventInfo - { - int event; - std::string role; - uint64_t delay; - } EventInfo; - - typedef struct AreaState - { - std::string name; - std::string category; - std::string role; - } AreaState; - - typedef std::vector<AreaState> AreaList; - typedef struct LayoutState - { - std::string name; - std::map<std::string, int> category_num; - AreaList area_list; - } LayoutState; - - typedef struct LayerState - { - std::string name; - LayoutState layout_state; - bool changed; - } LayerState; - - // Convert map - std::unordered_map<std::string, int> eventname2no; - std::unordered_map<std::string, int> categoryname2no; - std::unordered_map<std::string, int> areaname2no; - - std::unordered_map<std::string, std::string> role2category; - std::unordered_map<std::string, std::string> category2role; - std::unordered_map<std::string, std::string> role2defaultarea; - - struct sd_event *event_loop; - std::queue<EventInfo> event_info_queue; - std::map<int, struct sd_event_source *> event_source_list; - std::map<int, std::string> req_role_list; - - CallbackTable callback; - - std::unordered_map<std::string, LayerState> prv_layers; - std::unordered_map<std::string, LayerState> crr_layers; - - std::unordered_map<std::string, LayoutState> default_layouts; - - std::map<std::string, std::vector<std::string>> role_history; - - void initializeState(); - void initializeLayerState(); - void updateState(int event_data, StmState crr_state); - void updateLayerState(int event_data, StmState crr_state); - void createOutputInformation(StmState crr_state, json_object **json_out); - int setStateTransitionProcessToSystemd(int event, uint64_t delay_ms, std::string role); - - void pushRoleHistory(std::string category, std::string role); - std::string popRoleHistory(std::string category); - - int loadRoleDb(); - int loadLayoutDb(); - - void dumpLayerState(std::unordered_map<std::string, LayerState> &layers); - void dumpRoleHistory(); - - void addStateToJson(const char *name, bool changed, - std::string state, json_object **json_out); - void addStateToJson(const char *layer_name, bool changed, - AreaList area_list, json_object **json_out); - const char *getStringFromJson(json_object *obj, const char *key); - int inputJsonFilie(const char *file, json_object **obj); - - std::vector<std::string> parseString(std::string str, char delimiter); - std::string deleteSpace(std::string str); - - static const char *kDefaultRoleDb; - static const char *kDefaultLayoutDb; -}; - -#endif // TMCAGLWM_POLICY_MANAGER_HPP diff --git a/src/policy_manager/stm/stub/src/CMakeLists.txt b/src/policy_manager/stm/stub/src/CMakeLists.txt deleted file mode 100644 index 76b4eff..0000000 --- a/src/policy_manager/stm/stub/src/CMakeLists.txt +++ /dev/null @@ -1,53 +0,0 @@ -# -# Copyright (c) 2017 TOYOTA MOTOR CORPORATION -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# - -include(FindPkgConfig) - -# We do not want a prefix for our module -set(CMAKE_SHARED_MODULE_PREFIX "") - -set(TARGETS_STM libstm) - -add_library(${TARGETS_STM} MODULE - stm.c -) - -target_include_directories(${TARGETS_STM} - PRIVATE - ./include -) - -target_compile_definitions(${TARGETS_STM} - PRIVATE - _GNU_SOURCE -) - -target_compile_options(${TARGETS_STM} - PRIVATE - -Wall -Wextra -Wno-unused-parameter -Wno-comment) - -set_target_properties(${TARGETS_STM} - PROPERTIES - C_EXTENSIONS OFF - C_STANDARD 99 - C_STANDARD_REQUIRED ON -) - -install( - TARGETS ${TARGET_STM} - DESTINATION ${CMAKE_INSTALL_LIBDIR} - COMPONENT "runtime" -) diff --git a/src/policy_manager/stm/stub/src/include/stm.h b/src/policy_manager/stm/stub/src/include/stm.h deleted file mode 100644 index 5f672b1..0000000 --- a/src/policy_manager/stm/stub/src/include/stm.h +++ /dev/null @@ -1,170 +0,0 @@ -/* - * Copyright (c) 2018 TOYOTA MOTOR CORPORATION - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#ifndef TMCAGLWM_STUB_STM_HPP -#define TMCAGLWM_STUB_STM_HPP - -#define STM_TRUE 1 -#define STM_FALSE 0 - -#define STM_CREATE_EVENT_ID(evt, ctg, area) \ - ((evt) | ((ctg) << 8) | ((area) << 16)) - -#define STM_GET_EVENT_FROM_ID(id) \ - ((id) & 0xFF) - -#define STM_GET_CATEGORY_FROM_ID(id) \ - (((id) >> 8) & 0xFF) - -#define STM_GET_AREA_FROM_ID(id) \ - (((id) >> 16) & 0xFF) - -// Event number -enum StmEvtNo { - StmEvtNoNone = 0, - StmEvtNoActivate, - StmEvtNoDeactivate, - StmEvtNoRestrictionModeOff, - StmEvtNoRestrictionMode1On, - StmEvtNoRestrictionMode2On, - StmEvtNoUndo, - - StmEvtNoNum, - - StmEvtNoMin = StmEvtNoNone, - StmEvtNoMax = StmEvtNoNum - 1, -}; - -// Category number -enum StmCtgNo { - StmCtgNoNone = 0, - StmCtgNoHomescreen, - StmCtgNoMap, - StmCtgNoGeneral, - StmCtgNoSplitable, - StmCtgNoPopUp, - StmCtgNoSystemAlert, - StmCtgNoRestriction, - StmCtgNoSystem, - StmCtgNoSoftwareKeyboard, - - StmCtgNoNum, - - StmCtgNoMin = StmCtgNoNone, - StmCtgNoMax = StmCtgNoNum - 1, -}; - -// Area number -enum StmAreaNo { - StmAreaNoNone = 0, - StmAreaNoFullscreen, - StmAreaNoNormal, - StmAreaNoSplitMain, - StmAreaNoSplitSub, - StmAreaNoOnScreen, - StmAreaNoRestrictionNormal, - StmAreaNoRestrictionSplitMain, - StmAreaNoRestrictionSplitSub, - StmAreaNoSoftwareKyeboard, - - StmAreaNoNum, - - StmAreaNoMin = StmAreaNoNone, - StmAreaNoMax = StmAreaNoNum - 1, -}; - -// Layer number -enum StmLayerNo { - StmLayerNoHomescreen = 0, - StmLayerNoApps, - StmLayerNoNearHomescreen, - StmLayerNoRestriction, - StmLayerNoOnScreen, - - StmLayerNoNum, - - StmLayerNoMin = StmLayerNoHomescreen, - StmLayerNoMax = StmLayerNoNum - 1, -}; - -// Layout kind number -enum StmLayoutNo { - StmLayoutNoNone = 0, - StmLayoutNoPopUp, - StmLayoutNoSysAlt, - StmLayoutNoMapNml, - StmLayoutNoMapSpl, - StmLayoutNoMapFll, - StmLayoutNoSplNml, - StmLayoutNoSplSpl, - StmLayoutNoGenNml, - StmLayoutNoHms, - StmLayoutNoRstNml, - StmLayoutNoRstSplMain, - StmLayoutNoRstSplSub, - StmLayoutNoSysNml, - StmLayoutNoSftKbd, - - StmLayoutNoNum, - - StmLayoutNoMin = StmLayoutNoNone, - StmLayoutNoMax = StmLayoutNoNum - 1, -}; - -// Mode kind number -enum StmModeNo { - StmModeNoRestrictionMode = 0, - - StmModeNoNum, - - StmModeNoMin = StmModeNoRestrictionMode, - StmModeNoMax = StmModeNoNum - 1, -}; - -// Enum for mode state -enum StmRestrictionModeSttNo { - StmRestrictionModeSttNoOff = 0, - StmRestrictionModeSttNo1On, - StmRestrictionModeSttNo2On, -}; - -// String for state -extern const char* kStmEventName[]; -extern const char* kStmCategoryName[]; -extern const char* kStmAreaName[]; -extern const char* kStmLayoutName[]; -extern const char* kStmLayerName[]; -extern const char* kStmModeName[]; -extern const char** kStmModeStateNameList[]; - -// Struct for state -typedef struct StmBaseState { - int changed; - int state; -} StmBaseState; - -typedef struct StmState { - StmBaseState mode[StmModeNoNum]; - StmBaseState layer[StmLayerNoNum]; -} StmState; - -// API -void stmInitialize(); -int stmTransitionState(int event_no, StmState* state); -void stmUndoState(); - - -#endif // TMCAGLWM_STUB_STM_HPP diff --git a/src/policy_manager/stm/stub/src/stm.c b/src/policy_manager/stm/stub/src/stm.c deleted file mode 100644 index 222dc91..0000000 --- a/src/policy_manager/stm/stub/src/stm.c +++ /dev/null @@ -1,237 +0,0 @@ -/* - * Copyright (c) 2018 TOYOTA MOTOR CORPORATION - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#include <string.h> -#include "stm.h" - -const char* kStmEventName[] = { - "none", - "activate", - "deactivate", - "restriction_mode_off", - "restriction_mode_1_on", - "restriction_mode_2_on", - "undo", -}; - -const char* kStmCategoryName[] = { - "none", - "homescreen", - "map", - "general", - "splitable", - "pop_up", - "system_alert", - "restriction", - "system", - "software_keyboard", -}; - -const char* kStmAreaName[] = { - "none", - "fullscreen", - "normal", - "split.main", - "split.sub", - "on_screen", - "restriction.normal", - "restriction.split.main", - "restriction.split.sub", - "software_keyboard", -}; - -const char* kStmLayoutName[] = { - "none", - "pop_up", - "system_alert", - "map.normal", - "map.split", - "map.fullscreen", - "splitable.normal", - "splitable.split", - "general.normal", - "homescreen", - "restriction.normal", - "restriction.split.main", - "restriction.split.sub", - "system.normal", - "software_keyboard", -}; - -const char* kStmLayerName[] = { - "homescreen", - "apps", - "near_homescreen", - "restriction", - "on_screen", -}; - -const char* kStmModeName[] = { - "trans_gear", - "parking_brake", - "accel_pedal", - "running", - "lamp", - "lightstatus_brake", - "restriction_mode", -}; - -const char* kStmRestrictionModeStateName[] = { - "off", - "1on", - "2on", -}; - -const char** kStmModeStateNameList[] = { - kStmRestrictionModeStateName, -}; - -static StmState g_crr_state; -static StmState g_prv_state; - -void stmInitialize() { - // Initialize previous state - memset(&g_prv_state, 0, sizeof(g_prv_state)); - - // Initialize current state - g_crr_state = g_prv_state; -} - -int stmTransitionState(int event, StmState* state) { - int event_no, category_no; - - event_no = STM_GET_EVENT_FROM_ID(event); - category_no = STM_GET_CATEGORY_FROM_ID(event); - - // Backup previous state - g_prv_state = g_crr_state; - - // Clear current state - memset(&g_prv_state, 0, sizeof(g_prv_state)); - - // ------------------------------------------------------- - // There is no policy table by default. - // Therefore update each layers - // to draw the applications in normal.full area - // in accordance with inputed activate/deactivate events. - // ------------------------------------------------------- - if (StmEvtNoActivate == event_no) - { - if (StmCtgNoHomescreen == category_no) - { - g_crr_state.layer[StmLayerNoHomescreen].state = StmLayoutNoHms; - g_crr_state.layer[StmLayerNoHomescreen].changed = STM_TRUE; - - g_crr_state.layer[StmLayerNoApps].state = StmLayoutNoNone; - g_crr_state.layer[StmLayerNoApps].changed = STM_TRUE; - } - else if (StmCtgNoMap == category_no) - { - g_crr_state.layer[StmLayerNoApps].state = StmLayoutNoMapNml; - g_crr_state.layer[StmLayerNoApps].changed = STM_TRUE; - } - else if (StmCtgNoGeneral == category_no) - { - g_crr_state.layer[StmLayerNoApps].state = StmLayoutNoGenNml; - g_crr_state.layer[StmLayerNoApps].changed = STM_TRUE; - } - else if (StmCtgNoSystem == category_no) - { - g_crr_state.layer[StmLayerNoApps].state = StmLayoutNoSysNml; - g_crr_state.layer[StmLayerNoApps].changed = STM_TRUE; - } - else if (StmCtgNoSplitable == category_no) - { - g_crr_state.layer[StmLayerNoApps].state = StmLayoutNoSplNml; - g_crr_state.layer[StmLayerNoApps].changed = STM_TRUE; - } - else if (StmCtgNoPopUp == category_no) - { - g_crr_state.layer[StmLayerNoOnScreen].state = StmLayoutNoPopUp; - g_crr_state.layer[StmLayerNoOnScreen].changed = STM_TRUE; - } - else if (StmCtgNoSystemAlert == category_no) - { - g_crr_state.layer[StmLayerNoOnScreen].state = StmLayoutNoSysAlt; - g_crr_state.layer[StmLayerNoOnScreen].changed = STM_TRUE; - } - } - else if (StmEvtNoDeactivate == event_no) - { - if (StmCtgNoHomescreen == category_no) - { - g_crr_state.layer[StmLayerNoHomescreen].state = StmLayoutNoNone; - g_crr_state.layer[StmLayerNoHomescreen].changed = STM_TRUE; - } - else if (StmCtgNoMap == category_no) - { - if (StmLayoutNoMapNml == g_prv_state.layer[StmLayerNoApps].state ) - { - g_crr_state.layer[StmLayerNoApps].state = StmLayoutNoNone; - g_crr_state.layer[StmLayerNoApps].changed = STM_TRUE; - } - } - else if (StmCtgNoGeneral == category_no) - { - if (StmLayoutNoGenNml == g_prv_state.layer[StmLayerNoApps].state ) - { - g_crr_state.layer[StmLayerNoApps].state = StmLayoutNoNone; - g_crr_state.layer[StmLayerNoApps].changed = STM_TRUE; - } - } - else if (StmCtgNoSystem == category_no) - { - if (StmLayoutNoSysNml == g_prv_state.layer[StmLayerNoApps].state ) - { - g_crr_state.layer[StmLayerNoApps].state = StmLayoutNoNone; - g_crr_state.layer[StmLayerNoApps].changed = STM_TRUE; - } - } - else if (StmCtgNoSplitable == category_no) - { - if (StmLayoutNoSplNml == g_prv_state.layer[StmLayerNoApps].state ) - { - g_crr_state.layer[StmLayerNoApps].state = StmLayoutNoNone; - g_crr_state.layer[StmLayerNoApps].changed = STM_TRUE; - } - } - else if (StmCtgNoPopUp == category_no) - { - if (StmLayoutNoPopUp == g_prv_state.layer[StmLayerNoOnScreen].state ) - { - g_crr_state.layer[StmLayerNoOnScreen].state = StmLayoutNoNone; - g_crr_state.layer[StmLayerNoOnScreen].changed = STM_TRUE; - } - } - else if (StmCtgNoSystemAlert == category_no) - { - if (StmLayoutNoSysAlt == g_prv_state.layer[StmLayerNoOnScreen].state ) - { - g_crr_state.layer[StmLayerNoOnScreen].state = StmLayoutNoNone; - g_crr_state.layer[StmLayerNoOnScreen].changed = STM_TRUE; - } - } - } - - // Copy current state for return - memcpy(state, &g_crr_state, sizeof(g_crr_state)); - - return 0; -} - -void stmUndoState() { - g_crr_state = g_prv_state; -} diff --git a/src/window_manager.cpp b/src/window_manager.cpp index b35c767..eadf7ff 100644 --- a/src/window_manager.cpp +++ b/src/window_manager.cpp @@ -55,7 +55,6 @@ const char kKeyIds[] = "ids"; static sd_event_source *g_timer_ev_src = nullptr; static AppList g_app_list; -static WindowManager *g_context; namespace { @@ -100,15 +99,6 @@ static int processTimerHandler(sd_event_source *s, uint64_t usec, void *userdata return 0; } -static void onStateTransitioned(std::vector<WMAction> actions) -{ - g_context->startTransitionWrapper(actions); -} - -static void onError() -{ - g_context->processError(WMError::LAYOUT_CHANGE_FAIL); -} } // namespace /** @@ -174,15 +164,6 @@ int WindowManager::init() // Load old_role.db this->loadOldRoleDb(); - // Store my context for calling callback from PolicyManager - g_context = this; - - // Initialize PMWrapper - this->pmw.initialize(); - - // Register callback to PolicyManager - this->pmw.registerCallback(onStateTransitioned, onError); - // Make afb event for (int i = Event_Val_Min; i <= Event_Val_Max; i++) { @@ -465,9 +446,6 @@ void WindowManager::api_enddraw(char const *appid, char const *drawing_name) if(ret != WMError::SUCCESS) { //this->emit_error(); - - // Undo state of PolicyManager - this->pmw.undoState(); } this->emitScreenUpdated(current_req); HMI_SEQ_INFO(current_req, "Finish request status: %s", errorDescription(ret)); @@ -530,6 +508,18 @@ result<json_object *> WindowManager::api_get_area_info(char const *drawing_name) return Err<json_object *>("Surface is not on any layer!"); } + auto o_state = *this->layers.get_layout_state(*surface_id); + if (o_state == nullptr) + { + return Err<json_object *>("Could not find layer for surface"); + } + + struct LayoutState &state = *o_state; + if ((state.main != *surface_id) && (state.sub != *surface_id)) + { + return Err<json_object *>("Surface is inactive"); + } + // Set area rectangle compositor::rect area_info = this->area_info[*surface_id]; json_object *object = json_object_new_object(); @@ -630,82 +620,6 @@ void WindowManager::timerHandler() this->processNextRequest(); } -void WindowManager::startTransitionWrapper(std::vector<WMAction> &actions) -{ - WMError ret; - unsigned req_num = g_app_list.currentRequestNumber(); - - if (actions.empty()) - { - if (g_app_list.haveRequest()) - { - HMI_SEQ_DEBUG(req_num, "There is no WMAction for this request"); - goto proc_remove_request; - } - else - { - HMI_SEQ_DEBUG(req_num, "There is no request"); - return; - } - } - - for (auto &act : actions) - { - if ("" != act.role) - { - bool found; - auto const &surface_id = this->lookup_id(act.role.c_str()); - std::string appid = g_app_list.getAppID(*surface_id, act.role, &found); - if (!found) - { - goto error; - } - act.appid = appid; - } - - ret = g_app_list.setAction(req_num, act); - if (ret != WMError::SUCCESS) - { - goto error; - } - } - - HMI_SEQ_DEBUG(req_num, "Start transition."); - ret = this->startTransition(req_num); - if (ret != WMError::SUCCESS) - { - if (ret == WMError::NO_LAYOUT_CHANGE) - { - goto proc_remove_request; - } - else - { - goto error; - } - } - - return; - -error: - //this->emit_error() - HMI_SEQ_ERROR(req_num, errorDescription(ret)); - this->pmw.undoState(); - -proc_remove_request: - g_app_list.removeRequest(req_num); - this->processNextRequest(); -} - -void WindowManager::processError(WMError error) -{ - unsigned req_num = g_app_list.currentRequestNumber(); - - //this->emit_error() - HMI_SEQ_ERROR(req_num, errorDescription(error)); - g_app_list.removeRequest(req_num); - this->processNextRequest(); -} - /* ******* Private Functions ******* */ @@ -1016,6 +930,12 @@ WMError WindowManager::doTransition(unsigned req_num) { HMI_SEQ_DEBUG(req_num, "check policy"); WMError ret = this->checkPolicy(req_num); + if (ret != WMError::SUCCESS) + { + return ret; + } + HMI_SEQ_DEBUG(req_num, "Start transition."); + ret = this->startTransition(req_num); return ret; } @@ -1026,6 +946,7 @@ WMError WindowManager::checkPolicy(unsigned req_num) */ // get current trigger bool found = false; + bool split = false; WMError ret = WMError::LAYOUT_CHANGE_FAIL; auto trigger = g_app_list.getRequest(req_num, &found); if (!found) @@ -1035,33 +956,89 @@ WMError WindowManager::checkPolicy(unsigned req_num) } std::string req_area = trigger.area; + // >>>> Compatible with current window manager until policy manager coming if (trigger.task == Task::TASK_ALLOCATE) { + HMI_SEQ_DEBUG(req_num, "Check split or not"); const char *msg = this->check_surface_exist(trigger.role.c_str()); if (msg) { HMI_SEQ_ERROR(req_num, msg); + ret = WMError::LAYOUT_CHANGE_FAIL; return ret; } - } - // Input event data to PolicyManager - if (0 > this->pmw.setInputEventData(trigger.task, trigger.role, trigger.area)) + auto const &surface_id = this->lookup_id(trigger.role.c_str()); + auto o_state = *this->layers.get_layout_state(*surface_id); + struct LayoutState &state = *o_state; + + unsigned curernt_sid = state.main; + split = this->can_split(state, *surface_id); + + if (split) + { + HMI_SEQ_DEBUG(req_num, "Split happens"); + // Get current visible role + std::string add_role = this->lookup_name(state.main).value(); + // Set next area + std::string add_area = std::string(kNameLayoutSplit) + "." + std::string(kNameAreaMain); + // Change request area + req_area = std::string(kNameLayoutSplit) + "." + std::string(kNameAreaSub); + HMI_SEQ_NOTICE(req_num, "Change request area from %s to %s, because split happens", + trigger.area.c_str(), req_area.c_str()); + // set another action + std::string add_name = g_app_list.getAppID(curernt_sid, add_role, &found); + if (!found) + { + HMI_SEQ_ERROR(req_num, "Couldn't widhdraw with surfaceID : %d", curernt_sid); + ret = WMError::NOT_REGISTERED; + return ret; + } + HMI_SEQ_INFO(req_num, "Additional split app %s, role: %s, area: %s", + add_name.c_str(), add_role.c_str(), add_area.c_str()); + // Set split action + bool end_draw_finished = false; + WMAction split_action{ + add_name, + add_role, + add_area, + TaskVisible::VISIBLE, + end_draw_finished}; + WMError ret = g_app_list.setAction(req_num, split_action); + if (ret != WMError::SUCCESS) + { + HMI_SEQ_ERROR(req_num, "Failed to set action"); + return ret; + } + g_app_list.reqDump(); + } + } + else { - HMI_SEQ_ERROR(req_num, "Failed to set input event data to PolicyManager"); - return ret; + HMI_SEQ_DEBUG(req_num, "split doesn't happen"); } - // Execute state transition of PolicyManager - if (0 > this->pmw.executeStateTransition()) + // Set invisible task(Remove if policy manager finish) + ret = this->setInvisibleTask(trigger.role, split); + if(ret != WMError::SUCCESS) { - HMI_SEQ_ERROR(req_num, "Failed to execute state transition of PolicyManager"); + HMI_SEQ_ERROR(req_num, "Failed to set invisible task: %s", errorDescription(ret)); return ret; } - ret = WMError::SUCCESS; + /* get new status from Policy Manager */ + HMI_SEQ_NOTICE(req_num, "ATM, Policy manager does't exist, then set WMAction as is"); + if(trigger.role == "homescreen") + { + // TODO : Remove when Policy Manager completed + HMI_SEQ_NOTICE(req_num, "Hack. This process will be removed. Change HomeScreen code!!"); + req_area = "fullscreen"; + } + TaskVisible task_visible = + (trigger.task == Task::TASK_ALLOCATE) ? TaskVisible::VISIBLE : TaskVisible::INVISIBLE; + ret = g_app_list.setAction(req_num, trigger.appid, trigger.role, req_area, task_visible); g_app_list.reqDump(); return ret; @@ -1083,7 +1060,7 @@ WMError WindowManager::startTransition(unsigned req_num) for (const auto &action : actions) { - if (action.visible == TaskVisible::VISIBLE) + if (action.visible != TaskVisible::INVISIBLE) { sync_draw_happen = true; @@ -1114,11 +1091,155 @@ WMError WindowManager::startTransition(unsigned req_num) this->deactivate(client->surfaceID(x.role)); } } - ret = WMError::NO_LAYOUT_CHANGE; + ret = NO_LAYOUT_CHANGE; } return ret; } +WMError WindowManager::setInvisibleTask(const std::string &role, bool split) +{ + unsigned req_num = g_app_list.currentRequestNumber(); + HMI_SEQ_DEBUG(req_num, "set current visible app to invisible task"); + // This task is copied from original actiavete surface + const char *drawing_name = this->rolenew2old[role].c_str(); + auto const &surface_id = this->lookup_id(role.c_str()); + auto layer_id = this->layers.get_layer_id(*surface_id); + auto o_state = *this->layers.get_layout_state(*surface_id); + struct LayoutState &state = *o_state; + std::string add_name, add_role; + std::string add_area = ""; + int surface; + TaskVisible task_visible = TaskVisible::INVISIBLE; + bool end_draw_finished = true; + bool found = false; + + for (auto const &l : this->layers.mapping) + { + if (l.second.layer_id <= *layer_id) + { + continue; + } + HMI_DEBUG("wm", "debug: main %d , sub : %d", l.second.state.main, l.second.state.sub); + if (l.second.state.main != -1) + { + //this->deactivate(l.second.state.main); + surface = l.second.state.main; + add_role = *this->id_alloc.lookup(surface); + add_name = g_app_list.getAppID(surface, add_role, &found); + if(!found){ + return WMError::NOT_REGISTERED; + } + HMI_SEQ_INFO(req_num, "Invisible %s", add_name.c_str()); + WMAction act{add_name, add_role, add_area, task_visible, end_draw_finished}; + g_app_list.setAction(req_num, act); + l.second.state.main = -1; + } + + if (l.second.state.sub != -1) + { + //this->deactivate(l.second.state.sub); + surface = l.second.state.sub; + add_role = *this->id_alloc.lookup(surface); + add_name = g_app_list.getAppID(surface, add_role, &found); + if (!found) + { + return WMError::NOT_REGISTERED; + } + HMI_SEQ_INFO(req_num, "Invisible %s", add_name.c_str()); + WMAction act{add_name, add_role, add_area, task_visible, end_draw_finished}; + g_app_list.setAction(req_num, act); + l.second.state.sub = -1; + } + } + + // change current state here, but this is hack + auto layer = this->layers.get_layer(*layer_id); + + if (state.main == -1) + { + HMI_DEBUG("wm", "Layout: %s", kNameLayoutNormal); + } + else + { + if (0 != strcmp(drawing_name, "HomeScreen")) + { + if (split) + { + if (state.sub != *surface_id) + { + if (state.sub != -1) + { + //this->deactivate(state.sub); + WMAction deact_sub; + deact_sub.role = + std::move(*this->id_alloc.lookup(state.sub)); + deact_sub.area = add_area; + deact_sub.appid = g_app_list.getAppID(state.sub, deact_sub.role, &found); + if (!found) + { + HMI_SEQ_ERROR(req_num, "App doesn't exist for role : %s", + deact_sub.role.c_str()); + return WMError::NOT_REGISTERED; + } + deact_sub.visible = task_visible; + deact_sub.end_draw_finished = end_draw_finished; + HMI_SEQ_DEBUG(req_num, "Set invisible task for %s", deact_sub.appid.c_str()); + g_app_list.setAction(req_num, deact_sub); + } + } + //state = LayoutState{state.main, *surface_id}; + } + else + { + HMI_DEBUG("wm", "Layout: %s", kNameLayoutNormal); + + //this->surface_set_layout(*surface_id); + if (state.main != *surface_id) + { + // this->deactivate(state.main); + WMAction deact_main; + deact_main.role = std::move(*this->id_alloc.lookup(state.main)); + ; + deact_main.area = add_area; + deact_main.appid = g_app_list.getAppID(state.main, deact_main.role, &found); + if (!found) + { + HMI_SEQ_DEBUG(req_num, "sub surface ddoesn't exist"); + return WMError::NOT_REGISTERED; + } + deact_main.visible = task_visible; + deact_main.end_draw_finished = end_draw_finished; + HMI_SEQ_DEBUG(req_num, "sub surface doesn't exist"); + g_app_list.setAction(req_num, deact_main); + } + if (state.sub != -1) + { + if (state.sub != *surface_id) + { + //this->deactivate(state.sub); + WMAction deact_sub; + deact_sub.role = std::move(*this->id_alloc.lookup(state.sub)); + ; + deact_sub.area = add_area; + deact_sub.appid = g_app_list.getAppID(state.sub, deact_sub.role, &found); + if (!found) + { + HMI_SEQ_DEBUG(req_num, "sub surface ddoesn't exist"); + return WMError::NOT_REGISTERED; + } + deact_sub.visible = task_visible; + deact_sub.end_draw_finished = end_draw_finished; + HMI_SEQ_DEBUG(req_num, "sub surface doesn't exist"); + g_app_list.setAction(req_num, deact_sub); + } + } + //state = LayoutState{*surface_id}; + } + } + } + return WMError::SUCCESS; +} + WMError WindowManager::doEndDraw(unsigned req_num) { // get actions @@ -1136,36 +1257,36 @@ WMError WindowManager::doEndDraw(unsigned req_num) // layout change and make it visible for (const auto &act : actions) { - if(act.visible != TaskVisible::NO_CHANGE) + // layout change + if(!g_app_list.contains(act.appid)){ + ret = WMError::NOT_REGISTERED; + } + ret = this->layoutChange(act); + if(ret != WMError::SUCCESS) { - // layout change - if(!g_app_list.contains(act.appid)){ - ret = WMError::NOT_REGISTERED; - } - ret = this->layoutChange(act); - if(ret != WMError::SUCCESS) - { - HMI_SEQ_WARNING(req_num, - "Failed to manipulate surfaces while state change : %s", errorDescription(ret)); - return ret; - } - ret = this->visibilityChange(act); - if (ret != WMError::SUCCESS) - { - HMI_SEQ_WARNING(req_num, - "Failed to manipulate surfaces while state change : %s", errorDescription(ret)); - return ret; - } - HMI_SEQ_DEBUG(req_num, "visible %s", act.role.c_str()); - //this->lm_enddraw(act.role.c_str()); + HMI_SEQ_WARNING(req_num, + "Failed to manipulate surfaces while state change : %s", errorDescription(ret)); + return ret; } + ret = this->visibilityChange(act); + if (ret != WMError::SUCCESS) + { + HMI_SEQ_WARNING(req_num, + "Failed to manipulate surfaces while state change : %s", errorDescription(ret)); + return ret; + } + HMI_SEQ_DEBUG(req_num, "visible %s", act.role.c_str()); + //this->lm_enddraw(act.role.c_str()); } + // Change current state + this->changeCurrentState(req_num); + HMI_SEQ_INFO(req_num, "emit flushDraw"); for(const auto &act_flush : actions) { - if(act_flush.visible == TaskVisible::VISIBLE) + if(act_flush.visible != TaskVisible::INVISIBLE) { // TODO: application requests by old role, // so convert role new to old for emitting event @@ -1231,6 +1352,74 @@ WMError WindowManager::setSurfaceSize(unsigned surface, const std::string &area) return WMError::SUCCESS; } +WMError WindowManager::changeCurrentState(unsigned req_num) +{ + HMI_SEQ_DEBUG(req_num, "Change current layout state"); + bool trigger_found = false, action_found = false; + auto trigger = g_app_list.getRequest(req_num, &trigger_found); + auto actions = g_app_list.getActions(req_num, &action_found); + if (!trigger_found || !action_found) + { + HMI_SEQ_ERROR(req_num, "Action not found"); + return WMError::LAYOUT_CHANGE_FAIL; + } + + // Layout state reset + struct LayoutState reset_state{-1, -1}; + HMI_SEQ_DEBUG(req_num,"Reset layout state"); + for (const auto &action : actions) + { + if(!g_app_list.contains(action.appid)){ + return WMError::NOT_REGISTERED; + } + auto client = g_app_list.lookUpClient(action.appid); + auto pCurState = *this->layers.get_layout_state((int)client->surfaceID(action.role)); + if(pCurState == nullptr) + { + HMI_SEQ_ERROR(req_num, "Counldn't find current status"); + continue; + } + pCurState->main = reset_state.main; + pCurState->sub = reset_state.sub; + } + + HMI_SEQ_DEBUG(req_num, "Change state"); + for (const auto &action : actions) + { + auto client = g_app_list.lookUpClient(action.appid); + auto pLayerCurState = *this->layers.get_layout_state((int)client->surfaceID(action.role)); + if (pLayerCurState == nullptr) + { + HMI_SEQ_ERROR(req_num, "Counldn't find current status"); + continue; + } + int surface = -1; + + if (action.visible != TaskVisible::INVISIBLE) + { + surface = (int)client->surfaceID(action.role); + HMI_SEQ_INFO(req_num, "Change %s surface : %d, state visible area : %s", + action.role.c_str(), surface, action.area.c_str()); + // visible == true -> layout changes + if(action.area == "normal.full" || action.area == "split.main") + { + pLayerCurState->main = surface; + } + else if (action.area == "split.sub") + { + pLayerCurState->sub = surface; + } + else + { + // normalfull + pLayerCurState->main = surface; + } + } + } + + return WMError::SUCCESS; +} + void WindowManager::emitScreenUpdated(unsigned req_num) { // Get visible apps @@ -1432,10 +1621,63 @@ const char *WindowManager::check_surface_exist(const char *drawing_name) return "Surface is not on any layer!"; } + auto o_state = *this->layers.get_layout_state(*surface_id); + + if (o_state == nullptr) + { + return "Could not find layer for surface"; + } + HMI_DEBUG("wm", "surface %d is detected", *surface_id); return nullptr; } +bool WindowManager::can_split(struct LayoutState const &state, int new_id) +{ + if (state.main != -1 && state.main != new_id) + { + auto new_id_layer = this->layers.get_layer_id(new_id).value(); + auto current_id_layer = this->layers.get_layer_id(state.main).value(); + + // surfaces are on separate layers, don't bother. + if (new_id_layer != current_id_layer) + { + return false; + } + + std::string const &new_id_str = this->lookup_name(new_id).value(); + std::string const &cur_id_str = this->lookup_name(state.main).value(); + + auto const &layer = this->layers.get_layer(new_id_layer); + + HMI_DEBUG("wm", "layer info name: %s", layer->name.c_str()); + + if (layer->layouts.empty()) + { + return false; + } + + for (auto i = layer->layouts.cbegin(); i != layer->layouts.cend(); i++) + { + HMI_DEBUG("wm", "%d main_match '%s'", new_id_layer, i->main_match.c_str()); + auto rem = std::regex(i->main_match); + if (std::regex_match(cur_id_str, rem)) + { + // build the second one only if the first already matched + HMI_DEBUG("wm", "%d sub_match '%s'", new_id_layer, i->sub_match.c_str()); + auto res = std::regex(i->sub_match); + if (std::regex_match(new_id_str, res)) + { + HMI_DEBUG("wm", "layout matched!"); + return true; + } + } + } + } + + return false; +} + const char* WindowManager::kDefaultOldRoleDb = "{ \ \"old_roles\": [ \ { \ diff --git a/src/window_manager.hpp b/src/window_manager.hpp index 1237a60..0fb1805 100644 --- a/src/window_manager.hpp +++ b/src/window_manager.hpp @@ -25,7 +25,6 @@ #include "layers.hpp" #include "layout.hpp" #include "wayland_ivi_wm.hpp" -#include "pm_wrapper.hpp" #include "hmi-debug.h" #include "request.hpp" #include "wm_error.hpp" @@ -226,11 +225,8 @@ class WindowManager void removeClient(const std::string &appid); void exceptionProcessForTransition(); - - // Do not use these functions + // Do not use this function void timerHandler(); - void startTransitionWrapper(std::vector<WMAction> &actions); - void processError(WMError error); private: bool pop_pending_events(); @@ -257,11 +253,13 @@ class WindowManager WMError doTransition(unsigned sequence_number); WMError checkPolicy(unsigned req_num); WMError startTransition(unsigned req_num); + WMError setInvisibleTask(const std::string &role, bool split); WMError doEndDraw(unsigned req_num); WMError layoutChange(const WMAction &action); WMError visibilityChange(const WMAction &action); WMError setSurfaceSize(unsigned surface, const std::string& area); + WMError changeCurrentState(unsigned req_num); void emitScreenUpdated(unsigned req_num); void setTimer(); @@ -273,13 +271,13 @@ class WindowManager const char *check_surface_exist(const char *drawing_name); + bool can_split(struct LayoutState const &state, int new_id); + private: std::unordered_map<std::string, struct compositor::rect> area2size; std::unordered_map<std::string, std::string> roleold2new; std::unordered_map<std::string, std::string> rolenew2old; - PMWrapper pmw; - static const char* kDefaultOldRoleDb; }; |