Change homescreen over appsY
[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 "util.hpp"
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("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(std::string ecu_name)
47 {
48     int ret = 0;
49
50     ret = this->pm.initialize(ecu_name);
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 if (Task::TASK_PARKING_BRAKE_OFF == task)
85     {
86         event = "parking_brake_off";
87     }
88     else if (Task::TASK_PARKING_BRAKE_ON == task)
89     {
90         event = "parking_brake_on";
91     }
92     else if (Task::TASK_ACCEL_PEDAL_OFF == task)
93     {
94         event = "accel_pedal_off";
95     }
96     else if (Task::TASK_ACCEL_PEDAL_ON == task)
97     {
98         event = "accel_pedal_on";
99     }
100     else if (Task::TASK_HEDLAMP_OFF == task)
101     {
102         event = "headlamp_off";
103     }
104     else if (Task::TASK_HEDLAMP_ON == task)
105     {
106         event = "headlamp_on";
107     }
108     else if (Task::TASK_LIGHTSTATUS_BRAKE_OFF == task)
109     {
110         event = "lightstatus_brake_off";
111     }
112     else if (Task::TASK_LIGHTSTATUS_BRAKE_ON == task)
113     {
114         event = "lightstatus_brake_on";
115     }
116    else
117     {
118         event = "";
119     }
120
121     json_object *json_in = json_object_new_object();
122     json_object_object_add(json_in, "event", json_object_new_string(event));
123     json_object_object_add(json_in, "role", json_object_new_string(role.c_str()));
124     json_object_object_add(json_in, "area", json_object_new_string(area.c_str()));
125
126     int ret;
127     ret = this->pm.setInputEventData(json_in);
128     if (0 > ret)
129     {
130         HMI_ERROR("wm:pmw", "Faild to set input event data to PolicyManager");
131     }
132     json_object_put(json_in);
133
134     return ret;
135 }
136
137 int PMWrapper::executeStateTransition()
138 {
139     int ret;
140     ret = this->pm.executeStateTransition();
141     if (0 > ret)
142     {
143         HMI_ERROR("wm:pmw", "Failed to execute state transition for PolicyManager");
144     }
145
146     return ret;
147 }
148
149 void PMWrapper::undoState()
150 {
151     this->pm.undoState();
152
153     this->crrlayer2rolestate = this->prvlayer2rolestate;
154 }
155
156 void PMWrapper::updateStates(json_object *json_out)
157 {
158     std::vector<WMAction> actions;
159
160     HMI_DEBUG("json_out dump:%s", json_object_get_string(json_out));
161
162     this->createCarStateChangeAction(json_out, actions);
163     this->createLayoutChangeAction(json_out, actions);
164
165     this->on_state_transitioned(actions);
166 }
167
168 void PMWrapper::createCarStateChangeAction(json_object *json_out, std::vector<WMAction> &actions)
169 {
170     json_object *json_car_ele;
171     if (!json_object_object_get_ex(json_out, "car_elements", &json_car_ele))
172     {
173         HMI_DEBUG("Not found key \"car_elements\"");
174         return;
175     }
176
177     int len = json_object_array_length(json_car_ele);
178     HMI_DEBUG("json_car_ele len:%d", len);
179
180     for (int i = 0; i < len; i++)
181     {
182         json_object *json_tmp = json_object_array_get_idx(json_car_ele, i);
183
184         std::string car_ele_name = jh::getStringFromJson(json_tmp, "name");
185         std::string state = jh::getStringFromJson(json_tmp, "state");
186         json_bool changed = jh::getBoolFromJson(json_tmp, "changed");
187         HMI_DEBUG("car_element:%s changed:%d", car_ele_name.c_str(), changed);
188
189         if (changed)
190         {
191             TaskCarState task = TaskCarState::NO_TASK;
192             if ("parking_brake" == car_ele_name)
193             {
194                 if ("off" == state)
195                 {
196                     task = TaskCarState::PARKING_BRAKE_OFF;
197                 }
198                 else if ("on" == state)
199                 {
200                     task = TaskCarState::PARKING_BRAKE_ON;
201                 }
202                 else
203                 {
204                     HMI_DEBUG("Unknown parking brake state: %s", state.c_str());
205                 }
206             }
207             else if ("accel_pedal" == car_ele_name)
208             {
209                 if ("off" == state)
210                 {
211                     task = TaskCarState::ACCEL_PEDAL_OFF;
212                 }
213                 else if ("on" == state)
214                 {
215                     task = TaskCarState::ACCEL_PEDAL_ON;
216                 }
217                 else
218                 {
219                     HMI_DEBUG("Unknown accel pedal state: %s", state.c_str());
220                 }
221             }
222             else if ("lamp" == car_ele_name)
223             {
224                 if ("off" == state)
225                 {
226                     task = TaskCarState::HEDLAMP_OFF;
227                 }
228                 else if ("on" == state)
229                 {
230                     task = TaskCarState::HEDLAMP_ON;
231                 }
232                 else
233                 {
234                     HMI_DEBUG("Unknown lamp state: %s", state.c_str());
235                 }
236             }
237             else if ("lightstatus_brake" == car_ele_name)
238             {
239                 if ("off" == state)
240                 {
241                     task = TaskCarState::LIGHTSTATUS_BRAKE_OFF;
242                 }
243                 else if ("on" == state)
244                 {
245                     task = TaskCarState::LIGHTSTATUS_BRAKE_ON;
246                 }
247                 else
248                 {
249                     HMI_DEBUG("Unknown lightstatus brake state: %s", state.c_str());
250                 }
251             }
252             else if ("running" == car_ele_name)
253             {
254                 if ("stop" == state)
255                 {
256                     task = TaskCarState::CAR_STOP;
257                 }
258                 else if ("run" == state)
259                 {
260                     task = TaskCarState::CAR_RUN;
261                 }
262                 else
263                 {
264                     HMI_DEBUG("Unknown car state: %s", state.c_str());
265                 }
266             }
267             else if ("restriction_mode" == car_ele_name)
268             {
269                 if ("off" == state)
270                 {
271                     task = TaskCarState::RESTRICTION_MODE_OFF;
272                 }
273                 else if ("on" == state)
274                 {
275                     task = TaskCarState::RESTRICTION_MODE_ON;
276                 }
277                 else
278                 {
279                     HMI_DEBUG("Unknown car state: %s", state.c_str());
280                 }
281             }
282             else
283             {
284                 HMI_DEBUG("Unknown car element: %s", car_ele_name.c_str());
285             }
286
287             // Set action
288             if (TaskCarState::NO_TASK != task)
289             {
290                 bool end_draw_finished = true;
291                 WMAction act
292                 {
293                     0,
294                     nullptr,
295                     "",
296                     "",
297                     TaskVisible::NO_CHANGE,
298                     end_draw_finished,
299                     task
300                 };
301                 actions.push_back(act);
302             }
303         }
304     }
305 }
306
307 void PMWrapper::createLayoutChangeAction(json_object *json_out, std::vector<WMAction> &actions)
308 {
309     // Get displayed roles from previous layout
310     json_object *json_layers;
311     if (!json_object_object_get_ex(json_out, "layers", &json_layers))
312     {
313         HMI_DEBUG("Not found key \"layers\"");
314         return;
315     }
316
317     int len = json_object_array_length(json_layers);
318     HMI_DEBUG("json_layers len:%d", len);
319
320     for (int i = 0; i < len; i++)
321     {
322         json_object *json_tmp = json_object_array_get_idx(json_layers, i);
323
324         std::string layer_name = jh::getStringFromJson(json_tmp, "name");
325         json_bool changed = jh::getBoolFromJson(json_tmp, "changed");
326         HMI_DEBUG("layer:%s changed:%d", layer_name.c_str(), changed);
327
328         if (changed)
329         {
330             json_object *json_areas;
331             if (!json_object_object_get_ex(json_tmp, "areas", &json_areas))
332             {
333                 HMI_DEBUG("Not found key \"areas\"");
334                 return;
335             }
336
337             int len = json_object_array_length(json_areas);
338             HMI_DEBUG("json_layers len:%d", len);
339
340             // Store previous role state in this layer
341             this->prvlayer2rolestate[layer_name] = this->crrlayer2rolestate[layer_name];
342
343             RoleState crr_roles;
344             RoleState prv_roles = this->prvlayer2rolestate[layer_name];
345             for (int j = 0; j < len; j++)
346             {
347                 json_object *json_tmp2 = json_object_array_get_idx(json_areas, j);
348
349                 std::string area_name = jh::getStringFromJson(json_tmp2, "name");
350                 std::string role_name = jh::getStringFromJson(json_tmp2, "role");
351
352                 crr_roles[role_name] = area_name;
353
354                 auto i_prv = prv_roles.find(role_name);
355                 HMI_DEBUG("current role:%s area:%s",
356                           role_name.c_str(), area_name.c_str());
357
358                 // If current role does not exist in previous
359                 if (prv_roles.end() == i_prv)
360                 {
361                     HMI_DEBUG("current role does not exist in previous");
362
363                     // Set activate action
364                     bool end_draw_finished = false;
365                     WMAction act
366                     {
367                         0,
368                         nullptr,
369                         role_name,
370                         area_name,
371                         TaskVisible::VISIBLE,
372                         end_draw_finished,
373                         TaskCarState::NO_TASK
374                     };
375                     actions.push_back(act);
376                 }
377                 else
378                 {
379                     HMI_DEBUG("previous role:%s area:%s",
380                               i_prv->first.c_str(), i_prv->second.c_str());
381
382                     // If current role exists in previous and area is different with previous
383                     if (area_name != i_prv->second)
384                     {
385                         HMI_DEBUG("current role exists in previous and area is different with previous");
386
387                         // Set activate action
388                         bool end_draw_finished = false;
389                         WMAction act
390                         {
391                             0,
392                             nullptr,
393                             role_name,
394                             area_name,
395                             TaskVisible::VISIBLE,
396                             end_draw_finished,
397                             TaskCarState::NO_TASK
398                         };
399                         actions.push_back(act);
400                     }
401
402                     // Remove role which exist in current list from previous list
403                     prv_roles.erase(i_prv);
404                 }
405             }
406
407             // Deactivate roles which remains in previous list
408             // because these are not displayed in current layout
409             for (auto i_prv : prv_roles)
410             {
411                 HMI_DEBUG("Deactivate role:%s", i_prv.first.c_str());
412
413                 // Set deactivate action
414                 bool end_draw_finished = true;
415                 WMAction act
416                 {
417                     0,
418                     nullptr,
419                     i_prv.first,
420                     "",
421                     TaskVisible::INVISIBLE,
422                     end_draw_finished,
423                     TaskCarState::NO_TASK
424                 };
425                 actions.push_back(act);
426             }
427
428             // Update previous role list
429             this->crrlayer2rolestate[layer_name] = crr_roles;
430         }
431     }
432 }
433
434 void PMWrapper::processError()
435 {
436     this->on_error();
437 }
438
439 } // namespace wm