Improve window manager
[apps/agl-service-windowmanager-2017.git] / src / window_manager.cpp
index f209f12..cdf57c2 100644 (file)
@@ -57,8 +57,25 @@ const char kKeyHeightMm[]    = "height_mm";
 const char kKeyScale[]       = "scale";
 const char kKeyIds[]         = "ids";
 
-static const char kPathOldRolesConfigFile[] = "/etc/old_roles.json";
+static const vector<string> kListEventName{
+        "active",
+        "inactive",
+        "visible",
+        "invisible",
+        "syncDraw",
+        "flushDraw",
+        "screenUpdated",
+        "headlampOff",
+        "headlampOn",
+        "parkingBrakeOff",
+        "parkingBrakeOn",
+        "lightstatusBrakeOff",
+        "lightstatusBrakeOn",
+        "carStop",
+        "carRun",
+        "error"};
 
+static const char kPathOldRolesConfigFile[] = "/etc/old_roles.json";
 static sd_event_source *g_timer_ev_src = nullptr;
 static AppList g_app_list;
 static WindowManager *g_context;
@@ -159,7 +176,7 @@ int WindowManager::init()
     // Make afb event
     for (int i = Event_Val_Min; i <= Event_Val_Max; i++)
     {
-        map_afb_event[kListEventName[i]] = afb_daemon_make_event(kListEventName[i]);
+        map_afb_event[kListEventName[i]] = afb_daemon_make_event(kListEventName[i].c_str());
     }
 
     const struct rect css_bg = this->lc->getAreaSize("fullscreen");
@@ -189,13 +206,10 @@ result<int> WindowManager::api_request_surface(char const *appid, char const *dr
 
     if(!g_app_list.contains(s_appid))
     {
-        // auto lid = this->layers.get_layer_id(string(role));
         unsigned l_id = this->lc->getNewLayerID(s_role, &l_name);
         if (l_id == 0)
         {
-            /**
-             * register drawing_name as fallback and make it displayed.
-             */
+            // register drawing_name as fallback and make it displayed.
             l_id = this->lc->getNewLayerID("fallback", &l_name);
             HMI_DEBUG("%s is not registered in layers.json, then fallback as normal app", role);
             if (l_id == 0)
@@ -415,7 +429,7 @@ bool WindowManager::api_set_role(char const *appid, char const *drawing_name)
     return true;
 }
 
-void WindowManager::api_activate_surface(char const *appid, char const *drawing_name,
+void WindowManager::api_activate_window(char const *appid, char const *drawing_name,
                                char const *drawing_area, const reply_func &reply)
 {
     // TODO: application requests by old role,
@@ -608,7 +622,7 @@ void WindowManager::api_activate_surface_to_master(
     this->setTimer();
 }
 
-void WindowManager::api_deactivate_surface(char const *appid, char const *drawing_name,
+void WindowManager::api_deactivate_window(char const *appid, char const *drawing_name,
                                  const reply_func &reply)
 {
     // TODO: application requests by old role,
@@ -799,6 +813,12 @@ void WindowManager::api_enddraw(char const *appid, char const *drawing_name)
     }
 }
 
+int WindowManager::api_subscribe(afb_req req, int event_id)
+{
+    struct afb_event event = this->map_afb_event[kListEventName[event_id]];
+    return afb_req_subscribe(req, event);
+}
+
 void WindowManager::api_enddraw_for_remote(char const *appid, char const *drawing_name)
 {
     int ret = this->wmcon.sendRequest("endDraw", appid, drawing_name, "");
@@ -870,7 +890,7 @@ result<json_object *> WindowManager::api_get_area_info(char const *drawing_name)
     const char *role = this->convertRoleOldToNew(drawing_name);
 
     // Check drawing name, surface/layer id
-    auto const &surface_id = this->id_alloc.lookup(string(role));
+    auto const &surface_id = this->id_alloc.lookup(role);
     if (!surface_id)
     {
         return Err<json_object *>("Surface does not exist");
@@ -927,9 +947,9 @@ result<json_object *> WindowManager::api_get_car_info(char const *label)
     return Ok<json_object *>(j_out);
 }
 
-void WindowManager::send_event(char const *evname)
+void WindowManager::send_event(const string& evname)
 {
-    HMI_DEBUG("%s: %s", __func__, evname);
+    HMI_DEBUG("%s: %s", __func__, evname.c_str());
 
     int ret = afb_event_push(this->map_afb_event[evname], nullptr);
     if (ret != 0)
@@ -938,12 +958,12 @@ void WindowManager::send_event(char const *evname)
     }
 }
 
-void WindowManager::send_event(char const *evname, char const *label)
+void WindowManager::send_event(const string& evname, const string& role)
 {
-    HMI_DEBUG("%s: %s(%s)", __func__, evname, label);
+    HMI_DEBUG("%s: %s(%s)", __func__, evname.c_str(), role.c_str());
 
     json_object *j = json_object_new_object();
-    json_object_object_add(j, kKeyDrawingName, json_object_new_string(label));
+    json_object_object_add(j, kKeyDrawingName, json_object_new_string(role.c_str()));
 
     int ret = afb_event_push(this->map_afb_event[evname], j);
     if (ret != 0)
@@ -952,11 +972,11 @@ void WindowManager::send_event(char const *evname, char const *label)
     }
 }
 
-void WindowManager::send_event(char const *evname, char const *label, char const *area,
+void WindowManager::send_event(const string& evname, const string& role, const string& area,
                      int x, int y, int w, int h)
 {
     HMI_DEBUG("%s: %s(%s, %s) x:%d y:%d w:%d h:%d",
-              __func__, evname, label, area, x, y, w, h);
+              __func__, evname.c_str(), role.c_str(), area.c_str(), x, y, w, h);
 
     json_object *j_rect = json_object_new_object();
     json_object_object_add(j_rect, kKeyX, json_object_new_int(x));
@@ -965,8 +985,8 @@ void WindowManager::send_event(char const *evname, char const *label, char const
     json_object_object_add(j_rect, kKeyHeight, json_object_new_int(h));
 
     json_object *j = json_object_new_object();
-    json_object_object_add(j, kKeyDrawingName, json_object_new_string(label));
-    json_object_object_add(j, kKeyDrawingArea, json_object_new_string(area));
+    json_object_object_add(j, kKeyDrawingName, json_object_new_string(role.c_str()));
+    json_object_object_add(j, kKeyDrawingArea, json_object_new_string(area.c_str()));
     json_object_object_add(j, kKeyDrawingRect, j_rect);
 
     int ret = afb_event_push(this->map_afb_event[evname], j);
@@ -1116,7 +1136,6 @@ void WindowManager::surface_removed(unsigned surface_id)
 {
     HMI_DEBUG("Delete surface_id %u", surface_id);
     this->id_alloc.remove_id(surface_id);
-    // this->layers.remove_surface(surface_id);
     g_app_list.removeSurface(surface_id);
 }
 
@@ -1124,7 +1143,7 @@ void WindowManager::removeClient(const string &appid)
 {
     HMI_DEBUG("Remove clinet %s from list", appid.c_str());
     auto client = g_app_list.lookUpClient(appid);
-    this->lc->terminateApp(client);
+    this->lc->appTerminated(client);
     g_app_list.removeClient(appid);
 }
 
@@ -1227,7 +1246,7 @@ void WindowManager::startTransitionWrapper(vector<WMAction> &actions)
                 continue;
             }
 
-            std::string appid = g_app_list.getAppID(*surface_id, &found);
+            string appid = g_app_list.getAppID(*surface_id, &found);
             if (!found)
             {
                 if (TaskVisible::INVISIBLE == act.visible)
@@ -1316,6 +1335,9 @@ void WindowManager::processForRemoteRequest(json_object *data)
     const char *appid        = jh::getStringFromJson(data, "appid");
     const char *drawing_name = jh::getStringFromJson(data, "drawing_name");
     const char *drawing_area = jh::getStringFromJson(data, "drawing_area");
+    string request = req;
+    string role = drawing_name;
+    string area = drawing_area;
 
     if (!req || !drawing_name)
     {
@@ -1339,7 +1361,7 @@ void WindowManager::processForRemoteRequest(json_object *data)
             }
         };
 
-        if ("activateWindow" == std::string(req))
+        if ("activateWindow" == request)
         {
             if (!drawing_area)
             {
@@ -1350,19 +1372,19 @@ void WindowManager::processForRemoteRequest(json_object *data)
             this->api_activate_surface_for_slave(
                 appid, drawing_name, drawing_area, reply);
         }
-        else if ("deactivateWindow" == std::string(req))
+        else if ("deactivateWindow" == request)
         {
             this->api_deactivate_surface_for_slave(
                 appid, drawing_name, reply);
         }
-        else if ("endDraw" == std::string(req))
+        else if ("endDraw" == request)
         {
             this->api_enddraw(appid, drawing_name);
         }
     }
     else
     {
-        if ("syncDraw" == std::string(req))
+        if ("syncDraw" == request)
         {
             this->stopTimer();
 
@@ -1386,7 +1408,7 @@ void WindowManager::processForRemoteRequest(json_object *data)
                 req_num,
                 client,
                 string(c_role),
-                string(drawing_area),
+                area,
                 TaskVisible::REMOTE_VISIBLE,
                 end_draw_finished,
                 TaskCarState::NO_TASK
@@ -1400,16 +1422,16 @@ void WindowManager::processForRemoteRequest(json_object *data)
                 return;
             }
 
-            this->emit_syncdraw(string(drawing_name), string(drawing_area));
+            this->emit_syncdraw(role, area);
             this->wmcon.startSyncDrawForRemote(appid);
             this->setTimer();
         }
-        else if ("activated" == std::string(req))
+        else if ("activated" == request)
         {
-            this->emit_visible(drawing_name);
-            this->emit_activated(drawing_name);
+            this->emit_visible(role);
+            this->emit_activated(area);
         }
-        else if ("deactivated" == std::string(req))
+        else if ("deactivated" == request)
         {
             this->stopTimer();
 
@@ -1443,16 +1465,16 @@ void WindowManager::processForRemoteRequest(json_object *data)
             this->lc->renderLayers();
             this->lc->renderLayersRemote();
 
-            this->emit_invisible(drawing_name);
-            this->emit_deactivated(drawing_name);
+            this->emit_invisible(role);
+            this->emit_deactivated(role);
             this->emitScreenUpdated(req_num);
 
             g_app_list.removeRequest(req_num);
             this->processNextRequest();
         }
-        else if ("flushDraw" == std::string(req))
+        else if ("flushDraw" == request)
         {
-            this->emit_flushdraw(drawing_name);
+            this->emit_flushdraw(role);
         }
     }
 }
@@ -1461,44 +1483,44 @@ void WindowManager::processForRemoteRequest(json_object *data)
  ******* Private Functions *******
  */
 
-void WindowManager::emit_activated(char const *label)
+void WindowManager::emit_activated(const string& role)
 {
-    this->send_event(kListEventName[Event_Active], label);
+    this->send_event(kListEventName[Event_Active], role);
 }
 
-void WindowManager::emit_deactivated(char const *label)
+void WindowManager::emit_deactivated(const string& role)
 {
-    this->send_event(kListEventName[Event_Inactive], label);
+    this->send_event(kListEventName[Event_Inactive], role);
 }
 
-void WindowManager::emit_syncdraw(char const *label, char const *area, int x, int y, int w, int h)
+void WindowManager::emit_syncdraw(const string& role, char const *area, int x, int y, int w, int h)
 {
-    this->send_event(kListEventName[Event_SyncDraw], label, area, x, y, w, h);
+    this->send_event(kListEventName[Event_SyncDraw], role, area, x, y, w, h);
 }
 
 void WindowManager::emit_syncdraw(const string &role, const string &area)
 {
-    rect rect = this->lc->getAreaSize(area);
+    struct rect rect = this->lc->getAreaSize(area);
     this->send_event(kListEventName[Event_SyncDraw],
-                     role.c_str(), area.c_str(), rect.x, rect.y, rect.w, rect.h);
+        role.c_str(), area.c_str(), rect.x, rect.y, rect.w, rect.h);
 }
 
-void WindowManager::emit_flushdraw(char const *label)
+void WindowManager::emit_flushdraw(const string& role)
 {
-    this->send_event(kListEventName[Event_FlushDraw], label);
+    this->send_event(kListEventName[Event_FlushDraw], role);
 }
 
-void WindowManager::emit_visible(char const *label, bool is_visible)
+void WindowManager::emit_visible(const string& role, bool is_visible)
 {
-    this->send_event(is_visible ? kListEventName[Event_Visible] : kListEventName[Event_Invisible], label);
+    this->send_event(is_visible ? kListEventName[Event_Visible] : kListEventName[Event_Invisible], role);
 }
 
-void WindowManager::emit_invisible(char const *label)
+void WindowManager::emit_invisible(const string& role)
 {
-    return emit_visible(label, false);
+    return emit_visible(role, false);
 }
 
-void WindowManager::emit_visible(char const *label) { return emit_visible(label, true); }
+void WindowManager::emit_visible(const string& role) { return emit_visible(role, true); }
 
 void WindowManager::emitHeadlampOff()
 {
@@ -1764,7 +1786,7 @@ WMError WindowManager::startTransition(unsigned req_num)
 
             if (x.visible == TaskVisible::INVISIBLE)
             {
-                emit_deactivated(old_role.c_str());
+                emit_deactivated(old_role);
             }
             else if (x.visible == TaskVisible::REQ_REMOTE_INVISIBLE)
             {
@@ -1846,6 +1868,7 @@ WMError WindowManager::doEndDraw(unsigned req_num)
 {
     // get actions
     bool found;
+    bool trigger_homescreen = false;
     auto actions = g_app_list.getActions(req_num, &found);
     WMError ret = WMError::SUCCESS;
     if (!found)
@@ -1853,6 +1876,13 @@ WMError WindowManager::doEndDraw(unsigned req_num)
         ret = WMError::NO_ENTRY;
         return ret;
     }
+    auto trigger = g_app_list.getRequest(req_num, &found);
+    HMI_SEQ_INFO(req_num, "trigger.role = %s", trigger.role.c_str());
+
+    if(trigger.role == "homescreen")
+    {
+        trigger_homescreen = true;
+    }
 
     HMI_SEQ_INFO(req_num, "do endDraw");
 
@@ -1869,42 +1899,45 @@ WMError WindowManager::doEndDraw(unsigned req_num)
                     "Failed to manipulate surfaces while state change : %s", errorDescription(ret));
                 return ret;
             }
-            ret = this->lc->visibilityChange(act);
 
-            // Emit active/deactive event
-            string old_role = this->rolenew2old[act.role];
-            if(act.visible == TaskVisible::VISIBLE)
+            if(trigger_homescreen && (act.visible == TaskVisible::INVISIBLE))
             {
-                emit_visible(old_role.c_str());
-                emit_activated(old_role.c_str());
+                HMI_SEQ_NOTICE(req_num, "don't change visible if homescreen role is trigger");
             }
-            else if(act.visible == TaskVisible::REQ_REMOTE_VISIBLE)
+            else
             {
-                // If this action is for slave, send to slave
-                int i_ret = this->wmcon.sendRequest("activated", "", old_role.c_str(), "");
-                if (0 > i_ret)
-                {
-                    ret = WMError::FAIL;
-                }
+                ret = this->lc->visibilityChange(act);
             }
-            else if(act.visible == TaskVisible::REQ_REMOTE_INVISIBLE)
+
+            // Emit active/deactive event
+            string old_role = this->rolenew2old[act.role];
+            switch(act.visible)
             {
-                // If this action is for slave, send to slave
-                int i_ret = this->wmcon.sendRequest("deactivated", "", old_role.c_str(), "");
-                if (0 > i_ret)
+                case TaskVisible::VISIBLE : 
+                    emit_visible(old_role);
+                    emit_activated(old_role);
+                    break;
+                case TaskVisible::REQ_REMOTE_VISIBLE :
                 {
-                    ret = WMError::FAIL;
+                    // If this action is for slave, send to slave
+                    int i_ret = this->wmcon.sendRequest("activated", "", old_role.c_str(), "");
+                    if (0 > i_ret)
+                    {
+                        ret = WMError::FAIL;
+                    }
+                    break;
                 }
-            }
-            else if((act.visible == TaskVisible::REMOTE_VISIBLE) ||
-                    (act.visible == TaskVisible::REMOTE_INVISIBLE))
-            {
-                // nop because emit active/deactive by event from remote
-            }
-            else
-            {
-                emit_invisible(old_role.c_str());
-                emit_deactivated(old_role.c_str());
+                case TaskVisible::INVISIBLE :
+                    if(!trigger_homescreen)
+                    {
+                        emit_invisible(old_role);
+                        emit_deactivated(old_role);
+                    }
+                    break;
+                default :
+                    // TaskVisible::REMOTE_VISIBLE, TaskVisible::REMOTE_INVISIBLE is this case
+                    // If this action is for slave, send to slave
+                    break;
             }
 
             if (ret != WMError::SUCCESS)
@@ -1929,7 +1962,7 @@ WMError WindowManager::doEndDraw(unsigned req_num)
 
         if(act_flush.visible == TaskVisible::VISIBLE)
         {
-            this->emit_flushdraw(old_role.c_str());
+            this->emit_flushdraw(old_role);
         }
         else if(act_flush.visible == TaskVisible::REQ_REMOTE_VISIBLE)
         {