Fix to request sticker feature only once
[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 (!is_init_sap()) {
177                 initialize_sap();
178                 request_all_sticker_data(mode, type);
179             }
180         }
181     }
182     else if (strcmp(request, "oobe") == 0) {
183         initialize_sap();
184         request_sticker_feature();
185     }
186     else {
187         STLOGW("Unknown command : %s", request);
188         if (!is_init_sap()) {
189             service_app_exit();
190         }
191     }
192
193 cleanup:
194     if (NULL != mode)
195         free(mode);
196
197     if (NULL != type)
198         free(type);
199 }
200
201 static void process_auto_sync()
202 {
203     if (is_init_sap()) {
204         STLOGD("continue doing current job");
205         return;
206     }
207
208     if (check_sync_time_condition()) {
209         if (check_battery_condition()) {
210             STLOGD("Starting auto synchronization");
211             initialize_sap();
212             if (get_receive_sticker_feature()) {
213                 STLOGI("Already sticker feature is received");
214             }
215             else {
216                 request_sticker_feature();
217             }
218
219             request_auto_sync();
220         }
221         else {
222             STLOGI("The status of battery is low");
223             if (!get_job_progress()) {
224                 STLOGD("exit");
225                 service_app_exit();
226             }
227         }
228     }
229     else {
230         if (!get_job_progress()) {
231             STLOGD("exit");
232             service_app_exit();
233         }
234     }
235 }
236
237 static void get_sticker_feature()
238 {
239     if (get_receive_sticker_feature()) {
240         STLOGI("Already sticker feature is received");
241         if (!is_init_sap())
242             service_app_exit();
243
244         return;
245     }
246
247 #ifdef VCONFKEY_STICKER_SUPPORTED_FEATURE
248     // Check whether oobe has been done
249     int feature_flag = 0;
250     if (vconf_get_int(VCONFKEY_STICKER_SUPPORTED_FEATURE, &feature_flag) == 0 && feature_flag == 0) {
251         STLOGD("Request to get sticker feature");
252         initialize_sap();
253         request_sticker_feature();
254     }
255     else {
256         if (!is_init_sap())
257             service_app_exit();
258     }
259 #endif
260 }
261
262 static void app_control(app_control_h app_control, void *data)
263 {
264     /* Handle the launch request. */
265     char* request = NULL;
266     char* operation = NULL;
267     char* event_value = NULL;
268     char* uri = NULL;
269     const char *event_uri = "event://tizen.system.event.battery_charger_status";
270     int res;
271
272     if (!check_rw_mount())
273         service_app_exit();
274
275     // operation
276     int ret = app_control_get_operation(app_control, &operation);
277     if (ret != APP_CONTROL_ERROR_NONE) {
278         STLOGW("Failed to get operation. error : %d", ret);
279         return;
280     }
281
282     STLOGD("operation: %s", operation);
283
284     if (!operation) {
285         goto cleanup;
286     }
287
288     if (strcmp(operation, APP_CONTROL_OPERATION_LAUNCH_ON_EVENT) == 0)
289     {
290         ret = app_control_get_uri(app_control, &uri);
291         if (ret == APP_CONTROL_ERROR_NONE && uri)
292         {
293             if (strncmp(uri, event_uri, strlen(event_uri) + 1) == 0)
294             {
295                 ret = app_control_get_extra_data(app_control, "battery_charger_status", &event_value);
296                 if (ret == APP_CONTROL_ERROR_NONE && event_value)
297                 {
298                     if (string(event_value) == "connected")
299                     {
300                         STLOGI("The charger state is connected");
301                         process_auto_sync();
302                     }
303                     free(event_value);
304                 }
305             }
306             free(uri);
307         }
308     }
309     else if (strcmp(operation, APP_CONTROL_OPERATION_DEFAULT) == 0) {
310         res = app_control_get_extra_data(app_control, "request", &request);
311         STLOGD("get extra data result : %d, request : %s", res, request);
312         if (APP_CONTROL_ERROR_NONE == res && NULL != request) {
313             process_request(app_control, request);
314         }
315         else {
316             STLOGD("booting");
317             get_sticker_feature();
318         }
319     }
320
321 cleanup:
322     if (NULL != operation)
323         free(operation);
324
325     if (NULL != request)
326         free(request);
327 }
328
329 static void app_terminate(void *data)
330 {
331     /* Release all resources. */
332     STLOGD("");
333     destroy_sticker_provider_handle();
334     deinitialize_sap();
335 }
336
337 int main(int argc, char *argv[])
338 {
339     int ret = 0;
340
341     service_app_lifecycle_callback_s event_callback;
342     memset(&event_callback, 0x0, sizeof(service_app_lifecycle_callback_s));
343
344     event_callback.create = (service_app_create_cb)app_create;
345     event_callback.terminate = (service_app_terminate_cb)app_terminate;
346     event_callback.app_control = (service_app_control_cb)app_control;
347
348     ret = service_app_main(argc, argv, &event_callback, NULL);
349     if (ret != APP_ERROR_NONE) {
350         STLOGE("app_main() is failed. err = %d", ret);
351     }
352     return ret;
353 }