Merge "Revert "[SystemInfo] Replace deprecated native wifi API with wifi-manager...
[platform/core/api/webapi-plugins.git] / src / convergence / convergence_remote_app_control_service.cc
1 /*
2  * Copyright (c) 2015 Samsung Electronics Co., Ltd All Rights Reserved
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 // TODO check includes
18 #include "convergence/convergence_remote_app_control_service.h"
19
20 #include <glib.h>
21 #include <d2d_conv_internal.h>
22
23 #include "convergence/convergence_instance.h"
24 #include "convergence/convergence_payload.h"
25 #include "common/logger.h"
26
27 namespace extension {
28 namespace convergence {
29
30 using common::TizenResult;
31 using common::TizenSuccess;
32
33 namespace {
34 // Payload data keys and some values
35 static const std::string kPayload = "payload"; // ---
36
37 // Service connection status keys
38 static const std::string kServiceConnectionStatus = "connect_status"; // ---
39 static const std::string kServiceConnectionStatusConnected = "service_connected";
40 static const std::string kServiceConnectionStatusNotConnected = "service_not_connected";
41
42 // Service listener status keys
43 static const std::string kServiceListenerStatus = "listener_status"; //---
44 static const std::string kServiceListenerStatusOk = "listener_ok"; // ---
45 static const std::string kServiceListenerStatusError = "listener_error"; //---
46 static const std::string kServiceListenerError = "listener_error"; //---
47 } // namespace
48
49 ConvergenceRemoteAppControlService::ConvergenceRemoteAppControlService()
50  : ConvergenceService()
51  , started_(false) {
52   ScopeLogger();
53 }
54
55 ConvergenceRemoteAppControlService::ConvergenceRemoteAppControlService(conv_device_h device, ConvergenceInstance *convergence_plugin)
56  : ConvergenceService(device, CONV_SERVICE_REMOTE_APP_CONTROL, convergence_plugin)
57  , started_(false) {
58   ScopeLogger();
59 }
60
61 ConvergenceRemoteAppControlService::~ConvergenceRemoteAppControlService() {
62   ScopeLogger();
63
64   // Release all memory, used by callback paramerers
65   for (size_t i = 0; i < callback_param_gc_.size(); i++) {
66     delete callback_param_gc_[i];
67   }
68   callback_param_gc_.clear();
69 }
70
71 void ConvergenceRemoteAppControlService::ServiceConnectedCb(conv_service_h service_handle,
72   conv_error_e error, conv_payload_h result, void* user_data) {
73   ScopeLogger();
74
75   CallbackParam *callbackParam = static_cast<CallbackParam *>(user_data);
76   if (!callbackParam) {
77     LoggerE("ERROR! NULL user data in Service Connect Callback");
78     return;
79   }
80
81   picojson::object param;
82   param["result_type"] = picojson::value("Connected");
83   //param[kPayload] = ConvergenceRemoteAppControlService::PayloadToJson(result);
84
85   if (CONV_ERROR_NONE == error) {
86     param[kServiceConnectionStatus] = picojson::value(kServiceConnectionStatusConnected);
87     callbackParam->plugin_->ReplyAsync(kRemoteAppControlListenerCallback,
88       callbackParam->callback_id_,
89       true,
90       param);
91   } else {
92     // Error occured during connection
93     param[kServiceConnectionStatus] = picojson::value(kServiceConnectionStatusNotConnected);
94     callbackParam->plugin_->ReplyAsync(kRemoteAppControlListenerCallback,
95       callbackParam->callback_id_,
96       false,
97       param);
98   }
99 }
100
101 common::TizenResult ConvergenceRemoteAppControlService::Connect(const int cur_listener_id) {
102   ScopeLogger();
103
104   conv_service_h service = FindServiceHandle();
105   if (!service) {
106     return LogAndCreateTizenError(NotFoundError,
107       "Service with specified type does not exist");
108   }
109
110   // TODO: make a garbage collection and release this memory when service is disconnected
111   // and when whole manager is destructed
112   CallbackParam *param = new CallbackParam(convergence_plugin_, cur_listener_id);
113   callback_param_gc_.push_back(param);
114
115   const int error = conv_service_connect(service, ServiceConnectedCb, param);
116   if (CONV_ERROR_NONE != error) {
117     // TODO: Handle error
118     trace_conv_error(error, __LINE__, "conv_service_connect");
119   }
120
121   return TizenSuccess();
122 }
123
124 common::TizenResult ConvergenceRemoteAppControlService::Disconnect() {
125   ScopeLogger();
126
127   conv_service_h service = FindServiceHandle();
128   if (!service)
129     return LogAndCreateTizenError(NotFoundError,
130       "Service with specified type does not exist");
131
132   const int error = conv_service_disconnect(service);
133   if (CONV_ERROR_NONE != error) {
134     // TODO: Handle error
135     trace_conv_error(error, __LINE__, "conv_service_disconnect");
136   }
137
138   return TizenSuccess();
139 }
140
141 void ConvergenceRemoteAppControlService::ServiceListenerCb(conv_service_h service_handle,
142   conv_channel_h channel_handle,
143   conv_error_e error, conv_payload_h result, void* user_data) {
144   ScopeLogger();
145
146   CallbackParam *callbackParam = static_cast<CallbackParam *>(user_data);
147   if (!callbackParam) {
148     LoggerE("ERROR! NULL user data in Service Listener Callback");
149     return;
150   }
151
152   picojson::object param;
153   param["payload"] = picojson::value("TODO");
154
155   // TODO parse the payload and fill the param
156
157   const std::string result_type = ConvergencePayloadArray::ExtractPayloadString(result, "result_type"); // TODO extract to constant kResultType = "result_type";
158   param["result_type"] = picojson::value(result_type);
159
160
161   if (CONV_ERROR_NONE == error) {
162     param[kServiceListenerStatus] = picojson::value(kServiceListenerStatusOk);
163     callbackParam->plugin_->ReplyAsync(kRemoteAppControlListenerCallback,
164       callbackParam->callback_id_,
165       true,
166       param);
167   } else {
168     // Error occured during connection
169     param[kServiceListenerStatus] = picojson::value(kServiceListenerStatusError);
170     param[kServiceListenerError] = picojson::value(static_cast<double>(error));
171     callbackParam->plugin_->ReplyAsync(kRemoteAppControlListenerCallback,
172       callbackParam->callback_id_,
173       false,
174       param);
175   }
176 }
177
178 void ConvergenceRemoteAppControlService::UpdateListener(const int cur_listener_id) {
179   ScopeLogger();
180   // TODO: make a garbage collection and release this memory when callback unset
181   // and when whole manager is destructed
182   CallbackParam *param = new CallbackParam(convergence_plugin_, cur_listener_id);
183   callback_param_gc_.push_back(param);
184
185   conv_service_h service_handle = FindServiceHandle();
186   if (!service_handle) {
187     LoggerE("AAAAAA!!! Service not found");
188     return;
189   }
190   const int error = conv_service_set_listener_cb(service_handle, ServiceListenerCb, param);
191   if (CONV_ERROR_NONE != error) {
192     // TODO: Handle error
193     trace_conv_error(error, __LINE__, "conv_service_set_listener_cb");
194   } else {
195     LoggerI("Listener is set correctly");
196   }
197 }
198
199 void ConvergenceRemoteAppControlService::EnsureStarted() {
200   ScopeLogger();
201   if (started_)
202     return;
203
204   conv_service_h service_handle = FindServiceHandle();
205   if (!service_handle) {
206     LoggerE("AAAAAA!!! Service not found");
207     return; // TODO handle error
208   }
209
210   const int error = conv_service_start(service_handle, nullptr, nullptr);
211   if (CONV_ERROR_NONE != error) {
212     // TODO: Handle error
213     trace_conv_error(error, __LINE__, "conv_service_publish START");
214   } else {
215     LoggerI("APP CONTROL SERVICE IS STARTED");
216     started_ = true;
217   }
218 }
219
220 common::TizenResult ConvergenceRemoteAppControlService::Launch(const char *appId, bool reply, const int cur_listener_id) {
221   ScopeLogger();
222
223   conv_service_h service_handle = FindServiceHandle();
224   if (!service_handle) {
225     LoggerE("AAAAAA!!! Service not found");
226     return LogAndCreateTizenError(NotFoundError,
227      "Service with specified type does not exist");
228   }
229
230   // Create app control payload with passed appId
231   conv_payload_h payload = CreateAppIdPayload(appId, reply);
232   if (!payload) {
233     // Handle error
234     return TizenSuccess(); // TODO TizenError
235   }
236
237   // Update listener: assign it if it is not yet assigned
238   if (reply)
239     UpdateListener(cur_listener_id);
240
241   // Ensure the service was started
242   EnsureStarted();
243
244   // Sending app control on the remote device
245   const int error = conv_service_publish(service_handle, nullptr, payload);
246   if (CONV_ERROR_NONE != error) {
247     // TODO: Handle error
248     trace_conv_error(error, __LINE__, "conv_service_publish LAUNCH");
249   } else {
250     LoggerI("---- SEEMS APP CONTROL WAS LAUNCHED ----");
251   }
252
253 /*
254         conv_service_start(service_handle, NULL, NULL);
255         conv_payload_h payload_handle;
256         conv_payload_create(&payload_handle);
257         app_control_h app_control = NULL;
258         app_control_create(&app_control);
259         app_control_set_app_id(app_control, "org.example.d2d_test");
260         app_control_set_operation(app_control, APP_CONTROL_OPERATION_MAIN);
261         conv_payload_set_app_control(payload_handle, "app_control", app_control);
262         conv_payload_set_string(payload_handle, "reply", "0");
263         conv_service_publish(service_handle, NULL, payload_handle);
264 */
265
266   conv_payload_destroy(payload);
267   return TizenSuccess();
268 }
269
270 conv_payload_h ConvergenceRemoteAppControlService::CreateAppIdPayload(const char *appId, bool reply) const {
271   ScopeLogger();
272
273   conv_payload_h payload = nullptr;
274   int error = conv_payload_create(&payload);
275   if (CONV_ERROR_NONE != error) {
276     // Handle error
277   }
278
279   app_control_h app_control = nullptr;
280   error = app_control_create(&app_control);
281   if (APP_CONTROL_ERROR_NONE != error) {
282     LoggerE("ERROR! AppControl API error [%d]", error);
283   }
284
285   error = app_control_set_app_id(app_control, appId);
286   if (APP_CONTROL_ERROR_NONE != error) {
287     LoggerE("ERROR! AppControl API error [%d]", error);
288   }
289
290   error = app_control_set_operation(app_control, APP_CONTROL_OPERATION_MAIN);
291   if (CONV_ERROR_NONE != error) {
292     // Handle error
293   }
294
295   error = conv_payload_set_app_control(payload, "app_control", app_control);
296   if (APP_CONTROL_ERROR_NONE != error) {
297     // Handle error
298   }
299
300   if (reply) {
301     error = conv_payload_set_string(payload, "reply", "1");
302     if (CONV_ERROR_NONE != error) {
303       // Handle error
304     }
305   }
306
307   return payload;
308 }
309
310 picojson::value ConvergenceRemoteAppControlService::PayloadToJson(conv_payload_h payload) {
311   ScopeLogger();
312   picojson::value payload_json;
313
314   // TODO convert payload to array of ApplicationControlData
315
316   return payload_json;
317 }
318
319 } // namespace convergence
320 }  // namespace extension