Init/Deinit sync when BT attached/detached
[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             request_show_sync_notification();
118             result = false;
119         } else {
120             if (timediff > SYNC_INTERVAL)
121                 result = true;
122             else
123                 result = false;
124         }
125     }
126     else
127     {
128         result = false;
129     }
130 #endif /* VCONFKEY_STICKER_SUPPORTED_FEATURE */
131
132     return result;
133 }
134
135 bool check_rw_mount()
136 {
137     char *data_path = NULL;
138     bool rw_mount = false;
139     data_path = app_get_shared_data_path();
140     if (!data_path) return false;
141
142     if (access(data_path, R_OK) == 0)
143         rw_mount = true;
144
145     free(data_path);
146
147     if (!rw_mount) {
148         SECURE_LOGE("Can't access rw storage\n");
149     }
150
151     return rw_mount;
152 }
153
154 static void process_request(app_control_h app_control, char *request)
155 {
156     char* mode = NULL;
157     char* type = NULL;
158
159     if (strcmp(request, "sync") == 0) {
160         bool param_error = false;
161         if (app_control_get_extra_data(app_control, "mode", &mode) != APP_CONTROL_ERROR_NONE) {
162             STLOGE("No given mode");
163             param_error = true;
164         }
165
166         if (app_control_get_extra_data(app_control, "type", &type) != APP_CONTROL_ERROR_NONE) {
167             STLOGE("No given type");
168             param_error = true;
169         }
170
171         STLOGI("[sync request] mode : %s, type : %s", mode, type);
172         if (param_error)
173             goto cleanup;
174
175         if (mode && type) {
176             if (check_battery_condition()) {
177                 if (check_sync_time_condition()) {
178                     if (preference_set_int(LAST_SYNC_STATUS, LAST_SYNC_STATUS_SYNC_NEEDED) != PREFERENCE_ERROR_NONE)
179                         STLOGE("Failed to set sync status as NEEDED");
180
181                     if (!is_init_sap())
182                         initialize_sap();
183                     request_all_sticker_data(mode, type);
184                 } else { // Under the sync interval time. Need to check whether last sync was succeded or not.
185                     int last_sync_status = 0;
186
187                     if (preference_get_int(LAST_SYNC_STATUS, &last_sync_status) != PREFERENCE_ERROR_NONE) {
188                         STLOGE("Failed to get sync status. Default action is exit.");
189                         goto cleanup;
190                     }
191
192                     if (last_sync_status == LAST_SYNC_STATUS_SYNC_NEEDED) {
193                         STLOGD("Last sync status is NEEDED(code: %d). Retrying to sync.", last_sync_status);
194                         if (!is_init_sap())
195                             initialize_sap();
196                         request_all_sticker_data(mode, type);
197                     } else {
198                         STLOGD("Last sync status is SUCCESS(code: %d). Don't have to retrying sync", last_sync_status);
199                     }
200                 }
201             } else {
202                 STLOGD("Not enough battery.");
203             }
204         }
205     }
206     else if (strcmp(request, "oobe") == 0) {
207         initialize_sap();
208         request_sticker_feature();
209     }
210     else {
211         STLOGW("Unknown command : %s", request);
212         if (!is_init_sap()) {
213             service_app_exit();
214         }
215     }
216
217 cleanup:
218     if (NULL != mode)
219         free(mode);
220
221     if (NULL != type)
222         free(type);
223 }
224
225 static void process_auto_sync()
226 {
227     if (is_init_sap()) {
228         STLOGD("continue doing current job");
229         return;
230     }
231
232     if (check_sync_time_condition()) {
233         if (check_battery_condition()) {
234             STLOGD("Starting auto synchronization");
235             if (preference_set_int(LAST_SYNC_STATUS, LAST_SYNC_STATUS_SYNC_NEEDED) != PREFERENCE_ERROR_NONE)
236                 STLOGE("Failed to set sync status as NEEDED");
237             initialize_sap();
238             request_sticker_feature();
239             request_auto_sync();
240         }
241         else {
242             STLOGI("The status of battery is low");
243             if (!get_job_progress()) {
244                 STLOGD("exit");
245                 service_app_exit();
246             }
247         }
248     }
249     else {
250         if (!get_job_progress()) {
251             int last_sync_status = 0;
252             if (preference_get_int(LAST_SYNC_STATUS, &last_sync_status) != PREFERENCE_ERROR_NONE) {
253                 STLOGE("Failed to get sync status. Default action is exit.");
254                 service_app_exit();
255             }
256
257             if (last_sync_status == LAST_SYNC_STATUS_SYNC_NEEDED) {
258                 STLOGD("Last sync status is NEEDED(code: %d). Retrying to sync.", last_sync_status);
259                 initialize_sap();
260                 request_sticker_feature();
261                 request_auto_sync();
262             } else {
263                 STLOGD("Last sync status is SUCCESS(code: %d). Don't have to retrying sync", last_sync_status);
264                 service_app_exit();
265             }
266         }
267     }
268 }
269
270 static void get_sticker_feature()
271 {
272 #ifdef VCONFKEY_STICKER_SUPPORTED_FEATURE
273     // Check whether oobe has been done
274     int feature_flag = 0;
275     if (vconf_get_int(VCONFKEY_STICKER_SUPPORTED_FEATURE, &feature_flag) == 0 && feature_flag == 0) {
276         STLOGD("Request to get sticker feature");
277         initialize_sap();
278         request_sticker_feature();
279     }
280     else {
281         if (!is_init_sap())
282             service_app_exit();
283     }
284 #endif
285 }
286
287 static void app_control(app_control_h app_control, void *data)
288 {
289     /* Handle the launch request. */
290     char* request = NULL;
291     char* operation = NULL;
292     char* event_value = NULL;
293     char* uri = NULL;
294     const char *event_uri = "event://tizen.system.event.battery_charger_status";
295     int res;
296
297     if (!check_rw_mount())
298         service_app_exit();
299
300     // operation
301     int ret = app_control_get_operation(app_control, &operation);
302     if (ret != APP_CONTROL_ERROR_NONE) {
303         STLOGW("Failed to get operation. error : %d", ret);
304         return;
305     }
306
307     STLOGD("operation: %s", operation);
308
309     if (!operation) {
310         goto cleanup;
311     }
312
313     if (strcmp(operation, APP_CONTROL_OPERATION_LAUNCH_ON_EVENT) == 0)
314     {
315         ret = app_control_get_uri(app_control, &uri);
316         if (ret == APP_CONTROL_ERROR_NONE && uri)
317         {
318             if (strncmp(uri, event_uri, strlen(event_uri) + 1) == 0)
319             {
320                 ret = app_control_get_extra_data(app_control, "battery_charger_status", &event_value);
321                 if (ret == APP_CONTROL_ERROR_NONE && event_value)
322                 {
323                     if (string(event_value) == "connected")
324                     {
325                         STLOGI("The charger state is connected");
326                         process_auto_sync();
327                     }
328                     free(event_value);
329                 }
330             }
331             free(uri);
332         }
333     }
334     else if (strcmp(operation, APP_CONTROL_OPERATION_DEFAULT) == 0) {
335         res = app_control_get_extra_data(app_control, "request", &request);
336         STLOGD("get extra data result : %d, request : %s", res, request);
337         if (APP_CONTROL_ERROR_NONE == res && NULL != request) {
338             process_request(app_control, request);
339         }
340         else {
341             STLOGD("booting");
342             get_sticker_feature();
343         }
344     }
345
346 cleanup:
347     if (NULL != operation)
348         free(operation);
349
350     if (NULL != request)
351         free(request);
352 }
353
354 static void app_terminate(void *data)
355 {
356     /* Release all resources. */
357     STLOGD("");
358     destroy_sticker_provider_handle();
359     deinitialize_sap();
360 }
361
362 int main(int argc, char *argv[])
363 {
364     int ret = 0;
365
366     service_app_lifecycle_callback_s event_callback;
367     memset(&event_callback, 0x0, sizeof(service_app_lifecycle_callback_s));
368
369     event_callback.create = (service_app_create_cb)app_create;
370     event_callback.terminate = (service_app_terminate_cb)app_terminate;
371     event_callback.app_control = (service_app_control_cb)app_control;
372
373     ret = service_app_main(argc, argv, &event_callback, NULL);
374     if (ret != APP_ERROR_NONE) {
375         STLOGE("app_main() is failed. err = %d", ret);
376     }
377     return ret;
378 }