From: Amritanshu Date: Thu, 27 Aug 2020 05:47:05 +0000 (+0530) Subject: Initial version of FOTA UI App X-Git-Tag: submit/tizen/20200828.043945^0 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=3f747bb64014e15585808c044390778903044264;p=profile%2Fcommon%2Fapps%2Fnative%2Ffirmware-update-app-ui.git Initial version of FOTA UI App Change-Id: I60bf8d0c6a9d0bf546e3647888f4f7e7a93a7f71 Signed-off-by: Amritanshu --- diff --git a/.cproject b/.cproject new file mode 100755 index 0000000..e43282d --- /dev/null +++ b/.cproject @@ -0,0 +1,668 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/.exportMap b/.exportMap new file mode 100755 index 0000000..de30516 --- /dev/null +++ b/.exportMap @@ -0,0 +1,5 @@ +{ + global: main; + _IO_*; + local: *; +}; diff --git a/.package-stamp b/.package-stamp new file mode 100755 index 0000000..40cbe59 --- /dev/null +++ b/.package-stamp @@ -0,0 +1 @@ +TPK \ No newline at end of file diff --git a/.project b/.project new file mode 100755 index 0000000..dbcc63c --- /dev/null +++ b/.project @@ -0,0 +1,46 @@ + + + firmware-update-ui + + + + + + org.eclipse.cdt.managedbuilder.core.genmakebuilder + + + + + org.eclipse.cdt.managedbuilder.core.ScannerConfigBuilder + full,incremental, + + + + + + org.eclipse.cdt.core.cnature + org.eclipse.cdt.core.ccnature + org.eclipse.cdt.managedbuilder.core.managedBuildNature + org.eclipse.cdt.managedbuilder.core.ScannerConfigNature + + + + 1593260406225 + + 26 + + org.eclipse.ui.ide.multiFilter + 1.0-projectRelativePath-matches-false-false-*/.tpk + + + + 1593260406230 + + 6 + + org.eclipse.ui.ide.multiFilter + 1.0-name-matches-false-false-project_def.prop + + + + diff --git a/.tproject b/.tproject new file mode 100755 index 0000000..a1f14e6 --- /dev/null +++ b/.tproject @@ -0,0 +1,12 @@ + + + + + iot-headed-5.5 + + + + + + + diff --git a/LICENSE b/LICENSE new file mode 100755 index 0000000..47680a4 --- /dev/null +++ b/LICENSE @@ -0,0 +1,203 @@ +Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved. + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + 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. \ No newline at end of file diff --git a/NOTICE b/NOTICE new file mode 100755 index 0000000..4649903 --- /dev/null +++ b/NOTICE @@ -0,0 +1,3 @@ +Copyright (c) 2020 Samsung Electronics Co., Ltd. All rights reserved. +Except as noted, this software is licensed under Apache License, Version 2. +Please, see the LICENSE file for Apache License terms and conditions. \ No newline at end of file diff --git a/build_def.prop b/build_def.prop new file mode 100755 index 0000000..6bb5e2f --- /dev/null +++ b/build_def.prop @@ -0,0 +1,6 @@ + +# Add pre/post build process +PREBUILD_DESC = +PREBUILD_COMMAND = +POSTBUILD_DESC = +POSTBUILD_COMMAND = diff --git a/inc/firmware-update-ui.h b/inc/firmware-update-ui.h new file mode 100755 index 0000000..c51784f --- /dev/null +++ b/inc/firmware-update-ui.h @@ -0,0 +1,74 @@ +/* + * 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. + */ + +#ifndef __FIRMWAREUPDATEUI_H__ +#define __FIRMWAREUPDATEUI_H__ + +#include +#include +#include +#include +#include +#include +#include +#include + +#ifdef LOG_TAG +#undef LOG_TAG +#endif +#define LOG_TAG "FOTA" + +#if !defined(PACKAGE) +#define PACKAGE "org.tizen.firmware-update-ui" +#endif + +typedef struct appdata { + Evas_Object *win; + Evas_Object *conform; + Evas_Object *nf; + Evas_Object *label; +} appdata_s; + +typedef enum +{ + FOTA_OPERATION_DOWNLOAD = 0, + FOTA_OPERATION_INSTALL, +}fota_operation; + +gchar *download_cmd; + +#define RED "\033[0;31m" +#define YELLOW "\033[0;33m" +#define DCOLOR "\033[0;m" + +#define LOGI(fmt, arg...) dlog_print(DLOG_INFO, LOG_TAG, "%s (%d) %s : " YELLOW fmt DCOLOR, __FILE__, __LINE__, __FUNCTION__, ##arg) +#define LOGD(fmt, arg...) dlog_print(DLOG_DEBUG, LOG_TAG, "%s (%d) %s : " fmt, __FILE__, __LINE__, __FUNCTION__, ##arg) +#define LOGE(fmt, arg...) dlog_print(DLOG_ERROR, LOG_TAG, "%s (%d) %s : " RED fmt DCOLOR, __FILE__, __LINE__, __FUNCTION__, ##arg) +#define LOGW(fmt, arg...) dlog_print(DLOG_WARN, LOG_TAG, "%s (%d) %s : " fmt, __FILE__, __LINE__, __FUNCTION__, ##arg) + +#define UPDATE_TITLE "Software Update" +#define DOWNLOAD_TITLE "Software Download" +#define FOTA_MODE_DOWNLOAD "fota-plug" +#define FOTA_MODE_INSTALL "fota-install" +#define FOTA_MODE_UNPLUG "fota-unplug" +#define FOTA_MODE_REBOOT "fota-reboot" +#define UPDATE_SUCCESS "00" + +extern void fota_show_install_popup(Evas_Object* nf, char *title); +extern void fota_show_download_popup(Evas_Object* nf, char *title); +extern void fota_show_result_popup(Evas_Object *nf,fota_operation e_oper, bool status, int error); + +#endif /* __FIRMWAREUPDATEUI_H__ */ diff --git a/project_def.prop b/project_def.prop new file mode 100755 index 0000000..0ec711a --- /dev/null +++ b/project_def.prop @@ -0,0 +1,58 @@ + +# Project Name +APPNAME = firmware-update-ui + +# Project Type +type = app + +# Project Profile +profile = iot-headed-5.5 + +# C/CPP Sources +USER_SRCS = src/firmware-update-ui.c src/interaction.c + +# EDC Sources +USER_EDCS = + +# PO Sources +USER_POS = + +# User Defines +USER_DEFS = TIZEN_DEPRECATION DEPRECATION_WARNING +USER_CPP_DEFS = + +# User Undefines +USER_UNDEFS = +USER_CPP_UNDEFS = + +# User Libraries +USER_LIBS = + +# User Objects +USER_OBJS = + +# User Includes +## C Compiler +USER_C_INC_DIRS = inc +USER_INC_FILES = +## C++ Compiler +USER_CPP_INC_DIRS = +USER_CPP_INC_FILES = + +USER_INC_DIRS = $(USER_C_INC_DIRS) $(USER_CPP_INC_DIRS) + +# User Library Path +USER_LIB_DIRS = lib + +# EDC Resource Path +USER_EDCS_IMAGE_DIRS = ${OUTPUT_DIR} +USER_EDCS_SOUND_DIRS = ${OUTPUT_DIR} +USER_EDCS_FONT_DIRS = ${OUTPUT_DIR} + +# EDC Flags +USER_EXT_EDC_KEYS = + +# Resource Filter +USER_RES_INCLUDE = +USER_RES_EXCLUDE = + diff --git a/res/images/FirmwareUpdate_BG.png b/res/images/FirmwareUpdate_BG.png new file mode 100755 index 0000000..8755213 Binary files /dev/null and b/res/images/FirmwareUpdate_BG.png differ diff --git a/shared/res/firmware-update-ui.png b/shared/res/firmware-update-ui.png new file mode 100755 index 0000000..9765b1b Binary files /dev/null and b/shared/res/firmware-update-ui.png differ diff --git a/src/firmware-update-ui.c b/src/firmware-update-ui.c new file mode 100755 index 0000000..88b1061 --- /dev/null +++ b/src/firmware-update-ui.c @@ -0,0 +1,261 @@ +/* + * 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 "firmware-update-ui.h" + +static void +win_delete_request_cb(void *data, Evas_Object *obj, void *event_info) +{ + ui_app_exit(); +} + +static void +win_back_cb(void *data, Evas_Object *obj, void *event_info) +{ + appdata_s *ad = data; + /* Let window go to hide state. */ + elm_win_lower(ad->win); +} + +static void +create_base_gui(appdata_s *ad) +{ + ad->win = elm_win_util_standard_add(PACKAGE, PACKAGE); + elm_win_autodel_set(ad->win, EINA_TRUE); + + if (elm_win_wm_rotation_supported_get(ad->win)) { + int rots[4] = {0, 90, 180, 270}; + elm_win_wm_rotation_available_rotations_set(ad->win, (const int *)(&rots), 4); + } + + evas_object_smart_callback_add(ad->win, "delete,request", win_delete_request_cb, NULL); + eext_object_event_callback_add(ad->win, EEXT_CALLBACK_BACK, win_back_cb, ad); + + /* Conformant */ + ad->conform = elm_conformant_add(ad->win); + elm_win_indicator_mode_set(ad->win, ELM_WIN_INDICATOR_HIDE); + evas_object_size_hint_weight_set(ad->conform, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND); + elm_win_resize_object_add(ad->win, ad->conform); + evas_object_show(ad->conform); + + /* Naviframe */ + ad->nf = elm_naviframe_add(ad->conform); + evas_object_show(ad->nf); + // elm_naviframe_prev_btn_auto_pushed_set(ad->nf, EINA_TRUE); + elm_object_content_set(ad->conform, ad->nf); + + Evas_Object *bg; + char buf[PATH_MAX]; + char *res_path = app_get_resource_path(); + snprintf(buf, sizeof(buf), "%simages/FirmwareUpdate_BG.png", res_path); + LOGI("Bg Image path : %s", buf); + if(res_path) free(res_path); + + bg = elm_bg_add(ad->nf); + elm_bg_option_set(bg, ELM_BG_OPTION_CENTER); + elm_bg_file_set(bg, buf, NULL); + Elm_Object_Item *nf_it = elm_naviframe_item_push(ad->nf, NULL, NULL, NULL, bg, "tabbar/notitle"); + //elm_naviframe_item_pop_cb_set(nf_it, naviframe_pop_cb, ad->nf); + + Evas_Object * toolbar = elm_bg_add(ad->nf); + toolbar = elm_bg_add(ad->nf); + elm_bg_option_set(toolbar, ELM_BG_OPTION_STRETCH); + elm_bg_file_set(toolbar, buf, NULL); + elm_object_item_part_content_set(nf_it, "tabbar", toolbar); + + evas_object_show(ad->win); +} + +static bool +app_create(void *data) +{ + appdata_s *ad = data; + + create_base_gui(ad); + + return true; +} + +static void +app_control(app_control_h app_control, void *data) +{ + int ret = 0; + char *value = NULL, *shared_path = NULL; + appdata_s *ad = data; + + notification_h notify = notification_load_by_tag(LOG_TAG); + if(notify) { + LOGI("App-control Notification delete"); + notification_delete(notify); + notification_free(notify); + } + + /* Will be triggered if update image attached for download */ + LOGI("Inside app_control"); + ret = app_control_get_extra_data(app_control, FOTA_MODE_DOWNLOAD, &value); + if (ret == APP_CONTROL_ERROR_NONE) { + LOGI("App-control %s : %s", FOTA_MODE_DOWNLOAD, value); + shared_path = app_get_shared_data_path(); + LOGI("Shared path : %s", shared_path); + + download_cmd = g_strjoin(" ", "cp", value, shared_path, NULL); + if(shared_path) free(shared_path); + LOGI("Download command in App-control %s", download_cmd); + + fota_show_download_popup(ad->nf, UPDATE_TITLE); + + } else if (ret != APP_CONTROL_ERROR_KEY_NOT_FOUND) { + LOGE("App-control %s Error : %d", FOTA_MODE_DOWNLOAD, ret); + } + + /* Will be triggered if update image is ready to install */ + ret = app_control_get_extra_data(app_control, FOTA_MODE_INSTALL, &value); + if (ret == APP_CONTROL_ERROR_NONE) { + LOGI("App-control %s : %s", FOTA_MODE_INSTALL, value); + + shared_path = app_get_shared_data_path(); + LOGI("Shared path : %s", shared_path); + download_cmd = g_strjoin(" ", "cp", value, shared_path, NULL); + if(shared_path) free(shared_path); + LOGI("Download command in App-control %s", download_cmd); + + fota_show_install_popup(ad->nf, UPDATE_TITLE); + + } else if (ret != APP_CONTROL_ERROR_KEY_NOT_FOUND) { + LOGE("App-control %s Error : %d", FOTA_MODE_INSTALL, ret); + } + + /* Will be triggered if external storage device is unplugged and UI app terminates */ + ret = app_control_get_extra_data(app_control, FOTA_MODE_UNPLUG, &value); + if (ret == APP_CONTROL_ERROR_NONE) { + LOGI("App-control %s : %s", FOTA_MODE_UNPLUG, value); + ui_app_exit(); + + } else if (ret != APP_CONTROL_ERROR_KEY_NOT_FOUND) { + LOGE("App-control %s Error : %d", FOTA_MODE_UNPLUG, ret); + } + + /* Will be triggered if update image is ready to install */ + ret = app_control_get_extra_data(app_control, FOTA_MODE_REBOOT, &value); + if (ret == APP_CONTROL_ERROR_NONE) { + LOGI("App-control %s : %s", FOTA_MODE_REBOOT, value); + + /* fota-reboot sends value=00 in case of RO/RW update success */ + if (strncmp(value, UPDATE_SUCCESS, strlen(UPDATE_SUCCESS)) == 0) { + fota_show_result_popup(ad->nf, FOTA_OPERATION_INSTALL, TRUE, APP_CONTROL_ERROR_NONE); + } else { + int error = atoi(value); + LOGI("Update Firmware error %s : %d", value, error); + fota_show_result_popup(ad->nf, FOTA_OPERATION_INSTALL, FALSE, error); + } + + } else if (ret != APP_CONTROL_ERROR_KEY_NOT_FOUND) { + LOGE("App-control %s Error : %d", FOTA_MODE_REBOOT, ret); + } + +} + +static void +app_pause(void *data) +{ + /* Take necessary actions when application becomes invisible. */ +} + +static void +app_resume(void *data) +{ + /* Take necessary actions when application becomes visible. */ +} + +static void +app_terminate(void *data) +{ + /* Release all resources. */ +} + +static void +ui_app_lang_changed(app_event_info_h event_info, void *user_data) +{ + /*APP_EVENT_LANGUAGE_CHANGED*/ + + int ret; + char *language; + + ret = app_event_get_language(event_info, &language); + if (ret != APP_ERROR_NONE) { + LOGE("app_event_get_language() failed. Err = %d.", ret); + return; + } + + if (language != NULL) { + elm_language_set(language); + free(language); + } +} + +static void +ui_app_orient_changed(app_event_info_h event_info, void *user_data) +{ + /*APP_EVENT_DEVICE_ORIENTATION_CHANGED*/ + return; +} + +static void +ui_app_region_changed(app_event_info_h event_info, void *user_data) +{ + /*APP_EVENT_REGION_FORMAT_CHANGED*/ +} + +static void +ui_app_low_battery(app_event_info_h event_info, void *user_data) +{ + /*APP_EVENT_LOW_BATTERY*/ +} + +static void +ui_app_low_memory(app_event_info_h event_info, void *user_data) +{ + /*APP_EVENT_LOW_MEMORY*/ +} + +int +main(int argc, char *argv[]) +{ + appdata_s ad = {0,}; + int ret = 0; + + ui_app_lifecycle_callback_s event_callback = {0,}; + app_event_handler_h handlers[5] = {NULL, }; + + event_callback.create = app_create; + event_callback.terminate = app_terminate; + event_callback.pause = app_pause; + event_callback.resume = app_resume; + event_callback.app_control = app_control; + + ui_app_add_event_handler(&handlers[APP_EVENT_LOW_BATTERY], APP_EVENT_LOW_BATTERY, ui_app_low_battery, &ad); + ui_app_add_event_handler(&handlers[APP_EVENT_LOW_MEMORY], APP_EVENT_LOW_MEMORY, ui_app_low_memory, &ad); + ui_app_add_event_handler(&handlers[APP_EVENT_DEVICE_ORIENTATION_CHANGED], APP_EVENT_DEVICE_ORIENTATION_CHANGED, ui_app_orient_changed, &ad); + ui_app_add_event_handler(&handlers[APP_EVENT_LANGUAGE_CHANGED], APP_EVENT_LANGUAGE_CHANGED, ui_app_lang_changed, &ad); + ui_app_add_event_handler(&handlers[APP_EVENT_REGION_FORMAT_CHANGED], APP_EVENT_REGION_FORMAT_CHANGED, ui_app_region_changed, &ad); + + ret = ui_app_main(argc, argv, &event_callback, &ad); + if (ret != APP_ERROR_NONE) { + LOGE("app_main() is failed. err = %d", ret); + } + + return ret; +} diff --git a/src/interaction.c b/src/interaction.c new file mode 100755 index 0000000..28cef4b --- /dev/null +++ b/src/interaction.c @@ -0,0 +1,338 @@ +/* + * 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 "firmware-update-ui.h" + +static char path[PATH_MAX]; + +static void +_popup_block_clicked_cb(void *data, Evas_Object *obj, void *event_info) +{ + //elm_popup_dismiss(obj); + evas_object_del(obj); +} + +static void +_popup_hide_cb(void *data, Evas_Object *obj, void *event_info) +{ + //elm_popup_dismiss(obj); + evas_object_del(obj); +} + +static void +_popup_hide_finished_cb(void *data, Evas_Object *obj, void *event_info) +{ + evas_object_del(obj); +} + +static void +_app_terminate_request_cb(void *data, Evas_Object *obj, void *event_info) +{ + ui_app_exit(); +} + +static void notification_launch_cb(notification_h notification, const char *operation, const char *argument, const char *pkgname) +{ + LOGI("Inside notification_launch_cb"); + app_control_h service = NULL; + int ret = app_control_create(&service); + if (ret != APP_CONTROL_ERROR_NONE) { + LOGI("app_control_create API failed. Err = %d", ret); + return; + } + + if (pkgname) + app_control_set_app_id(service, pkgname); + + LOGI("Value = %s", argument); + if (operation && argument) + app_control_add_extra_data(service, operation, argument); + + notification_set_launch_option(notification, NOTIFICATION_LAUNCH_OPTION_APP_CONTROL, service); + app_control_destroy(service); +} + +static char* fota_get_update_image_version() +{ + + bool flag_image = FALSE; + char *image_path = NULL, *directory = NULL, *version = NULL, *token = NULL; + char *cmd = strdup(download_cmd); + LOGI("cmd : %s", download_cmd); + + while ((token = strsep(&cmd, " "))) { + if (strstr(token, "delta.tar")) { + image_path = strdup(token); + break; + } + } + LOGI("Update image path : %s", image_path); + if(!image_path) + return NULL; + + snprintf(path, sizeof(path), "%s", image_path); + + while ((token = strsep(&image_path, "/"))) { + if (strncmp(token, "delta.tar", strlen("delta.tar")) == 0) { + flag_image = TRUE; + break; + } + directory = strdup(token); + } + LOGI("Image directory : %s", directory); + if(!directory || !flag_image) + return NULL; + + while ((token = strsep(&directory, "-"))) { + version = strdup(token); + } + LOGI("Update image version : %s", version); + if(!version) + return NULL; + + free(directory); + free(image_path); + return version; +} + +void fota_show_result_popup(Evas_Object *nf,fota_operation e_oper, bool status, int error) +{ + LOGI("Inside fota_show_result_popup"); + char title[PATH_MAX], text[PATH_MAX]; + Evas_Object *popup = elm_popup_add(nf); + elm_popup_align_set(popup, ELM_NOTIFY_ALIGN_FILL, 1.0); + evas_object_size_hint_weight_set(popup, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND); + + if (e_oper == FOTA_OPERATION_DOWNLOAD ) { + snprintf(title, sizeof(title), "%s Failed",DOWNLOAD_TITLE); + snprintf(text, sizeof(text), "%s failed.
[error:%d]",DOWNLOAD_TITLE, error); + + } else if (e_oper == FOTA_OPERATION_INSTALL && status) { + snprintf(title, sizeof(title), "%s Succeeded",UPDATE_TITLE); + snprintf(text, sizeof(text), "Software update is successfully done!"); + + } else if (e_oper == FOTA_OPERATION_INSTALL && !status) { + snprintf(title, sizeof(title), "%s Failed",UPDATE_TITLE); + snprintf(text, sizeof(text), "%s failed.
[error:%d]
Please contact the service center",UPDATE_TITLE, error); + } + elm_object_part_text_set(popup, "title,text", title); + elm_object_text_set(popup,text); + + eext_object_event_callback_add(popup, EEXT_CALLBACK_BACK, _popup_hide_cb, NULL); + evas_object_smart_callback_add(popup, "dismissed", _popup_hide_finished_cb, NULL); + evas_object_smart_callback_add(popup, "block,clicked", _popup_block_clicked_cb, NULL); + + /* Ok button */ + Evas_Object *btn1 = elm_button_add(popup); + elm_object_text_set(btn1, "OK"); + elm_object_part_content_set(popup, "button1", btn1); + evas_object_smart_callback_add(btn1, "clicked", _app_terminate_request_cb, nf); + + evas_object_show(popup); +} + +static void +_send_notification_install_update_cb(void *data, Evas_Object *obj, void *event_info) +{ + LOGI("Inside _send_notification_install_update_cb"); + Evas_Object *popup = data; + //elm_popup_dismiss(popup); + //evas_object_del(popup); + + notification_h notify = notification_create(NOTIFICATION_TYPE_ONGOING); + if (!notify) { + LOGE("notification_create(NOTIFICATION_TYPE_ONGOING) failed."); + return; + } + + notification_set_text(notify, NOTIFICATION_TEXT_TYPE_TITLE, UPDATE_TITLE, NULL, NOTIFICATION_VARIABLE_TYPE_NONE); + notification_set_text(notify, NOTIFICATION_TEXT_TYPE_CONTENT, "Software update is available. Click to update", NULL, NOTIFICATION_VARIABLE_TYPE_NONE); + + notification_set_layout(notify, NOTIFICATION_LY_ONGOING_EVENT); + notification_set_property(notify, NOTIFICATION_PROP_PERMANENT_DISPLAY); + notification_set_tag(notify, LOG_TAG); + + LOGI("Image path in _send_notification_install_update_cb = %s",path); + + /* Relaunch App to install update when user clicks notification */ + notification_launch_cb(notify, FOTA_MODE_INSTALL, path, PACKAGE); + + notification_post(notify); + elm_popup_dismiss(popup); + ui_app_exit(); +} + +static void +_install_update_cb(void *data, Evas_Object *obj, void *event_info) +{ + LOGI("Inside _install_update_cb"); + Evas_Object *nf = data; + int ret = 0; + + LOGI("Start Update"); + /* Install update-image downloaded at shared location on device */ + ret = update_control_initialize(); + if(ret != UPDATE_CONTROL_ERROR_NONE) { + LOGE("update_control_initialize API Failed, error : %d", ret); + fota_show_result_popup(nf, FOTA_OPERATION_INSTALL, FALSE, ret); + } + + ret = update_control_do_update(); + if(ret != UPDATE_CONTROL_ERROR_NONE) { + LOGE("update_control_do_update API Failed, error : %d", ret); + fota_show_result_popup(nf, FOTA_OPERATION_INSTALL, FALSE, ret); + } + + ret = update_control_deinitialize(); + if(ret != UPDATE_CONTROL_ERROR_NONE) { + LOGE("update_control_deinitialize API Failed, error : %d", ret); + fota_show_result_popup(nf, FOTA_OPERATION_INSTALL, FALSE, ret); + } + + elm_popup_dismiss(nf); + ui_app_exit(); +} + +static void +_send_notification_download_image_cb(void *data, Evas_Object *obj, void *event_info) +{ + LOGI("Inside _send_notification_download_image_cb"); + Evas_Object *popup = data; + + notification_h notify = notification_create(NOTIFICATION_TYPE_ONGOING); + if (!notify) { + LOGE("notification_create(NOTIFICATION_TYPE_ONGOING) failed."); + return; + } + + notification_set_text(notify, NOTIFICATION_TEXT_TYPE_TITLE, "SoftwareUpdate", NULL, NOTIFICATION_VARIABLE_TYPE_NONE); + notification_set_text(notify, NOTIFICATION_TEXT_TYPE_CONTENT, "Software update is available. Click to update", NULL, NOTIFICATION_VARIABLE_TYPE_NONE); + + notification_set_layout(notify, NOTIFICATION_LY_ONGOING_EVENT); + notification_set_property(notify, NOTIFICATION_PROP_PERMANENT_DISPLAY); + notification_set_tag(notify, LOG_TAG); + + LOGI("Image path in _send_notification_download_image_cb = %s",path); + /* Relaunch App to download update-image when user clicks notification */ + notification_launch_cb(notify, FOTA_MODE_DOWNLOAD, path, PACKAGE); + + notification_post(notify); + + elm_popup_dismiss(popup); + ui_app_exit(); +} + +static void +_download_image_cb(void *data, Evas_Object *obj, void *event_info) +{ + LOGI("Inside _download_image_cb"); + Evas_Object *nf = data; + LOGI("System Command : %s", download_cmd); + + /* Copy update-image from attached USB to shared location on device */ + int ret = system(download_cmd); + LOGI("System command return : %d", ret); + + if (ret == -1 || WEXITSTATUS(ret) != 0) { + fota_show_result_popup(nf, FOTA_OPERATION_DOWNLOAD, FALSE, ret); + } else { + fota_show_install_popup(nf, UPDATE_TITLE); + } + + elm_popup_dismiss(nf); +} + +void fota_show_install_popup(Evas_Object *nf, char *title) +{ + char buf[PATH_MAX] = {0}; + char *version = fota_get_update_image_version(); + if(!version) + { + LOGE("Invalid update image version : %s", version); + fota_show_result_popup(nf, FOTA_OPERATION_INSTALL, FALSE, FALSE); + } else { + snprintf(buf, sizeof(buf), "Software Updates ready to install
-Version: %s", version); + free(version); + LOGI("Inside fota_show_install_popup"); + + Evas_Object *popup = elm_popup_add(nf); + elm_popup_align_set(popup, ELM_NOTIFY_ALIGN_FILL, 1.0); + evas_object_size_hint_weight_set(popup, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND); + elm_object_part_text_set(popup, "title,text", title); + elm_object_text_set(popup,buf); + + eext_object_event_callback_add(popup, EEXT_CALLBACK_BACK, _popup_hide_cb, NULL); + evas_object_smart_callback_add(popup, "dismissed", _popup_hide_finished_cb, NULL); + evas_object_smart_callback_add(popup, "block,clicked", _popup_block_clicked_cb, NULL); + + /* Not Now button */ + Evas_Object *btn1 = elm_button_add(popup); + elm_object_style_set(btn1, "border"); + elm_object_text_set(btn1, "Not Now"); + elm_object_part_content_set(popup, "button1", btn1); + evas_object_smart_callback_add(btn1, "clicked", _send_notification_install_update_cb, popup); + + /* Install button */ + Evas_Object *btn2 = elm_button_add(popup); + elm_object_text_set(btn2, "Install"); + elm_object_part_content_set(popup, "button2", btn2); + evas_object_smart_callback_add(btn2, "clicked", _install_update_cb, nf); + evas_object_show(popup); + } +} + +void fota_show_download_popup(Evas_Object *nf, char *title) +{ + char buf[PATH_MAX] = {0}; + char *version = fota_get_update_image_version(); + if(!version) + { + LOGE("Invalid update image version : %s", version); + + /* Need to check if show popup for wrong image path */ + fota_show_result_popup(nf, FOTA_OPERATION_DOWNLOAD, FALSE, FALSE); + } else { + snprintf(buf, sizeof(buf), "Updated software is now available
-Version: %s", version); + free(version); + LOGI("Inside fota_show_download_popup"); + + Evas_Object *popup = elm_popup_add(nf); + elm_popup_align_set(popup, ELM_NOTIFY_ALIGN_FILL, 1.0); + evas_object_size_hint_weight_set(popup, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND); + elm_object_part_text_set(popup, "title,text", title); + elm_object_text_set(popup,buf); + + eext_object_event_callback_add(popup, EEXT_CALLBACK_BACK, _popup_hide_cb, NULL); + evas_object_smart_callback_add(popup, "dismissed", _popup_hide_finished_cb, NULL); + evas_object_smart_callback_add(popup, "block,clicked", _popup_block_clicked_cb, NULL); + + /* Not Now button */ + Evas_Object *btn1 = elm_button_add(popup); + elm_object_style_set(btn1, "border"); + elm_object_text_set(btn1, "Not Now"); + elm_object_part_content_set(popup, "button1", btn1); + evas_object_smart_callback_add(btn1, "clicked", _send_notification_download_image_cb, popup); + + /* Download button */ + Evas_Object *btn2 = elm_button_add(popup); + //elm_object_style_set(btn2, "popup"); + elm_object_text_set(btn2, "Download"); + elm_object_part_content_set(popup, "button2", btn2); + evas_object_smart_callback_add(btn2, "clicked", _download_image_cb, nf); + + evas_object_show(popup); + } +} diff --git a/tizen-manifest.xml b/tizen-manifest.xml new file mode 100755 index 0000000..3f494f1 --- /dev/null +++ b/tizen-manifest.xml @@ -0,0 +1,18 @@ + + + + + + firmware-update-ui.png + + + + http://tizen.org/privilege/appdir.shareddata + http://tizen.org/privilege/d2d.datasharing + http://tizen.org/privilege/updatecontrol.admin + http://tizen.org/privilege/notification + http://tizen.org/privilege/datasharing + http://tizen.org/privilege/externalstorage.appdata + http://tizen.org/privilege/externalstorage + +