Support to request sticker sync periodically 28/226028/20
authorJihoon Kim <jihoon48.kim@samsung.com>
Wed, 26 Feb 2020 07:37:45 +0000 (16:37 +0900)
committerJihoon Kim <jihoon48.kim@samsung.com>
Tue, 10 Mar 2020 09:59:59 +0000 (18:59 +0900)
Change-Id: I73467303f4a1cfec69b02a6c1ee4a4410cde0e58
Signed-off-by: Jihoon Kim <jihoon48.kim@samsung.com>
packaging/capi-ui-sticker.spec
receiver/CMakeLists.txt
receiver/inc/sync_alarm.h [new file with mode: 0644]
receiver/src/ft.cpp
receiver/src/main.cpp
receiver/src/sync_alarm.cpp [new file with mode: 0644]
receiver/tizen-manifest.xml

index 97e6304..967fe41 100644 (file)
@@ -28,6 +28,8 @@ BuildRequires:  pkgconfig(sqlite3)
 BuildRequires:  pkgconfig(capi-base-common)
 BuildRequires:  pkgconfig(capi-appfw-service-application)
 BuildRequires:  pkgconfig(capi-message-port)
+BuildRequires:  pkgconfig(capi-appfw-alarm)
+BuildRequires:  pkgconfig(capi-system-device)
 BuildRequires:  pkgconfig(sap-client-stub-api)
 BuildRequires:  pkgconfig(vconf)
 BuildRequires:  hash-signer
index 9cd44fb..73d4503 100644 (file)
@@ -6,6 +6,7 @@ SET(SRCS
        src/ft.cpp
        src/sticker_info.cpp
        src/message.cpp
+       src/sync_alarm.cpp
 )
 
 INCLUDE(FindPkgConfig)
@@ -14,6 +15,9 @@ pkg_check_modules(pkgs_test REQUIRED
     dlog
     capi-appfw-service-application
     capi-message-port
+    capi-appfw-app-common
+    capi-appfw-alarm
+    capi-system-device
     sap-client-stub-api
     json-glib-1.0
     vconf
diff --git a/receiver/inc/sync_alarm.h b/receiver/inc/sync_alarm.h
new file mode 100644 (file)
index 0000000..e46515c
--- /dev/null
@@ -0,0 +1,28 @@
+/*
+ * 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 <glib.h>
+
+#ifndef __ALARM_H__
+#define __ALARM_H__
+
+#define APP_CONTROL_OPERATION_SYNC_ALARM "http://tizen.org/appcontrol/operation/sticker_sync_alarm"
+#define SYNC_ALARM_DELAY 0
+#define SYNC_ALARM_INTERVAL 12*60*60
+
+bool sync_alarm_register(const char *operation, int delay, int period);
+bool sync_alarm_exist();
+
+#endif /* __ALARM_H__ */
index fae0991..c8c7bdb 100644 (file)
@@ -36,6 +36,7 @@
 #include "log.h"
 #include "sticker_info.h"
 #include "message.h"
+#include "sync_alarm.h"
 
 #define ACCESSORY_SERVICE_PROFILE_ID "/sample/filetransfersender"
 #define ACCESSORY_SERVICE_CHANNEL_ID 107
@@ -80,7 +81,7 @@ struct sticker_info {
 
 static struct sap_info_s priv_data = { 0 };
 static struct sticker_info sticker_data;
-static struct sync_request pending_sync_request;
+static struct sync_request pending_sync_request, current_sync_request;
 
 enum {
     SYNC_START_RSP_SUCCESS = 1000,
@@ -303,6 +304,11 @@ void request_sticker_data(const char *mode, const char *category, const char *ty
 
         LOGI("Push sync request");
     }
+    else {
+        current_sync_request.mode = string(mode ? mode : "manual");
+        current_sync_request.category = string(category? category : "arsticker");
+        current_sync_request.type = string(type ? type : "input");
+    }
 
     json_object_unref(j_object);
 }
@@ -522,6 +528,15 @@ on_data_received(sap_socket_h socket, unsigned short int channel_id, unsigned in
             }
 
             json_object_set_string_member(j_object, "result", "success");
+
+            if (current_sync_request.mode == string("oobe")) {
+                LOGD("alarm exist : %d", sync_alarm_exist());
+                sync_alarm_register(APP_CONTROL_OPERATION_SYNC_ALARM, SYNC_ALARM_DELAY, SYNC_ALARM_INTERVAL);
+            }
+            else if (current_sync_request.mode == string("manual")) {
+                if (!sync_alarm_exist())
+                    sync_alarm_register(APP_CONTROL_OPERATION_SYNC_ALARM, SYNC_ALARM_DELAY, SYNC_ALARM_INTERVAL);
+            }
         }
 
         if (_send_json_data(j_object) == FALSE)
@@ -530,6 +545,10 @@ on_data_received(sap_socket_h socket, unsigned short int channel_id, unsigned in
         send_message("sync_stop_result", reason.c_str());
 
         json_object_unref(j_object);
+
+        current_sync_request.mode.clear();
+        current_sync_request.category.clear();
+        current_sync_request.type.clear();
     } else
         LOGW("unknown msg id : %s", msg_id.c_str());
 
@@ -608,6 +627,7 @@ _on_service_connection_created(sap_peer_agent_h peer_agent,
                                                                                 pending_sync_request.type.c_str());
 
             request_sticker_data(pending_sync_request.mode.c_str(), pending_sync_request.category.c_str(), pending_sync_request.type.c_str());
+
             pending_sync_request.mode.clear();
             pending_sync_request.category.clear();
             pending_sync_request.type.clear();
index 6f728fe..1a2ad84 100644 (file)
@@ -1,10 +1,15 @@
 #include <app_common.h>
 #include <service_app.h>
 #include <stdlib.h>
+#include <app_alarm.h>
+#include <device/battery.h>
 
 #include "main.h"
 #include "ft.h"
 #include "log.h"
+#include "sync_alarm.h"
+
+#define MINIMUM_BATTERY 15
 
 static bool app_create(void *data)
 {
@@ -25,35 +30,68 @@ static void app_control(app_control_h app_control, void *data)
     char* mode = NULL;
     char* category = NULL;
     char* type = NULL;
+    char* operation = NULL;
+    char* alarm_data = NULL;
 
     int res;
 
+    // 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;
+            }
+
+            LOGD("alarm data : %s", alarm_data);
+
+            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");
+                }
+            }
+            else {
+               LOGW("Failed to get battery percent. error : %d", ret);
+            }
+
+            goto cleanup;
+        }
+    }
+    else {
+        LOGW("Failed to get operation. error : %d", ret);
+    }
+
     // 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)
-        {
-            if (app_control_get_extra_data(app_control, "mode", &mode) != APP_CONTROL_ERROR_NONE)
-            {
+    if (APP_CONTROL_ERROR_NONE == res && NULL != request) {
+        if (strcmp(request, "sync") == 0) {
+            LOGI("[sync request] mode : %s, category : %s, type : %s", mode, category, type);
+            if (app_control_get_extra_data(app_control, "mode", &mode) != APP_CONTROL_ERROR_NONE) {
                 LOGE("No given mode");
                 goto cleanup;
             }
 
-            if (app_control_get_extra_data(app_control, "category", &category) != APP_CONTROL_ERROR_NONE)
-            {
+            if (app_control_get_extra_data(app_control, "category", &category) != APP_CONTROL_ERROR_NONE) {
                 LOGE("No given category");
                 goto cleanup;
             }
 
-            if (app_control_get_extra_data(app_control, "type", &type) != APP_CONTROL_ERROR_NONE)
-            {
+            if (app_control_get_extra_data(app_control, "type", &type) != APP_CONTROL_ERROR_NONE) {
                 LOGE("No given type");
                 goto cleanup;
             }
 
-            LOGI("[sync request] mode : %s, category : %s, type : %s", mode, category, type);
-
             if (mode && category && type)
                 request_sticker_data(mode, category, type);
         }
@@ -61,9 +99,12 @@ static void app_control(app_control_h app_control, void *data)
         {
             LOGW("Unknown command : %s", request);
         }
-
     }
+
 cleanup:
+    if (NULL != operation)
+        free(operation);
+
     if (NULL != request)
         free(request);
 
diff --git a/receiver/src/sync_alarm.cpp b/receiver/src/sync_alarm.cpp
new file mode 100644 (file)
index 0000000..d4879d8
--- /dev/null
@@ -0,0 +1,107 @@
+/*
+ * 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_alarm.h>
+#include <app_common.h>
+#include <stdlib.h>
+
+#include "log.h"
+
+static int recurring_alarm_id = -1;
+
+static bool
+on_foreach_registered_alarm(int alarm_id, void *user_data)
+{
+    bool *result = (bool *)user_data;
+
+    LOGD("alarm id : %d", alarm_id);
+
+    *result = *result | 0x1;
+
+    return false;
+}
+
+bool sync_alarm_register(const char *operation, int delay, int period)
+{
+    int ret;
+    app_control_h app_control = NULL;
+    char *app_id = NULL;
+    bool result = false;
+
+    ret = app_control_create(&app_control);
+    if (ret != APP_CONTROL_ERROR_NONE)
+    {
+        LOGE("Function app_control_create() failed.");
+        return false;
+    }
+
+    ret = app_control_set_operation(app_control, operation);
+    if (ret != APP_CONTROL_ERROR_NONE)
+    {
+        LOGE("Function app_control_set_operation() failed.");
+        goto cleanup;
+    }
+
+    if (app_get_id(&app_id) != APP_ERROR_NONE) {
+        goto cleanup;
+    }
+
+    LOGD("app id : %s", app_id);
+    if (!app_id) {
+        goto cleanup;
+    }
+
+    ret = app_control_set_app_id(app_control, app_id);
+    if (ret != APP_CONTROL_ERROR_NONE)
+    {
+        LOGE("Function app_control_set_app_id() failed.");
+        goto cleanup;
+    }
+
+    alarm_cancel_all();
+
+    ret = alarm_schedule_after_delay(app_control, delay, period, &recurring_alarm_id);
+    if (ret != ALARM_ERROR_NONE)
+        LOGE("Function alarm_schedule_after_delay() failed.");
+    else
+        LOGD("Function alarm_schedule_after_delay() succeed. delay : %d, interval : %d", delay, period);
+
+    result = true;
+
+cleanup:
+    if (app_id)
+        free(app_id);
+
+    if (app_control) {
+        ret = app_control_destroy(app_control);
+        if (ret != APP_CONTROL_ERROR_NONE)
+            LOGE("Function app_control_destroy() failed.");
+        else
+            LOGD("Set recurring alarm with id: %i", recurring_alarm_id);
+    }
+
+    return result;
+}
+
+bool sync_alarm_exist()
+{
+    bool result = false;
+    int ret = alarm_foreach_registered_alarm(on_foreach_registered_alarm, &result);
+    if (ret != ALARM_ERROR_NONE)
+        LOGD("Listing error : %d", ret);
+
+    return result;
+}
\ No newline at end of file
index 0d73867..b53fdc6 100644 (file)
@@ -5,6 +5,8 @@
         <label>sticker-receiver</label>
                 <metadata key="accessory-services-location" value="/res/xml/accessoryservices.xml"/>
                 <metadata key="launch-on-attach" value="false"/>
+                <background-category value="background-network"/>
+                <background-category value="iot-communication"/>
                 <background-category value="system"/>
         </service-application>
         <privileges>
@@ -12,6 +14,9 @@
             <privilege>http://tizen.org/privilege/content.write</privilege>
             <privilege>http://tizen.org/privilege/mediastorage</privilege>
             <privilege>http://tizen.org/privilege/appdir.shareddata</privilege>
+            <privilege>http://tizen.org/privilege/alarm.set</privilege>
+            <privilege>http://tizen.org/privilege/alarm.get</privilege>
+            <privilege>http://tizen.org/privilege/appmanager.launch</privilege>
         </privileges>
         <category name="http://tizen.org/category/sticker"/>
 </manifest>