1454bf9cb51860cf29ff7f6838bb6a8180e91474
[apps/agl-service-windowmanager-2017.git] / src / pm_wrapper.cpp
1 /*
2  * Copyright (c) 2018 TOYOTA MOTOR CORPORATION
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16
17 #include "pm_wrapper.hpp"
18 #include "json_helper.hpp"
19 #include "hmi-debug.h"
20
21 namespace wm
22 {
23
24 static PMWrapper *g_context;
25
26 namespace
27 {
28
29 static void onStateTransitioned(json_object *json_out)
30 {
31     g_context->updateStates(json_out);
32 }
33
34 static void onError(json_object *json_out)
35 {
36     HMI_DEBUG("wm", "error message from PolicyManager:%s",
37               json_object_get_string(json_out));
38
39     g_context->processError();
40 }
41
42 } // namespace
43
44 PMWrapper::PMWrapper() {}
45
46 int PMWrapper::initialize()
47 {
48     int ret = 0;
49
50     ret = this->pm.initialize();
51     if (0 > ret)
52     {
53         HMI_ERROR("wm:pmw", "Faild to initialize PolicyManager");
54     }
55
56     g_context = this;
57
58     return ret;
59 }
60
61 void PMWrapper::registerCallback(StateTransitionHandler on_state_transitioned,
62                                  ErrorHandler on_error)
63 {
64     this->on_state_transitioned = on_state_transitioned;
65     this->on_error = on_error;
66
67     PolicyManager::CallbackTable my_callback;
68     my_callback.onStateTransitioned = onStateTransitioned;
69     my_callback.onError = onError;
70     this->pm.registerCallback(my_callback);
71 }
72
73 int PMWrapper::setInputEventData(Task task, std::string role, std::string area)
74 {
75     const char* event;
76     if (Task::TASK_ALLOCATE == task)
77     {
78         event = "activate";
79     }
80     else if (Task::TASK_RELEASE == task)
81     {
82         event = "deactivate";
83     }
84     else
85     {
86         event = "";
87     }
88
89     json_object *json_in = json_object_new_object();
90     json_object_object_add(json_in, "event", json_object_new_string(event));
91     json_object_object_add(json_in, "role", json_object_new_string(role.c_str()));
92     json_object_object_add(json_in, "area", json_object_new_string(area.c_str()));
93
94     int ret;
95     ret = this->pm.setInputEventData(json_in);
96     if (0 > ret)
97     {
98         HMI_ERROR("wm:pmw", "Faild to set input event data to PolicyManager");
99     }
100     json_object_put(json_in);
101
102     return ret;
103 }
104
105 int PMWrapper::executeStateTransition()
106 {
107     int ret;
108     ret = this->pm.executeStateTransition();
109     if (0 > ret)
110     {
111         HMI_ERROR("wm:pmw", "Failed to execute state transition for PolicyManager");
112     }
113
114     return ret;
115 }
116
117 void PMWrapper::undoState()
118 {
119     this->pm.undoState();
120
121     this->crrlayer2rolestate = this->prvlayer2rolestate;
122 }
123
124 void PMWrapper::updateStates(json_object *json_out)
125 {
126     std::vector<WMAction> actions;
127
128     HMI_DEBUG("wm", "json_out dump:%s", json_object_get_string(json_out));
129
130     this->createLayoutChangeAction(json_out, actions);
131
132     this->on_state_transitioned(actions);
133 }
134
135 void PMWrapper::createLayoutChangeAction(json_object *json_out, std::vector<WMAction> &actions)
136 {
137     // Get displayed roles from previous layout
138     json_object *json_layers;
139     if (!json_object_object_get_ex(json_out, "layers", &json_layers))
140     {
141         HMI_DEBUG("wm", "Not found key \"layers\"");
142         return;
143     }
144
145     int len = json_object_array_length(json_layers);
146     HMI_DEBUG("wm", "json_layers len:%d", len);
147
148     for (int i = 0; i < len; i++)
149     {
150         json_object *json_tmp = json_object_array_get_idx(json_layers, i);
151
152         std::string layer_name = jh::getStringFromJson(json_tmp, "name");
153         json_bool changed = jh::getBoolFromJson(json_tmp, "changed");
154         HMI_DEBUG("wm", "layer:%s changed:%d", layer_name.c_str(), changed);
155
156         if (changed)
157         {
158             json_object *json_areas;
159             if (!json_object_object_get_ex(json_tmp, "areas", &json_areas))
160             {
161                 HMI_DEBUG("wm", "Not found key \"areas\"");
162                 return;
163             }
164
165             int len = json_object_array_length(json_areas);
166             HMI_DEBUG("wm", "json_layers len:%d", len);
167
168             // Store previous role state in this layer
169             this->prvlayer2rolestate[layer_name] = this->crrlayer2rolestate[layer_name];
170
171             RoleState crr_roles;
172             RoleState prv_roles = this->prvlayer2rolestate[layer_name];
173             for (int j = 0; j < len; j++)
174             {
175                 json_object *json_tmp2 = json_object_array_get_idx(json_areas, j);
176
177                 std::string area_name = jh::getStringFromJson(json_tmp2, "name");
178                 std::string role_name = jh::getStringFromJson(json_tmp2, "role");
179
180                 crr_roles[role_name] = area_name;
181
182                 auto i_prv = prv_roles.find(role_name);
183                 HMI_DEBUG("wm", "current role:%s area:%s",
184                           role_name.c_str(), area_name.c_str());
185
186                 // If current role does not exist in previous
187                 if (prv_roles.end() == i_prv)
188                 {
189                     HMI_DEBUG("wm", "current role does not exist in previous");
190
191                     // Set activate action
192                     bool end_draw_finished = false;
193                     WMAction act
194                     {
195                         "",
196                         role_name,
197                         area_name,
198                         TaskVisible::VISIBLE,
199                         end_draw_finished
200                     };
201                     actions.push_back(act);
202                 }
203                 else
204                 {
205                     HMI_DEBUG("wm", "previous role:%s area:%s",
206                               i_prv->first.c_str(), i_prv->second.c_str());
207
208                     // If current role exists in previous and area is different with previous
209                     if (area_name != i_prv->second)
210                     {
211                         HMI_DEBUG("wm", "current role exists in previous and area is different with previous");
212
213                         // Set activate action
214                         bool end_draw_finished = false;
215                         WMAction act
216                         {
217                             "",
218                             role_name,
219                             area_name,
220                             TaskVisible::VISIBLE,
221                             end_draw_finished
222                         };
223                         actions.push_back(act);
224                     }
225
226                     // Remove role which exist in current list from previous list
227                     prv_roles.erase(i_prv);
228                 }
229             }
230
231             // Deactivate roles which remains in previous list
232             // because these are not displayed in current layout
233             for (auto i_prv : prv_roles)
234             {
235                 HMI_DEBUG("wm", "Deactivate role:%s", i_prv.first.c_str());
236
237                 // Set deactivate action
238                 bool end_draw_finished = true;
239                 WMAction act
240                 {
241                     "",
242                     i_prv.first,
243                     "",
244                     TaskVisible::INVISIBLE,
245                     end_draw_finished
246                 };
247                 actions.push_back(act);
248             }
249
250             // Update previous role list
251             this->crrlayer2rolestate[layer_name] = crr_roles;
252         }
253     }
254 }
255
256 void PMWrapper::processError()
257 {
258     this->on_error();
259 }
260
261 } // namespace wm