Init/Deinit sync when BT attached/detached
[platform/core/uifw/capi-ui-sticker.git] / receiver / src / main.cpp
index 3799557..6ba29ed 100644 (file)
@@ -1,15 +1,39 @@
+/*
+ * Copyright (c) 2020 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
 #include <app_common.h>
 #include <service_app.h>
 #include <stdlib.h>
-#include <app_alarm.h>
+#include <app_event.h>
 #include <device/battery.h>
+#include <vconf.h>
+#include <string>
+#include <app_preference.h>
+#include <Ecore.h>
 
 #include "main.h"
 #include "ft.h"
 #include "log.h"
-#include "sync_alarm.h"
+#include "config.h"
+#include "receiver_preference.h"
+#include "sticker_info.h"
+
+using namespace std;
 
-#define MINIMUM_BATTERY 15
+static bool check_rw_mount();
 
 static bool app_create(void *data)
 {
@@ -18,89 +42,304 @@ static bool app_create(void *data)
        If this function returns true, the main loop of application starts
        If this function returns false, the application is terminated */
 
-    initialize_sap();
+    if (!check_rw_mount()) {
+        service_app_exit();
+        return true;
+    }
+
+    STLOGD("");
+
+    char log_path[PATH_MAX];
+    char *data_path = NULL;
+    data_path = app_get_shared_data_path();
+    snprintf(log_path, sizeof(log_path), "%s/log", data_path);
+
+    if (data_path)
+        free(data_path);
+
+    if (access(log_path, F_OK) != 0) {
+        if (mkdir(log_path, 0755) == -1) {
+            STLOGE("directory create error");
+        }
+    }
+
+    create_sticker_provider_handle();
 
     return true;
 }
 
-static void app_control(app_control_h app_control, void *data)
+static bool check_battery_condition()
+{
+    int battery_percentage = 0;
+    int ret;
+
+    // check battery percentage
+    ret = device_battery_get_percent(&battery_percentage);
+    if (ret != DEVICE_ERROR_NONE)
+    {
+        STLOGW("No sync. Failed to get battery percent. error : %d", ret);
+        return false;
+    }
+
+    STLOGI("battery percent : %d", battery_percentage);
+    if (battery_percentage >= MINIMUM_BATTERY)
+        return true;
+    else
+    {
+        STLOGI("No sync due to insufficient battery");
+        return false;
+    }
+}
+
+static bool check_sync_time_condition()
+{
+    double last_sync_time;
+    int feature_flag = 0;
+    bool result = false;
+
+#ifdef VCONFKEY_STICKER_SUPPORTED_FEATURE
+    // Check whether oobe has been done
+    if (vconf_get_int(VCONFKEY_STICKER_SUPPORTED_FEATURE, &feature_flag) == 0 && feature_flag > 0)
+    {
+        if (preference_get_double(LAST_SYNC_TIME, &last_sync_time) != PREFERENCE_ERROR_NONE)
+        {
+            STLOGD("Can't get last sync time.");
+            return true;
+        }
+
+        // compare time
+        double timediff = ecore_time_unix_get() - last_sync_time;
+        STLOGD("current time : %.3f, last_sync_time : %.3f, diff : %.3f", ecore_time_unix_get(), last_sync_time, timediff);
+
+        if (timediff > MAX_WAIT_TIME) {
+            STLOGD("Starting manual synchronization");
+            initialize_sap();
+            request_show_sync_notification();
+            result = false;
+        } else {
+            if (timediff > SYNC_INTERVAL)
+                result = true;
+            else
+                result = false;
+        }
+    }
+    else
+    {
+        result = false;
+    }
+#endif /* VCONFKEY_STICKER_SUPPORTED_FEATURE */
+
+    return result;
+}
+
+bool check_rw_mount()
+{
+    char *data_path = NULL;
+    bool rw_mount = false;
+    data_path = app_get_shared_data_path();
+    if (!data_path) return false;
+
+    if (access(data_path, R_OK) == 0)
+        rw_mount = true;
+
+    free(data_path);
+
+    if (!rw_mount) {
+        SECURE_LOGE("Can't access rw storage\n");
+    }
+
+    return rw_mount;
+}
+
+static void process_request(app_control_h app_control, char *request)
 {
-    /* Handle the launch request. */
-    char* request = NULL;
     char* mode = NULL;
     char* type = NULL;
-    char* operation = NULL;
-    char* alarm_data = NULL;
 
-    int res;
+    if (strcmp(request, "sync") == 0) {
+        bool param_error = false;
+        if (app_control_get_extra_data(app_control, "mode", &mode) != APP_CONTROL_ERROR_NONE) {
+            STLOGE("No given mode");
+            param_error = true;
+        }
 
-    // operation
-    int ret = app_control_get_operation(app_control, &operation);
-    if (ret == APP_CONTROL_ERROR_NONE) {
-        LOGD("operation: %s", operation);
-
-        if (operation && (strncmp(operation, APP_CONTROL_OPERATION_SYNC_ALARM, strlen(APP_CONTROL_OPERATION_SYNC_ALARM)) == 0)) {
-            ret = app_control_get_extra_data(app_control, APP_CONTROL_DATA_ALARM_ID, &alarm_data);
-            if (ret != APP_CONTROL_ERROR_NONE) {
-                dlog_print(DLOG_ERROR, LOG_TAG, "Function app_control_get_extra_data() failed.");
-                goto cleanup;
-            }
+        if (app_control_get_extra_data(app_control, "type", &type) != APP_CONTROL_ERROR_NONE) {
+            STLOGE("No given type");
+            param_error = true;
+        }
 
-            LOGD("alarm data : %s", alarm_data);
+        STLOGI("[sync request] mode : %s, type : %s", mode, type);
+        if (param_error)
+            goto cleanup;
 
-            int battery_percentage = 0;
-            int ret = device_battery_get_percent(&battery_percentage);
-            if (ret == DEVICE_ERROR_NONE) {
-                LOGD("battery percent : %d", battery_percentage);
-                if (battery_percentage >= MINIMUM_BATTERY) {
-                    request_sticker_data("auto", "arsticker", "input");
-                    request_sticker_data("auto", "bitmoji", "input");
-                }
-                else {
-                    LOGD("No sync request due to insufficient battery");
+        if (mode && type) {
+            if (check_battery_condition()) {
+                if (check_sync_time_condition()) {
+                    if (preference_set_int(LAST_SYNC_STATUS, LAST_SYNC_STATUS_SYNC_NEEDED) != PREFERENCE_ERROR_NONE)
+                        STLOGE("Failed to set sync status as NEEDED");
+
+                    if (!is_init_sap())
+                        initialize_sap();
+                    request_all_sticker_data(mode, type);
+                } else { // Under the sync interval time. Need to check whether last sync was succeded or not.
+                    int last_sync_status = 0;
+
+                    if (preference_get_int(LAST_SYNC_STATUS, &last_sync_status) != PREFERENCE_ERROR_NONE) {
+                        STLOGE("Failed to get sync status. Default action is exit.");
+                        goto cleanup;
+                    }
+
+                    if (last_sync_status == LAST_SYNC_STATUS_SYNC_NEEDED) {
+                        STLOGD("Last sync status is NEEDED(code: %d). Retrying to sync.", last_sync_status);
+                        if (!is_init_sap())
+                            initialize_sap();
+                        request_all_sticker_data(mode, type);
+                    } else {
+                        STLOGD("Last sync status is SUCCESS(code: %d). Don't have to retrying sync", last_sync_status);
+                    }
                 }
+            } else {
+                STLOGD("Not enough battery.");
             }
-            else {
-               LOGW("Failed to get battery percent. error : %d", ret);
-            }
-
-            goto cleanup;
         }
     }
+    else if (strcmp(request, "oobe") == 0) {
+        initialize_sap();
+        request_sticker_feature();
+    }
     else {
-        LOGW("Failed to get operation. error : %d", ret);
+        STLOGW("Unknown command : %s", request);
+        if (!is_init_sap()) {
+            service_app_exit();
+        }
+    }
+
+cleanup:
+    if (NULL != mode)
+        free(mode);
+
+    if (NULL != type)
+        free(type);
+}
+
+static void process_auto_sync()
+{
+    if (is_init_sap()) {
+        STLOGD("continue doing current job");
+        return;
     }
 
-    // sync request
-    res = app_control_get_extra_data(app_control, "request", &request);
-    if (APP_CONTROL_ERROR_NONE == res && NULL != request) {
-        if (strcmp(request, "sync") == 0) {
-            bool param_error = false;
-            if (app_control_get_extra_data(app_control, "mode", &mode) != APP_CONTROL_ERROR_NONE) {
-                LOGE("No given mode");
-                param_error = true;
+    if (check_sync_time_condition()) {
+        if (check_battery_condition()) {
+            STLOGD("Starting auto synchronization");
+            if (preference_set_int(LAST_SYNC_STATUS, LAST_SYNC_STATUS_SYNC_NEEDED) != PREFERENCE_ERROR_NONE)
+                STLOGE("Failed to set sync status as NEEDED");
+            initialize_sap();
+            request_sticker_feature();
+            request_auto_sync();
+        }
+        else {
+            STLOGI("The status of battery is low");
+            if (!get_job_progress()) {
+                STLOGD("exit");
+                service_app_exit();
+            }
+        }
+    }
+    else {
+        if (!get_job_progress()) {
+            int last_sync_status = 0;
+            if (preference_get_int(LAST_SYNC_STATUS, &last_sync_status) != PREFERENCE_ERROR_NONE) {
+                STLOGE("Failed to get sync status. Default action is exit.");
+                service_app_exit();
             }
 
-            if (app_control_get_extra_data(app_control, "type", &type) != APP_CONTROL_ERROR_NONE) {
-                LOGE("No given type");
-                param_error = true;
+            if (last_sync_status == LAST_SYNC_STATUS_SYNC_NEEDED) {
+                STLOGD("Last sync status is NEEDED(code: %d). Retrying to sync.", last_sync_status);
+                initialize_sap();
+                request_sticker_feature();
+                request_auto_sync();
+            } else {
+                STLOGD("Last sync status is SUCCESS(code: %d). Don't have to retrying sync", last_sync_status);
+                service_app_exit();
             }
+        }
+    }
+}
+
+static void get_sticker_feature()
+{
+#ifdef VCONFKEY_STICKER_SUPPORTED_FEATURE
+    // Check whether oobe has been done
+    int feature_flag = 0;
+    if (vconf_get_int(VCONFKEY_STICKER_SUPPORTED_FEATURE, &feature_flag) == 0 && feature_flag == 0) {
+        STLOGD("Request to get sticker feature");
+        initialize_sap();
+        request_sticker_feature();
+    }
+    else {
+        if (!is_init_sap())
+            service_app_exit();
+    }
+#endif
+}
+
+static void app_control(app_control_h app_control, void *data)
+{
+    /* Handle the launch request. */
+    char* request = NULL;
+    char* operation = NULL;
+    char* event_value = NULL;
+    char* uri = NULL;
+    const char *event_uri = "event://tizen.system.event.battery_charger_status";
+    int res;
 
-            LOGI("[sync request] mode : %s, type : %s", mode, type);
-            if (param_error)
-                goto cleanup;
+    if (!check_rw_mount())
+        service_app_exit();
 
-            if (mode && type)
-                request_sticker_data(mode, "arsticker", type);
+    // operation
+    int ret = app_control_get_operation(app_control, &operation);
+    if (ret != APP_CONTROL_ERROR_NONE) {
+        STLOGW("Failed to get operation. error : %d", ret);
+        return;
+    }
+
+    STLOGD("operation: %s", operation);
+
+    if (!operation) {
+        goto cleanup;
+    }
+
+    if (strcmp(operation, APP_CONTROL_OPERATION_LAUNCH_ON_EVENT) == 0)
+    {
+        ret = app_control_get_uri(app_control, &uri);
+        if (ret == APP_CONTROL_ERROR_NONE && uri)
+        {
+            if (strncmp(uri, event_uri, strlen(event_uri) + 1) == 0)
+            {
+                ret = app_control_get_extra_data(app_control, "battery_charger_status", &event_value);
+                if (ret == APP_CONTROL_ERROR_NONE && event_value)
+                {
+                    if (string(event_value) == "connected")
+                    {
+                        STLOGI("The charger state is connected");
+                        process_auto_sync();
+                    }
+                    free(event_value);
+                }
+            }
+            free(uri);
         }
-        else if (strcmp(request, "oobe") == 0) {
-            LOGI("[OOBE] register sync alarm");
-            sync_alarm_register(APP_CONTROL_OPERATION_SYNC_ALARM, SYNC_ALARM_DELAY, SYNC_ALARM_INTERVAL);
-            request_sticker_feature();
+    }
+    else if (strcmp(operation, APP_CONTROL_OPERATION_DEFAULT) == 0) {
+        res = app_control_get_extra_data(app_control, "request", &request);
+        STLOGD("get extra data result : %d, request : %s", res, request);
+        if (APP_CONTROL_ERROR_NONE == res && NULL != request) {
+            process_request(app_control, request);
         }
-        else
-        {
-            LOGW("Unknown command : %s", request);
+        else {
+            STLOGD("booting");
+            get_sticker_feature();
         }
     }
 
@@ -110,17 +349,13 @@ cleanup:
 
     if (NULL != request)
         free(request);
-
-    if (NULL != mode)
-        free(mode);
-
-    if (NULL != type)
-        free(type);
 }
 
 static void app_terminate(void *data)
 {
     /* Release all resources. */
+    STLOGD("");
+    destroy_sticker_provider_handle();
     deinitialize_sap();
 }
 
@@ -137,7 +372,7 @@ int main(int argc, char *argv[])
 
     ret = service_app_main(argc, argv, &event_callback, NULL);
     if (ret != APP_ERROR_NONE) {
-        LOGE("app_main() is failed. err = %d", ret);
+        STLOGE("app_main() is failed. err = %d", ret);
     }
     return ret;
 }