Pop item from queue to prevent duplicated request
[platform/core/uifw/capi-ui-sticker.git] / receiver / src / main.cpp
1 /*
2  * Copyright (c) 2020 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 #include <app_common.h>
18 #include <service_app.h>
19 #include <stdlib.h>
20 #include <app_event.h>
21 #include <device/battery.h>
22 #include <vconf.h>
23 #include <string>
24 #include <app_preference.h>
25 #include <Ecore.h>
26
27 #include "main.h"
28 #include "ft.h"
29 #include "log.h"
30 #include "config.h"
31 #include "receiver_preference.h"
32 #include "sticker_info.h"
33
34 using namespace std;
35
36 static bool check_rw_mount();
37
38 static bool app_create(void *data)
39 {
40     /* Hook to take necessary actions before main event loop starts
41        Initialize UI resources and application's data
42        If this function returns true, the main loop of application starts
43        If this function returns false, the application is terminated */
44
45     if (!check_rw_mount()) {
46         service_app_exit();
47         return true;
48     }
49
50     STLOGD("");
51
52     char log_path[PATH_MAX];
53     char *data_path = NULL;
54     data_path = app_get_shared_data_path();
55     snprintf(log_path, sizeof(log_path), "%s/log", data_path);
56
57     if (data_path)
58         free(data_path);
59
60     if (access(log_path, F_OK) != 0) {
61         if (mkdir(log_path, 0755) == -1) {
62             STLOGE("directory create error");
63         }
64     }
65
66     create_sticker_provider_handle();
67
68     return true;
69 }
70
71 static bool check_battery_condition()
72 {
73     int battery_percentage = 0;
74     int ret;
75
76     // check battery percentage
77     ret = device_battery_get_percent(&battery_percentage);
78     if (ret != DEVICE_ERROR_NONE)
79     {
80         STLOGW("No sync. Failed to get battery percent. error : %d", ret);
81         return false;
82     }
83
84     STLOGI("battery percent : %d", battery_percentage);
85     if (battery_percentage >= MINIMUM_BATTERY)
86         return true;
87     else
88     {
89         STLOGI("No sync due to insufficient battery");
90         return false;
91     }
92 }
93
94 static bool check_sync_time_condition()
95 {
96     double last_sync_time;
97     int feature_flag = 0;
98     bool result = false;
99
100 #ifdef VCONFKEY_STICKER_SUPPORTED_FEATURE
101     // Check whether oobe has been done
102     if (vconf_get_int(VCONFKEY_STICKER_SUPPORTED_FEATURE, &feature_flag) == 0 && feature_flag > 0)
103     {
104         if (preference_get_double(LAST_SYNC_TIME, &last_sync_time) != PREFERENCE_ERROR_NONE)
105         {
106             STLOGD("Can't get last sync time.");
107             return true;
108         }
109
110         // compare time
111         double timediff = ecore_time_unix_get() - last_sync_time;
112         STLOGD("current time : %.3f, last_sync_time : %.3f, diff : %.3f", ecore_time_unix_get(), last_sync_time, timediff);
113
114         if (timediff > MAX_WAIT_TIME) {
115             STLOGD("Starting manual synchronization");
116             initialize_sap();
117             if (false == request_show_sync_notification())
118                 push_sticker_request(REQUEST_TYPE_SHOW_NOTIFICATION, NULL, NULL, NULL);
119             result = false;
120         } else {
121             if (timediff > SYNC_INTERVAL)
122                 result = true;
123             else
124                 result = false;
125         }
126     }
127     else
128     {
129         result = false;
130     }
131 #endif /* VCONFKEY_STICKER_SUPPORTED_FEATURE */
132
133     return result;
134 }
135
136 bool check_rw_mount()
137 {
138     char *data_path = NULL;
139     bool rw_mount = false;
140     data_path = app_get_shared_data_path();
141     if (!data_path) return false;
142
143     if (access(data_path, R_OK) == 0)
144         rw_mount = true;
145
146     free(data_path);
147
148     if (!rw_mount) {
149         SECURE_LOGE("Can't access rw storage\n");
150     }
151
152     return rw_mount;
153 }
154
155 static void process_request(app_control_h app_control, char *request)
156 {
157     char* mode = NULL;
158     char* type = NULL;
159
160     if (strcmp(request, "sync") == 0) {
161         bool param_error = false;
162         if (app_control_get_extra_data(app_control, "mode", &mode) != APP_CONTROL_ERROR_NONE) {
163             STLOGE("No given mode");
164             param_error = true;
165         }
166
167         if (app_control_get_extra_data(app_control, "type", &type) != APP_CONTROL_ERROR_NONE) {
168             STLOGE("No given type");
169             param_error = true;
170         }
171
172         STLOGI("[sync request] mode : %s, type : %s", mode, type);
173         if (param_error)
174             goto cleanup;
175
176         if (mode && type) {
177             if (check_battery_condition()) {
178                 if (check_sync_time_condition()) {
179                     if (preference_set_int(LAST_SYNC_STATUS, LAST_SYNC_STATUS_SYNC_NEEDED) != PREFERENCE_ERROR_NONE)
180                         STLOGE("Failed to set sync status as NEEDED");
181
182                     if (!is_init_sap())
183                         initialize_sap();
184                     request_all_sticker_data(mode, type);
185                 } else { // Under the sync interval time. Need to check whether last sync was succeded or not.
186                     int last_sync_status = 0;
187
188                     if (preference_get_int(LAST_SYNC_STATUS, &last_sync_status) != PREFERENCE_ERROR_NONE) {
189                         STLOGE("Failed to get sync status. Default action is exit.");
190                         goto cleanup;
191                     }
192
193                     if (last_sync_status == LAST_SYNC_STATUS_SYNC_NEEDED) {
194                         STLOGD("Last sync status is NEEDED(code: %d). Retrying to sync.", last_sync_status);
195                         if (!is_init_sap())
196                             initialize_sap();
197                         request_all_sticker_data(mode, type);
198                     } else {
199                         STLOGD("Last sync status is SUCCESS(code: %d). Don't have to retrying sync", last_sync_status);
200                     }
201                 }
202             } else {
203                 STLOGD("Not enough battery.");
204             }
205         }
206     }
207     else if (strcmp(request, "oobe") == 0) {
208         initialize_sap();
209
210         if (false == request_sticker_feature())
211             push_sticker_request(REQUEST_TYPE_FEATURE_REQ, NULL, NULL, NULL);
212     }
213     else {
214         STLOGW("Unknown command : %s", request);
215         if (!is_init_sap()) {
216             service_app_exit();
217         }
218     }
219
220 cleanup:
221     if (NULL != mode)
222         free(mode);
223
224     if (NULL != type)
225         free(type);
226 }
227
228 static void process_auto_sync()
229 {
230     if (is_init_sap()) {
231         STLOGD("continue doing current job");
232         return;
233     }
234
235     if (check_sync_time_condition()) {
236         if (check_battery_condition()) {
237             STLOGD("Starting auto synchronization");
238             if (preference_set_int(LAST_SYNC_STATUS, LAST_SYNC_STATUS_SYNC_NEEDED) != PREFERENCE_ERROR_NONE)
239                 STLOGE("Failed to set sync status as NEEDED");
240             initialize_sap();
241
242             if (false == request_sticker_feature())
243                 push_sticker_request(REQUEST_TYPE_FEATURE_REQ, NULL, NULL, NULL);
244
245             push_sticker_request(REQUEST_TYPE_AUTOSYNC, NULL, NULL, NULL);
246         }
247         else {
248             STLOGI("The status of battery is low");
249             if (!get_job_progress()) {
250                 STLOGD("exit");
251                 service_app_exit();
252             }
253         }
254     }
255     else {
256         if (!get_job_progress()) {
257             int last_sync_status = 0;
258             if (preference_get_int(LAST_SYNC_STATUS, &last_sync_status) != PREFERENCE_ERROR_NONE) {
259                 STLOGE("Failed to get sync status. Default action is exit.");
260                 service_app_exit();
261             }
262
263             if (last_sync_status == LAST_SYNC_STATUS_SYNC_NEEDED) {
264                 STLOGD("Last sync status is NEEDED(code: %d). Retrying to sync.", last_sync_status);
265                 initialize_sap();
266
267                 if (false == request_sticker_feature())
268                     push_sticker_request(REQUEST_TYPE_FEATURE_REQ, NULL, NULL, NULL);
269
270                 push_sticker_request(REQUEST_TYPE_AUTOSYNC, NULL, NULL, NULL);
271             } else {
272                 STLOGD("Last sync status is SUCCESS(code: %d). Don't have to retrying sync", last_sync_status);
273                 service_app_exit();
274             }
275         }
276     }
277 }
278
279 static void get_sticker_feature()
280 {
281 #ifdef VCONFKEY_STICKER_SUPPORTED_FEATURE
282     // Check whether oobe has been done
283     int feature_flag = 0;
284     if (vconf_get_int(VCONFKEY_STICKER_SUPPORTED_FEATURE, &feature_flag) == 0 && feature_flag == 0) {
285         STLOGD("Request to get sticker feature");
286         initialize_sap();
287
288         if (false == request_sticker_feature())
289             push_sticker_request(REQUEST_TYPE_FEATURE_REQ, NULL, NULL, NULL);
290     }
291     else {
292         if (!is_init_sap())
293             service_app_exit();
294     }
295 #endif
296 }
297
298 static void app_control(app_control_h app_control, void *data)
299 {
300     /* Handle the launch request. */
301     char* request = NULL;
302     char* operation = NULL;
303     char* event_value = NULL;
304     char* uri = NULL;
305     const char *event_uri = "event://tizen.system.event.battery_charger_status";
306     int res;
307
308     if (!check_rw_mount())
309         service_app_exit();
310
311     // operation
312     int ret = app_control_get_operation(app_control, &operation);
313     if (ret != APP_CONTROL_ERROR_NONE) {
314         STLOGW("Failed to get operation. error : %d", ret);
315         return;
316     }
317
318     STLOGD("operation: %s", operation);
319
320     if (!operation) {
321         goto cleanup;
322     }
323
324     if (strcmp(operation, APP_CONTROL_OPERATION_LAUNCH_ON_EVENT) == 0)
325     {
326         ret = app_control_get_uri(app_control, &uri);
327         if (ret == APP_CONTROL_ERROR_NONE && uri)
328         {
329             if (strncmp(uri, event_uri, strlen(event_uri) + 1) == 0)
330             {
331                 ret = app_control_get_extra_data(app_control, "battery_charger_status", &event_value);
332                 if (ret == APP_CONTROL_ERROR_NONE && event_value)
333                 {
334                     if (string(event_value) == "connected")
335                     {
336                         STLOGI("The charger state is connected");
337                         process_auto_sync();
338                     }
339                     free(event_value);
340                 }
341             }
342             free(uri);
343         }
344     }
345     else if (strcmp(operation, APP_CONTROL_OPERATION_DEFAULT) == 0) {
346         res = app_control_get_extra_data(app_control, "request", &request);
347         STLOGD("get extra data result : %d, request : %s", res, request);
348         if (APP_CONTROL_ERROR_NONE == res && NULL != request) {
349             process_request(app_control, request);
350         }
351         else {
352             STLOGD("booting");
353             get_sticker_feature();
354         }
355     }
356
357 cleanup:
358     if (NULL != operation)
359         free(operation);
360
361     if (NULL != request)
362         free(request);
363 }
364
365 static void app_terminate(void *data)
366 {
367     /* Release all resources. */
368     STLOGD("");
369     destroy_sticker_provider_handle();
370     deinitialize_sap();
371 }
372
373 int main(int argc, char *argv[])
374 {
375     int ret = 0;
376
377     service_app_lifecycle_callback_s event_callback;
378     memset(&event_callback, 0x0, sizeof(service_app_lifecycle_callback_s));
379
380     event_callback.create = (service_app_create_cb)app_create;
381     event_callback.terminate = (service_app_terminate_cb)app_terminate;
382     event_callback.app_control = (service_app_control_cb)app_control;
383
384     ret = service_app_main(argc, argv, &event_callback, NULL);
385     if (ret != APP_ERROR_NONE) {
386         STLOGE("app_main() is failed. err = %d", ret);
387     }
388     return ret;
389 }