From 59f51ea0639dd33359cd77c773fb55a3723bac50 Mon Sep 17 00:00:00 2001 From: mamingshuai Date: Thu, 11 Mar 2021 18:48:31 +0800 Subject: [PATCH] update openharmony 1.0.1 --- .gitee/ISSUE_TEMPLATE.zh-CN.md | 13 - .gitee/PULL_REQUEST_TEMPLATE.zh-CN.md | 15 - README.md | 97 ++- README_zh.md | 88 +++ figures/en-us_image_0000001085773976.gif | Bin 0 -> 2578 bytes figures/en-us_image_0000001086697634.png | Bin 0 -> 19951 bytes figures/en-us_image_0000001133175707.png | Bin 0 -> 21913 bytes figures/zh-cn_image_0000001085773976.gif | Bin 0 -> 4948 bytes figures/zh-cn_image_0000001086697634.png | Bin 0 -> 30833 bytes figures/zh-cn_image_0000001133175707.png | Bin 0 -> 39933 bytes frameworks/ability_lite/BUILD.gn | 128 ++++ frameworks/ability_lite/LICENSE | 177 ++++++ frameworks/ability_lite/README.md | 50 ++ .../ability_lite/include/ability_env_impl.h | 50 ++ .../ability_lite/include/ability_scheduler.h | 66 ++ .../include/ability_slice_manager.h | 57 ++ .../include/ability_slice_route.h | 40 ++ .../include/ability_slice_scheduler.h | 57 ++ .../include/ability_slice_stack.h | 46 ++ .../ability_lite/include/ability_thread.h | 62 ++ .../ability_lite/include/ability_window.h | 43 ++ frameworks/ability_lite/include/app_info.h | 30 + frameworks/ability_lite/src/ability.cpp | 285 +++++++++ .../ability_lite/src/ability_context.cpp | 47 ++ frameworks/ability_lite/src/ability_env.cpp | 39 ++ .../ability_lite/src/ability_env_impl.cpp | 45 ++ .../src/ability_event_handler.cpp | 73 +++ .../ability_lite/src/ability_loader.cpp | 55 ++ frameworks/ability_lite/src/ability_main.cpp | 47 ++ .../ability_lite/src/ability_scheduler.cpp | 210 +++++++ frameworks/ability_lite/src/ability_slice.cpp | 98 +++ .../src/ability_slice_manager.cpp | 104 ++++ .../ability_lite/src/ability_slice_route.cpp | 62 ++ .../src/ability_slice_scheduler.cpp | 241 ++++++++ .../ability_lite/src/ability_slice_stack.cpp | 85 +++ .../ability_lite/src/ability_thread.cpp | 385 ++++++++++++ .../ability_lite/src/ability_window.cpp | 86 +++ .../ability_lite/src/slite/lite_context.cpp | 31 + .../ability_lite/src/slite/slite_ability.cpp | 50 ++ frameworks/abilitymgr_lite/BUILD.gn | 58 ++ frameworks/abilitymgr_lite/LICENSE | 177 ++++++ .../abilitymgr_lite/include/ability_kit.h | 50 ++ .../include/ability_service_manager.h | 59 ++ .../include/abilityms_client.h | 49 ++ .../include/abilityms_slite_client.h | 52 ++ .../abilitymgr_lite/src/ability_kit.cpp | 76 +++ .../abilitymgr_lite/src/ability_manager.cpp | 69 +++ .../src/ability_service_manager.cpp | 178 ++++++ .../abilitymgr_lite/src/abilityms_client.cpp | 95 +++ .../src/slite/ability_manager.cpp | 30 + .../src/slite/ability_manager_inner.cpp | 30 + .../src/slite/abilityms_slite_client.cpp | 115 ++++ frameworks/want_lite/BUILD.gn | 42 ++ frameworks/want_lite/LICENSE | 177 ++++++ frameworks/want_lite/README.md | 2 + frameworks/want_lite/include/want_utils.h | 40 ++ frameworks/want_lite/src/want.cpp | 325 ++++++++++ interfaces/innerkits/abilitymgr_lite/LICENSE | 177 ++++++ .../innerkits/abilitymgr_lite/README.md | 2 + .../abilitymgr_lite/ability_kit_command.h | 39 ++ .../innerkits/abilitymgr_lite/ability_main.h | 33 + .../ability_service_interface.h | 79 +++ .../slite/ability_manager_inner.h | 37 ++ interfaces/kits/ability_lite/LICENSE | 177 ++++++ interfaces/kits/ability_lite/README.md | 3 + interfaces/kits/ability_lite/ability.h | 215 +++++++ .../kits/ability_lite/ability_connection.h | 82 +++ .../kits/ability_lite/ability_context.h | 123 ++++ interfaces/kits/ability_lite/ability_env.h | 76 +++ interfaces/kits/ability_lite/ability_errors.h | 77 +++ .../kits/ability_lite/ability_event_handler.h | 100 ++++ interfaces/kits/ability_lite/ability_loader.h | 137 +++++ .../kits/ability_lite/ability_manager.h | 94 +++ interfaces/kits/ability_lite/ability_slice.h | 153 +++++ interfaces/kits/ability_lite/ability_state.h | 90 +++ .../kits/ability_lite/slite/ability_manager.h | 41 ++ .../kits/ability_lite/slite/lite_context.h | 51 ++ .../kits/ability_lite/slite/slite_ability.h | 89 +++ interfaces/kits/want_lite/LICENSE | 177 ++++++ interfaces/kits/want_lite/README.md | 2 + want.h => interfaces/kits/want_lite/want.h | 0 services/abilitymgr_lite/.gitignore | 1 + services/abilitymgr_lite/BUILD.gn | 123 ++++ services/abilitymgr_lite/LICENSE | 177 ++++++ services/abilitymgr_lite/README.md | 121 ++++ .../include/ability_connect_mission.h | 46 ++ .../include/ability_connect_record.h | 68 +++ .../include/ability_connect_trans_param.h | 71 +++ .../include/ability_inner_feature.h | 64 ++ .../abilitymgr_lite/include/ability_list.h | 38 ++ .../include/ability_message_id.h | 69 +++ .../include/ability_mgr_context.h | 41 ++ .../include/ability_mgr_feature.h | 79 +++ .../include/ability_mgr_handler.h | 63 ++ .../include/ability_mgr_service.h | 46 ++ .../include/ability_mgr_slite_feature.h | 57 ++ .../include/ability_mission_record.h | 55 ++ .../include/ability_mission_stack.h | 54 ++ .../abilitymgr_lite/include/ability_record.h | 165 +++++ .../abilitymgr_lite/include/ability_service.h | 77 +++ .../abilitymgr_lite/include/ability_stack.h | 38 ++ .../include/ability_stack_manager.h | 58 ++ .../abilitymgr_lite/include/ability_worker.h | 49 ++ .../abilitymgr_lite/include/app_manager.h | 47 ++ services/abilitymgr_lite/include/app_record.h | 60 ++ .../include/client/ability_dump_client.h | 35 ++ .../include/client/ability_thread_client.h | 64 ++ .../include/client/app_spawn_client.h | 35 ++ .../include/client/bundlems_client.h | 37 ++ .../include/client/wms_client.h | 29 + .../abilitymgr_lite/include/js_app_host.h | 57 ++ .../include/page_ability_record.h | 120 ++++ .../include/task/ability_activate_task.h | 36 ++ .../include/task/ability_attach_task.h | 33 + .../include/task/ability_background_task.h | 36 ++ .../include/task/ability_connect_done_task.h | 37 ++ .../include/task/ability_connect_task.h | 39 ++ .../task/ability_disconnect_done_task.h | 35 ++ .../include/task/ability_disconnect_task.h | 36 ++ .../include/task/ability_dump_task.h | 34 ++ .../include/task/ability_inactivate_task.h | 34 ++ .../include/task/ability_start_task.h | 45 ++ .../include/task/ability_stop_task.h | 34 ++ .../include/task/ability_task.h | 42 ++ .../task/ability_terminate_service_task.h | 35 ++ .../include/task/ability_terminate_task.h | 35 ++ .../include/task/app_restart_task.h | 35 ++ .../include/task/app_terminate_task.h | 34 ++ .../include/util/abilityms_helper.h | 43 ++ .../include/util/abilityms_log.h | 91 +++ .../include/util/abilityms_status.h | 167 ++++++ .../src/ability_connect_mission.cpp | 154 +++++ .../src/ability_inner_feature.cpp | 180 ++++++ services/abilitymgr_lite/src/ability_list.cpp | 81 +++ .../src/ability_mgr_context.cpp | 71 +++ .../src/ability_mgr_feature.cpp | 504 ++++++++++++++++ .../src/ability_mgr_handler.cpp | 378 ++++++++++++ .../src/ability_mgr_service.cpp | 103 ++++ .../src/ability_mgr_slite_feature.cpp | 108 ++++ .../src/ability_mission_record.cpp | 186 ++++++ .../src/ability_mission_stack.cpp | 151 +++++ .../abilitymgr_lite/src/ability_record.cpp | 67 +++ .../abilitymgr_lite/src/ability_service.cpp | 564 ++++++++++++++++++ .../abilitymgr_lite/src/ability_stack.cpp | 61 ++ .../src/ability_stack_manager.cpp | 237 ++++++++ .../abilitymgr_lite/src/ability_worker.cpp | 184 ++++++ services/abilitymgr_lite/src/app_manager.cpp | 112 ++++ services/abilitymgr_lite/src/app_record.cpp | 183 ++++++ .../src/client/ability_dump_client.cpp | 72 +++ .../src/client/ability_thread_client.cpp | 241 ++++++++ .../src/client/app_spawn_client.cpp | 157 +++++ .../src/client/bundlems_client.cpp | 73 +++ .../abilitymgr_lite/src/client/wms_client.cpp | 53 ++ services/abilitymgr_lite/src/js_app_host.cpp | 149 +++++ .../src/page_ability_record.cpp | 485 +++++++++++++++ .../src/task/ability_activate_task.cpp | 55 ++ .../src/task/ability_attach_task.cpp | 61 ++ .../src/task/ability_background_task.cpp | 38 ++ .../src/task/ability_connect_done_task.cpp | 43 ++ .../src/task/ability_connect_task.cpp | 87 +++ .../src/task/ability_disconnect_done_task.cpp | 40 ++ .../src/task/ability_disconnect_task.cpp | 40 ++ .../src/task/ability_dump_task.cpp | 49 ++ .../src/task/ability_inactivate_task.cpp | 64 ++ .../src/task/ability_start_task.cpp | 110 ++++ .../src/task/ability_stop_task.cpp | 67 +++ .../task/ability_terminate_service_task.cpp | 52 ++ .../src/task/ability_terminate_task.cpp | 45 ++ .../src/task/app_restart_task.cpp | 52 ++ .../src/task/app_terminate_task.cpp | 52 ++ .../src/util/abilityms_helper.cpp | 146 +++++ .../src/util/abilityms_status.cpp | 69 +++ services/abilitymgr_lite/tools/BUILD.gn | 81 +++ services/abilitymgr_lite/tools/LICENSE | 177 ++++++ services/abilitymgr_lite/tools/README.md | 24 + .../tools/include/ability_tool.h | 51 ++ .../tools/src/ability_tool.cpp | 310 ++++++++++ services/abilitymgr_lite/tools/src/main.cpp | 108 ++++ 178 files changed, 15910 insertions(+), 30 deletions(-) delete mode 100755 .gitee/ISSUE_TEMPLATE.zh-CN.md delete mode 100755 .gitee/PULL_REQUEST_TEMPLATE.zh-CN.md create mode 100755 README_zh.md create mode 100755 figures/en-us_image_0000001085773976.gif create mode 100755 figures/en-us_image_0000001086697634.png create mode 100755 figures/en-us_image_0000001133175707.png create mode 100755 figures/zh-cn_image_0000001085773976.gif create mode 100755 figures/zh-cn_image_0000001086697634.png create mode 100755 figures/zh-cn_image_0000001133175707.png create mode 100755 frameworks/ability_lite/BUILD.gn create mode 100755 frameworks/ability_lite/LICENSE create mode 100755 frameworks/ability_lite/README.md create mode 100644 frameworks/ability_lite/include/ability_env_impl.h create mode 100755 frameworks/ability_lite/include/ability_scheduler.h create mode 100755 frameworks/ability_lite/include/ability_slice_manager.h create mode 100644 frameworks/ability_lite/include/ability_slice_route.h create mode 100644 frameworks/ability_lite/include/ability_slice_scheduler.h create mode 100644 frameworks/ability_lite/include/ability_slice_stack.h create mode 100755 frameworks/ability_lite/include/ability_thread.h create mode 100644 frameworks/ability_lite/include/ability_window.h create mode 100644 frameworks/ability_lite/include/app_info.h create mode 100755 frameworks/ability_lite/src/ability.cpp create mode 100755 frameworks/ability_lite/src/ability_context.cpp create mode 100644 frameworks/ability_lite/src/ability_env.cpp create mode 100644 frameworks/ability_lite/src/ability_env_impl.cpp create mode 100644 frameworks/ability_lite/src/ability_event_handler.cpp create mode 100644 frameworks/ability_lite/src/ability_loader.cpp create mode 100644 frameworks/ability_lite/src/ability_main.cpp create mode 100644 frameworks/ability_lite/src/ability_scheduler.cpp create mode 100644 frameworks/ability_lite/src/ability_slice.cpp create mode 100755 frameworks/ability_lite/src/ability_slice_manager.cpp create mode 100644 frameworks/ability_lite/src/ability_slice_route.cpp create mode 100644 frameworks/ability_lite/src/ability_slice_scheduler.cpp create mode 100644 frameworks/ability_lite/src/ability_slice_stack.cpp create mode 100755 frameworks/ability_lite/src/ability_thread.cpp create mode 100644 frameworks/ability_lite/src/ability_window.cpp create mode 100755 frameworks/ability_lite/src/slite/lite_context.cpp create mode 100755 frameworks/ability_lite/src/slite/slite_ability.cpp create mode 100755 frameworks/abilitymgr_lite/BUILD.gn create mode 100755 frameworks/abilitymgr_lite/LICENSE create mode 100644 frameworks/abilitymgr_lite/include/ability_kit.h create mode 100755 frameworks/abilitymgr_lite/include/ability_service_manager.h create mode 100644 frameworks/abilitymgr_lite/include/abilityms_client.h create mode 100755 frameworks/abilitymgr_lite/include/abilityms_slite_client.h create mode 100644 frameworks/abilitymgr_lite/src/ability_kit.cpp create mode 100755 frameworks/abilitymgr_lite/src/ability_manager.cpp create mode 100755 frameworks/abilitymgr_lite/src/ability_service_manager.cpp create mode 100644 frameworks/abilitymgr_lite/src/abilityms_client.cpp create mode 100755 frameworks/abilitymgr_lite/src/slite/ability_manager.cpp create mode 100755 frameworks/abilitymgr_lite/src/slite/ability_manager_inner.cpp create mode 100755 frameworks/abilitymgr_lite/src/slite/abilityms_slite_client.cpp create mode 100755 frameworks/want_lite/BUILD.gn create mode 100755 frameworks/want_lite/LICENSE create mode 100644 frameworks/want_lite/README.md create mode 100644 frameworks/want_lite/include/want_utils.h create mode 100755 frameworks/want_lite/src/want.cpp create mode 100755 interfaces/innerkits/abilitymgr_lite/LICENSE create mode 100644 interfaces/innerkits/abilitymgr_lite/README.md create mode 100644 interfaces/innerkits/abilitymgr_lite/ability_kit_command.h create mode 100644 interfaces/innerkits/abilitymgr_lite/ability_main.h create mode 100755 interfaces/innerkits/abilitymgr_lite/ability_service_interface.h create mode 100755 interfaces/innerkits/abilitymgr_lite/slite/ability_manager_inner.h create mode 100755 interfaces/kits/ability_lite/LICENSE create mode 100644 interfaces/kits/ability_lite/README.md create mode 100644 interfaces/kits/ability_lite/ability.h create mode 100644 interfaces/kits/ability_lite/ability_connection.h create mode 100644 interfaces/kits/ability_lite/ability_context.h create mode 100644 interfaces/kits/ability_lite/ability_env.h create mode 100755 interfaces/kits/ability_lite/ability_errors.h create mode 100644 interfaces/kits/ability_lite/ability_event_handler.h create mode 100644 interfaces/kits/ability_lite/ability_loader.h create mode 100644 interfaces/kits/ability_lite/ability_manager.h create mode 100644 interfaces/kits/ability_lite/ability_slice.h create mode 100644 interfaces/kits/ability_lite/ability_state.h create mode 100755 interfaces/kits/ability_lite/slite/ability_manager.h create mode 100755 interfaces/kits/ability_lite/slite/lite_context.h create mode 100755 interfaces/kits/ability_lite/slite/slite_ability.h create mode 100755 interfaces/kits/want_lite/LICENSE create mode 100644 interfaces/kits/want_lite/README.md rename want.h => interfaces/kits/want_lite/want.h (100%) mode change 100755 => 100644 create mode 100644 services/abilitymgr_lite/.gitignore create mode 100644 services/abilitymgr_lite/BUILD.gn create mode 100755 services/abilitymgr_lite/LICENSE create mode 100755 services/abilitymgr_lite/README.md create mode 100644 services/abilitymgr_lite/include/ability_connect_mission.h create mode 100755 services/abilitymgr_lite/include/ability_connect_record.h create mode 100755 services/abilitymgr_lite/include/ability_connect_trans_param.h create mode 100755 services/abilitymgr_lite/include/ability_inner_feature.h create mode 100644 services/abilitymgr_lite/include/ability_list.h create mode 100644 services/abilitymgr_lite/include/ability_message_id.h create mode 100644 services/abilitymgr_lite/include/ability_mgr_context.h create mode 100755 services/abilitymgr_lite/include/ability_mgr_feature.h create mode 100644 services/abilitymgr_lite/include/ability_mgr_handler.h create mode 100755 services/abilitymgr_lite/include/ability_mgr_service.h create mode 100755 services/abilitymgr_lite/include/ability_mgr_slite_feature.h create mode 100644 services/abilitymgr_lite/include/ability_mission_record.h create mode 100644 services/abilitymgr_lite/include/ability_mission_stack.h create mode 100755 services/abilitymgr_lite/include/ability_record.h create mode 100755 services/abilitymgr_lite/include/ability_service.h create mode 100755 services/abilitymgr_lite/include/ability_stack.h create mode 100644 services/abilitymgr_lite/include/ability_stack_manager.h create mode 100644 services/abilitymgr_lite/include/ability_worker.h create mode 100644 services/abilitymgr_lite/include/app_manager.h create mode 100644 services/abilitymgr_lite/include/app_record.h create mode 100755 services/abilitymgr_lite/include/client/ability_dump_client.h create mode 100755 services/abilitymgr_lite/include/client/ability_thread_client.h create mode 100644 services/abilitymgr_lite/include/client/app_spawn_client.h create mode 100644 services/abilitymgr_lite/include/client/bundlems_client.h create mode 100644 services/abilitymgr_lite/include/client/wms_client.h create mode 100755 services/abilitymgr_lite/include/js_app_host.h create mode 100755 services/abilitymgr_lite/include/page_ability_record.h create mode 100644 services/abilitymgr_lite/include/task/ability_activate_task.h create mode 100644 services/abilitymgr_lite/include/task/ability_attach_task.h create mode 100644 services/abilitymgr_lite/include/task/ability_background_task.h create mode 100644 services/abilitymgr_lite/include/task/ability_connect_done_task.h create mode 100644 services/abilitymgr_lite/include/task/ability_connect_task.h create mode 100644 services/abilitymgr_lite/include/task/ability_disconnect_done_task.h create mode 100644 services/abilitymgr_lite/include/task/ability_disconnect_task.h create mode 100644 services/abilitymgr_lite/include/task/ability_dump_task.h create mode 100644 services/abilitymgr_lite/include/task/ability_inactivate_task.h create mode 100644 services/abilitymgr_lite/include/task/ability_start_task.h create mode 100644 services/abilitymgr_lite/include/task/ability_stop_task.h create mode 100644 services/abilitymgr_lite/include/task/ability_task.h create mode 100644 services/abilitymgr_lite/include/task/ability_terminate_service_task.h create mode 100644 services/abilitymgr_lite/include/task/ability_terminate_task.h create mode 100644 services/abilitymgr_lite/include/task/app_restart_task.h create mode 100644 services/abilitymgr_lite/include/task/app_terminate_task.h create mode 100755 services/abilitymgr_lite/include/util/abilityms_helper.h create mode 100755 services/abilitymgr_lite/include/util/abilityms_log.h create mode 100644 services/abilitymgr_lite/include/util/abilityms_status.h create mode 100644 services/abilitymgr_lite/src/ability_connect_mission.cpp create mode 100644 services/abilitymgr_lite/src/ability_inner_feature.cpp create mode 100644 services/abilitymgr_lite/src/ability_list.cpp create mode 100755 services/abilitymgr_lite/src/ability_mgr_context.cpp create mode 100644 services/abilitymgr_lite/src/ability_mgr_feature.cpp create mode 100644 services/abilitymgr_lite/src/ability_mgr_handler.cpp create mode 100755 services/abilitymgr_lite/src/ability_mgr_service.cpp create mode 100755 services/abilitymgr_lite/src/ability_mgr_slite_feature.cpp create mode 100644 services/abilitymgr_lite/src/ability_mission_record.cpp create mode 100644 services/abilitymgr_lite/src/ability_mission_stack.cpp create mode 100755 services/abilitymgr_lite/src/ability_record.cpp create mode 100755 services/abilitymgr_lite/src/ability_service.cpp create mode 100644 services/abilitymgr_lite/src/ability_stack.cpp create mode 100644 services/abilitymgr_lite/src/ability_stack_manager.cpp create mode 100644 services/abilitymgr_lite/src/ability_worker.cpp create mode 100644 services/abilitymgr_lite/src/app_manager.cpp create mode 100755 services/abilitymgr_lite/src/app_record.cpp create mode 100644 services/abilitymgr_lite/src/client/ability_dump_client.cpp create mode 100644 services/abilitymgr_lite/src/client/ability_thread_client.cpp create mode 100644 services/abilitymgr_lite/src/client/app_spawn_client.cpp create mode 100644 services/abilitymgr_lite/src/client/bundlems_client.cpp create mode 100755 services/abilitymgr_lite/src/client/wms_client.cpp create mode 100755 services/abilitymgr_lite/src/js_app_host.cpp create mode 100644 services/abilitymgr_lite/src/page_ability_record.cpp create mode 100644 services/abilitymgr_lite/src/task/ability_activate_task.cpp create mode 100644 services/abilitymgr_lite/src/task/ability_attach_task.cpp create mode 100644 services/abilitymgr_lite/src/task/ability_background_task.cpp create mode 100644 services/abilitymgr_lite/src/task/ability_connect_done_task.cpp create mode 100644 services/abilitymgr_lite/src/task/ability_connect_task.cpp create mode 100644 services/abilitymgr_lite/src/task/ability_disconnect_done_task.cpp create mode 100644 services/abilitymgr_lite/src/task/ability_disconnect_task.cpp create mode 100644 services/abilitymgr_lite/src/task/ability_dump_task.cpp create mode 100644 services/abilitymgr_lite/src/task/ability_inactivate_task.cpp create mode 100644 services/abilitymgr_lite/src/task/ability_start_task.cpp create mode 100644 services/abilitymgr_lite/src/task/ability_stop_task.cpp create mode 100644 services/abilitymgr_lite/src/task/ability_terminate_service_task.cpp create mode 100644 services/abilitymgr_lite/src/task/ability_terminate_task.cpp create mode 100644 services/abilitymgr_lite/src/task/app_restart_task.cpp create mode 100644 services/abilitymgr_lite/src/task/app_terminate_task.cpp create mode 100755 services/abilitymgr_lite/src/util/abilityms_helper.cpp create mode 100644 services/abilitymgr_lite/src/util/abilityms_status.cpp create mode 100755 services/abilitymgr_lite/tools/BUILD.gn create mode 100755 services/abilitymgr_lite/tools/LICENSE create mode 100755 services/abilitymgr_lite/tools/README.md create mode 100755 services/abilitymgr_lite/tools/include/ability_tool.h create mode 100755 services/abilitymgr_lite/tools/src/ability_tool.cpp create mode 100755 services/abilitymgr_lite/tools/src/main.cpp diff --git a/.gitee/ISSUE_TEMPLATE.zh-CN.md b/.gitee/ISSUE_TEMPLATE.zh-CN.md deleted file mode 100755 index f09d98d..0000000 --- a/.gitee/ISSUE_TEMPLATE.zh-CN.md +++ /dev/null @@ -1,13 +0,0 @@ -### 该问题是怎么引起的? - - - -### 重现步骤 - - - -### 报错信息 - - - - diff --git a/.gitee/PULL_REQUEST_TEMPLATE.zh-CN.md b/.gitee/PULL_REQUEST_TEMPLATE.zh-CN.md deleted file mode 100755 index 33948fd..0000000 --- a/.gitee/PULL_REQUEST_TEMPLATE.zh-CN.md +++ /dev/null @@ -1,15 +0,0 @@ -### 相关的Issue - - -### 原因(目的、解决的问题等) - - -### 描述(做了什么,变更了什么) - - -### 测试用例(新增、改动、可能影响的功能) - - - - - diff --git a/README.md b/README.md index 5ee1745..6e6a837 100755 --- a/README.md +++ b/README.md @@ -1,2 +1,95 @@ -## Introduction -A data struct named Want utilized to encapsulate some elements in order to simplify the process of starting an application. \ No newline at end of file +# Ability Management Framework + +- [Introduction](#section11660541593) +- [\#EN-US\_TOPIC\_0000001062157546/section5503249756](#section5503249756) +- [Directory Structure](#section1464106163817) +- [Usage](#section1954314201620) +- [Repositories Involved](#section93061357133720) + +## Introduction + +The ability management framework is provided by OpenHarmony for you to develop OpenHarmony applications. The following figure shows the architecture of the ability management framework. + +**Figure 1** Ability management framework + +![](figures/en-us_image_0000001133175707.png) + +- **AbilityKit** is a development kit provided by the ability management framework. You can use this kit to develop applications based on the **Ability** component. There are two types of applications developed based on the **Ability** component: **JS Ability** developed using the JavaScript language and **Native Ability** developed using the C/C++ language. The **JS application development framework** encapsulates JavaScript UI components on the basis of the AbilityKit and is used to help you quickly develop JS Ability-based applications. +- **Ability** is the minimum unit for the system to schedule applications. It is a component that can implement an independent functionality. An application can contain one or more **Ability** instances. There are two types of templates that you can use to create an **Ability** instance: Page and Service. + - An **Ability using the Page template** \(Page ability for short\) provides a UI for interacting with users. + - An **Ability using the Service template** \(Service ability for short\) does not have a UI and is used for running background tasks. + +- An **AbilitySlice** represents a single screen and its control logic. It is specific to Page abilities. A Page ability may contain one ability slice or multiple ability slices that provide highly relevant capabilities. The following figure shows the relationship between a Page ability and its ability slices. + +**Figure 2** Relationship between a Page ability and its ability slices + +![](figures/en-us_image_0000001085773976.gif) + +- **Lifecycle** is a general term for all states of an ability, including **UNINITIALIZED**, **INITIAL**, **INACTIVE**, **ACTIVE**, and **BACKGROUND**. The following figure shows the lifecycle state transition of an ability. + +**Figure 3** Lifecycle state transition of a Page ability + +![](figures/en-us_image_0000001086697634.png) + +- Description of ability lifecycle states: + - **UNINITIALIZED**: The ability is not initialized. This state is a temporary state. An ability changes directly to the **INITIAL** state upon its creation. + + - **INITIAL**: This state refers to the initial or stopped state. The ability in this state is not running. The ability enters the **INACTIVE** state after it is started. + + - **INACTIVE**: The ability is visible but does not gain focus. + + - **ACTIVE**: The ability is in the foreground and has focus. The ability changes from the **ACTIVE** state to the **INACTIVE** state before returning to the background. + + - **BACKGROUND**: The ability returns to the background. After being re-activated, the ability enters the **ACTIVE** state. After being destroyed, the ability enters the **INITIAL** state. + +- **AbilityLoader** is used to register and load **Ability** classes. After creating an **Ability** class, you should first call the registration API defined in **AbilityLoader** to register the **Ability** class name with the ability management framework so that this **Ability** can be instantiated when being started. +- **AbilityManager** enables inter-process communication \(IPC\) between the AbilityKit and the Ability Manager Service. +- **EventHandler** is provided by the AbilityKit to enable inter-thread communication between abilities. +- The **Ability Manager Service** is a system service used to coordinate the running relationships and lifecycle states of **Ability** instances. It consists of the following sub-modules: + - The **service startup** sub-module starts and registers the Ability Manager Service. + - The **service interface management** sub-module manages external capabilities provided by the Ability Manager Service. + - The **process management** sub-module starts and destroys processes where **Ability** instances are running, and maintains the process information. + - The **ability stack management** sub-module maintains the presentation sequence of abilities in the stack. + - The **lifecycle scheduling** sub-module changes an ability to a particular state based on the current operation of the system. + - The **connection management** sub-module manages connections to Service abilities. + +- **AppSpawn** is a system service used to create the process for running an ability. This service has high permissions. It sets permissions for **Ability** instances and pre-loads some common modules to accelerate application startup. + +## Directory Structure + +``` +/foundation/aafwk/aafwk_lite + ├── frameworks + │ ├── ability_lite # Core implementation code of AbilityKit + │ ├── abilitymgr_lite # Client code used for communication between the AbilityKit and Ability Manager Service + │ └── want_lite # Implementation code of the information carrier for interaction between abilities + ├── interfaces + │ ├── kits + │ │ ├── ability_lite # AbilityKit APIs exposed externally + │ │ └── want_lite # External APIs of the information carrier for interaction between abilities + │ └── innerkits + │ └── abilitymgr_lite # Internal APIs provided by the Ability Manager Service for other subsystems + └── services + └── abilitymgr_lite # Implementation code of the Ability Manager Service +``` + +## Usage + +- The Ability Manager Service is running in the foundation process. +- The Ability Manager Service is registered with **sa\_manager**. **sa\_manager** runs in the foundation process and sets up a thread runtime environment for the service. For details about how to create and use the Ability Manager Service, see [SA Framework](en-us_topic_0000001051589563.md). +- The Ability Manager Service starts upon OS startup. + +- After the HAP installation is complete, you can use the aa tool to run the demo for starting the specified ability through the following command. \(Taking **hispark\_taurus** as an example, you can obtain the aa tool from the **out/hispark\_taurus/ipcamera\_hispark\_taurus/dev\_tools/bin** directory after the version building.\) + +``` +./bin/aa start -p com.xxxxxx.hiability -n MainAbility +``` + +## Repositories Involved + +Application framework + +**aafwk\_lite** + +appexecfwk\_lite + diff --git a/README_zh.md b/README_zh.md new file mode 100755 index 0000000..b46b40d --- /dev/null +++ b/README_zh.md @@ -0,0 +1,88 @@ +# 元能力组件 + +- [简介](#section11660541593) +- [\#ZH-CN\_TOPIC\_0000001062157546/section5503249756](#section5503249756) +- [目录](#section1464106163817) +- [使用说明](#section1954314201620) +- [相关仓](#section93061357133720) + +## 简介 + +**元能力组件**,是OpenHarmony为开发者提供的一套开发鸿蒙应用的开发框架。元能力组件由如下模块组成: + +**图1** 元能力组件框架图 + +![](figures/zh-cn_image_0000001133175707.png) + +- **AbilityKit**是Ability框架提供给开发者的开发包,开发者基于该开发包可以开发出基于Ability组件的应用。基于Ability组件开发的应用有两种类型:基于Javascript语言开发的Ability(**JS Ability**)和基于C/C++语言开发的Ability(**Native Ability**)。**JS应用开发框架**是开发者开发JS Ability所用到框架,是在AbilityKit基础封装的包含JS UI组件的一套方便开发者能够迅速开发Ability应用的框架。 +- **Ability**是系统调度应用的最小单元,是能够完成一个独立功能的组件,一个应用可以包含一个或多个Ability。Ability分为两种类型:Page类型的Ability和Service类型的Ability + - **Page类型的Ability:**带有界面,为用户提供人机交互的能力。 + - **Service类型的Ability**:不带界面,为用户提供后台任务机制。 + +- **AbilitySlice**是单个页面及其控制逻辑的总和,是Page类型Ability特有的组件,一个Page类型的Ability可以包含多个AbilitySlice,此时,这些页面提供的业务能力应当是高度相关的。Page类型的Ability和AbilitySlice的关系如下图2所示: + +**图2 **Ability与AbilitySlice的关系图 + +![](figures/zh-cn_image_0000001085773976.gif) + +- **生命周期**是Ability被调度到启动、激活、隐藏和退出等各个状态的的统称。Ability各生命周期流转如下图所示: + +**图3** Ability生命周期流转图 + +![](figures/zh-cn_image_0000001086697634.png) + +- Ability生命周期各状态解析: + - **UNINITIALIZED**:未初始状态,为临时状态,Ability被创建后会由UNINITIALIZED状态进入INITIAL状态; + + - **INITIAL**:初始化状态,也表示停止状态,表示当前Ability未运行,Ability被启动后由INITIAL态进入INACTIVE状态; + + - **INACTIVE**:未激活状态,表示当前窗口已显示但是无焦点状态。 + + - **ACTIVE**:前台激活状态,表示当前窗口已显示,并获取焦点,Ability在退到后台之前先由ACTIVE状态进入INACTIVE状态; + + - **BACKGROUND**: 后台状态,表示当前Ability退到后台,Ability在被销毁后由BACKGROUND状态进入INITIAL状态,或者重新被激活后由BACKGROUND状态进入ACTIVE状态。 + +- **AbilityLoader**负责注册和加载开发者Ability的模块。开发者开发的Ability先要调用AbilityLoader的注册接口注册到框架中,接着Ability启动时会被实例化。 +- **AbilityManager**负责AbilityKit和Ability管理服务进行IPC的通信。 +- **EventHandler**是AbilityKit提供给开发者的用于在Ability中实现线程间通信的一个模块。 +- **Ability运行管理服务**是用于协调各Ability运行关系、及生命周期进行调度的系统服务。其中,**服务启动**模块负责Ability管理服务的启动、注册等。**服务接口管理模块**负责Ability管理服务对外能力的管理。**进程管理模块**负责Ability应用所在进程的启动和销毁、及其进程信息维护等功能。**Ability栈管理模块**负责维护各个Ability之间跳转的先后关系。**生命周期调度模块**是Ability管理服务根据系统当前的操作调度Ability进入相应的状态的模块**。连接管理模块**是Ability管理服务对Service类型Ability连接管理的模块 +- **AppSpawn**是负责创建Ability应用所在进程的系统服务,该服务有较高的权限,为Ability应用设置相应的权限,并预加载一些通用的模块,加速应用的启动。 + +## 目录 + +``` +/foundation/aafwk/aafwk_lite + ├── frameworks + │ ├── ability_lite # AbilityKit实现的核心代码 + │ ├── abilitymgr_lite # 管理AbilityKit与Ability管理服务通信的客户端代码 + │ └── want_lite # Ability之间交互的信息载体的实现代码 + ├── interfaces + │ ├── kits + │ │ ├── ability_lite # AbilityKit为开发者提供的接口 + │ │ └── want_lite # Ability之间交互的信息载体的对外接口 + │ └── innerkits + │ └── abilitymgr_lite # Ability管理服务为其它子系统提供的接口 + └── services + └── abilitymgr_lite # Ability管理服务的实现代码 +``` + +## 使用说明 + +- 元能力运行管理服务为AbilityMs,服务运行于foudation进程中; +- AbilityMs注册到sa\_manager中,sa\_manager运行于foundation进程中,sa\_manager为AbilityMs创建线程运行环境。具体创建AbilityMs服务的方式以及使用该服务的方式,可参考[系统服务框架子系统](zh-cn_topic_0000001051589563.md); +- 系统启动后,AbilityMs会随系统启动而启动; + +- 包安装完成后,通过如下命令(以hispark\_taurus为例,aa工具在系统构建后放置在out/hispark\_taurus/ipcamera\_hispark\_taurus/dev\_tools/bin下),运行Demo启动相应Ability: + +``` +./bin/aa start -p com.xxxxxx.hiability -n MainAbility +``` + +## 相关仓 + +用户程序框架子系统 + +**aafwk\_lite** + +appexecfwk\_lite + diff --git a/figures/en-us_image_0000001085773976.gif b/figures/en-us_image_0000001085773976.gif new file mode 100755 index 0000000000000000000000000000000000000000..783f02fe2b93203d093dea385c69682cbde62808 GIT binary patch literal 2578 zcmV+t3hnhrNk%w1VX*+(0B`^RA^8LW000vJEC2ui0I>kt0E7Sl0B~?{_xJZ^W@e(I zqSn^dA|fJ1MMZ^$g}uGKCx_Ya`v17U!$U?#ousGG+1+DjX(1vbfrg0y0000000000 z00000000000000000000000000000000000000I5;3SS?V4i5Iu59bRa4gSsJ(GAK z?0oP4z@TtQEEO*2!Ej0qh3IIyWTUEowXF z^}>e$BD8=2>Dl8kv0wro-pqx>bgVrB2hZ9N`SLyG=bIh5fh)K z9=Hf{Gq}(IvvS*124RUrpATgKnBn`SQ2 zXFsbufvlz1l}A~yM0p@JYIY^sM-Y9mb4ID6-naUw=7UIh=t-;0@M00KA0YH z$`QaxWt8UKd)pY}WykM)0-y%zn#h8av+Bx5f($n3;DZo82#9||C?LQB7-p#9h8%Y2;fElG zDB_4Df@mQc0{Wmpi7dA0;)^hbc;Xo;_ON1%IOeG1jx(B3BM&$3DCCetde~zaKkg7@ zkxVw3BW{^f@x-zVs=5MhzvxsVFL|x2cj6s$rl9#F^ov9Y*?RqaQ+Wz=jbFuqmsZc9P3N41^(OND4uuR@+#hM^C@ah5pNN}nu7)D^~oX5t=DY)Wd*eI_6 z*twy!gf3t%hP>L@K)uXn`)M1Yg1GJg_1;-H-H)>@SK^0wL-G68MRssttJTuDIwbJmMutjp@s8ZNk$a_CIc7B4WZhQsyg^S^cI3aP>wLK3XXP%n(|x(f`@K+LTY zdh^xI=8PuSe0bfV!y2}^=e`-T-Lk%>(%PoC89uF{1XNpnF~k~TjCYYgQ^9SA zE>)~}hSf%0vy+ieF?p@d*2*K@g4o^Z=+5hyycElyN%W=FKMB1fLU%8|_pav}{`ly- zczu7b4>5B3@Nc+279kH9|NSz4Z;SLIM(F?l01Ti2C6piY!Hz}m!yo+SmpvIN@PYDE zLIX_%!3r*bf%Q`n0xbwZ47RUA8|0t@J!nApg;0d|BO$=}=Rg#uP=Xn>(Ft9c|2`FV z?R+FkV4F;KDq=ZmX@J95)IOxOjFnDqwX$K|aEK)lxr$bt`#PYx*64?(mshJmPg8j1kLv?x9Wj&o_G@69luq{!zB({7<(AD9+%Dnt}~!b z^bqbmce%{TDtAEyr@d$e0a{V-X7(}_pi;LwDCW|l05zdCIV3x0#w%szQCTchFqLXsGx}ENnU$SOt!wq}Dps`WwNQMWD^>pr*tL$buX!bG zVdENB!H!k2UkWTQ-3nPSNp_K2t?ZR9D>6oEc5aMi>tyNrSu1hY|9+V*ZR?U6Lm+up zwTKMuVIAvN*nW()itKD^ZTnK(?h><<Moy+}kR*wMu$zb8&Rq zY6f?@)-xm-1YXy6cf2hsZ*gAGj z?~5h+;+47l#jk%63*Z3HSGL%12uql_F&*t-E!@8W8@Iw7 z_SA&`YpW1n__?`7?Sf6Lq5Lv6Oe}6NhUKc^$Hq8e|X0{=8%i`d*dOq zH^xR@agjY-)RIc)j8+&CCQ#r{~3Vt$}H=N}$+gQy1QP!=J zk(_1~hdIb*b~2i+EM+o(xy{ynGmqnpiG{WkaL*w}7^^pbtIUE(1BsTK;r#O)X?pf0fdi7WJb^o#6GZ zdDED-wWdwX=~I_E*ZMs&u3@cfSr41m4>mThf&F5vx*E#F4)(2=9qndc@Y$(m0(7Ol z>k#+4)zAL6{ID(V7L%LVM4q*(Gn{BSPa4@2_O+kkO=57ny4)}hH@byQZF=k2-l)d6 zv-Mr=bRT=&G;VjFJ+18&M_SRBuJ-@V9c?98JHq+3IK}<#g^M#d<4N#rxPd{A1d#`r zU^;SpbY&z1i3Qm_5qTEI>^ z+$+v?wtGF{V7I&2c^>ou`u*>K4?Kb54xs&Psqlv1I^yYb_{B3`@s4*-<0CJ5$WtCW olfOLXEw6dZWWMvB=RD|@^7+w|o)|Vrz3Nxb`qsN%^&tQNI|zC3@Bjb+ literal 0 HcmV?d00001 diff --git a/figures/en-us_image_0000001086697634.png b/figures/en-us_image_0000001086697634.png new file mode 100755 index 0000000000000000000000000000000000000000..7257ce2a000ff4c7b29591dcd3ead4deee09eaab GIT binary patch literal 19951 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 literal 0 HcmV?d00001 diff --git a/figures/en-us_image_0000001133175707.png b/figures/en-us_image_0000001133175707.png new file mode 100755 index 0000000000000000000000000000000000000000..5c36589713f0264b5d3f87e3af9b63b05dda17d7 GIT binary patch literal 21913 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 ARsaA1 literal 0 HcmV?d00001 diff --git a/figures/zh-cn_image_0000001086697634.png b/figures/zh-cn_image_0000001086697634.png new file mode 100755 index 0000000000000000000000000000000000000000..4738bd586c05221fcc00943792c96b4c4a5de963 GIT binary patch literal 30833 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 W|DoRGY#SZ;r*&HIRL)7;TmKK6kbsl` literal 0 HcmV?d00001 diff --git a/figures/zh-cn_image_0000001133175707.png b/figures/zh-cn_image_0000001133175707.png new file mode 100755 index 0000000000000000000000000000000000000000..37b1f5215e362c156ca5de27145c3711cc14083b GIT binary patch literal 39933 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

}LN7{3iXadYdT*fxLJ0|H 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 literal 0 HcmV?d00001 diff --git a/frameworks/ability_lite/BUILD.gn b/frameworks/ability_lite/BUILD.gn new file mode 100755 index 0000000..85b1a61 --- /dev/null +++ b/frameworks/ability_lite/BUILD.gn @@ -0,0 +1,128 @@ +# Copyright (c) 2020 Huawei Device Co., Ltd. +# 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. +import("//build/lite/config/component/lite_component.gni") +import("//build/lite/config/subsystem/aafwk/config.gni") +import("//build/lite/ndk/ndk.gni") + +generate_notice_file("ability_notice_file") { + module_name = "ability" + module_source_dir_list = [ + "//third_party/bounds_checking_function", + "//third_party/cJSON", + ] +} + +lite_library("ability") { + target_type = "shared_library" + cflags = [ + "-Wall", + "-Wno-format", + "-Wno-format-extra-args", + ] + cflags_cc = cflags + sources = [ + "src/ability.cpp", + "src/ability_context.cpp", + "src/ability_env.cpp", + "src/ability_env_impl.cpp", + "src/ability_event_handler.cpp", + "src/ability_loader.cpp", + "src/ability_main.cpp", + "src/ability_scheduler.cpp", + "src/ability_thread.cpp", + ] + + if (enable_ohos_appexecfwk_feature_ability == true) { + sources += [ + "src/ability_slice.cpp", + "src/ability_slice_manager.cpp", + "src/ability_slice_route.cpp", + "src/ability_slice_scheduler.cpp", + "src/ability_slice_stack.cpp", + "src/ability_window.cpp", + ] + } + + public_deps = [ + "${aafwk_lite_path}/frameworks/abilitymgr_lite:abilitymanager", + "${appexecfwk_lite_path}/frameworks/bundle_lite:bundle", + "//base/hiviewdfx/hilog_lite/frameworks/featured:hilog_shared", + "//foundation/communication/ipc_lite:liteipc_adapter", + "//utils/native/lite/kv_store:kv_store", + ] + + if (enable_ohos_appexecfwk_feature_ability == true) { + public_deps += [ "//foundation/graphic/ui:lite_ui" ] + } + + include_dirs = [ + "${aafwk_lite_path}/frameworks/abilitymgr_lite/include", + "${aafwk_lite_path}/frameworks/want_lite/include", + "${aafwk_lite_path}/interfaces/innerkits/abilitymgr_lite", + "${aafwk_lite_path}/interfaces/kits/want_lite", + "${aafwk_lite_path}/interfaces/kits/ability_lite", + "${appexecfwk_lite_path}/utils/bundle_lite", + "${appexecfwk_lite_path}/interfaces/kits/bundle_lite", + "${appexecfwk_lite_path}/frameworks/bundle_lite/include", + "//foundation/graphic/ui/frameworks", + "//foundation/graphic/surface/interfaces/kits", + "//foundation/distributedschedule/samgr_lite/interfaces/kits/registry", + "//foundation/distributedschedule/samgr_lite/interfaces/kits/samgr", + "//foundation/communication/ipc_lite/frameworks/liteipc/include", + "//kernel/liteos_a/kernel/include", + "//kernel/liteos_a/kernel/common", + "//third_party/bounds_checking_function/include", + "//third_party/freetype/include", + "//utils/native/lite/kv_store/innerkits", + "//utils/native/lite/include", + "./include", + "./", + ] + + defines = [ "OHOS_APPEXECFWK_BMS_BUNDLEMANAGER" ] + + if (board_name == "hispark_taurus") { + defines += [ "OPENHARMONY_FONT_PATH" ] + } + + if (enable_ohos_appexecfwk_feature_ability == true) { + defines += [ "ABILITY_WINDOW_SUPPORT" ] + } +} + +lite_component("aafwk_abilitykit_lite") { + if (enable_ohos_appexecfwk_feature_ability == true) { + public_configs = [ ":abilitykit_config" ] + } + + features = [ ":ability" ] +} + +config("abilitykit_config") { + ldflags = [ + "-lstdc++", + "-Wl,-rpath-link=$ohos_root_path/$root_out_dir", + ] +} + +ndk_lib("ability_notes") { + lib_extension = ".so" + deps = [ + ":ability", + "${aafwk_lite_path}/frameworks/abilitymgr_lite:abilitymanager", + ] + head_files = [ + "${aafwk_lite_path}/interfaces/kits/ability_lite", + "${aafwk_lite_path}/interfaces/kits/want_lite", + ] +} diff --git a/frameworks/ability_lite/LICENSE b/frameworks/ability_lite/LICENSE new file mode 100755 index 0000000..4a45986 --- /dev/null +++ b/frameworks/ability_lite/LICENSE @@ -0,0 +1,177 @@ + + 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 \ No newline at end of file diff --git a/frameworks/ability_lite/README.md b/frameworks/ability_lite/README.md new file mode 100755 index 0000000..9750565 --- /dev/null +++ b/frameworks/ability_lite/README.md @@ -0,0 +1,50 @@ +# AbilityKit - ability development kit + +## Introduction + +The cpp file is the implementation of AbilityKit class. + +## Features + +- provides methods for users to write their own applications. +- manage slices of the ability in an application +- create the application main thread and display the window + +## Directions + +``` + +. +└── ability_lite + ├── BUILD.gn + ├── include + │   ├── ability_env_impl.h # implementation of ability_env.h + │   ├── ability_scheduler.h # execute ability task from ability manager service + │   ├── ability_service_manager.h # manage the ability of service + │   ├── ability_slice_manager.h # manage the slice of the ability + │   ├── ability_slice_route.h # manage the entry of an ability + │   ├── ability_slice_scheduler.h # scheduler the slices of an ability + │   ├── ability_slice_stack.h # store all the slices in an ability and supply method to operate them + │   ├── ability_thread.h # the main thread of the kit + │   ├── ability_window.h # handle the window during a whole ability lifecycle + │   └── app_info.h # a struct that records the information of an application + ├── README.md + └── src + ├── ability.cpp + ├── ability_context.cpp + ├── ability_env.cpp + ├── ability_env_impl.cpp + ├── ability_loader.cpp + ├── ability_manager.cpp + ├── ability_scheduler.cpp + ├── ability_service_manager.cpp + ├── ability_slice.cpp + ├── ability_slice_manager.cpp + ├── ability_slice_route.cpp + ├── ability_slice_scheduler.cpp + ├── ability_slice_stack.cpp + ├── ability_thread.cpp + ├── ability_window.cpp + └── main.cpp + +``` \ No newline at end of file diff --git a/frameworks/ability_lite/include/ability_env_impl.h b/frameworks/ability_lite/include/ability_env_impl.h new file mode 100644 index 0000000..0531da4 --- /dev/null +++ b/frameworks/ability_lite/include/ability_env_impl.h @@ -0,0 +1,50 @@ +/* + * Copyright (c) 2020 Huawei Device Co., Ltd. + * 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 OHOS_ABILITY_ENV_IMPL_H +#define OHOS_ABILITY_ENV_IMPL_H + +#include +#include + +#include "nocopyable.h" + +namespace OHOS { +class AbilityEnvImpl : public NoCopyable { +public: + static AbilityEnvImpl &GetInstance() + { + static AbilityEnvImpl instance; + return instance; + } + + ~AbilityEnvImpl() override = default; + + void SetAppInfo(const AppInfo& appInfo); + + const std::string& GetBundleName() const; + + const std::string& GetSrcPath() const; + + const std::string& GetDataPath() const; + +private: + AbilityEnvImpl() = default; + + std::string bundleName_; + std::string srcPath_; + std::string dataPath_; +}; +} // namespace OHOS +#endif // OHOS_ABILITY_ENV_IMPL_H diff --git a/frameworks/ability_lite/include/ability_scheduler.h b/frameworks/ability_lite/include/ability_scheduler.h new file mode 100755 index 0000000..7cd4be6 --- /dev/null +++ b/frameworks/ability_lite/include/ability_scheduler.h @@ -0,0 +1,66 @@ +/* + * Copyright (c) 2020 Huawei Device Co., Ltd. + * 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 OHOS_ABILITY_SCHEDULER_H +#define OHOS_ABILITY_SCHEDULER_H + +#include + +#include "ability_event_handler.h" +#include "nocopyable.h" +#include "liteipc_adapter.h" +#include "serializer.h" +#include "want.h" + +namespace OHOS { +class Scheduler { +public: + virtual ~Scheduler() = default; + + /* perform application start and stop */ + virtual void PerformAppInit(const AppInfo& appInfo) = 0; + virtual void PerformAppExit() = 0; + + /* perform transact ability lifecycle state */ + virtual void PerformTransactAbilityState(const Want &want, int state, uint64_t token, int abilityType) = 0; + /* perform connect ability */ + virtual void PerformConnectAbility(const Want &want, uint64_t token) = 0; + virtual void PerformDisconnectAbility(const Want &want, uint64_t token) = 0; + /* perform dump ability info */ + virtual void PerformDumpAbility(const Want &want, uint64_t token) = 0; +}; + +class AbilityScheduler : public NoCopyable { +public: + AbilityScheduler() = delete; + AbilityScheduler(AbilityEventHandler &eventHandler, Scheduler &scheduler); + ~AbilityScheduler() override = default; + + static int32_t AmsCallback(const IpcContext* context, void *ipcMsg, IpcIo *data, void *arg); + +private: + void PerformAppInit(const AppInfo& appInfo); + void PerformTransactAbilityState(const Want &want, int state, uint64_t token, int abilityType); + void PerformConnectAbility(const Want &want, uint64_t token); + void PerformDisconnectAbility(const Want &want, uint64_t token); + void PerformAppExit(); + void PerformDumpAbility(const Want &want, uint64_t token); + static void ClearIpcMsg(void *ipcMsg); + + AbilityEventHandler &eventHandler_; + Scheduler &scheduler_; +}; +} // namespace OHOS +#endif // OHOS_ABILITY_SCHEDULER_H diff --git a/frameworks/ability_lite/include/ability_slice_manager.h b/frameworks/ability_lite/include/ability_slice_manager.h new file mode 100755 index 0000000..faeeddb --- /dev/null +++ b/frameworks/ability_lite/include/ability_slice_manager.h @@ -0,0 +1,57 @@ +/* + * Copyright (c) 2020 Huawei Device Co., Ltd. + * 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 OHOS_ABILITY_SLICE_MANAGER_H +#define OHOS_ABILITY_SLICE_MANAGER_H + +#include +#include + +namespace OHOS { +class AbilitySliceScheduler; + +class AbilitySliceManager { +public: + explicit AbilitySliceManager(Ability &ability); + ~AbilitySliceManager(); + + void OnAbilityStart(const Want &want); + void OnAbilityInactive(); + void OnAbilityActive(const Want &want); + void OnAbilityBackground(); + void OnAbilityStop(); + + void Present(const AbilitySlice &caller, AbilitySlice &target, const Want &want); + void Terminate(AbilitySlice &slice); + + void SetMainRoute(const std::string &entry); + void AddActionRoute(const std::string &action, const std::string &entry); + + void SetUIContent(RootView *rootView); + int GetAbilityState(); + + int TerminateAbility(); + + std::string GetSliceStackInfo() const; + + uint64_t GetToken() const; + +private: + AbilitySliceScheduler *abilitySliceScheduler_ { nullptr }; + Ability &ability_; +}; +} // namespace OHOS + +#endif // OHOS_ABILITY_SLICE_MANAGER_H \ No newline at end of file diff --git a/frameworks/ability_lite/include/ability_slice_route.h b/frameworks/ability_lite/include/ability_slice_route.h new file mode 100644 index 0000000..98b4256 --- /dev/null +++ b/frameworks/ability_lite/include/ability_slice_route.h @@ -0,0 +1,40 @@ +/* + * Copyright (c) 2020 Huawei Device Co., Ltd. + * 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 OHOS_ABILITY_SLICE_ROUTE_H +#define OHOS_ABILITY_SLICE_ROUTE_H + +#include +#include + +namespace OHOS { +class AbilitySliceRoute { +public: + AbilitySliceRoute() = default; + ~AbilitySliceRoute(); + + void SetMainRoute(const std::string &entry); + const std::string &GetMainRoute() const; + void AddActionRoute(const std::string &action, const std::string &entry); + std::string MatchRoute(const std::string &action); + void Clear(); + +private: + std::string mainEntry_ {}; + std::map actionEntries_ {}; +}; +} // namespace OHOS + +#endif // OHOS_ABILITY_SLICE_ROUTE_H diff --git a/frameworks/ability_lite/include/ability_slice_scheduler.h b/frameworks/ability_lite/include/ability_slice_scheduler.h new file mode 100644 index 0000000..4141d13 --- /dev/null +++ b/frameworks/ability_lite/include/ability_slice_scheduler.h @@ -0,0 +1,57 @@ +/* + * Copyright (c) 2020 Huawei Device Co., Ltd. + * 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 OHOS_ABILITY_SLICE_SCHEDULER_H +#define OHOS_ABILITY_SLICE_SCHEDULER_H + +#include + +#include "ability_slice_manager.h" +#include "ability_slice_route.h" +#include "ability_slice_stack.h" + +namespace OHOS { +class AbilitySliceScheduler { +public: + explicit AbilitySliceScheduler(AbilitySliceManager &abilitySliceManager); + ~AbilitySliceScheduler(); + + void HandleStartAbilitySlice(const Want &want); + void HandleInactiveAbilitySlice(); + void HandleActiveAbilitySlice(const Want &want); + void HandleMoveAbilitySliceToBackground(); + void HandleStopAbilitySlice(); + + void AddAbilitySlice(const AbilitySlice &caller, AbilitySlice &target, const Want &want); + void RemoveAbilitySlice(AbilitySlice &slice); + + void SetMainRoute(const std::string &entry); + void AddActionRoute(const std::string &action, const std::string &entry); + + const std::string GetSliceStackInfo() const; +private: + AbilitySlice *GetTargetAbilitySlice() const; + bool CheckLegalForAdd(const AbilitySlice &caller, AbilitySlice &target, const Want &want); + bool CheckLegalForRemove(const AbilitySlice &slice); + + AbilitySliceRoute *abilitySliceRoute_ { nullptr }; + AbilitySliceStack *abilitySliceStack_ { nullptr }; + AbilitySlice *topAbilitySlice_ { nullptr }; + AbilitySliceManager &abilitySliceManager_; +}; +} // namespace OHOS + +#endif // OHOS_ABILITY_SLICE_SCHEDULER_H + diff --git a/frameworks/ability_lite/include/ability_slice_stack.h b/frameworks/ability_lite/include/ability_slice_stack.h new file mode 100644 index 0000000..5429125 --- /dev/null +++ b/frameworks/ability_lite/include/ability_slice_stack.h @@ -0,0 +1,46 @@ +/* + * Copyright (c) 2020 Huawei Device Co., Ltd. + * 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 OHOS_ABILITY_SLICE_STACK_H +#define OHOS_ABILITY_SLICE_STACK_H + +#include + +#include "nocopyable.h" + +namespace OHOS { +class AbilitySlice; + +class AbilitySliceStack : public NoCopyable { +public: + AbilitySliceStack() = default; + ~AbilitySliceStack() override; + + bool IsEmpty() const; + int Size() const; + bool Exist(const AbilitySlice *slice) const; + void Remove(AbilitySlice *slice); + const AbilitySlice *Top() const; + AbilitySlice *Pop(); + void Push(AbilitySlice *slice); + std::list GetAllSlices() const; + void Clear(); + +private: + std::list slices_ {}; +}; +} + +#endif // OHOS_ABILITY_SLICE_STACK_H diff --git a/frameworks/ability_lite/include/ability_thread.h b/frameworks/ability_lite/include/ability_thread.h new file mode 100755 index 0000000..88311dd --- /dev/null +++ b/frameworks/ability_lite/include/ability_thread.h @@ -0,0 +1,62 @@ +/* + * Copyright (c) 2020 Huawei Device Co., Ltd. + * 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 OHOS_ABILITY_THREAD_H +#define OHOS_ABILITY_THREAD_H + +#include +#include +#include + +#include "abilityms_client.h" +#include "ability_scheduler.h" +#include "ability_event_handler.h" + +namespace OHOS { +class AbilityThread : public Scheduler, public NoCopyable { +public: + ~AbilityThread() override; + static void ThreadMain(uint64_t token); + +private: + AbilityThread() = default; + + void PerformAppInit(const AppInfo &appInfo) override; + void PerformAppExit() override; + void PerformTransactAbilityState(const Want &want, int state, uint64_t token, int abilityType) override; + void PerformConnectAbility(const Want &want, uint64_t token) override; + void PerformDisconnectAbility(const Want &want, uint64_t token) override; + void PerformDumpAbility(const Want &want, uint64_t token) override; + +#ifdef ABILITY_WINDOW_SUPPORT + static void *UITaskPost(void *arg); + void InitUITaskEnv(); +#endif + void StartAbilityCallback(const Want &want); + static void HandleLifecycleTransaction(Ability &ability, const Want &want, int state); + void AttachBundle(uint64_t token); + void Run(); + + AbilityEventHandler *eventHandler_ { nullptr }; + AbilityScheduler *abilityScheduler_ { nullptr }; + std::map abilities_ {}; + SvcIdentity *identity_ { nullptr }; + std::list handle_ {}; + static bool isNativeApp_; + static bool isAppRunning_; + static bool isDisplayInited_; +}; +} // namespace OHOS +#endif // OHOS_ABILITY_THREAD_H diff --git a/frameworks/ability_lite/include/ability_window.h b/frameworks/ability_lite/include/ability_window.h new file mode 100644 index 0000000..92889f3 --- /dev/null +++ b/frameworks/ability_lite/include/ability_window.h @@ -0,0 +1,43 @@ +/* + * Copyright (c) 2020 Huawei Device Co., Ltd. + * 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 OHOS_ABILITY_WINDOW_H +#define OHOS_ABILITY_WINDOW_H + +#include + +#include "nocopyable.h" + +namespace OHOS { +class AbilityWindow : public NoCopyable { +public: + AbilityWindow() = default; + ~AbilityWindow() override = default; + + void SetRootView(RootView *rootView, int16_t x = 0, int16_t y = 0); + + void OnPostAbilityStart(); + void OnPostAbilityActive(); + void OnPostAbilityBackground(); + void OnPostAbilityStop(); +private: + void EnsureLatestUIAttached() const; + + Window *window_ { nullptr }; + bool isWindowAttached_ { false }; +}; +} // namespace OHOS + +#endif // OHOS_ABILITY_WINDOW_H \ No newline at end of file diff --git a/frameworks/ability_lite/include/app_info.h b/frameworks/ability_lite/include/app_info.h new file mode 100644 index 0000000..24d5ac8 --- /dev/null +++ b/frameworks/ability_lite/include/app_info.h @@ -0,0 +1,30 @@ +/* + * Copyright (c) 2020 Huawei Device Co., Ltd. + * 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 OHOS_APP_INFO_H +#define OHOS_APP_INFO_H + +#include +#include + +typedef struct { + std::string bundleName; + std::string srcPath; + std::string dataPath; + bool isNativeApp; + std::list moduleNames; +} AppInfo; + +#endif // OHOS_APP_INFO_H diff --git a/frameworks/ability_lite/src/ability.cpp b/frameworks/ability_lite/src/ability.cpp new file mode 100755 index 0000000..2d17c4d --- /dev/null +++ b/frameworks/ability_lite/src/ability.cpp @@ -0,0 +1,285 @@ +/* + * Copyright (c) 2020 Huawei Device Co., Ltd. + * 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 "ability.h" + +#include +#include +#include +#include + +#include "ability_info.h" +#include "ability_loader.h" +#ifdef ABILITY_WINDOW_SUPPORT +#include "ability_slice_manager.h" +#include "ability_window.h" +#endif +#include "adapter.h" +#include "liteipc_adapter.h" + +namespace OHOS { +void Ability::OnStart(const Want &want) +{ + HILOG_INFO(HILOG_MODULE_APP, "Ability OnStart"); + if (abilityState_ != STATE_INITIAL) { + HILOG_ERROR(HILOG_MODULE_APP, "Start ability error, state: %{public}d", abilityState_); + exit(-1); + } + +#ifdef ABILITY_WINDOW_SUPPORT + DeliverAbilityLifecycle(START, &want); + if (abilityWindow_ != nullptr) { + abilityWindow_->OnPostAbilityStart(); + } +#endif + abilityState_ = STATE_INACTIVE; +} + +void Ability::OnInactive() +{ + HILOG_INFO(HILOG_MODULE_APP, "Ability OnInactive"); + if (abilityState_ != STATE_ACTIVE) { + HILOG_ERROR(HILOG_MODULE_APP, "Inactive ability error, state: %{public}d", abilityState_); + exit(-1); + } + +#ifdef ABILITY_WINDOW_SUPPORT + DeliverAbilityLifecycle(INACTIVE); +#endif + abilityState_ = STATE_INACTIVE; +} + +void Ability::OnActive(const Want &want) +{ + HILOG_INFO(HILOG_MODULE_APP, "Ability OnActive"); + if ((abilityState_ != STATE_INACTIVE) && (abilityState_ != STATE_BACKGROUND)) { + HILOG_ERROR(HILOG_MODULE_APP, "Active ability error, state: %{public}d", abilityState_); + exit(-1); + } + +#ifdef ABILITY_WINDOW_SUPPORT + DeliverAbilityLifecycle(ACTIVE, &want); + if ((abilityWindow_ != nullptr) && (abilityState_ == STATE_BACKGROUND)) { + abilityWindow_->OnPostAbilityActive(); + } +#endif + abilityState_ = STATE_ACTIVE; +} + +void Ability::OnBackground() +{ + HILOG_INFO(HILOG_MODULE_APP, "Ability OnBackground"); + if (abilityState_ != STATE_INACTIVE) { + HILOG_ERROR(HILOG_MODULE_APP, "Background ability error, state: %{public}d", abilityState_); + exit(-1); + } + +#ifdef ABILITY_WINDOW_SUPPORT + DeliverAbilityLifecycle(BACKGROUND); + if (abilityWindow_ != nullptr) { + abilityWindow_->OnPostAbilityBackground(); + } +#endif + abilityState_ = STATE_BACKGROUND; +} + +void Ability::OnStop() +{ + HILOG_INFO(HILOG_MODULE_APP, "Ability OnStop"); + if (abilityState_ != STATE_BACKGROUND) { + HILOG_ERROR(HILOG_MODULE_APP, "Stop ability error, state: %{public}d", abilityState_); + exit(-1); + } + +#ifdef ABILITY_WINDOW_SUPPORT + DeliverAbilityLifecycle(STOP); + if (abilityWindow_ != nullptr) { + abilityWindow_->OnPostAbilityStop(); + delete abilityWindow_; + } + delete abilitySliceManager_; + abilitySliceManager_ = nullptr; + abilityWindow_ = nullptr; +#endif + abilityState_ = STATE_INITIAL; +} + +const SvcIdentity *Ability::OnConnect(const Want &want) +{ + HILOG_INFO(HILOG_MODULE_APP, "Ability Connect"); + sid_ = static_cast(AdapterMalloc(sizeof(SvcIdentity))); + if (sid_ == nullptr) { + HILOG_ERROR(HILOG_MODULE_APP, "malloc memory error, sid_ is null"); + return nullptr; + } + int32_t ret = RegisterIpcCallback(Ability::MsgHandleInner, 0, IPC_WAIT_FOREVER, sid_, this); + if (ret != 0) { + HILOG_ERROR(HILOG_MODULE_APP, "register ipc callback error, ret is %{public}d", ret); + AdapterFree(sid_); + sid_ = nullptr; + return nullptr; + } + return sid_; +} + +void Ability::OnDisconnect(const Want &want) +{ + HILOG_INFO(HILOG_MODULE_APP, "Ability OnDisconnect"); + + // clear + UnregisterIpcCallback(*sid_); + AdapterFree(sid_); + sid_ = nullptr; +} + +#ifdef ABILITY_WINDOW_SUPPORT +void Ability::SetMainRoute(const std::string &entry) +{ + if (abilitySliceManager_ == nullptr) { + HILOG_ERROR(HILOG_MODULE_APP, "AbilitySliceManager is null, fail to set main route"); + exit(-1); + } + + abilitySliceManager_->SetMainRoute(entry); +} + +void Ability::SetUIContent(RootView *rootView) +{ + if (abilityWindow_ == nullptr) { + HILOG_ERROR(HILOG_MODULE_APP, "AbilityWindow is null, fail to SetUIContent"); + exit(-1); + } + + abilityWindow_->SetRootView(rootView); +} +#endif + +void Ability::MsgHandle(uint32_t funcId, IpcIo *request, IpcIo *reply) +{ +} + +void Ability::Dump(const std::string &extra) +{ +} + +void Ability::Init(uint64_t token, int abilityType, bool isNativeApp) +{ + HILOG_INFO(HILOG_MODULE_APP, "Ability Init"); +#ifdef ABILITY_WINDOW_SUPPORT + if (abilityType == PAGE) { + if (isNativeApp) { + abilitySliceManager_ = new AbilitySliceManager(*this); + } + abilityWindow_ = new AbilityWindow(); + } +#endif + + abilityType_ = abilityType; + token_ = token; + AbilityContext::token_ = token; + abilityState_ = STATE_INITIAL; +} + +int Ability::GetState() const +{ + return abilityState_; +} + +std::string Ability::GetDumpInfo() const +{ + std::string dumpInfo; + dumpInfo += "Ability Type: [" + std::to_string(abilityType_) + "]\n"; + dumpInfo += "Ability State: [" + std::to_string(abilityState_) + "]\n"; +#ifdef ABILITY_WINDOW_SUPPORT + dumpInfo += "AbilitySlice stack:\n"; + if ((abilityType_ == PAGE) && (abilitySliceManager_ != nullptr)) { + // Add slice stack information + dumpInfo += abilitySliceManager_->GetSliceStackInfo(); + } else { + dumpInfo += " none"; + } +#endif + + return dumpInfo; +} + +#ifdef ABILITY_WINDOW_SUPPORT +void Ability::DeliverAbilityLifecycle(Action action, const Want *want) +{ + if (abilitySliceManager_ == nullptr) { + HILOG_WARN(HILOG_MODULE_APP, "AbilitySliceManager is null, no need to dispatch lifecycle state change"); + return; + } + + if ((action == START || action == ACTIVE) && want == nullptr) { + HILOG_ERROR(HILOG_MODULE_APP, "want is null"); + return; + } + + switch (action) { + case START: + abilitySliceManager_->OnAbilityStart(*want); + break; + case INACTIVE: + abilitySliceManager_->OnAbilityInactive(); + break; + case ACTIVE: + abilitySliceManager_->OnAbilityActive(*want); + break; + case BACKGROUND: + abilitySliceManager_->OnAbilityBackground(); + break; + case STOP: + abilitySliceManager_->OnAbilityStop(); + break; + default: + HILOG_ERROR(HILOG_MODULE_APP, "action is error"); + break; + } +} +#endif + +int32_t Ability::MsgHandleInner(const IpcContext* context, void *ipcMsg, IpcIo *data, void *arg) +{ + auto ability = static_cast(arg); + if (ability == nullptr) { + HILOG_INFO(HILOG_MODULE_APP, "handle message error, ability is null"); + FreeBuffer(nullptr, ipcMsg); + return LITEIPC_EINVAL; + } + uint32_t fundId = 0; + int32_t ret = GetCode(ipcMsg, &fundId); + if (ret == LITEIPC_EINVAL) { + FreeBuffer(nullptr, ipcMsg); + return LITEIPC_EINVAL; + } + + IpcIo reply; + char buffer[IPC_IO_DATA_MAX]; + IpcIoInit(&reply, buffer, IPC_IO_DATA_MAX, MAX_OBJECTS); + + // call user method + ability->MsgHandle(fundId, data, &reply); + + uint32_t flag = 0; + GetFlag(ipcMsg, &flag); + if (flag == LITEIPC_FLAG_DEFAULT) { + SendReply(nullptr, ipcMsg, &reply); + } else { + FreeBuffer(nullptr, ipcMsg); + } + return LITEIPC_OK; +} +} // namespace OHOS diff --git a/frameworks/ability_lite/src/ability_context.cpp b/frameworks/ability_lite/src/ability_context.cpp new file mode 100755 index 0000000..bdb6981 --- /dev/null +++ b/frameworks/ability_lite/src/ability_context.cpp @@ -0,0 +1,47 @@ +/* + * Copyright (c) 2020 Huawei Device Co., Ltd. + * 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 "ability_context.h" + +#include "ability_service_interface.h" +#include "ability_service_manager.h" +#include "abilityms_client.h" + +namespace OHOS { +int AbilityContext::StartAbility(const Want &want) +{ + return AbilityMsClient::GetInstance().ScheduleAms(&want, 0, nullptr, START_ABILITY); +} + +int AbilityContext::TerminateAbility() +{ + return AbilityMsClient::GetInstance().ScheduleAms(nullptr, token_, nullptr, TERMINATE_ABILITY); +} + +int AbilityContext::StopAbility(const Want &want) +{ + return AbilityMsClient::GetInstance().ScheduleAms(&want, 0, nullptr, TERMINATE_SERVICE); +} + +int AbilityContext::ConnectAbility(const Want &want, const IAbilityConnection &conn, void *storeArg) +{ + return AbilityServiceManager::GetInstance().ConnectAbility(want, conn, token_, storeArg); +} + +int AbilityContext::DisconnectAbility(const IAbilityConnection &conn) +{ + return AbilityServiceManager::GetInstance().DisconnectAbility(conn, token_); +} +} // namespace OHOS \ No newline at end of file diff --git a/frameworks/ability_lite/src/ability_env.cpp b/frameworks/ability_lite/src/ability_env.cpp new file mode 100644 index 0000000..b625260 --- /dev/null +++ b/frameworks/ability_lite/src/ability_env.cpp @@ -0,0 +1,39 @@ +/* + * Copyright (c) 2020 Huawei Device Co., Ltd. + * 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 "ability_env.h" + +#include + +#include "ability_env_impl.h" + +extern "C" { +const char *GetBundleName() +{ + const std::string &bundleName = OHOS::AbilityEnvImpl::GetInstance().GetBundleName(); + return bundleName.c_str(); +} + +const char *GetSrcPath() +{ + const std::string &srcPath = OHOS::AbilityEnvImpl::GetInstance().GetSrcPath(); + return srcPath.c_str(); +} + +const char *GetDataPath() +{ + const std::string &dataPath = OHOS::AbilityEnvImpl::GetInstance().GetDataPath(); + return dataPath.c_str(); +} +} diff --git a/frameworks/ability_lite/src/ability_env_impl.cpp b/frameworks/ability_lite/src/ability_env_impl.cpp new file mode 100644 index 0000000..9465768 --- /dev/null +++ b/frameworks/ability_lite/src/ability_env_impl.cpp @@ -0,0 +1,45 @@ +/* + * Copyright (c) 2020 Huawei Device Co., Ltd. + * 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 "ability_env_impl.h" + +namespace OHOS { +constexpr static char PATH_SEPARATOR[] = "/"; + +void AbilityEnvImpl::SetAppInfo(const AppInfo& appInfo) +{ + bundleName_ = appInfo.bundleName; + dataPath_ = appInfo.dataPath; + srcPath_ = appInfo.srcPath; + if (!appInfo.isNativeApp && !appInfo.moduleNames.empty()) { + srcPath_ += PATH_SEPARATOR + appInfo.moduleNames.front(); + } +} + +const std::string& AbilityEnvImpl::GetBundleName() const +{ + return bundleName_; +} + +const std::string& AbilityEnvImpl::GetSrcPath() const +{ + return srcPath_; +} + +const std::string& AbilityEnvImpl::GetDataPath() const +{ + return dataPath_; +} +} // namespace OHOS diff --git a/frameworks/ability_lite/src/ability_event_handler.cpp b/frameworks/ability_lite/src/ability_event_handler.cpp new file mode 100644 index 0000000..87b8477 --- /dev/null +++ b/frameworks/ability_lite/src/ability_event_handler.cpp @@ -0,0 +1,73 @@ +/* + * Copyright (c) 2020 Huawei Device Co., Ltd. + * 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 "ability_event_handler.h" + +namespace OHOS { +namespace { + thread_local AbilityEventHandler* g_currentHandler; +} + +AbilityEventHandler::AbilityEventHandler() +{ + g_currentHandler = this; + (void) pthread_mutex_init(&queueMutex_, nullptr); + (void) pthread_cond_init(&pthreadCond_, nullptr); +} + +AbilityEventHandler::~AbilityEventHandler() +{ + (void) pthread_mutex_destroy(&queueMutex_); + (void) pthread_cond_destroy(&pthreadCond_); + + g_currentHandler = nullptr; +} + +void AbilityEventHandler::Run() +{ + while (!quit_) { + (void) pthread_mutex_lock(&queueMutex_); + if (taskQueue_.empty()) { + (void) pthread_cond_wait(&pthreadCond_, &queueMutex_); + } + Task task = std::move(taskQueue_.front()); + taskQueue_.pop(); + (void) pthread_mutex_unlock(&queueMutex_); + task(); + } +} + +void AbilityEventHandler::PostTask(const Task& task) +{ + (void) pthread_mutex_lock(&queueMutex_); + taskQueue_.push(task); + (void) pthread_mutex_unlock(&queueMutex_); + + (void) pthread_cond_signal(&pthreadCond_); +} + +void AbilityEventHandler::PostQuit() +{ + Task task = [this]() { + quit_ = true; + }; + PostTask(task); +} + +AbilityEventHandler* AbilityEventHandler::GetCurrentHandler() +{ + return g_currentHandler; +} +} // namespace OHOS \ No newline at end of file diff --git a/frameworks/ability_lite/src/ability_loader.cpp b/frameworks/ability_lite/src/ability_loader.cpp new file mode 100644 index 0000000..a08ebba --- /dev/null +++ b/frameworks/ability_lite/src/ability_loader.cpp @@ -0,0 +1,55 @@ +/* + * Copyright (c) 2020 Huawei Device Co., Ltd. + * 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 "ability_loader.h" +#include "log.h" + +namespace OHOS { +void AbilityLoader::RegisterAbility(const std::string &abilityName, const CreateAblity &createFunc) +{ + abilities_.emplace(abilityName, createFunc); + HILOG_INFO(HILOG_MODULE_APP, "RegisterAbility %s", abilityName.c_str()); +} + +Ability *AbilityLoader::GetAbilityByName(const std::string &abilityName) +{ + auto it = abilities_.find(abilityName); + if (it == abilities_.end()) { + HILOG_ERROR(HILOG_MODULE_APP, "GetAbilityByName failed: %s", abilityName.c_str()); + return nullptr; + } else { + return it->second(); + } +} + +#ifdef ABILITY_WINDOW_SUPPORT +void AbilityLoader::RegisterAbilitySlice(const std::string &sliceName, const CreateSlice &createFunc) +{ + slices_.emplace(sliceName, createFunc); + HILOG_INFO(HILOG_MODULE_APP, "RegisterAbilitySlice %s", sliceName.c_str()); +} + +AbilitySlice *AbilityLoader::GetAbilitySliceByName(const std::string &sliceName) +{ + auto it = slices_.find(sliceName); + if (it == slices_.end()) { + HILOG_ERROR(HILOG_MODULE_APP, "GetAbilitySliceByName failed: %s", sliceName.c_str()); + return nullptr; + } else { + return it->second(); + } +} +#endif +} // namespace OHOS \ No newline at end of file diff --git a/frameworks/ability_lite/src/ability_main.cpp b/frameworks/ability_lite/src/ability_main.cpp new file mode 100644 index 0000000..63aa8fa --- /dev/null +++ b/frameworks/ability_lite/src/ability_main.cpp @@ -0,0 +1,47 @@ +/* + * Copyright (c) 2020 Huawei Device Co., Ltd. + * 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 "ability_main.h" + +#include +#include + +#include "ability_thread.h" +#include "liteipc_pri.h" +#include "log.h" + +namespace { + constexpr int HEX = 10; +} + +int AbilityMain(const char *token) +{ + if (token == nullptr) { + return -1; + } + + ResetLiteIpc(); + char *endPtr = nullptr; + errno = 0; + uint64_t tokenId = std::strtoull(token, &endPtr, HEX); + if ((errno == ERANGE && tokenId == ULLONG_MAX) || (errno != 0 && tokenId == 0) || + endPtr == nullptr || *endPtr != '\0') { + HILOG_ERROR(HILOG_MODULE_APP, "token is invalid"); + return -1; + } + + OHOS::AbilityThread::ThreadMain(tokenId); + return 0; +} diff --git a/frameworks/ability_lite/src/ability_scheduler.cpp b/frameworks/ability_lite/src/ability_scheduler.cpp new file mode 100644 index 0000000..536ccfd --- /dev/null +++ b/frameworks/ability_lite/src/ability_scheduler.cpp @@ -0,0 +1,210 @@ +/* + * Copyright (c) 2020 Huawei Device Co., Ltd. + * 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 "ability_scheduler.h" + +#include +#include + +#include "ability_errors.h" +#include "ability_kit_command.h" +#include "ability_service_interface.h" +#include "liteipc_adapter.h" +#include "want_utils.h" + +namespace OHOS { +const int MAX_MODULE_SIZE = 16; +AbilityScheduler::AbilityScheduler(AbilityEventHandler &eventHandler, Scheduler &scheduler) + : eventHandler_(eventHandler), scheduler_(scheduler) +{ +} + +int32_t AbilityScheduler::AmsCallback(const IpcContext* context, void *ipcMsg, IpcIo *data, void *arg) +{ + if (ipcMsg == nullptr) { + HILOG_ERROR(HILOG_MODULE_APP, "ams call back error, ipcMsg is null"); + return PARAM_NULL_ERROR; + } + + auto scheduler = static_cast(arg); + if (scheduler == nullptr) { + HILOG_ERROR(HILOG_MODULE_APP, "ams call back error, scheduler is null"); + // if you need to send reply to the client, please use SendReply method + ClearIpcMsg(ipcMsg); + return PARAM_NULL_ERROR; + } + + int result = 0; + uint32_t funcId = COMMAND_ERROR; + GetCode(ipcMsg, &funcId); + switch (funcId) { + case SCHEDULER_APP_INIT: { + AppInfo appInfo = {}; + char *bundleName = reinterpret_cast(IpcIoPopString(data, nullptr)); + char *srcPath = reinterpret_cast(IpcIoPopString(data, nullptr)); + char *dataPath = reinterpret_cast(IpcIoPopString(data, nullptr)); + if ((bundleName == nullptr) || (srcPath == nullptr) || (dataPath == nullptr)) { + HILOG_ERROR(HILOG_MODULE_APP, "ams call back error, bundleName, srcPath or dataPath is null"); + ClearIpcMsg(ipcMsg); + return PARAM_NULL_ERROR; + } + appInfo.bundleName = bundleName; + appInfo.srcPath = srcPath; + appInfo.dataPath = dataPath; + appInfo.isNativeApp = IpcIoPopBool(data); + int moduleSize = IpcIoPopInt32(data); + if (moduleSize > MAX_MODULE_SIZE) { + HILOG_ERROR(HILOG_MODULE_APP, "moduleSize is too big"); + ClearIpcMsg(ipcMsg); + return COMMAND_ERROR; + } + for (int i = 0; i < moduleSize; i++) { + char *moduleName = reinterpret_cast(IpcIoPopString(data, nullptr)); + if ((moduleName != nullptr) && (strlen(moduleName) > 0)) { + appInfo.moduleNames.emplace_front(moduleName); + } + } + scheduler->PerformAppInit(appInfo); + break; + } + case SCHEDULER_ABILITY_LIFECYCLE: { + int state = IpcIoPopInt32(data); + uint64_t token = IpcIoPopUint64(data); + int abilityType = IpcIoPopInt32(data); + Want want = { nullptr, nullptr, nullptr, 0 }; + if (!DeserializeWant(&want, data)) { + result = SERIALIZE_ERROR; + break; + } + scheduler->PerformTransactAbilityState(want, state, token, abilityType); + break; + } + case SCHEDULER_ABILITY_CONNECT: { + uint64_t token = IpcIoPopUint64(data); + Want want = { nullptr, nullptr, nullptr, 0 }; + if (!DeserializeWant(&want, data)) { + result = SERIALIZE_ERROR; + break; + } + scheduler->PerformConnectAbility(want, token); + break; + } + case SCHEDULER_ABILITY_DISCONNECT: { + uint64_t token = IpcIoPopUint64(data); + Want want = { nullptr, nullptr, nullptr, 0 }; + if (!DeserializeWant(&want, data)) { + result = SERIALIZE_ERROR; + break; + } + scheduler->PerformDisconnectAbility(want, token); + break; + } + case SCHEDULER_APP_EXIT: { + scheduler->PerformAppExit(); + break; + } + case SCHEDULER_DUMP_ABILITY: { + Want want = {}; + if (!DeserializeWant(&want, data)) { + result = SERIALIZE_ERROR; + break; + } + uint64_t token = IpcIoPopUint64(data); + scheduler->PerformDumpAbility(want, token); + break; + } + default: { + result = COMMAND_ERROR; + break; + } + } + ClearIpcMsg(ipcMsg); + return result; +} + +void AbilityScheduler::PerformAppInit(const AppInfo &appInfo) +{ + auto task = [this, appInfo] { + scheduler_.PerformAppInit(appInfo); + }; + eventHandler_.PostTask(task); +} + +void AbilityScheduler::PerformTransactAbilityState(const Want &want, int state, uint64_t token, int abilityType) +{ + auto task = [this, want, state, token, abilityType] { + scheduler_.PerformTransactAbilityState(want, state, token, abilityType); + ClearWant(const_cast(&want)); + }; + eventHandler_.PostTask(task); +} + +void AbilityScheduler::PerformConnectAbility(const Want &want, uint64_t token) +{ + auto task = [this, want, token] { + scheduler_.PerformConnectAbility(want, token); + ClearWant(const_cast(&want)); + }; + eventHandler_.PostTask(task); +} + +void AbilityScheduler::PerformDisconnectAbility(const Want &want, uint64_t token) +{ + auto task = [this, want, token] { + scheduler_.PerformDisconnectAbility(want, token); + ClearWant(const_cast(&want)); + }; + eventHandler_.PostTask(task); +} + +void AbilityScheduler::PerformAppExit() +{ + auto task = [this] { + scheduler_.PerformAppExit(); + }; + eventHandler_.PostTask(task); +} + +void AbilityScheduler::PerformDumpAbility(const Want &want, uint64_t token) +{ +#ifdef __LINUX__ + if (want.sid == nullptr) { + HILOG_ERROR(HILOG_MODULE_APP, "svcId is invalid when dump ability"); + return; + } + BinderAcquire(want.sid->ipcContext, want.sid->handle); +#endif + auto task = [this, want, token] { + scheduler_.PerformDumpAbility(want, token); + ClearWant(const_cast(&want)); + }; + eventHandler_.PostTask(task); +} + +void AbilityScheduler::ClearIpcMsg(void *ipcMsg) +{ + if (ipcMsg == nullptr) { + return; + } + uint32_t flag = 0; + GetFlag(ipcMsg, &flag); + if (flag == LITEIPC_FLAG_DEFAULT) { + // send reply to client, the second param is reply + SendReply(nullptr, ipcMsg, nullptr); + } else { + FreeBuffer(nullptr, ipcMsg); + } +} +} // namespace OHOS diff --git a/frameworks/ability_lite/src/ability_slice.cpp b/frameworks/ability_lite/src/ability_slice.cpp new file mode 100644 index 0000000..416d3e1 --- /dev/null +++ b/frameworks/ability_lite/src/ability_slice.cpp @@ -0,0 +1,98 @@ +/* + * Copyright (c) 2020 Huawei Device Co., Ltd. + * 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 "ability_slice.h" + +#include +#include + +#include "ability_loader.h" +#include "ability_slice_manager.h" + +namespace OHOS { +void AbilitySlice::Init(AbilitySliceManager &abilitySliceManager) +{ + HILOG_INFO(HILOG_MODULE_APP, "AbilitySlice Init"); + abilitySliceManager_ = &abilitySliceManager; + sliceState_ = STATE_INITIAL; + AbilityContext::token_ = abilitySliceManager.GetToken(); +} + +void AbilitySlice::Present(AbilitySlice &abilitySlice, const Want &want) +{ + if (abilitySliceManager_ == nullptr) { + HILOG_ERROR(HILOG_MODULE_APP, "AbilitySlice Present failed"); + return; + } + abilitySliceManager_->Present(*this, abilitySlice, want); +} + +void AbilitySlice::Terminate() +{ + if (abilitySliceManager_ == nullptr) { + HILOG_ERROR(HILOG_MODULE_APP, "AbilitySlice Terminate failed"); + return; + } + abilitySliceManager_->Terminate(*this); +} + +void AbilitySlice::SetUIContent(RootView *rootView) +{ + if (abilitySliceManager_ == nullptr) { + HILOG_ERROR(HILOG_MODULE_APP, "AbilitySlice SetUIContent failed"); + return; + } + curRootView_ = rootView; + abilitySliceManager_->SetUIContent(rootView); +} + +void AbilitySlice::OnStart(const Want &want) +{ + HILOG_INFO(HILOG_MODULE_APP, "AbilitySlice OnStart"); + sliceState_ = STATE_INACTIVE; +} + +void AbilitySlice::OnInactive() +{ + HILOG_INFO(HILOG_MODULE_APP, "AbilitySlice OnInactive"); + sliceState_ = STATE_INACTIVE; +} + +void AbilitySlice::OnActive(const Want &want) +{ + HILOG_INFO(HILOG_MODULE_APP, "AbilitySlice OnActive"); + if ((sliceState_ == STATE_BACKGROUND) && (curRootView_ != nullptr)) { + SetUIContent(curRootView_); + } + sliceState_ = STATE_ACTIVE; +} + +void AbilitySlice::OnBackground() +{ + HILOG_INFO(HILOG_MODULE_APP, "AbilitySlice OnBackground"); + sliceState_ = STATE_BACKGROUND; +} + +void AbilitySlice::OnStop() +{ + HILOG_INFO(HILOG_MODULE_APP, "AbilitySlice OnStop"); + sliceState_ = STATE_INITIAL; +} + +int AbilitySlice::GetState() const +{ + return sliceState_; +} +} // namespace OHOS diff --git a/frameworks/ability_lite/src/ability_slice_manager.cpp b/frameworks/ability_lite/src/ability_slice_manager.cpp new file mode 100755 index 0000000..6a06796 --- /dev/null +++ b/frameworks/ability_lite/src/ability_slice_manager.cpp @@ -0,0 +1,104 @@ +/* + * Copyright (c) 2020 Huawei Device Co., Ltd. + * 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 "ability_slice_manager.h" + +#include + +#include "ability_slice_scheduler.h" +#include "ability_window.h" + +namespace OHOS { +AbilitySliceManager::AbilitySliceManager(Ability &ability) : ability_(ability) +{ + abilitySliceScheduler_ = new AbilitySliceScheduler(*this); +} + +AbilitySliceManager::~AbilitySliceManager() +{ + delete abilitySliceScheduler_; + abilitySliceScheduler_ = nullptr; +} + +void AbilitySliceManager::OnAbilityStart(const Want &want) +{ + abilitySliceScheduler_->HandleStartAbilitySlice(want); +} + +void AbilitySliceManager::OnAbilityInactive() +{ + abilitySliceScheduler_->HandleInactiveAbilitySlice(); +} + +void AbilitySliceManager::OnAbilityActive(const Want &want) +{ + abilitySliceScheduler_->HandleActiveAbilitySlice(want); +} + +void AbilitySliceManager::OnAbilityBackground() +{ + abilitySliceScheduler_->HandleMoveAbilitySliceToBackground(); +} + +void AbilitySliceManager::OnAbilityStop() +{ + abilitySliceScheduler_->HandleStopAbilitySlice(); +} + +void AbilitySliceManager::Present(const AbilitySlice &caller, AbilitySlice &target, const Want &want) +{ + abilitySliceScheduler_->AddAbilitySlice(caller, target, want); +} + +void AbilitySliceManager::Terminate(AbilitySlice &slice) +{ + abilitySliceScheduler_->RemoveAbilitySlice(slice); +} + +void AbilitySliceManager::SetMainRoute(const std::string &entry) +{ + abilitySliceScheduler_->SetMainRoute(entry); +} + +void AbilitySliceManager::AddActionRoute(const std::string &action, const std::string &entry) +{ + abilitySliceScheduler_->AddActionRoute(action, entry); +} + +void AbilitySliceManager::SetUIContent(RootView *rootView) +{ + ability_.SetUIContent(rootView); +} + +int AbilitySliceManager::GetAbilityState() +{ + return ability_.GetState(); +} + +int AbilitySliceManager::TerminateAbility() +{ + return ability_.TerminateAbility(); +} + +std::string AbilitySliceManager::GetSliceStackInfo() const +{ + return abilitySliceScheduler_->GetSliceStackInfo(); +} + +uint64_t AbilitySliceManager::GetToken() const +{ + return ability_.token_; +} +} // namespace OHOS \ No newline at end of file diff --git a/frameworks/ability_lite/src/ability_slice_route.cpp b/frameworks/ability_lite/src/ability_slice_route.cpp new file mode 100644 index 0000000..e4326c0 --- /dev/null +++ b/frameworks/ability_lite/src/ability_slice_route.cpp @@ -0,0 +1,62 @@ +/* + * Copyright (c) 2020 Huawei Device Co., Ltd. + * 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 "ability_slice_route.h" + +namespace OHOS { +AbilitySliceRoute::~AbilitySliceRoute() +{ + Clear(); +} + +void AbilitySliceRoute::SetMainRoute(const std::string &entry) +{ + if (entry.empty()) { + return; + } + + mainEntry_ = entry; +} + +const std::string &AbilitySliceRoute::GetMainRoute() const +{ + return mainEntry_; +} + +void AbilitySliceRoute::AddActionRoute(const std::string &action, const std::string &entry) +{ + if (action.empty() || entry.empty()) { + return; + } + + actionEntries_[action] = entry; +} + +std::string AbilitySliceRoute::MatchRoute(const std::string &action) +{ + auto iter = actionEntries_.find(action); + if (iter != actionEntries_.end()) { + return iter->second; + } + + return ""; +} + +void AbilitySliceRoute::Clear() +{ + mainEntry_.clear(); + actionEntries_.clear(); +} +} // namespace OHOS \ No newline at end of file diff --git a/frameworks/ability_lite/src/ability_slice_scheduler.cpp b/frameworks/ability_lite/src/ability_slice_scheduler.cpp new file mode 100644 index 0000000..8952a9b --- /dev/null +++ b/frameworks/ability_lite/src/ability_slice_scheduler.cpp @@ -0,0 +1,241 @@ +/* + * Copyright (c) 2020 Huawei Device Co., Ltd. + * 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 "ability_slice_scheduler.h" + +#include +#include + +#include "ability_loader.h" +#include "ability_slice_manager.h" + +namespace OHOS { +AbilitySliceScheduler::AbilitySliceScheduler(AbilitySliceManager &abilitySliceManager) + : abilitySliceManager_(abilitySliceManager) +{ + abilitySliceRoute_ = new AbilitySliceRoute(); + abilitySliceStack_ = new AbilitySliceStack(); +} + +AbilitySliceScheduler::~AbilitySliceScheduler() +{ + delete abilitySliceRoute_; + abilitySliceRoute_ = nullptr; + delete abilitySliceStack_; + abilitySliceStack_ = nullptr; +} + +void AbilitySliceScheduler::HandleStartAbilitySlice(const Want &want) +{ + if (topAbilitySlice_ == nullptr) { + topAbilitySlice_ = GetTargetAbilitySlice(); + if (topAbilitySlice_ == nullptr) { + HILOG_ERROR(HILOG_MODULE_APP, "Cannot get slice [%{public}s]", abilitySliceRoute_->GetMainRoute().c_str()); + return; + } + } + topAbilitySlice_->Init(abilitySliceManager_); + + topAbilitySlice_->OnStart(want); +} + +void AbilitySliceScheduler::HandleInactiveAbilitySlice() +{ + if (topAbilitySlice_ == nullptr) { + return; + } + + topAbilitySlice_->OnInactive(); +} + +void AbilitySliceScheduler::HandleActiveAbilitySlice(const Want &want) +{ + if (topAbilitySlice_ == nullptr) { + HILOG_ERROR(HILOG_MODULE_APP, "top ability slice is null, active slice error"); + return; + } + + // add want when implicit match, not support jump by want temporary. + + topAbilitySlice_->OnActive(want); +} + +void AbilitySliceScheduler::HandleMoveAbilitySliceToBackground() +{ + if (topAbilitySlice_ == nullptr) { + return; + } + + topAbilitySlice_->OnBackground(); +} + +void AbilitySliceScheduler::HandleStopAbilitySlice() +{ + if (topAbilitySlice_ == nullptr) { + return; + } + + topAbilitySlice_->OnStop(); + while (!abilitySliceStack_->IsEmpty()) { + auto abilitySlice = abilitySliceStack_->Pop(); + if (abilitySlice != nullptr) { + abilitySlice->OnStop(); + } + } + delete topAbilitySlice_; + topAbilitySlice_ = nullptr; +} + +void AbilitySliceScheduler::AddAbilitySlice(const AbilitySlice &caller, AbilitySlice &target, const Want &want) +{ + // Check if this jump is legal. + if (!CheckLegalForAdd(caller, target, want)) { + HILOG_WARN(HILOG_MODULE_APP, "Cannot jump to target AbilitySlice"); + return; + } + + // Scheduler top slice to inactive. + if (topAbilitySlice_->GetState() == STATE_ACTIVE) { + topAbilitySlice_->OnInactive(); + } + + // Scheduler target slice to Active. + if (target.GetState() == STATE_UNINITIALIZED) { + target.Init(abilitySliceManager_); + } + if (target.GetState() == STATE_INITIAL) { + target.OnStart(want); + } + target.OnActive(want); + + // Scheduler top slice to background. + if (topAbilitySlice_->GetState() == STATE_INACTIVE) { + topAbilitySlice_->OnBackground(); + } + + // Update the topAbilitySlice and stack. + abilitySliceStack_->Push(topAbilitySlice_); + topAbilitySlice_ = ⌖ +} + +void AbilitySliceScheduler::RemoveAbilitySlice(AbilitySlice &slice) +{ + // Check if this slice is legal. + if (!CheckLegalForRemove(slice)) { + HILOG_WARN(HILOG_MODULE_APP, "Cannot terminate target AbilitySlice"); + return; + } + + if (&slice == topAbilitySlice_) { + // Scheduler the slice need to exit to inactive. + topAbilitySlice_->OnInactive(); + + Want want { nullptr, nullptr, nullptr, 0 }; + // Scheduler the top slice in the stack to Active. + auto next = abilitySliceStack_->Pop(); + if (next == nullptr) { + topAbilitySlice_->OnActive(want); + return; + } + next->OnActive(want); + + // Scheduler the slice need to exit(State:initial). + topAbilitySlice_->OnBackground(); + topAbilitySlice_->OnStop(); + + // Update the topAbilitySLice and stack. + topAbilitySlice_ = next; + } else { + // Scheduler the background slice to stop + slice.OnStop(); + abilitySliceStack_->Remove(&slice); + } +} + +void AbilitySliceScheduler::SetMainRoute(const std::string &entry) +{ + abilitySliceRoute_->SetMainRoute(entry); +} + +void AbilitySliceScheduler::AddActionRoute(const std::string &action, const std::string &entry) +{ + abilitySliceRoute_->AddActionRoute(action, entry); +} + +AbilitySlice *AbilitySliceScheduler::GetTargetAbilitySlice() const +{ + std::string mainEntry = abilitySliceRoute_->GetMainRoute(); + + return AbilityLoader::GetInstance().GetAbilitySliceByName(mainEntry); +} + +bool AbilitySliceScheduler::CheckLegalForAdd(const AbilitySlice &caller, AbilitySlice &target, const Want &want) +{ + if (topAbilitySlice_ == nullptr) { + return false; + } + if (abilitySliceManager_.GetAbilityState() != STATE_ACTIVE) { + return false; + } + if (caller.GetState() <= STATE_INITIAL) { + return false; + } + if (target.GetState() == STATE_ACTIVE) { + return false; + } + if (&target == topAbilitySlice_) { + return false; + } + + return true; +} + +bool AbilitySliceScheduler::CheckLegalForRemove(const AbilitySlice &slice) +{ + if (topAbilitySlice_ == nullptr) { + return false; + } + if (abilitySliceManager_.GetAbilityState() != STATE_ACTIVE) { + return false; + } + if ((!abilitySliceStack_->Exist(&slice)) && (&slice != topAbilitySlice_)) { + return false; + } + if (slice.GetState() <= STATE_INITIAL) { + return false; + } + if (abilitySliceStack_->IsEmpty()) { + abilitySliceManager_.TerminateAbility(); + return false; + } + + return true; +} + +const std::string AbilitySliceScheduler::GetSliceStackInfo() const +{ + if (topAbilitySlice_ == nullptr) { + return " none"; + } + std::string buff; + buff += " [" + std::string(typeid(*topAbilitySlice_).name()) + + "] State: [" + std::to_string(topAbilitySlice_->GetState()) + "]\n"; + auto slices = abilitySliceStack_->GetAllSlices(); + for (auto slice : slices) { + buff += " [" + std::string(typeid(*slice).name()) + "] State: [" + std::to_string(slice->GetState()) + "]\n"; + } + return buff; +} +} // namespace OHOS \ No newline at end of file diff --git a/frameworks/ability_lite/src/ability_slice_stack.cpp b/frameworks/ability_lite/src/ability_slice_stack.cpp new file mode 100644 index 0000000..bb9da3b --- /dev/null +++ b/frameworks/ability_lite/src/ability_slice_stack.cpp @@ -0,0 +1,85 @@ +/* + * Copyright (c) 2020 Huawei Device Co., Ltd. + * 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 "ability_slice_stack.h" + +#include + +#include "ability_slice.h" + +namespace OHOS { +AbilitySliceStack::~AbilitySliceStack() +{ + Clear(); +} + +bool AbilitySliceStack::IsEmpty() const +{ + return slices_.empty(); +} + +int AbilitySliceStack::Size() const +{ + return slices_.size(); +} + +bool AbilitySliceStack::Exist(const AbilitySlice *slice) const +{ + return std::find(slices_.begin(), slices_.end(), slice) != slices_.end(); +} + +void AbilitySliceStack::Remove(AbilitySlice *slice) +{ + slices_.remove(slice); +} + +const AbilitySlice *AbilitySliceStack::Top() const +{ + if (slices_.empty()) { + return nullptr; + } + + return slices_.front(); +} + +AbilitySlice *AbilitySliceStack::Pop() +{ + if (slices_.empty()) { + return nullptr; + } + + AbilitySlice *topSlice = slices_.front(); + slices_.pop_front(); + return topSlice; +} + +void AbilitySliceStack::Push(AbilitySlice *slice) +{ + slices_.push_front(slice); +} + +std::list AbilitySliceStack::GetAllSlices() const +{ + return slices_; +} + +void AbilitySliceStack::Clear() +{ + for (auto node : slices_) { + delete node; + } + slices_.clear(); +} +} diff --git a/frameworks/ability_lite/src/ability_thread.cpp b/frameworks/ability_lite/src/ability_thread.cpp new file mode 100755 index 0000000..51154e9 --- /dev/null +++ b/frameworks/ability_lite/src/ability_thread.cpp @@ -0,0 +1,385 @@ +/* + * Copyright (c) 2020 Huawei Device Co., Ltd. + * 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 "ability_thread.h" + +#include +#include +#include +#include +#include +#include +#ifdef ABILITY_WINDOW_SUPPORT +#include +#include +#include +#include +#include +#endif +#include +#include + +#include "ability_env.h" +#include "ability_env_impl.h" +#include "ability_info.h" +#include "ability_loader.h" +#include "ability_service_interface.h" +#include "adapter.h" +#include "element_name_utils.h" +#include "liteipc_adapter.h" +#include "log.h" + +namespace OHOS { +namespace { +constexpr static char PATH_SEPARATOR[] = "/"; +constexpr static char LIB_PREFIX[] = "/lib"; +constexpr static char LIB_SUFFIX[] = ".so"; +constexpr static char ACE_ABILITY_NAME[] = "AceAbility"; +#ifdef ABILITY_WINDOW_SUPPORT +#ifdef OPENHARMONY_FONT_PATH +constexpr static char FONT_PATH[] = "/storage/data/"; +#else +constexpr static char FONT_PATH[] = "/sdcard/data/"; +#endif +constexpr static int UI_TASK_HANDLER_PERIOD = 10 * 1000; // UI task execute period is 10ms +constexpr static char UI_TASK_THREAD_NAME[] = "UITaskPost"; +static uint32_t g_fontPsramBaseAddr[MIN_FONT_PSRAM_LENGTH / 4]; +#endif +} +bool AbilityThread::isAppRunning_ = true; +bool AbilityThread::isNativeApp_ = true; +bool AbilityThread::isDisplayInited_ = false; + +AbilityThread::~AbilityThread() +{ + AdapterFree(identity_); + delete abilityScheduler_; + abilityScheduler_ = nullptr; + delete eventHandler_; + eventHandler_ = nullptr; +} + +void AbilityThread::ThreadMain(uint64_t token) +{ + HILOG_INFO(HILOG_MODULE_APP, "AbilityThread::ThreadMain enter"); + + AbilityThread abilityThread; + abilityThread.AttachBundle(token); + + HILOG_INFO(HILOG_MODULE_APP, "AbilityThread::ThreadMain start loop"); + abilityThread.Run(); +} + +#ifdef ABILITY_WINDOW_SUPPORT +void *AbilityThread::UITaskPost(void *arg) +{ + prctl(PR_SET_NAME, UI_TASK_THREAD_NAME); + + auto handler = static_cast(arg); + if (handler == nullptr) { + HILOG_ERROR(HILOG_MODULE_APP, "EventHandler is nullptr, fail to start loop"); + return nullptr; + } + + int ret = pthread_detach(pthread_self()); + if (ret != 0) { + HILOG_WARN(HILOG_MODULE_APP, "UITaskPost detach failed: %{public}d", ret); + } + + HILOG_INFO(HILOG_MODULE_APP, "start UITaskPost loop"); + while (isAppRunning_) { + handler->PostTask([] { + TaskManager::GetInstance()->TaskHandler(); + }); + usleep(UI_TASK_HANDLER_PERIOD); + } + return nullptr; +} + +void AbilityThread::InitUITaskEnv() +{ + if (isDisplayInited_) { + return; + } + + HILOG_INFO(HILOG_MODULE_APP, "Hal and UI init"); + GraphicStartUp::Init(); + GraphicStartUp::InitFontEngine(reinterpret_cast(g_fontPsramBaseAddr), MIN_FONT_PSRAM_LENGTH, + const_cast(FONT_PATH), DEFAULT_VECTOR_FONT_FILENAME); + auto screenDevice = new ScreenDevice(); + ScreenDeviceProxy::GetInstance()->SetDevice(screenDevice); + + HILOG_INFO(HILOG_MODULE_APP, "Create UITaskPost thread"); + pthread_t tid; + int ret = pthread_create(&tid, nullptr, AbilityThread::UITaskPost, eventHandler_); + if (ret != 0) { + HILOG_ERROR(HILOG_MODULE_APP, "create UI post thread error, %{public}d", ret); + exit(-1); + } + isDisplayInited_ = true; +} +#endif + +void AbilityThread::StartAbilityCallback(const Want &want) +{ + if ((want.sid == nullptr) || (want.element == nullptr)) { + return; + } + HILOG_INFO(HILOG_MODULE_APP, "start ability callback"); + IpcIo io; + char data[IPC_IO_DATA_MAX]; + IpcIoInit(&io, data, IPC_IO_DATA_MAX, 0); + if (!SerializeElement(&io, want.element)) { + return; + } + IpcIoPushInt32(&io, EC_SUCCESS); + if (Transact(nullptr, *(want.sid), SCHEDULER_APP_INIT, &io, nullptr, LITEIPC_FLAG_ONEWAY, nullptr) != LITEIPC_OK) { + HILOG_ERROR(HILOG_MODULE_APP, "start ability callback failed, ipc error"); + } +} + +void AbilityThread::PerformAppInit(const AppInfo &appInfo) +{ + HILOG_INFO(HILOG_MODULE_APP, "Start app init"); + if ((appInfo.bundleName.empty()) || (appInfo.srcPath.empty())) { + HILOG_ERROR(HILOG_MODULE_APP, "appInfo is null"); + return; + } + if (!appInfo.isNativeApp && (appInfo.moduleNames.size() != 1)) { + HILOG_ERROR(HILOG_MODULE_APP, "only native app support multi hap"); + return; + } + AbilityEnvImpl::GetInstance().SetAppInfo(appInfo); + AbilityThread::isNativeApp_ = appInfo.isNativeApp; + + for (const auto &module : appInfo.moduleNames) { + std::string modulePath; + if (appInfo.isNativeApp) { + modulePath = appInfo.srcPath + PATH_SEPARATOR + module + LIB_PREFIX + module + LIB_SUFFIX; + if (modulePath.size() > PATH_MAX) { + continue; + } + char realPath[PATH_MAX + 1] = { 0 }; + if (realpath(modulePath.c_str(), realPath) == nullptr) { + HILOG_ERROR(HILOG_MODULE_APP, "Fail to get realpath of %{public}s", modulePath.c_str()); + continue; + } + void *handle = dlopen(static_cast(realPath), RTLD_NOW | RTLD_GLOBAL); + if (handle == nullptr) { + HILOG_ERROR(HILOG_MODULE_APP, "Fail to dlopen %{public}s, [%{public}s]", modulePath.c_str(), dlerror()); + exit(-1); + } + handle_.emplace_front(handle); + } + } + + int ret = UtilsSetEnv(GetDataPath()); + HILOG_INFO(HILOG_MODULE_APP, "Set env ret: %{public}d, App init end", ret); +} + +void AbilityThread::PerformAppExit() +{ + HILOG_INFO(HILOG_MODULE_APP, "perform app exit"); + eventHandler_->PostTask([] { + AbilityThread::isAppRunning_ = false; + }); + for (auto handle : handle_) { + dlclose(handle); + } + eventHandler_->PostQuit(); + handle_.clear(); +} + +void AbilityThread::PerformTransactAbilityState(const Want &want, int state, uint64_t token, int abilityType) +{ + HILOG_INFO(HILOG_MODULE_APP, "perform transact ability state to [%{public}d]", state); + Ability *ability = nullptr; + auto iter = abilities_.find(token); + if ((iter == abilities_.end()) || (iter->second == nullptr)) { + if (want.element == nullptr) { + HILOG_ERROR(HILOG_MODULE_APP, "element name is null, fail to load ability"); + AbilityMsClient::GetInstance().SchedulerLifecycleDone(token, STATE_INITIAL); + return; + } + auto abilityName = isNativeApp_ ? want.element->abilityName : ACE_ABILITY_NAME; + ability = AbilityLoader::GetInstance().GetAbilityByName(abilityName); + if (ability == nullptr) { + HILOG_ERROR(HILOG_MODULE_APP, "fail to load ability: %{public}s", abilityName); + AbilityMsClient::GetInstance().SchedulerLifecycleDone(token, STATE_INITIAL); + return; + } + HILOG_INFO(HILOG_MODULE_APP, "Create ability success [%{public}s]", want.element->abilityName); + + // Only page ability need to init display +#ifdef ABILITY_WINDOW_SUPPORT + if (abilityType == PAGE) { + InitUITaskEnv(); + } +#endif + ability->Init(token, abilityType, AbilityThread::isNativeApp_); + abilities_[token] = ability; + } else { + ability = iter->second; + } + + if (ability->GetState() != state) { + HandleLifecycleTransaction(*ability, want, state); + } + + HILOG_INFO(HILOG_MODULE_APP, "perform transact ability state done [%{public}d]", ability->GetState()); + AbilityMsClient::GetInstance().SchedulerLifecycleDone(token, ability->GetState()); + if (ability->GetState() == STATE_ACTIVE) { + StartAbilityCallback(want); + } + + if (ability->GetState() == STATE_INITIAL) { + abilities_.erase(token); + delete ability; + } +} + +void AbilityThread::PerformConnectAbility(const Want &want, uint64_t token) +{ + auto iter = abilities_.find(token); + if (iter == abilities_.end() || iter->second == nullptr) { + HILOG_ERROR(HILOG_MODULE_APP, "app has been stopped"); + return; + } + const SvcIdentity *sid = iter->second->OnConnect(want); + AbilityMsClient::GetInstance().ScheduleAms(nullptr, token, sid, CONNECT_ABILITY_DONE); +} + +void AbilityThread::PerformDisconnectAbility(const Want &want, uint64_t token) +{ + auto iter = abilities_.find(token); + if (iter == abilities_.end() || iter->second == nullptr) { + HILOG_ERROR(HILOG_MODULE_APP, "app has been stopped"); + return; + } + iter->second->OnDisconnect(want); + AbilityMsClient::GetInstance().ScheduleAms(nullptr, token, nullptr, DISCONNECT_ABILITY_DONE); +} + +void AbilityThread::PerformDumpAbility(const Want &want, uint64_t token) +{ + auto iter = abilities_.find(token); + if (iter == abilities_.end() || iter->second == nullptr) { + HILOG_ERROR(HILOG_MODULE_APP, "app has been stopped"); + return; + } + if (want.sid == nullptr) { + HILOG_ERROR(HILOG_MODULE_APP, "SvcIdentity is null, dump failed"); + return; + } + std::string extra(""); + if (want.data != nullptr) { + auto str = static_cast(want.data); + if (want.dataLength == strlen(str) + 1) { + extra = str; + } + } + iter->second->Dump(extra); + std::string dumpInfo = iter->second->GetDumpInfo(); + IpcIo io; + char data[IPC_IO_DATA_MAX]; + IpcIoInit(&io, data, IPC_IO_DATA_MAX, 1); +#ifdef __LINUX__ + IpcIoPushString(&io, dumpInfo.c_str()); +#else + BuffPtr dataBuff = { + .buffSz = dumpInfo.length() + 1, // include \0 + .buff = const_cast(dumpInfo.c_str()), + }; + IpcIoPushDataBuff(&io, &dataBuff); +#endif + if (Transact(nullptr, *(want.sid), SCHEDULER_DUMP_ABILITY, &io, nullptr, LITEIPC_FLAG_ONEWAY, nullptr) != + LITEIPC_OK) { + HILOG_ERROR(HILOG_MODULE_APP, "dump ability failed, ipc error"); + } +#ifdef __LINUX__ + BinderRelease(want.sid->ipcContext, want.sid->handle); +#endif +} + +void AbilityThread::HandleLifecycleTransaction(Ability &ability, const Want &want, int state) +{ + // Switch INITIAL state to INACTIVE state + if (ability.GetState() == STATE_INITIAL) { + ability.OnStart(want); + } + + // Switch ACTIVE state to INACTIVE state + if (ability.GetState() == STATE_ACTIVE) { + ability.OnInactive(); + } + + switch (state) { + case STATE_INITIAL: { + if (ability.GetState() == STATE_INACTIVE) { + ability.OnBackground(); + } + ability.OnStop(); + break; + } + case STATE_INACTIVE: { + // Not support transact from BACKGROUND to INACTIVE state + break; + } + case STATE_ACTIVE: { + ability.OnActive(want); + break; + } + case STATE_BACKGROUND: { + if (ability.GetState() == STATE_INACTIVE) { + ability.OnBackground(); + } + break; + } + default: { + HILOG_ERROR(HILOG_MODULE_APP, "Unknown target state: %{public}d", state); + break; + } + } +} + +void AbilityThread::AttachBundle(uint64_t token) +{ + eventHandler_ = new AbilityEventHandler(); + abilityScheduler_ = new AbilityScheduler(*eventHandler_, *this); + if (!AbilityMsClient::GetInstance().Initialize()) { + HILOG_ERROR(HILOG_MODULE_APP, "ams feature is null"); + return; + } + + identity_ = static_cast(AdapterMalloc(sizeof(SvcIdentity))); + if (identity_ == nullptr) { + HILOG_ERROR(HILOG_MODULE_APP, "ams identity is null"); + return; + } + int32_t ret = RegisterIpcCallback(AbilityScheduler::AmsCallback, 0, IPC_WAIT_FOREVER, identity_, abilityScheduler_); + if (ret != 0) { + HILOG_ERROR(HILOG_MODULE_APP, "RegisterIpcCallback failed"); + AdapterFree(identity_); + return; + } + + AbilityMsClient::GetInstance().ScheduleAms(nullptr, token, identity_, ATTACH_BUNDLE); +} + +void AbilityThread::Run() +{ + eventHandler_->Run(); +} +} // namespace OHOS diff --git a/frameworks/ability_lite/src/ability_window.cpp b/frameworks/ability_lite/src/ability_window.cpp new file mode 100644 index 0000000..7e4cf4f --- /dev/null +++ b/frameworks/ability_lite/src/ability_window.cpp @@ -0,0 +1,86 @@ +/* + * Copyright (c) 2020 Huawei Device Co., Ltd. + * 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 "ability_window.h" + +#include "log.h" + +namespace OHOS { +void AbilityWindow::SetRootView(RootView *rootView, int16_t x, int16_t y) +{ + if (rootView == nullptr) { + return; + } + + if (window_ == nullptr) { + WindowConfig config = {}; + config.rect = rootView->GetRect(); + config.rect.SetPosition(x, y); + window_ = Window::CreateWindow(config); + if (window_ == nullptr) { + return; + } + } else { + Rect rect = rootView->GetRect(); + window_->Resize(rect.GetWidth(), rect.GetHeight()); + window_->MoveTo(x, y); + } + + window_->UnbindRootView(); + window_->BindRootView(rootView); + rootView->Invalidate(); + + isWindowAttached_ = true; +} + +void AbilityWindow::EnsureLatestUIAttached() const +{ + if (!isWindowAttached_ || (window_ == nullptr)) { + HILOG_ERROR(HILOG_MODULE_APP, "Should SetUIContent before slice active"); + exit(-1); + } +} + +void AbilityWindow::OnPostAbilityStart() +{ + EnsureLatestUIAttached(); + + window_->Show(); +} + +void AbilityWindow::OnPostAbilityActive() +{ + EnsureLatestUIAttached(); + + window_->RaiseToTop(); + window_->Show(); +} + +void AbilityWindow::OnPostAbilityBackground() +{ + EnsureLatestUIAttached(); + + window_->Hide(); +} + +void AbilityWindow::OnPostAbilityStop() +{ + EnsureLatestUIAttached(); + + window_->UnbindRootView(); + Window::DestoryWindow(window_); + window_ = nullptr; +} +} // namespace OHOS diff --git a/frameworks/ability_lite/src/slite/lite_context.cpp b/frameworks/ability_lite/src/slite/lite_context.cpp new file mode 100755 index 0000000..6f705b9 --- /dev/null +++ b/frameworks/ability_lite/src/slite/lite_context.cpp @@ -0,0 +1,31 @@ +/* + * Copyright (c) 2021 Huawei Device Co., Ltd. + * 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 "lite_context.h" + +#include "ability_state.h" +#include "abilityms_slite_client.h" + +namespace OHOS { +int LiteContext::StartAbility(const Want &want) +{ + return AbilityMsClient::GetInstance().StartAbility(&want); +} + +int LiteContext::TerminateAbility() +{ + return AbilityMsClient::GetInstance().TerminateAbility(token_); +} +} // namespace OHOS \ No newline at end of file diff --git a/frameworks/ability_lite/src/slite/slite_ability.cpp b/frameworks/ability_lite/src/slite/slite_ability.cpp new file mode 100755 index 0000000..8189f63 --- /dev/null +++ b/frameworks/ability_lite/src/slite/slite_ability.cpp @@ -0,0 +1,50 @@ +/* + * Copyright (c) 2021 Huawei Device Co., Ltd. + * 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 "slite_ability.h" + +#include "ability_state.h" +#include "abilityms_client.h" + +namespace OHOS { +void SliteAbility::OnStart(const Want &want) +{ + abilityState_ = STATE_INITIAL; + (void) AbilityMsClient::GetInstance().SchedulerLifecycleDone(token_, STATE_INITIAL); +} + +void SliteAbility::OnInactive() +{ + abilityState_ = STATE_INACTIVE; + (void) AbilityMsClient::GetInstance().SchedulerLifecycleDone(token_, STATE_INACTIVE); +} + +void SliteAbility::OnActive(const Want &want) +{ + abilityState_ = STATE_ACTIVE; + (void) AbilityMsClient::GetInstance().SchedulerLifecycleDone(token_, STATE_ACTIVE); +} + +void SliteAbility::OnBackground() +{ + abilityState_ = STATE_BACKGROUND; + (void) AbilityMsClient::GetInstance().SchedulerLifecycleDone(token_, STATE_BACKGROUND); +} + +int SliteAbility::GetState() const +{ + return abilityState_; +} +} // namespace OHOS diff --git a/frameworks/abilitymgr_lite/BUILD.gn b/frameworks/abilitymgr_lite/BUILD.gn new file mode 100755 index 0000000..e6f6180 --- /dev/null +++ b/frameworks/abilitymgr_lite/BUILD.gn @@ -0,0 +1,58 @@ +# Copyright (c) 2020 Huawei Device Co., Ltd. +# 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. +import("//build/lite/config/component/lite_component.gni") +import("//build/lite/config/subsystem/aafwk/config.gni") + +lite_library("abilitymanager") { + target_type = "shared_library" + cflags = [ "-Wall" ] + cflags_cc = cflags + + sources = [ + "src/ability_manager.cpp", + "src/ability_service_manager.cpp", + "src/abilityms_client.cpp", + ] + + deps = [ + "${appexecfwk_lite_path}/frameworks/bundle_lite:bundle", + "//base/hiviewdfx/hilog_lite/frameworks/featured:hilog_shared", + "//foundation/communication/ipc_lite:liteipc_adapter", + ] + + include_dirs = [ + "${aafwk_lite_path}/frameworks/abilitymgr_lite/include", + "${aafwk_lite_path}/frameworks/want_lite/include", + "${aafwk_lite_path}/interfaces/innerkits/abilitymgr_lite", + "${aafwk_lite_path}/interfaces/kits/want_lite", + "${aafwk_lite_path}/interfaces/kits/ability_lite", + "${appexecfwk_lite_path}/utils/bundle_lite", + "${appexecfwk_lite_path}/interfaces/kits/bundle_lite", + "${appexecfwk_lite_path}/frameworks/bundle_lite/include", + "//foundation/distributedschedule/samgr_lite/interfaces/kits/registry", + "//foundation/distributedschedule/samgr_lite/interfaces/kits/samgr", + "//kernel/liteos_a/kernel/include", + "//kernel/liteos_a/kernel/common", + "//third_party/bounds_checking_function/include", + "//utils/native/lite/kv_store/innerkits", + "//utils/native/lite/include", + "./include", + "./", + ] + + defines = [ "OHOS_APPEXECFWK_BMS_BUNDLEMANAGER" ] +} + +lite_component("aafwk_abilityManager_lite") { + features = [ ":abilitymanager" ] +} diff --git a/frameworks/abilitymgr_lite/LICENSE b/frameworks/abilitymgr_lite/LICENSE new file mode 100755 index 0000000..4a45986 --- /dev/null +++ b/frameworks/abilitymgr_lite/LICENSE @@ -0,0 +1,177 @@ + + 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 \ No newline at end of file diff --git a/frameworks/abilitymgr_lite/include/ability_kit.h b/frameworks/abilitymgr_lite/include/ability_kit.h new file mode 100644 index 0000000..8bc6758 --- /dev/null +++ b/frameworks/abilitymgr_lite/include/ability_kit.h @@ -0,0 +1,50 @@ +/* + * Copyright (c) 2020 Huawei Device Co., Ltd. + * 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 OHOS_ABILITYKIT_H +#define OHOS_ABILITYKIT_H + +#include "stdint.h" + +typedef int32_t (*SuccessCallback)(const void *data); +typedef int32_t (*FailCallback)(const void *data, uint16_t dataLength, uint16_t errorCode); + +namespace OHOS { +struct FeatureAbilityDataInfo { + char *bundleName { nullptr }; + void *message { nullptr }; + uint32_t messageLength { 0 }; + char *abilityName { nullptr }; + char *deviceID { nullptr }; +}; + +class AbilityKit { +public: + AbilityKit(); + ~AbilityKit(); + + static int32_t RegisterReceiver(const char *bundleName, SuccessCallback success, FailCallback fail, + uint32_t successCallbackFunc, uint32_t failCallbackFunc, uint32_t context); + static int32_t UnregisterReceiver(const char *bundleName); + static int32_t SendMsgToPeerApp(bool isLocalMsg, const char *callingPkgName, const char *calledPkgName, + const uint8_t *msgBody, uint32_t length, uint32_t successCallbackFunc, + uint32_t failCallbackFunc, uint32_t context); + static int32_t DetectPhoneApp(const char *callingPkgName, const char *calledPkgName, uint32_t successCallbackFunc, + uint32_t failCallbackFunc, uint32_t context); + static int32_t DetectResourceRelease(); + static int32_t SendMsgResourceRelease(); +}; +} // namespace OHOS +#endif // OHOS_ABILITYKIT_H \ No newline at end of file diff --git a/frameworks/abilitymgr_lite/include/ability_service_manager.h b/frameworks/abilitymgr_lite/include/ability_service_manager.h new file mode 100755 index 0000000..ac06efb --- /dev/null +++ b/frameworks/abilitymgr_lite/include/ability_service_manager.h @@ -0,0 +1,59 @@ +/* + * Copyright (c) 2020 Huawei Device Co., Ltd. + * 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 OHOS_ABILITY_SERVICE_MANAGER_H +#define OHOS_ABILITY_SERVICE_MANAGER_H + +#include "ability_connection.h" + +#include +#include + +#include "nocopyable.h" +#include "want.h" + +namespace OHOS { +typedef struct { + const IAbilityConnection *conn; + void *storeArg; + SvcIdentity *sid; +} StoreArgs; + +class AbilityServiceManager { +public: + static AbilityServiceManager &GetInstance() + { + static AbilityServiceManager instance; + return instance; + } + ~AbilityServiceManager(); + int ConnectAbility(const Want &want, const IAbilityConnection &conn, uint64_t token, void *storeArg); + int DisconnectAbility(const IAbilityConnection &conn, uint64_t token); + +private: + AbilityServiceManager() = default; + StoreArgs *AddStoreArgs(const IAbilityConnection &conn, void *storeArg); + StoreArgs *GetStoreArgs(const IAbilityConnection &conn) const; + StoreArgs *RemoveStoreArgs(const IAbilityConnection *conn, StoreArgs *storeArgs); + static int32_t ConnectAbilityCallBack(const IpcContext* context, void *ipcMsg, IpcIo *data, void *arg); + static void ClearStore(StoreArgs *storeArgs); + std::list storeList_; + std::mutex mutex_; + + DISALLOW_COPY_AND_MOVE(AbilityServiceManager); +}; +} // namespace OHOS + +#endif // OHOS_ABILITY_SERVICE_MANAGER_H diff --git a/frameworks/abilitymgr_lite/include/abilityms_client.h b/frameworks/abilitymgr_lite/include/abilityms_client.h new file mode 100644 index 0000000..e914155 --- /dev/null +++ b/frameworks/abilitymgr_lite/include/abilityms_client.h @@ -0,0 +1,49 @@ +/* + * Copyright (c) 2020 Huawei Device Co., Ltd. + * 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 OHOS_ABILITYMS_CLIENT_H +#define OHOS_ABILITYMS_CLIENT_H + +#include "iproxy_client.h" +#include "nocopyable.h" +#include "want.h" + +namespace OHOS { +class AbilityMsClient { +public: + static AbilityMsClient &GetInstance() + { + static AbilityMsClient instance; + return instance; + } + + ~AbilityMsClient() = default; + + bool Initialize() const; + + int SchedulerLifecycleDone(uint64_t token, int state) const; + + int ScheduleAms(const Want *want, uint64_t token, const SvcIdentity *sid, int commandType) const; + +private: + AbilityMsClient() = default; + + IClientProxy *amsProxy_ { nullptr }; + + DISALLOW_COPY_AND_MOVE(AbilityMsClient); +}; +} // namespace OHOS + +#endif // OHOS_ABILITYMS_CLIENT_H diff --git a/frameworks/abilitymgr_lite/include/abilityms_slite_client.h b/frameworks/abilitymgr_lite/include/abilityms_slite_client.h new file mode 100755 index 0000000..b1feab9 --- /dev/null +++ b/frameworks/abilitymgr_lite/include/abilityms_slite_client.h @@ -0,0 +1,52 @@ +/* + * Copyright (c) 2021 Huawei Device Co., Ltd. + * 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 OHOS_ABILITYMS_SLITE_CLIENT_H +#define OHOS_ABILITYMS_SLITE_CLIENT_H + +#include "iproxy_client.h" +#include "nocopyable.h" +#include "want.h" +#include "ability_service_interface.h" + +namespace OHOS { +class AbilityMsClient { +public: + static AbilityMsClient &GetInstance() + { + static AbilityMsClient instance; + return instance; + } + + ~AbilityMsClient() = default; + + bool Initialize() const; + + int StartAbility(const Want *want) const; + + int TerminateAbility(uint64_t token) const; + + int SchedulerLifecycleDone(uint64_t token, int state) const; + +private: + AbilityMsClient() = default; + + AmsSliteInterface *amsProxy_ { nullptr }; + + DISALLOW_COPY_AND_MOVE(AbilityMsClient); +}; +} // namespace OHOS + +#endif // OHOS_ABILITYMS_SLITE_CLIENT_H diff --git a/frameworks/abilitymgr_lite/src/ability_kit.cpp b/frameworks/abilitymgr_lite/src/ability_kit.cpp new file mode 100644 index 0000000..b220232 --- /dev/null +++ b/frameworks/abilitymgr_lite/src/ability_kit.cpp @@ -0,0 +1,76 @@ +/* + * Copyright (c) 2020 Huawei Device Co., Ltd. + * 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 "ability_kit.h" +#include "ability_service.h" + +namespace OHOS { +int32_t AbilityKit::RegisterReceiver(const char *bundleName, SuccessCallback success, FailCallback fail, + uint32_t successCallbackFunc, uint32_t failCallbackFunc, uint32_t context) +{ + return AbilityService::GetInstance().RegisterReceiver(bundleName, success, fail, successCallbackFunc, + failCallbackFunc, context); +} + +int32_t AbilityKit::UnregisterReceiver(const char *bundleName) +{ + return AbilityService::GetInstance().UnregisterReceiver(bundleName); +} + +int32_t AbilityKit::SendMsgToPeerApp(bool isLocalMsg, const char *callingPkgName, + const char *calledPkgName, const uint8_t *msgBody, uint32_t length, + uint32_t successCallbackFunc, uint32_t failCallbackFunc, uint32_t context) +{ + return AbilityService::GetInstance().SendMsgToPeerApp(isLocalMsg, callingPkgName, calledPkgName, + msgBody, length, successCallbackFunc, failCallbackFunc, context); +} + +int32_t AbilityKit::DetectPhoneApp(const char *callingPkgName, const char *calledPkgName, uint32_t successCallbackFunc, + uint32_t failCallbackFunc, uint32_t context) +{ + return AbilityService::GetInstance().DetectPhoneApp(callingPkgName, calledPkgName, successCallbackFunc, + failCallbackFunc, context); +} + +int32_t AbilityKit::DetectResourceRelease() +{ + return AbilityService::GetInstance().DetectResourceRelease(); +} + +int32_t AbilityKit::SendMsgResourceRelease() +{ + return AbilityService::GetInstance().SendMsgResourceRelease(); +} +} // namespace OHOS + +#ifdef APP_PLATFORM_WATCHGT +extern "C" { +int32_t RegisterReceiver(const char *bundleName, SuccessCallback success, FailCallback fail) +{ + return OHOS::AbilityKit::RegisterReceiver(bundleName, success, fail, 0, 0, 0); +} + +int32_t UnregisterReceiver(const char *bundleName) +{ + return OHOS::AbilityKit::UnregisterReceiver(bundleName); +} + +int32_t SendMsgToPeerApp(bool isLocalMsg, const char *callingPkgName, const char *calledPkgName, + const uint8_t *msgBody, uint32_t length) +{ + return OHOS::AbilityKit::SendMsgToPeerApp(isLocalMsg, callingPkgName, calledPkgName, msgBody, length, 0, 0, 0); +} +} +#endif // APP_PLATFORM_WATCHGT diff --git a/frameworks/abilitymgr_lite/src/ability_manager.cpp b/frameworks/abilitymgr_lite/src/ability_manager.cpp new file mode 100755 index 0000000..c63b523 --- /dev/null +++ b/frameworks/abilitymgr_lite/src/ability_manager.cpp @@ -0,0 +1,69 @@ +/* + * Copyright (c) 2020 Huawei Device Co., Ltd. + * 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 "ability_manager.h" + +#include + +#include "ability_service_interface.h" +#include "ability_service_manager.h" +#include "abilityms_client.h" + +extern "C" { +const int DEFAULT_TOKEN = 1; +int StartAbility(const Want *want) +{ + if (want == nullptr) { + HILOG_ERROR(HILOG_MODULE_APP, "want is null, StartAbility failed"); + return -1; + } + + OHOS::AbilityMsClient::GetInstance().Initialize(); + return OHOS::AbilityMsClient::GetInstance().ScheduleAms(want, 0, nullptr, START_ABILITY); +} + +int StopAbility(const Want *want) +{ + if (want == nullptr) { + HILOG_ERROR(HILOG_MODULE_APP, "want is null, StopAbility failed"); + return -1; + } + OHOS::AbilityMsClient::GetInstance().Initialize(); + return OHOS::AbilityMsClient::GetInstance().ScheduleAms(want, 0, nullptr, TERMINATE_SERVICE); +} + +int ConnectAbility(const Want *want, const IAbilityConnection *conn, void *data) +{ + if (want == nullptr) { + HILOG_ERROR(HILOG_MODULE_APP, "want is null, ConnectAbility failed"); + return -1; + } + if (conn == nullptr) { + HILOG_ERROR(HILOG_MODULE_APP, "conn is null, ConnectAbility failed"); + return -1; + } + + return OHOS::AbilityServiceManager::GetInstance().ConnectAbility(*want, *conn, DEFAULT_TOKEN, data); +} + +int DisconnectAbility(const IAbilityConnection *conn) +{ + if (conn == nullptr) { + HILOG_ERROR(HILOG_MODULE_APP, "conn is null, DisconnectAbility failed"); + return LITEIPC_EINVAL; + } + return OHOS::AbilityServiceManager::GetInstance().DisconnectAbility(*conn, DEFAULT_TOKEN); +} +} diff --git a/frameworks/abilitymgr_lite/src/ability_service_manager.cpp b/frameworks/abilitymgr_lite/src/ability_service_manager.cpp new file mode 100755 index 0000000..5d2856a --- /dev/null +++ b/frameworks/abilitymgr_lite/src/ability_service_manager.cpp @@ -0,0 +1,178 @@ +/* + * Copyright (c) 2020 Huawei Device Co., Ltd. + * 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 "ability_service_manager.h" + +#include + +#include "ability_kit_command.h" +#include "ability_service_interface.h" +#include "abilityms_client.h" +#include "ohos_errno.h" +#include "securec.h" +#include "utils.h" +#include "want.h" + +namespace OHOS { +AbilityServiceManager::~AbilityServiceManager() +{ + for (const auto &storeArgs : storeList_) { + if (storeArgs == nullptr) { + continue; + } + if (storeArgs->sid != nullptr) { + UnregisterIpcCallback(*(storeArgs->sid)); + delete storeArgs->sid; + } + delete storeArgs; + } + storeList_.clear(); +} + +int AbilityServiceManager::ConnectAbility(const Want &want, const IAbilityConnection &conn, uint64_t token, void *storeArg) +{ + if (conn.OnAbilityDisconnectDone == nullptr || conn.OnAbilityConnectDone == nullptr) { + HILOG_INFO(HILOG_MODULE_APP, "IAbilityConnection callback func is null"); + return LITEIPC_EINVAL; + } + + StoreArgs *storeArgs = AddStoreArgs(conn, storeArg); + if (storeArgs == nullptr) { + return LITEIPC_EINVAL; + } + AbilityMsClient::GetInstance().Initialize(); + int32_t result = RegisterIpcCallback(ConnectAbilityCallBack, 0, IPC_WAIT_FOREVER, storeArgs->sid, storeArgs); + if (result != LITEIPC_OK) { + RemoveStoreArgs(nullptr, storeArgs); + delete storeArgs->sid; + delete storeArgs; + return result; + } + result = AbilityMsClient::GetInstance().ScheduleAms(&want, token, storeArgs->sid, CONNECT_ABILITY); + if (result != EC_SUCCESS) { + UnregisterIpcCallback(*(storeArgs->sid)); + RemoveStoreArgs(nullptr, storeArgs); + delete storeArgs->sid; + delete storeArgs; + } + return result; +} + +int AbilityServiceManager::DisconnectAbility(const IAbilityConnection &conn, uint64_t token) +{ + StoreArgs *storeArgs = RemoveStoreArgs(&conn, nullptr); + if (storeArgs == nullptr) { + HILOG_INFO(HILOG_MODULE_APP, "no need to disconnect"); + return LITEIPC_EINVAL; + } + int result = AbilityMsClient::GetInstance().ScheduleAms(nullptr, token, storeArgs->sid, DISCONNECT_ABILITY); + + ClearStore(storeArgs); + return result; +} + +StoreArgs *AbilityServiceManager::AddStoreArgs(const IAbilityConnection &conn, void *storeArg) +{ + std::lock_guard lock(mutex_); + if (GetStoreArgs(conn) != nullptr) { + HILOG_ERROR(HILOG_MODULE_APP, "func has already used"); + return nullptr; + } + StoreArgs *storeArgs = new StoreArgs(); + storeArgs->conn = &conn; + storeArgs->storeArg = storeArg; + storeArgs->sid = new SvcIdentity(); + storeList_.emplace_back(storeArgs); + + return storeArgs; +} + +StoreArgs *AbilityServiceManager::GetStoreArgs(const IAbilityConnection &conn) const +{ + for (const auto storeArgs : storeList_) { + if (storeArgs->conn == &conn) { + return storeArgs; + } + } + return nullptr; +} + +StoreArgs *AbilityServiceManager::RemoveStoreArgs(const IAbilityConnection *conn, StoreArgs *storeArgs) +{ + std::lock_guard lock(mutex_); + if (storeArgs == nullptr) { + storeArgs = GetStoreArgs(*conn); + } + storeList_.remove(storeArgs); + + return storeArgs; +} + +int32_t AbilityServiceManager::ConnectAbilityCallBack(const IpcContext* context, void *ipcMsg, IpcIo *data, void *arg) +{ + // param check + StoreArgs *storeArgs = static_cast(arg); + if (storeArgs == nullptr || ipcMsg == nullptr || storeArgs->conn == nullptr || + storeArgs->conn->OnAbilityConnectDone == nullptr || storeArgs->conn->OnAbilityDisconnectDone == nullptr) { + HILOG_ERROR(HILOG_MODULE_APP, "storeArgs or callback func or ipcMsg is null"); + AbilityServiceManager::GetInstance().RemoveStoreArgs(nullptr, storeArgs); + ClearStore(storeArgs); + FreeBuffer(nullptr, ipcMsg); + return LITEIPC_EINVAL; + } + + // parse funcId + uint32_t funcId = 0; + GetCode(ipcMsg, &funcId); + int resultCode = (funcId != SCHEDULER_ABILITY_CONNECT_FAIL) ? 0 : -1; + // parse service sid + SvcIdentity *serviceSid = (funcId == SCHEDULER_ABILITY_CONNECT) ? IpcIoPopSvc(data) : nullptr; + if ((funcId == SCHEDULER_ABILITY_CONNECT) && (serviceSid == nullptr)) { + resultCode = -1; + } + // parse element + ElementName elementName = { nullptr }; + if (!DeserializeElement(&elementName, data)) { + resultCode = -1; + } + if (funcId == SCHEDULER_ABILITY_DISCONNECT) { + storeArgs->conn->OnAbilityDisconnectDone(&elementName, resultCode, storeArgs->storeArg); + } else { + storeArgs->conn->OnAbilityConnectDone(&elementName, serviceSid, resultCode, storeArgs->storeArg); + } + if (funcId != SCHEDULER_ABILITY_CONNECT || resultCode == -1) { + AbilityServiceManager::GetInstance().RemoveStoreArgs(nullptr, storeArgs); + ClearStore(storeArgs); + } +#ifdef __LINUX__ + AdapterFree(serviceSid); + serviceSid = nullptr; +#endif + ClearElement(&elementName); + FreeBuffer(nullptr, ipcMsg); + return LITEIPC_OK; +} + +void AbilityServiceManager::ClearStore(StoreArgs *storeArgs) +{ + if ((storeArgs == nullptr) || (storeArgs->sid == nullptr)) { + HILOG_INFO(HILOG_MODULE_APP, "no need to clear storeArgs"); + return; + } + UnregisterIpcCallback(*(storeArgs->sid)); + delete storeArgs->sid; + delete storeArgs; +} +} // namespace OHOS diff --git a/frameworks/abilitymgr_lite/src/abilityms_client.cpp b/frameworks/abilitymgr_lite/src/abilityms_client.cpp new file mode 100644 index 0000000..e80fa93 --- /dev/null +++ b/frameworks/abilitymgr_lite/src/abilityms_client.cpp @@ -0,0 +1,95 @@ +/* + * Copyright (c) 2020 Huawei Device Co., Ltd. + * 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 "abilityms_client.h" + +#include "ability_errors.h" +#include "ability_service_interface.h" +#include "liteipc_adapter.h" +#include "log.h" +#include "samgr_lite.h" +#include "serializer.h" +#include "want_utils.h" + +namespace OHOS { +const unsigned int ERROR_SLEEP_TIMES = 300000; +const unsigned int RETRY_TIMES = 20; + +bool AbilityMsClient::Initialize() const +{ + if (amsProxy_ != nullptr) { + return true; + } + int retry = RETRY_TIMES; + while (retry--) { + IUnknown *iUnknown = SAMGR_GetInstance()->GetFeatureApi(AMS_SERVICE, AMS_FEATURE); + if (iUnknown == nullptr) { + HILOG_ERROR(HILOG_MODULE_APP, "iUnknown is null"); + usleep(ERROR_SLEEP_TIMES); // sleep 300ms + continue; + } + + (void)iUnknown->QueryInterface(iUnknown, CLIENT_PROXY_VER, (void **)&amsProxy_); + if (amsProxy_ == nullptr) { + HILOG_ERROR(HILOG_MODULE_APP, "ams proxy is null"); + usleep(ERROR_SLEEP_TIMES); // sleep 300ms + continue; + } + + return true; + } + + return false; +} + +int AbilityMsClient::SchedulerLifecycleDone(uint64_t token, int state) const +{ + if (amsProxy_ == nullptr) { + return PARAM_NULL_ERROR; + } + IpcIo req; + char data[IPC_IO_DATA_MAX]; + IpcIoInit(&req, data, IPC_IO_DATA_MAX, 0); + IpcIoPushUint64(&req, token); + IpcIoPushInt32(&req, state); + return amsProxy_->Invoke(amsProxy_, ABILITY_TRANSACTION_DONE, &req, nullptr, nullptr); +} + +int AbilityMsClient::ScheduleAms(const Want *want, uint64_t token, const SvcIdentity *sid, int commandType) const +{ + if (amsProxy_ == nullptr) { + return PARAM_NULL_ERROR; + } + IpcIo req; + char data[IPC_IO_DATA_MAX]; + IpcIoInit(&req, data, IPC_IO_DATA_MAX, 3); + if (token != 0) { + IpcIoPushUint64(&req, token); + } + if (sid != nullptr) { + IpcIoPushSvc(&req, sid); +#ifdef __LINUX__ + if (commandType == ATTACH_BUNDLE) { + pid_t pid = getpid(); + IpcIoPushUint64(&req, pid); + } +#endif + } + if (want != nullptr && !SerializeWant(&req, want)) { + return SERIALIZE_ERROR; + } + return amsProxy_->Invoke(amsProxy_, commandType, &req, nullptr, nullptr); +} +} // namespace OHOS diff --git a/frameworks/abilitymgr_lite/src/slite/ability_manager.cpp b/frameworks/abilitymgr_lite/src/slite/ability_manager.cpp new file mode 100755 index 0000000..3ab8f7d --- /dev/null +++ b/frameworks/abilitymgr_lite/src/slite/ability_manager.cpp @@ -0,0 +1,30 @@ +/* + * Copyright (c) 2021 Huawei Device Co., Ltd. + * 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 "ability_manager.h" + +#include "abilityms_slite_client.h" + +extern "C" { +int StartAbility(const Want *want) +{ + return OHOS::AbilityMsClient::GetInstance().StartAbility(want); +} + +int TerminateAbility(uint64_t token) +{ + return OHOS::AbilityMsClient::GetInstance().TerminateAbility(token); +} +} diff --git a/frameworks/abilitymgr_lite/src/slite/ability_manager_inner.cpp b/frameworks/abilitymgr_lite/src/slite/ability_manager_inner.cpp new file mode 100755 index 0000000..7d36ad1 --- /dev/null +++ b/frameworks/abilitymgr_lite/src/slite/ability_manager_inner.cpp @@ -0,0 +1,30 @@ +/* + * Copyright (c) 2021 Huawei Device Co., Ltd. + * 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 "ability_manager_inner.h" + +#include "abilityms_slite_client.h" + +extern "C" { +int RegAbilityCallback(StartCheckFunc startChecktCallback) +{ + return 0; +} + +int SchedulerLifecycleDone(uint64_t token, int state) +{ + return OHOS::AbilityMsClient::GetInstance().SchedulerLifecycleDone(token, state); +} +} diff --git a/frameworks/abilitymgr_lite/src/slite/abilityms_slite_client.cpp b/frameworks/abilitymgr_lite/src/slite/abilityms_slite_client.cpp new file mode 100755 index 0000000..0d61854 --- /dev/null +++ b/frameworks/abilitymgr_lite/src/slite/abilityms_slite_client.cpp @@ -0,0 +1,115 @@ +/* + * Copyright (c) 2021 Huawei Device Co., Ltd. + * 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 "abilityms_slite_client.h" + +#include "ability_errors.h" +#include "ability_mgr_service.h" +#include "ability_service.h" +#include "abilityms_log.h" +#include "adapter.h" +#include "cmsis_os2.h" +#include "samgr_lite.h" +#include "securec.h" +#include "unistd.h" +#include "want_utils.h" + +namespace OHOS { +bool AbilityMsClient::Initialize() const +{ + if (amsProxy_ != nullptr) { + return true; + } + int retry = RETRY_TIMES; + while (retry--) { + IUnknown *iUnknown = SAMGR_GetInstance()->GetFeatureApi(AMS_SERVICE, AMS_SLITE_FEATURE); + if (iUnknown == nullptr) { + HILOG_ERROR(HILOG_MODULE_APP, "iUnknown is null"); + osDelay(ERROR_SLEEP_TIMES); // sleep 300ms + continue; + } + + (void)iUnknown->QueryInterface(iUnknown, DEFAULT_VERSION, (void **)&amsProxy_); + if (amsProxy_ == nullptr) { + HILOG_ERROR(HILOG_MODULE_APP, "ams proxy is null"); + osDelay(ERROR_SLEEP_TIMES); // sleep 300ms + continue; + } + return true; + } + return false; +} + +int AbilityMsClient::StartAbility(const Want *want) const +{ + if (want == nullptr || want->element == nullptr || !Initialize()) { + return PARAM_CHECK_ERROR; + } + + AbilityMgrService *service = AbilityMgrService::GetInstance(); + if (service == nullptr) { + return PARAM_CHECK_ERROR; + } + + // 申请want内存,在服务端用完释放 + Want *info = static_cast(AdapterMalloc(sizeof(Want))); + if (info == nullptr) { + return MEMORY_MALLOC_ERROR; + } + info->element = nullptr; + info->data = nullptr; + info->dataLength = 0; + SetWantElement(info, *(want->element)); + SetWantData(info, want->data, want->dataLength); + AbilityService::GetInstance().want_ = info; + Request request = { + .msgId = START_ABILITY, + .data = nullptr, + .len = 0, + .msgValue = 0, + }; + return SAMGR_SendRequest(service->GetIdentity(), &request, nullptr); +} + +int AbilityMsClient::TerminateAbility(uint64_t token) const +{ + AbilityMgrService *service = AbilityMgrService::GetInstance(); + if (service == nullptr) { + return PARAM_CHECK_ERROR; + } + Request request = { + .msgId = TERMINATE_ABILITY, + .data = nullptr, + .len = 0, + .msgValue = static_cast(token & 0xFFFF), + }; + return SAMGR_SendRequest(service->GetIdentity(), &request, nullptr); +} + +int AbilityMsClient::SchedulerLifecycleDone(uint64_t token, int state) const +{ + AbilityMgrService *service = AbilityMgrService::GetInstance(); + if (service == nullptr) { + return PARAM_CHECK_ERROR; + } + Request request = { + .msgId = ABILITY_TRANSACTION_DONE, + .data = nullptr, + .len = 0, + .msgValue = static_cast((token & 0xFF) | (state << 8)), + }; + return SAMGR_SendRequest(service->GetIdentity(), &request, nullptr); +} +} // namespace OHOS diff --git a/frameworks/want_lite/BUILD.gn b/frameworks/want_lite/BUILD.gn new file mode 100755 index 0000000..2d74e5a --- /dev/null +++ b/frameworks/want_lite/BUILD.gn @@ -0,0 +1,42 @@ +# Copyright (c) 2020 Huawei Device Co., Ltd. +# 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. +import("//build/lite/config/component/lite_component.gni") + +generate_notice_file("want_notice_file") { + module_name = "want" + module_source_dir_list = [ "//third_party/bounds_checking_function" ] +} + +source_set("want") { + sources = [ "src/want.cpp" ] + cflags = [ + "-fPIC", + "-Wall", + ] + cflags_cc = cflags + + include_dirs = [ + "include", + "//third_party/bounds_checking_function/include", + "//utils/native/lite/include", + "${aafwk_lite_path}/interfaces/kits/want_lite", + "${appexecfwk_lite_path}/interfaces/kits/bundle_lite", + "${appexecfwk_lite_path}/frameworks/bundle_lite/include", + "${appexecfwk_lite_path}/utils/bundle_lite", + "//foundation/communication/ipc_lite/interfaces/kits", + "//kernel/liteos_a/kernel/include", + "//kernel/liteos_a/kernel/common", + ] + + defines = [ "OHOS_APPEXECFWK_BMS_BUNDLEMANAGER" ] +} diff --git a/frameworks/want_lite/LICENSE b/frameworks/want_lite/LICENSE new file mode 100755 index 0000000..4a45986 --- /dev/null +++ b/frameworks/want_lite/LICENSE @@ -0,0 +1,177 @@ + + 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 \ No newline at end of file diff --git a/frameworks/want_lite/README.md b/frameworks/want_lite/README.md new file mode 100644 index 0000000..5e992fb --- /dev/null +++ b/frameworks/want_lite/README.md @@ -0,0 +1,2 @@ +## Introduction +The cpp file is the implementation of Want class. \ No newline at end of file diff --git a/frameworks/want_lite/include/want_utils.h b/frameworks/want_lite/include/want_utils.h new file mode 100644 index 0000000..e9c955e --- /dev/null +++ b/frameworks/want_lite/include/want_utils.h @@ -0,0 +1,40 @@ +/* + * Copyright (c) 2020 Huawei Device Co., Ltd. + * 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 OHOS_WANT_UTILS_H +#define OHOS_WANT_UTILS_H + +#include "want.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif +#endif // __cplusplus + +#ifdef OHOS_APPEXECFWK_BMS_BUNDLEMANAGER +#include + +bool SerializeWant(IpcIo *io, const Want *want); +bool DeserializeWant(Want *want, IpcIo *io); +#endif + +#ifdef __cplusplus +#if __cplusplus +} +#endif +#endif // __cplusplus + +#endif // OHOS_WANT_UTILS_H diff --git a/frameworks/want_lite/src/want.cpp b/frameworks/want_lite/src/want.cpp new file mode 100755 index 0000000..1525463 --- /dev/null +++ b/frameworks/want_lite/src/want.cpp @@ -0,0 +1,325 @@ +/* + * Copyright (c) 2020 Huawei Device Co., Ltd. + * 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 "want_utils.h" +#include "element_name_utils.h" + +#include +#ifdef OHOS_APPEXECFWK_BMS_BUNDLEMANAGER +#include +#include +#endif + +#include "utils.h" + +#ifdef OHOS_APPEXECFWK_BMS_BUNDLEMANAGER +using UriKeyType = enum { + BEGIN, + DEVICE, + BUNDLE, + ABILITY, + END, +}; + +using UriProperties = struct { + const char *key; /* key of uri property */ + uint8_t keyLen; /* key length of uri property */ + UriKeyType type; /* key type of uri property */ +}; + +const static UriProperties URI_PROPERTIES[] = { + { "#Want", 5, BEGIN }, + { "device=", 7, DEVICE }, + { "bundle=", 7, BUNDLE }, + { "ability=", 8, ABILITY }, + { "end", 3, END }, +}; + +constexpr static char URI_SEPARATOR = ';'; +constexpr static int VALUE_NULL = 0; +constexpr static int VALUE_OBJECT = 1; +constexpr static int DATA_LENGTH = 2048; +#endif + +void ClearWant(Want *want) +{ + if (want == nullptr) { + return; + } + + ClearElement(want->element); + AdapterFree(want->element); +#ifdef OHOS_APPEXECFWK_BMS_BUNDLEMANAGER + AdapterFree(want->sid); +#endif + AdapterFree(want->data); +} + +bool SetWantElement(Want *want, ElementName element) +{ + if (want == nullptr) { + return false; + } + + ClearElement(want->element); + AdapterFree(want->element); + want->element = reinterpret_cast(AdapterMalloc(sizeof(ElementName))); + if (want->element == nullptr) { + return false; + } + want->element->deviceId = OHOS::Utils::Strdup(element.deviceId); + want->element->bundleName = OHOS::Utils::Strdup(element.bundleName); + want->element->abilityName = OHOS::Utils::Strdup(element.abilityName); + return true; +} + +#ifdef OHOS_APPEXECFWK_BMS_BUNDLEMANAGER +bool SetWantSvcIdentity(Want *want, SvcIdentity sid) +{ + if (want == nullptr) { + return false; + } + + AdapterFree(want->sid); + want->sid = reinterpret_cast(AdapterMalloc(sizeof(SvcIdentity))); + if (want->sid == nullptr) { + return false; + } + if (memcpy_s(want->sid, sizeof(SvcIdentity), &sid, sizeof(SvcIdentity)) != EOK) { + AdapterFree(want->sid); + return false; + } + + return true; +} +#endif + +bool SetWantData(Want *want, const void *data, uint16_t dataLength) +{ + if (want == nullptr) { + return false; + } + + AdapterFree(want->data); + want->data = OHOS::Utils::Memdup(data, dataLength); + if (want->data == nullptr) { + want->dataLength = 0; + return false; + } + + want->dataLength = dataLength; + return true; +} + +#ifdef OHOS_APPEXECFWK_BMS_BUNDLEMANAGER +bool SerializeWant(IpcIo *io, const Want *want) +{ + if ((io == nullptr) || (want == nullptr) || (want->dataLength > DATA_LENGTH)) { + return false; + } + + if (want->element == nullptr) { + IpcIoPushInt32(io, VALUE_NULL); + } else { + IpcIoPushInt32(io, VALUE_OBJECT); + if (!SerializeElement(io, want->element)) { + return false; + } + } + IpcIoPushInt32(io, want->dataLength); + if (want->dataLength > 0) { +#ifdef __LINUX__ + IpcIoPushString(io, reinterpret_cast(want->data)); +#else + const BuffPtr buff = { + want->dataLength, + want->data, + }; + IpcIoPushDataBuff(io, &buff); +#endif + } + if (want->sid == nullptr) { + IpcIoPushInt32(io, VALUE_NULL); + } else { + IpcIoPushInt32(io, VALUE_OBJECT); + IpcIoPushSvc(io, want->sid); + } + + return true; +} + +bool DeserializeWant(Want *want, IpcIo *io) +{ + if ((want == nullptr) || (io == nullptr)) { + return false; + } + + if (IpcIoPopInt32(io) == VALUE_OBJECT) { + want->element = reinterpret_cast(AdapterMalloc(sizeof(ElementName))); + if (want->element == nullptr || + memset_s(want->element, sizeof(ElementName), 0, sizeof(ElementName)) != EOK || + !DeserializeElement(want->element, io)) { + AdapterFree(want->element); + return false; + } + } + if (IpcIoPopInt32(io) > 0) { +#ifdef __LINUX__ + size_t len = 0; + char *data = reinterpret_cast(IpcIoPopString(io, &len)); + if (!SetWantData(want, data, len + 1)) { + ClearWant(want); + return false; + } +#else + BuffPtr *buff = IpcIoPopDataBuff(io); + if (buff == nullptr) { + ClearWant(want); + return false; + } + if (!SetWantData(want, buff->buff, buff->buffSz)) { + FreeBuffer(nullptr, buff->buff); + ClearWant(want); + return false; + } + FreeBuffer(nullptr, buff->buff); +#endif + } + if (IpcIoPopInt32(io) == VALUE_OBJECT) { + auto sid = IpcIoPopSvc(io); + if ((sid == nullptr) || !SetWantSvcIdentity(want, *sid)) { +#ifdef __LINUX__ + AdapterFree(sid); + sid = nullptr; +#endif + ClearWant(want); + return false; + } +#ifdef __LINUX__ + AdapterFree(sid); + sid = nullptr; +#endif + } + + return true; +} + +Want *WantParseUri(const char *uri) +{ + if (uri == nullptr) { + return nullptr; + } + char *parseUri = OHOS::Utils::Strdup(uri); + if (parseUri == nullptr) { + return nullptr; + } + ElementName element = { nullptr, nullptr, nullptr }; + char *beginIndex = parseUri; + for (auto property : URI_PROPERTIES) { + if (strstr(beginIndex, property.key) != beginIndex) { + AdapterFree(parseUri); + return nullptr; + } + if (property.type == END) { + break; + } + char *endIndex = strchr(beginIndex, URI_SEPARATOR); + if ((endIndex == nullptr) || (endIndex <= beginIndex)) { + AdapterFree(parseUri); + return nullptr; + } + *endIndex = '\0'; + beginIndex += property.keyLen; + switch (property.type) { + case DEVICE: { + SetElementDeviceID(&element, beginIndex); + break; + } + case BUNDLE: { + SetElementBundleName(&element, beginIndex); + break; + } + case ABILITY: { + SetElementAbilityName(&element, beginIndex); + break; + } + default: { + break; + } + } + beginIndex = endIndex + 1; + } + AdapterFree(parseUri); + Want *want = new Want(); + if ((memset_s(want, sizeof(Want), 0, sizeof(Want)) != EOK) || !SetWantElement(want, element)) { + ClearElement(&element); + delete want; + return nullptr; + } + ClearElement(&element); + return want; +} + +const char *WantToUri(Want want) +{ + std::string uriString; + + for (auto property : URI_PROPERTIES) { + uriString += property.key; + switch (property.type) { + case BEGIN: { + uriString += URI_SEPARATOR; + break; + } + case DEVICE: { + if ((want.element != nullptr) && (want.element->deviceId != nullptr)) { + uriString += want.element->deviceId; + } + uriString += URI_SEPARATOR; + break; + } + case BUNDLE: { + if ((want.element != nullptr) && (want.element->bundleName != nullptr)) { + uriString += want.element->bundleName; + } + uriString += URI_SEPARATOR; + break; + } + case ABILITY: { + if ((want.element != nullptr) && (want.element->abilityName != nullptr)) { + uriString += want.element->abilityName; + } + uriString += URI_SEPARATOR; + break; + } + default: { + break; + } + } + } + + uint16_t len = uriString.size(); + char *uri = reinterpret_cast(AdapterMalloc(len + 1)); + if (uri == nullptr) { + return nullptr; + } + if (strncpy_s(uri, len + 1, uriString.c_str(), len) < 0) { + AdapterFree(uri); + return nullptr; + } + + return uri; +} +#endif diff --git a/interfaces/innerkits/abilitymgr_lite/LICENSE b/interfaces/innerkits/abilitymgr_lite/LICENSE new file mode 100755 index 0000000..4a45986 --- /dev/null +++ b/interfaces/innerkits/abilitymgr_lite/LICENSE @@ -0,0 +1,177 @@ + + 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 \ No newline at end of file diff --git a/interfaces/innerkits/abilitymgr_lite/README.md b/interfaces/innerkits/abilitymgr_lite/README.md new file mode 100644 index 0000000..498de26 --- /dev/null +++ b/interfaces/innerkits/abilitymgr_lite/README.md @@ -0,0 +1,2 @@ +## Features +Ability manager is devoted to support some interface functions to other outside processes. By using these functions, other processes can start, stop, connect or disconnect ability of some one application. \ No newline at end of file diff --git a/interfaces/innerkits/abilitymgr_lite/ability_kit_command.h b/interfaces/innerkits/abilitymgr_lite/ability_kit_command.h new file mode 100644 index 0000000..8483814 --- /dev/null +++ b/interfaces/innerkits/abilitymgr_lite/ability_kit_command.h @@ -0,0 +1,39 @@ +/* + * Copyright (c) 2020 Huawei Device Co., Ltd. + * 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 OHOS_ABILITY_KIT_COMMAND_H +#define OHOS_ABILITY_KIT_COMMAND_H + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif +#endif /* __cplusplus */ + +enum AbilityKitCommand { + SCHEDULER_APP_INIT = 0, + SCHEDULER_ABILITY_LIFECYCLE, + SCHEDULER_ABILITY_CONNECT, + SCHEDULER_ABILITY_DISCONNECT, + SCHEDULER_APP_EXIT, + SCHEDULER_DUMP_ABILITY, + SCHEDULER_ABILITY_CONNECT_FAIL, +}; +#ifdef __cplusplus +#if __cplusplus +} +#endif +#endif /* __cplusplus */ + +#endif // OHOS_ABILITY_KIT_COMMAND_H diff --git a/interfaces/innerkits/abilitymgr_lite/ability_main.h b/interfaces/innerkits/abilitymgr_lite/ability_main.h new file mode 100644 index 0000000..74ab6ef --- /dev/null +++ b/interfaces/innerkits/abilitymgr_lite/ability_main.h @@ -0,0 +1,33 @@ +/* + * Copyright (c) 2020 Huawei Device Co., Ltd. + * 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 OHOS_ABILITY_MAIN_H +#define OHOS_ABILITY_MAIN_H + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif +#endif // __cplusplus + +int AbilityMain(const char *token); + +#ifdef __cplusplus +#if __cplusplus +} +#endif +#endif // __cplusplus + +#endif // OHOS_ABILITY_MAIN_H diff --git a/interfaces/innerkits/abilitymgr_lite/ability_service_interface.h b/interfaces/innerkits/abilitymgr_lite/ability_service_interface.h new file mode 100755 index 0000000..7089861 --- /dev/null +++ b/interfaces/innerkits/abilitymgr_lite/ability_service_interface.h @@ -0,0 +1,79 @@ +/* + * Copyright (c) 2020 Huawei Device Co., Ltd. + * 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 OHOS_AMS_INTERFACE_H +#define OHOS_AMS_INTERFACE_H + +#include "feature.h" +#include "iproxy_server.h" +#include "want.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif +#endif /* __cplusplus */ + +const char AMS_SERVICE[] = "abilityms"; +const char AMS_FEATURE[] = "AmsFeature"; +const char AMS_SLITE_FEATURE[] = "AmsSliteFeature"; +const char AMS_INNER_FEATURE[] = "AmsInnerFeature"; + +enum AmsCommand { + START_ABILITY = 0, + TERMINATE_ABILITY, + ATTACH_BUNDLE, + CONNECT_ABILITY, + CONNECT_ABILITY_DONE, + DISCONNECT_ABILITY, + DISCONNECT_ABILITY_DONE, + ABILITY_TRANSACTION_DONE, + TERMINATE_SERVICE, + INNER_BEGIN, + TERMINATE_APP = INNER_BEGIN, + DUMP_ABILITY, + COMMAND_END, +}; + +/** + * Expose to start or terminate ability. + */ +struct AmsInterface { + INHERIT_SERVER_IPROXY; + int32 (*StartAbility)(const Want *want); + int32 (*TerminateAbility)(uint64_t token); + int32 (*ConnectAbility)(const Want *want, SvcIdentity *svc, uint64_t token); + int32 (*DisconnectAbility)(SvcIdentity *svc, uint64_t token); + int32 (*StopAbility)(const Want *want); +}; + +struct AmsInnerInterface { + INHERIT_SERVER_IPROXY; + int32 (*StartKeepAliveApps)(); + int32 (*TerminateApp)(const char *bundleName); +}; + +struct AmsSliteInterface { + INHERIT_IUNKNOWN; + int32 (*StartAbility)(const Want *want); + int32 (*TerminateAbility)(uint64_t token); + int32 (*SchedulerLifecycleDone)(uint64_t token, int state); +}; +#ifdef __cplusplus +#if __cplusplus +} +#endif +#endif /* __cplusplus */ +#endif // OHOS_AMS_INTERFACE_H diff --git a/interfaces/innerkits/abilitymgr_lite/slite/ability_manager_inner.h b/interfaces/innerkits/abilitymgr_lite/slite/ability_manager_inner.h new file mode 100755 index 0000000..3b5241d --- /dev/null +++ b/interfaces/innerkits/abilitymgr_lite/slite/ability_manager_inner.h @@ -0,0 +1,37 @@ +/* + * Copyright (c) 2021 Huawei Device Co., Ltd. + * 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 OHOS_ABILITY_MANAGER_INNER_H +#define OHOS_ABILITY_MANAGER_INNER_H + +#include "stdint.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif +#endif /* __cplusplus */ + +typedef int (*StartCheckFunc)(const char *bundleName); + +int RegAbilityCallback(StartCheckFunc startChecktCallback); + +int SchedulerLifecycleDone(uint64_t token, int state); +#ifdef __cplusplus +#if __cplusplus +} +#endif +#endif /* __cplusplus */ +#endif // OHOS_ABILITY_MANAGER_INNER_H diff --git a/interfaces/kits/ability_lite/LICENSE b/interfaces/kits/ability_lite/LICENSE new file mode 100755 index 0000000..4a45986 --- /dev/null +++ b/interfaces/kits/ability_lite/LICENSE @@ -0,0 +1,177 @@ + + 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 \ No newline at end of file diff --git a/interfaces/kits/ability_lite/README.md b/interfaces/kits/ability_lite/README.md new file mode 100644 index 0000000..5e51992 --- /dev/null +++ b/interfaces/kits/ability_lite/README.md @@ -0,0 +1,3 @@ +## Introduction +In order to support third developers to develop their java script applications, some interface functions are offered at here. By using these functions, third java script APPs can interactive with AMS `Ability Manager Service`. In addition, the life cycle of these applications ability will be managed by AMS, including, start, termination, stop, connection and disconnection. + diff --git a/interfaces/kits/ability_lite/ability.h b/interfaces/kits/ability_lite/ability.h new file mode 100644 index 0000000..7de9f76 --- /dev/null +++ b/interfaces/kits/ability_lite/ability.h @@ -0,0 +1,215 @@ +/* + * Copyright (c) 2020 Huawei Device Co., Ltd. + * 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. + */ + +/** + * @addtogroup AbilityKit + * @{ + * + * @brief Provides ability-related functions, including ability lifecycle callbacks and functions for connecting to or + * disconnecting from Particle Abilities. + * + * Abilities are classified into Feature Abilities and Particle Abilities. Feature Abilities support the Page template, + * and Particle Abilities support the Service template. An ability using the Page template is called a Page ability for + * short and that using the Service template is called a Service ability. + * + * @since 1.0 + * @version 1.0 + */ + +/** + * @file ability.h + * + * @brief Declares ability-related functions, including ability lifecycle callbacks and functions for connecting to or + * disconnecting from Particle Abilities. + * + * As the fundamental unit of OpenHarmony applications, abilities are classified into Feature Abilities and Particle + * Abilities. Feature Abilities support the Page template, and Particle Abilities support the Service template. + * An ability using the Page template is called Page ability for short and that using the Service template + * is called Service ability. + * + * @since 1.0 + * @version 1.0 + */ +#ifndef OHOS_ABILITY_H +#define OHOS_ABILITY_H + +#ifdef ABILITY_WINDOW_SUPPORT +#include +#endif +#include + +#include "ability_context.h" +#include "ability_manager.h" +#include "serializer.h" + +namespace OHOS { +#ifdef ABILITY_WINDOW_SUPPORT +class AbilitySliceManager; +class AbilityWindow; +#endif + +/** + * @brief Declares ability-related functions, including ability lifecycle callbacks and functions for connecting to or + * disconnecting from Particle Abilities. + * + * As the fundamental unit of OpenHarmony applications, abilities are classified into Feature Abilities and Particle + * Abilities. Feature Abilities support the Page template, and Particle Abilities support the Service template. + * An ability using the Page template is called Page ability for short and that using the Service template + * is called Service ability. + * + * @since 1.0 + * @version 1.0 + */ +class Ability : public AbilityContext { +public: + Ability() = default; + virtual ~Ability() = default; + + /** + * @brief Called when this ability is started. You must override this function if you want to perform some + * initialization operations during ability startup. + * + * This function can be called only once in the entire lifecycle of an ability. + * @param want Indicates the {@link Want} structure containing startup information about the ability. + */ + virtual void OnStart(const Want &want); + + /** + * @brief Called when this ability enters the STATE_INACTIVE state. + * + * STATE_INACTIVE is an instantaneous state. The ability in this state may be visible but does not have + * focus. You can override this function to implement your own processing logic. + */ + virtual void OnInactive(); + + /** + * @brief Called when this ability enters the STATE_ACTIVE state. + * + * The ability in the STATE_ACTIVE state is visible and has focus. + * You can override this function to implement your own processing logic. + * + * @param want Indicates the {@link Want} structure containing activation information about the ability. + */ + virtual void OnActive(const Want &want); + + /** + * @brief Called when this ability enters the STATE_BACKGROUND state. + * + * + * The ability in the STATE_BACKGROUND state is invisible. + * You can override this function to implement your own processing logic. + */ + virtual void OnBackground(); + + /** + * @brief Called when this ability enters the STATE_STOP state. + * + * The ability in the STATE_STOP is being destroyed. + * You can override this function to implement your own processing logic. + */ + virtual void OnStop(); + + /** + * @brief Called when this Service ability is connected for the first time. + * + * You can override this function to implement your own processing logic. + * + * @param want Indicates the {@link Want} structure containing connection information about the Service ability. + * @return Returns a pointer to the sid of the connected Service ability. + */ + virtual const SvcIdentity *OnConnect(const Want &want); + + /** + * @brief Called when all abilities connected to this Service ability are disconnected. + * + * You can override this function to implement your own processing logic. + * + * @param want Indicates the {@link Want} structure containing disconnection information about the Service + * ability. + */ + virtual void OnDisconnect(const Want &want); + +#ifdef ABILITY_WINDOW_SUPPORT + /** + * @brief Sets the main route for this ability. + * + * The main route, also called main entry, refers to the default AbilitySlice to present for this ability. + * This function should be called only on Feature Abilities. If this function is not called in the + * {@link OnStart(const Want &want)} function for a Feature Ability, the Feature Ability will fail to start. + * + * @param entry Indicates the main entry, which is the class name of the AbilitySlice instance to start. + */ + void SetMainRoute(const std::string &entry); + + /** + * @brief Sets the UI layout for this ability. + * You can call {@link GetWindowRootView()} to create a layout and add controls. + * + * @param rootView Indicates the pointer to the custom layout view you have created. + */ + void SetUIContent(RootView *rootView); +#endif + /** + * @brief Handles a message sent by the client to this Service ability. + * + * @param funcId Indicates the type of the message sent by the client. + * @param request Indicates the pointer to the serialized request parameters sent by the client. + * @param reply Indicates the pointer to the serialized result returned to the client. + */ + virtual void MsgHandle(uint32_t funcId, IpcIo *request, IpcIo *reply); + + /** + * @brief Prints ability information to the console. + * + * You can override this function to obtain or print extra parameters. + * + * @param extra Indicates the extra parameter to be obtained or printed to the console. + */ + virtual void Dump(const std::string &extra); + +private: + typedef enum { + START, + INACTIVE, + ACTIVE, + BACKGROUND, + STOP, + } Action; + + void Init(uint64_t token, int abilityType, bool isNativeApp); + int GetState() const; + std::string GetDumpInfo() const; +#ifdef ABILITY_WINDOW_SUPPORT + void DeliverAbilityLifecycle(Action action, const Want *want = nullptr); +#endif + static int32_t MsgHandleInner(const IpcContext* context, void *ipcMsg, IpcIo *data, void *arg); + +#ifdef ABILITY_WINDOW_SUPPORT + AbilitySliceManager *abilitySliceManager_ { nullptr }; + AbilityWindow *abilityWindow_ { nullptr }; +#endif + int abilityState_ { 0 }; + int abilityType_ { 0 }; + uint64_t token_ { 0 }; + SvcIdentity *sid_ { nullptr }; + static const int MAX_OBJECTS = 6; + + friend class AbilityThread; +#ifdef ABILITY_WINDOW_SUPPORT + friend class AbilitySliceManager; +#endif +}; +} // namespace OHOS +#endif // OHOS_ABILITY_H diff --git a/interfaces/kits/ability_lite/ability_connection.h b/interfaces/kits/ability_lite/ability_connection.h new file mode 100644 index 0000000..56f1616 --- /dev/null +++ b/interfaces/kits/ability_lite/ability_connection.h @@ -0,0 +1,82 @@ +/* + * Copyright (c) 2020 Huawei Device Co., Ltd. + * 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. + */ + +/** + * @addtogroup AbilityKit + * @{ + * + * @brief Provides ability-related functions, including ability lifecycle callbacks and functions for connecting to or + * disconnecting from Particle Abilities. + * + * Abilities are classified into Feature Abilities and Particle Abilities. Feature Abilities support the Page template, + * and Particle Abilities support the Service template. An ability using the Page template is called a Page ability for + * short and that using the Service template is called a Service ability. + * + * @since 1.0 + * @version 1.0 + */ + +/** + * @file ability_connection.h + * @brief Declares callbacks to be invoked when a remote Service ability is connected or disconnected. + * + * You must override the callbacks provided in {@link IAbilityConnection} to implement your processing logic for + * Service connection and disconnection. + * + * @since 1.0 + * @version 1.0 + */ + +#ifndef OHOS_ABILITY_CONNECTION_H +#define OHOS_ABILITY_CONNECTION_H + +#include "element_name.h" +#include "liteipc_adapter.h" + +typedef struct IAbilityConnection IAbilityConnection; + +/** +* @brief Provides callbacks to be invoked when a remote Service ability is connected or disconnected. +*/ +struct IAbilityConnection { + /** + * @brief Called when a client is connected to a Service ability. + * + * This callback is invoked to receive the connection result after a client is connected to a Service ability. + * + * @param elementName Indicates the pointer to the information about the connected Service ability. + * @param serviceSid Indicates the pointer to the remote proxy object of the Service ability. + * @param resultCode Indicates the connection result code. The value 0 indicates a successful connection, + * and any other value indicates a connection failure. + * @param data Indicates the pointer to the data stored during the connection. + */ + void (*OnAbilityConnectDone)(ElementName *elementName, SvcIdentity *serviceSid, int resultCode, void *data); + + /** + * @brief Called after all connections to a Service ability are disconnected. + * + * This callback is invoked to receive the disconnection result after the connected Service ability crashes or is + * killed. If the Service ability exits unexpectedly, all its connections are disconnected, and each ability + * previously connected to it will call + * {@link OnAbilityDisconnectDone(ElementName *elementName, int resultCode, void *data)}. + * + * @param elementName Indicates the pointer to the information about the disconnected Service ability. + * @param resultCode Indicates the disconnection result code. The value 0 indicates a successful + * disconnection, and any other value indicates a disconnection failure. + * @param data Indicates the pointer to the data stored during the connection. + */ + void (*OnAbilityDisconnectDone)(ElementName *elementName, int resultCode, void *data); +}; +#endif // OHOS_ABILITY_CONNECTION_H diff --git a/interfaces/kits/ability_lite/ability_context.h b/interfaces/kits/ability_lite/ability_context.h new file mode 100644 index 0000000..d7b03f0 --- /dev/null +++ b/interfaces/kits/ability_lite/ability_context.h @@ -0,0 +1,123 @@ +/* + * Copyright (c) 2020 Huawei Device Co., Ltd. + * 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. + */ + +/** + * @addtogroup AbilityKit + * @{ + * + * @brief Provides ability-related functions, including ability lifecycle callbacks and functions for connecting to or + * disconnecting from Particle Abilities. + * + * Abilities are classified into Feature Abilities and Particle Abilities. Feature Abilities support the Page template, + * and Particle Abilities support the Service template. An ability using the Page template is called a Page ability for + * short and that using the Service template is called a Service ability. + * + * @since 1.0 + * @version 1.0 + */ + +/** + * @file ability_context.h + * + * @brief Declares functions for starting and stopping an ability. + * + * The {@link Ability} and {@link AbilitySlice} classes are inherited from the AbilityContext class for you to + * call functions in this class for application development. + * + * @since 1.0 + * @version 1.0 + */ + +#ifndef OHOS_ABILITY_CONTEXT_H +#define OHOS_ABILITY_CONTEXT_H + +#include +#include +#include "ability_connection.h" + +namespace OHOS { +/** + * @brief Provides functions for starting and stopping an ability. + * + * The {@link Ability} and {@link AbilitySlice} classes are inherited from the AbilityContext class for you to + * call functions in this class for application development. + * + * @since 1.0 + * @version 1.0 + */ +class AbilityContext { +public: + AbilityContext() = default; + ~AbilityContext() = default; + + /** + * @brief Starts an {@link Ability} based on the specified {@link Want} information. + * + * @param want Indicates the pointer to the {@link Want} structure containing information about the ability to + * start. + * @return Returns 0 if the operation is successful; returns a non-zero value otherwise. + */ + int StartAbility(const Want &want); + + /** + * @brief Stops an {@link Ability} based on the specified {@link Want} information. + * + * This function takes effect only on Service abilities. + * + * @param want Indicates the pointer to the {@link Want} structure containing information about the ability to + * stop. + * @return Returns 0 if the operation is successful; returns a non-zero value otherwise. + */ + int StopAbility(const Want &want); + + /** + * @brief Destroys this {@link Ability}. + * + * This function can be called only by this ability. + * + * @return Returns 0 if the operation is successful; returns -1 otherwise. + */ + int TerminateAbility(); + + /** + * @brief Connects to a Service ability based on the specified {@link Want} information. + * + * After the Service ability is connected, the Ability Manager Service invokes a particular callback and returns + * the ID of the Service ability. The client can use this ID to communicate with the connected Service ability. + * + * @param want Indicates the pointer to the {@link Want} structure containing information about the Service + * ability to connect. + * @param conn Indicates the callback to be invoked when the connection is successful. + * @param data Indicates the pointer to the data to be passed to the callback. + * @return Returns 0 if this function is successfully called; returns another value otherwise. + */ + int ConnectAbility(const Want &want, const IAbilityConnection &conn, void *data); + + /** + * @brief Disconnects from a Service ability. + * + * @param conn Indicates the callback to be invoked when the connection is successful. + * @return Returns 0 if this function is successfully called; returns another value otherwise. + */ + int DisconnectAbility(const IAbilityConnection &conn); + +private: + friend class Ability; + friend class AbilitySlice; + uint64_t token_ { 0 }; +}; +} // OHOS + +#endif // OHOS_ABILITY_CONTEXT_H diff --git a/interfaces/kits/ability_lite/ability_env.h b/interfaces/kits/ability_lite/ability_env.h new file mode 100644 index 0000000..ec02536 --- /dev/null +++ b/interfaces/kits/ability_lite/ability_env.h @@ -0,0 +1,76 @@ +/* + * Copyright (c) 2020 Huawei Device Co., Ltd. + * 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. + */ + +/** + * @addtogroup AbilityKit + * @{ + * + * @brief Provides ability-related functions, including ability lifecycle callbacks and functions for connecting to or + * disconnecting from Particle Abilities. + * + * Abilities are classified into Feature Abilities and Particle Abilities. Feature Abilities support the Page template, + * and Particle Abilities support the Service template. An ability using the Page template is called a Page ability for + * short and that using the Service template is called a Service ability. + * + * @since 1.0 + * @version 1.0 + */ + +/** + * @file ability_env.h + * + * @brief Declares functions for obtaining information about the runtime environment of the application to which the + * ability belongs, including the bundle name, source code path, and data path. + * + * @since 1.0 + * @version 1.0 + */ +#ifndef OHOS_ABILITY_ENV_H +#define OHOS_ABILITY_ENV_H + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif +#endif + +/** + * @brief Obtains the bundle name of the application to which this ability belongs. + * + * @return Returns the pointer to the bundle name if the operation is successful; returns a null pointer otherwise. + */ +const char *GetBundleName(); + +/** + * @brief Obtains the source code path of this ability. + * + * @return Returns the pointer to the source code path of this ability. + */ +const char *GetSrcPath(); + +/** + * @brief Obtains the data path of this ability. + * + * @return Returns the pointer to the data path of this ability. + */ +const char *GetDataPath(); + +#ifdef __cplusplus +#if __cplusplus +} +#endif +#endif + +#endif // OHOS_ABILITY_ENV_H \ No newline at end of file diff --git a/interfaces/kits/ability_lite/ability_errors.h b/interfaces/kits/ability_lite/ability_errors.h new file mode 100755 index 0000000..ca007b5 --- /dev/null +++ b/interfaces/kits/ability_lite/ability_errors.h @@ -0,0 +1,77 @@ +/* + * Copyright (c) 2020 Huawei Device Co., Ltd. + * 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. + */ + +/** + * @addtogroup AbilityKit + * @{ + * + * @brief Provides ability-related functions, including ability lifecycle callbacks and functions for connecting to or + * disconnecting from Particle Abilities. + * + * Abilities are classified into Feature Abilities and Particle Abilities. Feature Abilities support the Page template, + * and Particle Abilities support the Service template. An ability using the Page template is called a Page ability for + * short and that using the Service template is called a Service ability. + * + * @since 1.0 + * @version 1.0 + */ + +/** + * @file ability_errors.h + * + * @brief Declares error codes returned by ability management functions. + * + * @since 1.0 + * @version 1.0 + */ + +#ifndef OHOS_ABILITY_ERRORS_H +#define OHOS_ABILITY_ERRORS_H + +/** +* @brief Declares error codes returned by ability management functions. +*/ +enum { + /** The function is successfully called. */ + ERR_OK = 0, + + /** The parameter is null. */ + PARAM_NULL_ERROR, + + /** Memory allocation error. */ + MEMORY_MALLOC_ERROR, + + /** An error occurred during the execution of the Dump function. */ + DUMP_ABILITIES_ERROR, + + /** IPC request error. */ + IPC_REQUEST_ERROR, + + /** Serialization error. */ + SERIALIZE_ERROR, + + /** Create app task error. */ + CREATE_APPTASK_ERROR, + + /** Scheduler lifecycle error. */ + SCHEDULER_LIFECYCLE_ERROR, + + /** The parameter is error. */ + PARAM_CHECK_ERROR, + + /** Command error. */ + COMMAND_ERROR = 0x7fff, +}; +#endif // OHOS_ABILITY_ERRORS_H \ No newline at end of file diff --git a/interfaces/kits/ability_lite/ability_event_handler.h b/interfaces/kits/ability_lite/ability_event_handler.h new file mode 100644 index 0000000..538e2a5 --- /dev/null +++ b/interfaces/kits/ability_lite/ability_event_handler.h @@ -0,0 +1,100 @@ +/* + * Copyright (c) 2020 Huawei Device Co., Ltd. + * 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. + */ + +/** + * @addtogroup AbilityKit + * @{ + * + * @brief Provides ability-related functions, including ability lifecycle callbacks and functions for connecting to or + * disconnecting from Particle Abilities. + * + * Abilities are classified into Feature Abilities and Particle Abilities. Feature Abilities support the Page template, + * and Particle Abilities support the Service template. An ability using the Page template is called a Page ability for + * short and that using the Service template is called a Service ability. + * + * @since 1.0 + * @version 1.0 + */ + +/** + * @file ability_event_handler.h + * + * @brief Declares functions for performing operations during inter-thread communication, including running and + * quitting the event loop of the current thread and posting tasks to an asynchronous thread. + * + * @since 1.0 + * @version 1.0 + */ + +#ifndef OHOS_ABILITY_EVENT_HANDLER_H +#define OHOS_ABILITY_EVENT_HANDLER_H + +#include +#include +#include + +namespace OHOS { +/** + * @brief Declares functions for performing operations during inter-thread communication, including running and + * quitting the event loop of the current thread and posting tasks to an asynchronous thread. + * + * @since 1.0 + * @version 1.0 + */ +class AbilityEventHandler { +public: + using Task = std::function; + + AbilityEventHandler(); + ~AbilityEventHandler(); + + /** + * @brief Starts running the event loop of the current thread. + */ + void Run(); + + /** + * @brief Posts a task to an asynchronous thread. + * + * @param task Indicates the task to post. + */ + void PostTask(const Task &task); + + /** + * @brief Quits the event loop of the current thread. + */ + void PostQuit(); + + /** + * @brief Obtains the event handler of the current thread. + * + * @return Returns the pointer to the {@link AbilityEventHandler} object of the current thread. + */ + static AbilityEventHandler* GetCurrentHandler(); +private: + std::queue taskQueue_; + + pthread_cond_t pthreadCond_ = PTHREAD_COND_INITIALIZER; + pthread_mutex_t queueMutex_ = PTHREAD_MUTEX_INITIALIZER; + + bool quit_ { false }; + + AbilityEventHandler(const AbilityEventHandler&) = delete; + AbilityEventHandler& operator = (const AbilityEventHandler&) = delete; + AbilityEventHandler(AbilityEventHandler&&) = delete; + AbilityEventHandler& operator= (AbilityEventHandler&&) = delete; +}; +} // namespace OHOS +#endif // OHOS_ABILITY_EVENT_HANDLER_H diff --git a/interfaces/kits/ability_lite/ability_loader.h b/interfaces/kits/ability_lite/ability_loader.h new file mode 100644 index 0000000..e35e223 --- /dev/null +++ b/interfaces/kits/ability_lite/ability_loader.h @@ -0,0 +1,137 @@ +/* + * Copyright (c) 2020 Huawei Device Co., Ltd. + * 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. +*/ + +/** + * @addtogroup AbilityKit + * @{ + * + * @brief Provides ability-related functions, including ability lifecycle callbacks and functions for connecting to or + * disconnecting from Particle Abilities. + * + * Abilities are classified into Feature Abilities and Particle Abilities. Feature Abilities support the Page template, + * and Particle Abilities support the Service template. An ability using the Page template is called a Page ability for + * short and that using the Service template is called a Service ability. + * + * @since 1.0 + * @version 1.0 + */ + +/** + * @file ability_loader.h + * + * @brief Declares functions for registering the class names of {@link Ability} and {@link AbilitySlice} with the + * ability management framework. + * + * After creating your own {@link Ability} and {@link AbilitySlice} child classes, you should register their class + * names with the ability management framework so that the application can start Ability instances created in + * the background. + * + * @since 1.0 + * @version 1.0 + */ + +#ifndef OHOS_ABILITY_LOADER_H +#define OHOS_ABILITY_LOADER_H + +#include +#include +#include + +#include "ability.h" +#ifdef ABILITY_WINDOW_SUPPORT +#include "ability_slice.h" +#endif + +namespace OHOS { +using CreateAblity = std::function; +#ifdef ABILITY_WINDOW_SUPPORT +using CreateSlice = std::function; +#endif + +/** + * @brief Declares functions for registering the class names of {@link Ability} and {@link AbilitySlice} with the + * ability management framework. + * + * After creating your own {@link Ability} and {@link AbilitySlice} child classes, you should register their class + * names with the ability management framework so that the application can start Ability instances created in + * the background. + * + * @since 1.0 + * @version 1.0 + */ +class AbilityLoader { +public: + static AbilityLoader &GetInstance() + { + static AbilityLoader abilityLoader; + return abilityLoader; + } + + ~AbilityLoader() = default; + + void RegisterAbility(const std::string &abilityName, const CreateAblity &createFunc); + Ability *GetAbilityByName(const std::string &abilityName); + +#ifdef ABILITY_WINDOW_SUPPORT + void RegisterAbilitySlice(const std::string &sliceName, const CreateSlice &createFunc); + AbilitySlice *GetAbilitySliceByName(const std::string &sliceName); +#endif + +private: + AbilityLoader() = default; + AbilityLoader(const AbilityLoader&) = delete; + AbilityLoader &operator=(const AbilityLoader &) = delete; + AbilityLoader(AbilityLoader &&) = delete; + AbilityLoader &operator=(AbilityLoader &&) = delete; + + std::unordered_map abilities_; +#ifdef ABILITY_WINDOW_SUPPORT + std::unordered_map slices_; +#endif +}; + +/** + * @brief Registers the class name of an {@link Ability} child class. + * + * After implementing your own {@link Ability} class, you should call this function so that the ability management + * framework can create Ability instances when loading your Ability class. + * + * @param className Indicates the {@link Ability} class name to register. + */ +#define REGISTER_AA(className) \ + __attribute__((constructor)) void RegisterAA##className() { \ + AbilityLoader::GetInstance().RegisterAbility(#className, []()->Ability* { \ + return new className; \ + }); \ + } + +/** + * @brief Registers the class name of an {@link AbilitySlice} child class. + * + * After implementing your own {@link AbilitySlice} class, you should call this function so that the ability + * management framework can create AbilitySlice instances when loading your AbilitySlice class. + * + * @param className Indicates the {@link AbilitySlice} class name to register. + */ +#ifdef ABILITY_WINDOW_SUPPORT +#define REGISTER_AS(className) \ + __attribute__((constructor)) void RegisterAS##className() { \ + AbilityLoader::GetInstance().RegisterAbilitySlice(#className, []()->AbilitySlice* { \ + return new className; \ + }); \ + } +#endif +} // namespace OHOS +#endif // OHOS_ABILITY_LOADER_H \ No newline at end of file diff --git a/interfaces/kits/ability_lite/ability_manager.h b/interfaces/kits/ability_lite/ability_manager.h new file mode 100644 index 0000000..b4122b5 --- /dev/null +++ b/interfaces/kits/ability_lite/ability_manager.h @@ -0,0 +1,94 @@ +/* + * Copyright (c) 2020 Huawei Device Co., Ltd. + * 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. + */ + +/** + * @addtogroup AbilityKit + * @{ + * + * @brief Provides ability-related functions, including ability lifecycle callbacks and functions for connecting to or + * disconnecting from Particle Abilities. + * + * Abilities are classified into Feature Abilities and Particle Abilities. Feature Abilities support the Page template, + * and Particle Abilities support the Service template. An ability using the Page template is called a Page ability for + * short and that using the Service template is called a Service ability. + * + * @since 1.0 + * @version 1.0 + */ + +/** + * @file ability_manager.h + * + * @brief Declares ability-related functions, including functions for starting, stopping, connecting to, + * and disconnecting from an ability, registering a callback, and unregistering a callback. + * + * @since 1.0 + * @version 1.0 + */ +#ifndef OHOS_ABILITY_MANAGER_H +#define OHOS_ABILITY_MANAGER_H + +#include "ability_connection.h" +#include "want.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif +#endif /* __cplusplus */ + +/** + * @brief Starts an ability based on the specified {@link Want} information. + * + * @param want Indicates the pointer to the {@link Want} structure containing information about the ability to start. + * @return Returns 0 if this function is successfully called; returns another value otherwise. + */ +int StartAbility(const Want *want); + +/** + * @brief Stops an ability based on the specified {@link Want} information. + * + * This function takes effect only on Service abilities. + * + * @param want Indicates the pointer to the {@link Want} structure containing information about the ability to stop. + * @return Returns 0 if this function is successfully called; returns another value otherwise. + */ +int StopAbility(const Want *want); + +/** + * @brief Connects to a Service ability based on the specified {@link Want} information. + * + * @param want Indicates the pointer to the {@link Want} structure containing + * information about the Service ability to connect. + * @param conn Indicates the callback object when the Service ability is connected. + * @param data Indicates the pointer to the data to be passed to the callback. + * @return Returns 0 if this function is successfully called; returns another value otherwise. + */ +int ConnectAbility(const Want *want, const IAbilityConnection *conn, void *data); + +/** + * @brief Disconnects from a Service ability. + * + * @param conn Indicates the callback object when the Service ability is connected. + * @return Returns 0 if this function is successfully called; returns another value otherwise. + */ +int DisconnectAbility(const IAbilityConnection *conn); + +#ifdef __cplusplus +#if __cplusplus +} +#endif +#endif /* __cplusplus */ +#endif /* OHOS_ABILITY_MANAGER_H */ diff --git a/interfaces/kits/ability_lite/ability_slice.h b/interfaces/kits/ability_lite/ability_slice.h new file mode 100644 index 0000000..a86e90f --- /dev/null +++ b/interfaces/kits/ability_lite/ability_slice.h @@ -0,0 +1,153 @@ +/* + * Copyright (c) 2020 Huawei Device Co., Ltd. + * 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. +*/ + +/** + * @addtogroup AbilityKit + * @{ + * + * @brief Provides ability-related functions, including ability lifecycle callbacks and functions for connecting to or + * disconnecting from Particle Abilities. + * + * Abilities are classified into Feature Abilities and Particle Abilities. Feature Abilities support the Page template, + * and Particle Abilities support the Service template. An ability using the Page template is called a Page ability for + * short and that using the Service template is called a Service ability. + * + * @since 1.0 + * @version 1.0 + */ + +/** + * @file ability_slice.h + * + * @brief Declares ability slice-related functions, including ability slice lifecycle callbacks and functions for + * connecting to or disconnecting from ability slices. + * + * AbilitySlice instances, which are specific to Feature Abilities (abilities using the Page template), + * are used to present different screens on an application's user interface. + * A Feature Ability can have multiple ability slices. + * + * @since 1.0 + * @version 1.0 + */ +#ifndef OHOS_ABILITY_SLICE_H +#define OHOS_ABILITY_SLICE_H + +#include "ability.h" + +namespace OHOS { +class AbilitySliceManager; + +/** + * @brief Provides ability slice-related functions, including ability slice lifecycle callbacks and functions for + * connecting to or disconnecting from ability slices. + * + * AbilitySlice instances, which are specific to Feature Abilities (abilities using the Page template), + * are used to present different screens on an application's user interface. + * A Feature Ability can have multiple ability slices. + * + * @since 1.0 + * @version 1.0 + */ +class AbilitySlice : public AbilityContext { +public: + AbilitySlice() = default; + virtual ~AbilitySlice() = default; + + /** + * @brief Called when this ability slice is started. You must override this function if you want to perform some + * initialization operations during ability slice startup. + * + * This function can be called only once in the entire lifecycle of an ability slice. + * You can override this function to implement your own processing logic. + * @param want Indicates the {@link Want} structure containing startup information about the ability slice. + */ + virtual void OnStart(const Want &want); + + /** + * @brief Called when this ability slice enters the STATE_INACTIVE state. + * + * STATE_INACTIVE is an instantaneous state. The ability slice in this state may be visible but does not + * have focus. You can override this function to implement your own processing logic. + */ + virtual void OnInactive(); + + /** + * @brief Called when this ability slice enters the STATE_ACTIVE state. + * + * The ability slice in the STATE_ACTIVE state is visible and has focus. + * You can override this function to implement your own processing logic. + * + * @param want Indicates the {@link Want} structure containing activation information about the ability slice. + */ + virtual void OnActive(const Want &want); + + /** + * @brief Called when this ability slice enters the STATE_BACKGROUND state. + * + * The ability slice in the STATE_BACKGROUND state is invisible. + * You can override this function to implement your own processing logic. + */ + virtual void OnBackground(); + + /** + * @brief Called when this ability slice enters the STATE_STOP state. + * + * The ability slice in the STATE_STOP state is being destroyed. + * You can override this function to implement your own processing logic. + */ + virtual void OnStop(); + + /** + * @brief Presents another ability slice, which can be an ability slice that is not started or an existing ability + * slice in the host ability. + * + * @attention This function can be called only when both of the following conditions are met: + *

  • The host ability is in the STATE_ACTIVE state.
  • + *
  • The target ability slice is not started or destroyed.
+ * + * @param abilitySlice Indicates the target ability slice. This parameter cannot be null. + * @param want Indicates the {@link Want} structure containing startup information about the target ability slice. + */ + void Present(AbilitySlice &abilitySlice, const Want &want); + + /** + * @brief Destroys this ability slice. + * + * This ability slice can call this function to destroy itself. If the ability slice to destroy is the only + * running one in the host ability, the host ability will also be destroyed. Otherwise, the host ability will + * not be affected. + */ + void Terminate(); + + /** + * @brief Sets the UI layout for the host ability of this ability slice. + * + * You can call {@link GetWindowRootView()} to create a layout and add controls. + * + * @param rootView Indicates the pointer to the custom layout view you have created. + */ + void SetUIContent(RootView *rootView); +private: + void Init(AbilitySliceManager &abilitySliceManager); + int GetState() const; + + AbilitySliceManager *abilitySliceManager_ { nullptr }; + RootView *curRootView_ { nullptr }; + int sliceState_ { 0 }; + + friend class AbilitySliceScheduler; +}; +} // namespace OHOS +#endif // OHOS_ABILITY_SLICE_H \ No newline at end of file diff --git a/interfaces/kits/ability_lite/ability_state.h b/interfaces/kits/ability_lite/ability_state.h new file mode 100644 index 0000000..060ba78 --- /dev/null +++ b/interfaces/kits/ability_lite/ability_state.h @@ -0,0 +1,90 @@ +/* + * Copyright (c) 2020 Huawei Device Co., Ltd. + * 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. + */ + +/** + * @addtogroup AbilityKit + * @{ + * + * @brief Provides ability-related functions, including ability lifecycle callbacks and functions for connecting to or + * disconnecting from Particle Abilities. + * + * Abilities are classified into Feature Abilities and Particle Abilities. Feature Abilities support the Page template, + * and Particle Abilities support the Service template. An ability using the Page template is called a Page ability for + * short and that using the Service template is called a Service ability. + * + * @since 1.0 + * @version 1.0 + */ + +/** + * @file ability_state.h + * + * @brief Declares ability-related functions, including ability lifecycle callbacks and functions for connecting to + * or disconnecting from Particle Abilities. + * As the fundamental unit of OpenHarmony applications, abilities are classified into Feature Abilities and Particle + * Abilities. Feature Abilities support the Page template, and Particle Abilities support the Service template. + * An ability using the Page template is called a Page ability for short and that using the Service template + * is called a Service ability. + * + * @since 1.0 + * @version 1.0 + */ +#ifndef OHOS_ABILITY_STATE_H +#define OHOS_ABILITY_STATE_H + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif +#endif /* __cplusplus */ +/** + * @brief Enumerates all lifecycle states that an ability will go through over the course of its lifetime. + * + * @since 1.0 + * @version 1.0 + */ +typedef enum { + /** + * Uninitialized state: An ability is in this state when it has not been initialized after being created. + */ + STATE_UNINITIALIZED, + + /** + * Initial state: An ability is in this state after it is initialized or stopped. + */ + STATE_INITIAL, + + /** + * Inactive state: An ability is in this state when it is switched to the foreground but is not interactive. + */ + STATE_INACTIVE, + + /** + * Active state: An ability is in this state when it is switched to the foreground and is interactive. + */ + STATE_ACTIVE, + + /** + * Background state: An ability is in this state after it returns to the background. + */ + STATE_BACKGROUND, +} State; +#ifdef __cplusplus +#if __cplusplus +} +#endif +#endif /* __cplusplus */ + +#endif // OHOS_ABILITY_STATE_H \ No newline at end of file diff --git a/interfaces/kits/ability_lite/slite/ability_manager.h b/interfaces/kits/ability_lite/slite/ability_manager.h new file mode 100755 index 0000000..aa26a67 --- /dev/null +++ b/interfaces/kits/ability_lite/slite/ability_manager.h @@ -0,0 +1,41 @@ +/* + * Copyright (c) 2021 Huawei Device Co., Ltd. + * 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 OHOS_ABILITY_MANAGER_H +#define OHOS_ABILITY_MANAGER_H + +#include "want.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif +#endif /* __cplusplus */ + +/** + * @brief Starts an ability based on the specified {@link Want} information. + * + * @param want Indicates the pointer to the {@link Want} structure containing information about the ability to start. + * @return Returns 0 if this function is successfully called; returns another value otherwise. + */ +int StartAbility(const Want *want); + +int TerminateAbility(uint64_t token); +#ifdef __cplusplus +#if __cplusplus +} +#endif +#endif /* __cplusplus */ +#endif /* OHOS_ABILITY_MANAGER_H */ diff --git a/interfaces/kits/ability_lite/slite/lite_context.h b/interfaces/kits/ability_lite/slite/lite_context.h new file mode 100755 index 0000000..8b07330 --- /dev/null +++ b/interfaces/kits/ability_lite/slite/lite_context.h @@ -0,0 +1,51 @@ +/* + * Copyright (c) 2021 Huawei Device Co., Ltd. + * 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 OHOS_LITE_CONTEXT_H +#define OHOS_LITE_CONTEXT_H + +#include "ability_manager.h" +#include "want.h" + +namespace OHOS { +class LiteContext { +public: + LiteContext() = default; + ~LiteContext() = default; + + /** + * @brief Starts an {@link Ability} based on the specified {@link Want} information. + * + * @param want Indicates the pointer to the {@link Want} structure containing information about the ability to + * start. + * @return Returns 0 if the operation is successful; returns a non-zero value otherwise. + */ + int StartAbility(const Want &want); + + /** + * @brief Destroys this {@link Ability}. + * + * This function can be called only by this ability. + * + * @return Returns 0 if the operation is successful; returns -1 otherwise. + */ + int TerminateAbility(); +private: + friend class SliteAbility; + uint64_t token_ { 0 }; +}; +} // OHOS + +#endif // OHOS_LITE_CONTEXT_H diff --git a/interfaces/kits/ability_lite/slite/slite_ability.h b/interfaces/kits/ability_lite/slite/slite_ability.h new file mode 100755 index 0000000..b501207 --- /dev/null +++ b/interfaces/kits/ability_lite/slite/slite_ability.h @@ -0,0 +1,89 @@ +/* + * Copyright (c) 2021 Huawei Device Co., Ltd. + * 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 OHOS_SLITE_ABILITY_H +#define OHOS_SLITE_ABILITY_H + +#include "lite_context.h" +#include "want.h" + +namespace OHOS { +/** + * @brief Declares ability-related functions, including ability lifecycle callbacks and functions for connecting to or + * disconnecting from Particle Abilities. + * + * As the fundamental unit of OpenHarmony applications, abilities are classified into Feature Abilities and Particle + * Abilities. Feature Abilities support the Page template, and Particle Abilities support the Service template. + * An ability using the Page template is called Page ability for short and that using the Service template + * is called Service ability. + * + * @since 1.0 + * @version 1.0 + */ +class SliteAbility : public LiteContext { +public: + SliteAbility() = default; + virtual ~SliteAbility() = default; + + /** + * @brief Called when this ability is started. You must override this function if you want to perform some + * initialization operations during ability startup. + * + * This function can be called only once in the entire lifecycle of an ability. + * @param want Indicates the {@link Want} structure containing startup information about the ability. + */ + virtual void OnStart(const Want &want); + + /** + * @brief Called when this ability enters the STATE_INACTIVE state. + * + * STATE_INACTIVE is an instantaneous state. The ability in this state may be visible but does not have + * focus. You can override this function to implement your own processing logic. + */ + virtual void OnInactive(); + + /** + * @brief Called when this ability enters the STATE_ACTIVE state. + * + * The ability in the STATE_ACTIVE state is visible and has focus. + * You can override this function to implement your own processing logic. + * + * @param want Indicates the {@link Want} structure containing activation information about the ability. + */ + virtual void OnActive(const Want &want); + + /** + * @brief Called when this ability enters the STATE_BACKGROUND state. + * + * + * The ability in the STATE_BACKGROUND state is invisible. + * You can override this function to implement your own processing logic. + */ + virtual void OnBackground(); + + /** + * @brief Called when this ability enters the STATE_STOP state. + * + * The ability in the STATE_STOP is being destroyed. + * You can override this function to implement your own processing logic. + */ + virtual void OnStop(); + + int GetState() const; +private: + int abilityState_ = 0; +}; +} // namespace OHOS +#endif // OHOS_SLITE_ABILITY_H diff --git a/interfaces/kits/want_lite/LICENSE b/interfaces/kits/want_lite/LICENSE new file mode 100755 index 0000000..4a45986 --- /dev/null +++ b/interfaces/kits/want_lite/LICENSE @@ -0,0 +1,177 @@ + + 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 \ No newline at end of file diff --git a/interfaces/kits/want_lite/README.md b/interfaces/kits/want_lite/README.md new file mode 100644 index 0000000..5ee1745 --- /dev/null +++ b/interfaces/kits/want_lite/README.md @@ -0,0 +1,2 @@ +## Introduction +A data struct named Want utilized to encapsulate some elements in order to simplify the process of starting an application. \ No newline at end of file diff --git a/want.h b/interfaces/kits/want_lite/want.h old mode 100755 new mode 100644 similarity index 100% rename from want.h rename to interfaces/kits/want_lite/want.h diff --git a/services/abilitymgr_lite/.gitignore b/services/abilitymgr_lite/.gitignore new file mode 100644 index 0000000..b075466 --- /dev/null +++ b/services/abilitymgr_lite/.gitignore @@ -0,0 +1 @@ +unittest diff --git a/services/abilitymgr_lite/BUILD.gn b/services/abilitymgr_lite/BUILD.gn new file mode 100644 index 0000000..3650914 --- /dev/null +++ b/services/abilitymgr_lite/BUILD.gn @@ -0,0 +1,123 @@ +# Copyright (c) 2020 Huawei Device Co., Ltd. +# 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. +import("//build/lite/config/component/lite_component.gni") +import("//build/lite/config/subsystem/aafwk/config.gni") + +lite_library("abilityms") { + target_type = "shared_library" + + cflags = [ + "-Wall", + "-Wno-format", + "-Wno-format-extra-args", + ] + cflags_cc = cflags + + ldflags = [ + "-lstdc++", + "-lpthread", + "-ldl", + ] + + sources = [ + "src/ability_connect_mission.cpp", + "src/ability_inner_feature.cpp", + "src/ability_mgr_context.cpp", + "src/ability_mgr_feature.cpp", + "src/ability_mgr_handler.cpp", + "src/ability_mgr_service.cpp", + "src/ability_mission_record.cpp", + "src/ability_mission_stack.cpp", + "src/ability_stack_manager.cpp", + "src/ability_worker.cpp", + "src/app_manager.cpp", + "src/app_record.cpp", + "src/client/ability_dump_client.cpp", + "src/client/ability_thread_client.cpp", + "src/client/app_spawn_client.cpp", + "src/client/bundlems_client.cpp", + "src/client/wms_client.cpp", + "src/page_ability_record.cpp", + "src/task/ability_activate_task.cpp", + "src/task/ability_attach_task.cpp", + "src/task/ability_background_task.cpp", + "src/task/ability_connect_done_task.cpp", + "src/task/ability_connect_task.cpp", + "src/task/ability_disconnect_done_task.cpp", + "src/task/ability_disconnect_task.cpp", + "src/task/ability_dump_task.cpp", + "src/task/ability_inactivate_task.cpp", + "src/task/ability_start_task.cpp", + "src/task/ability_stop_task.cpp", + "src/task/ability_terminate_service_task.cpp", + "src/task/ability_terminate_task.cpp", + "src/task/app_restart_task.cpp", + "src/task/app_terminate_task.cpp", + "src/util/abilityms_helper.cpp", + "src/util/abilityms_status.cpp", + ] + + include_dirs = [ + "${aafwk_lite_path}/interfaces/kits/ability_lite", + "${aafwk_lite_path}/interfaces/kits/want_lite", + "${aafwk_lite_path}/frameworks/want_lite/include", + "${aafwk_lite_path}/interfaces/innerkits/abilitymgr_lite", + "${appexecfwk_lite_path}/interfaces/kits/bundle_lite", + "${appexecfwk_lite_path}/utils/bundle_lite", + "${appexecfwk_lite_path}/interfaces/innerkits/bundlemgr_lite", + "${appexecfwk_lite_path}/frameworks/bundle_lite/include", + "//foundation/communication/ipc_lite/interfaces/kits", + "//foundation/distributedschedule/samgr_lite/interfaces/kits/registry", + "//foundation/distributedschedule/samgr_lite/interfaces/kits/samgr", + "//foundation/graphic/wms/interfaces/innerkits", + "//base/startup/appspawn_lite/services/include", + "//base/security/permission/interfaces/kits/permission_lite", + "//base/security/permission/services/permission_lite/pms/include", + "//kernel/liteos_a/kernel/include", + "//kernel/liteos_a/kernel/common", + "//third_party/bounds_checking_function/include", + "//utils/native/lite/include", + "include", + "include/task", + "//third_party/cJSON", + ] + + deps = [ + "${appexecfwk_lite_path}/frameworks/bundle_lite:bundle", + "//base/hiviewdfx/hilog_lite/frameworks/featured:hilog_shared", + "//foundation/communication/ipc_lite:liteipc_adapter", + "//foundation/distributedschedule/samgr_lite/samgr:samgr", + ] + + defines = [ "OHOS_APPEXECFWK_BMS_BUNDLEMANAGER" ] + + if (enable_ohos_appexecfwk_feature_ability == true) { + deps += [ "//foundation/graphic/surface" ] + defines += [ "ABILITY_WINDOW_SUPPORT" ] + } +} + +generate_notice_file("abilityms_notice_file") { + module_name = "abilityms" + module_source_dir_list = [ + "//third_party/bounds_checking_function", + "//third_party/cJSON", + ] +} + +lite_component("aafwk_services_lite") { + features = [ + ":abilityms", + "tools:aa", + ] +} diff --git a/services/abilitymgr_lite/LICENSE b/services/abilitymgr_lite/LICENSE new file mode 100755 index 0000000..4a45986 --- /dev/null +++ b/services/abilitymgr_lite/LICENSE @@ -0,0 +1,177 @@ + + 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 \ No newline at end of file diff --git a/services/abilitymgr_lite/README.md b/services/abilitymgr_lite/README.md new file mode 100755 index 0000000..631dcdc --- /dev/null +++ b/services/abilitymgr_lite/README.md @@ -0,0 +1,121 @@ +# AMS - Ability manager service of OpenHarmony + +## Introduction + +`Ability manager service` plays an important role in the OpenHarmony. This module focuses on aspect of introducing the feature of AMS aiming at managing ability stack, managing application process and controlling life cycle of ability slices. + +## Features + +- Manage ability stack. +- Manage application process. +- Controll life cycle of ability slices. +- AMS tools. + +## Directions + +``` +. +├── BUILD.gn +├── include +│   ├── ability_connect_mission.h +│   ├── ability_connect_record.h +│   ├── ability_connect_trans_param.h +│   ├── ability_inner_feature.h +│   ├── ability_list.h # ability map to store ability record +│   ├── ability_message_id.h # message id of AMS task +│   ├── ability_mgr_context.h +│   ├── ability_mgr_feature.h # AMS feature in Service Manager +│   ├── ability_mgr_handler.h # AMS message handler +│   ├── ability_mgr_service.h # register AMS in the Service Manager +│   ├── ability_mission_record.h # ability mission record +│   ├── ability_mission_stack.h # ability mission record stack +│   ├── ability_record.h # ability record including ability info for GT +│   ├── ability_service.h # AMS for GT +│   ├── ability_stack.h # stack of AMS for GT +│   ├── ability_stack_manager.h # ability stack manager +│   ├── ability_worker.h # ability task manager +│   ├── app_manager.h # application process record manager +│   ├── app_record.h # application process record +│   ├── client +│   │   ├── ability_dump_client.h +│   │   ├── ability_thread_client.h +│   │   ├── app_spawn_client.h +│   │   ├── bundlems_client.h +│   │   └── wms_client.h +│   ├── js_app_host.h +│   ├── page_ability_record.h +│   ├── task +│   │   ├── ability_activate_task.h +│   │   ├── ability_attach_task.h +│   │   ├── ability_background_task.h +│   │   ├── ability_connect_done_task.h +│   │   ├── ability_connect_task.h +│   │   ├── ability_disconnect_done_task.h +│   │   ├── ability_disconnect_task.h +│   │   ├── ability_dump_task.h +│   │   ├── ability_inactivate_task.h +│   │   ├── ability_start_task.h +│   │   ├── ability_stop_task.h +│   │   ├── ability_task.h +│   │   ├── ability_terminate_service_task.h +│   │   ├── ability_terminate_task.h +│   │   ├── app_restart_task.h +│   │   └── app_terminate_task.h +│   └── util +│   ├── abilityms_helper.h +│   ├── abilityms_log.h +│   └── abilityms_status.h +├── README.md +├── src +│   ├── ability_connect_mission.cpp +│   ├── ability_inner_feature.cpp +│   ├── ability_list.cpp +│   ├── ability_mgr_context.cpp +│   ├── ability_mgr_feature.cpp +│   ├── ability_mgr_handler.cpp +│   ├── ability_mgr_service.cpp +│   ├── ability_mission_record.cpp +│   ├── ability_mission_stack.cpp +│   ├── ability_record.cpp +│   ├── ability_service.cpp +│   ├── ability_stack.cpp +│   ├── ability_stack_manager.cpp +│   ├── ability_worker.cpp +│   ├── app_manager.cpp +│   ├── app_record.cpp +│   ├── client +│   │   ├── ability_dump_client.cpp +│   │   ├── ability_thread_client.cpp +│   │   ├── app_spawn_client.cpp +│   │   ├── bundlems_client.cpp +│   │   └── wms_client.cpp +│   ├── js_app_host.cpp +│   ├── page_ability_record.cpp +│   ├── task +│   │   ├── ability_activate_task.cpp +│   │   ├── ability_attach_task.cpp +│   │   ├── ability_background_task.cpp +│   │   ├── ability_connect_done_task.cpp +│   │   ├── ability_connect_task.cpp +│   │   ├── ability_disconnect_done_task.cpp +│   │   ├── ability_disconnect_task.cpp +│   │   ├── ability_dump_task.cpp +│   │   ├── ability_inactivate_task.cpp +│   │   ├── ability_start_task.cpp +│   │   ├── ability_stop_task.cpp +│   │   ├── ability_terminate_service_task.cpp +│   │   ├── ability_terminate_task.cpp +│   │   ├── app_restart_task.cpp +│   │   └── app_terminate_task.cpp +│   └── util +│   ├── abilityms_helper.cpp +│   └── abilityms_status.cpp +└── tools + ├── BUILD.gn + ├── include + │   └── ability_tool.h + └── src + ├── ability_tool.cpp + └── main.cpp + +``` diff --git a/services/abilitymgr_lite/include/ability_connect_mission.h b/services/abilitymgr_lite/include/ability_connect_mission.h new file mode 100644 index 0000000..830adb9 --- /dev/null +++ b/services/abilitymgr_lite/include/ability_connect_mission.h @@ -0,0 +1,46 @@ +/* + * Copyright (c) 2020 Huawei Device Co., Ltd. + * 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 OHOS_ABILITY_CONNECT_MISSION_H +#define OHOS_ABILITY_CONNECT_MISSION_H + +#include + +#include "page_ability_record.h" + +namespace OHOS { +class AbilityConnectMission { +public: + AbilityConnectMission() = default; + ~AbilityConnectMission(); + + void PushServiceRecord(PageAbilityRecord &abilityRecord); + PageAbilityRecord *FindServiceRecord(uint64_t token) const; + PageAbilityRecord *FindServiceRecord(const char *bundleName, const char *abilityName) const; + PageAbilityRecord *FindServiceRecord(const SvcIdentity &connectSid, uint64_t abilityToken) const; + void RemoveServiceRecord(uint64_t token); + void RemoveServiceRecord(const char *bundleName); + int32_t CountServiceInApp(const char *bundleName); +#ifdef OHOS_DEBUG + AbilityMsStatus DumpConnectMission() const; +#endif + void RemoveConnectRecordByPageToken(uint64_t token, const char *bundleName); + +private: + std::list serviceRecords_; +}; +} // namespace OHOS + +#endif // OHOS_ABILITY_CONNECT_MISSION_H diff --git a/services/abilitymgr_lite/include/ability_connect_record.h b/services/abilitymgr_lite/include/ability_connect_record.h new file mode 100755 index 0000000..b83e05d --- /dev/null +++ b/services/abilitymgr_lite/include/ability_connect_record.h @@ -0,0 +1,68 @@ +/* + * Copyright (c) 2020 Huawei Device Co., Ltd. + * 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 OHOS_ABILITY_CONNECT_RECORD_H +#define OHOS_ABILITY_CONNECT_RECORD_H + +#include "liteipc_adapter.h" +#include "samgr_lite.h" + +namespace OHOS { +enum ConnectStatus { + INIT, + WAIT_CONNECT, + CONNECTING, + CONNECTED, + DISCONNECTING, + DISCONNECT, + STOPPING, + STOPPED, +}; + +class AbilityConnectRecord { +public: + AbilityConnectRecord(const SvcIdentity &identity, uint64_t abilityToken) + : connectSid_(identity), abilityToken_(abilityToken) {}; + + ~AbilityConnectRecord() = default; + + void SetStatus(ConnectStatus status) + { + status_ = status; + } + + ConnectStatus GetStatus() const + { + return status_; + } + + const SvcIdentity &GetConnectSid() const + { + return connectSid_; + } + + uint64_t GetAbilityToken() const + { + return abilityToken_; + } + +private: + const SvcIdentity connectSid_; + const uint64_t abilityToken_; + ConnectStatus status_ = ConnectStatus::INIT; +}; +} // namespace OHOS + +#endif // OHOS_ABILITY_CONNECT_RECORD_H diff --git a/services/abilitymgr_lite/include/ability_connect_trans_param.h b/services/abilitymgr_lite/include/ability_connect_trans_param.h new file mode 100755 index 0000000..ca4267c --- /dev/null +++ b/services/abilitymgr_lite/include/ability_connect_trans_param.h @@ -0,0 +1,71 @@ +/* + * Copyright (c) 2020 Huawei Device Co., Ltd. + * 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 OHOS_ABILITY_CONNECT_TRANS_PARAM_H +#define OHOS_ABILITY_CONNECT_TRANS_PARAM_H + +#include +#include + +#include "liteipc_adapter.h" +#include "want.h" + +namespace OHOS { +class AbilityConnectTransParam { +public: + AbilityConnectTransParam(Want *want, const SvcIdentity &identity, uint64_t abilityToken) + : want_(want), identity_(identity), abilityToken_(abilityToken) {}; + + AbilityConnectTransParam() = delete; + ~AbilityConnectTransParam() + { + ClearWant(want_); + delete want_; + }; + + const SvcIdentity &GetSvcIdentity() const + { + return identity_; + } + + const Want *GetWant() const + { + return want_; + } + + uint64_t GetToken() const + { + return abilityToken_; + } + + void SetCallingUid(pid_t callingUid) + { + callingUid_ = callingUid; + } + + pid_t GetCallingUid() const + { + return callingUid_; + } + +private: + Want *want_ = { nullptr }; + SvcIdentity identity_; + uint64_t abilityToken_ = 0; + pid_t callingUid_ = -1; +}; +} // namespace OHOS + +#endif // OHOS_ABILITY_CONNECT_TRANS_PARAM_H diff --git a/services/abilitymgr_lite/include/ability_inner_feature.h b/services/abilitymgr_lite/include/ability_inner_feature.h new file mode 100755 index 0000000..8d2a44f --- /dev/null +++ b/services/abilitymgr_lite/include/ability_inner_feature.h @@ -0,0 +1,64 @@ +/* + * Copyright (c) 2020 Huawei Device Co., Ltd. + * 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 OHOS_ABILITYMANAGERSERVICE_INNER_FEATURE_H +#define OHOS_ABILITYMANAGERSERVICE_INNER_FEATURE_H + +#include "ability_service_interface.h" +#include "ability_mgr_handler.h" +#include "feature.h" +#include "iunknown.h" +#include "iproxy_client.h" +#include "nocopyable.h" + +namespace OHOS { +typedef int32 (*InvokeFunc)(const void *origin, IpcIo *req); + +class AbilityInnerFeature : public Feature { +public: + static int32 StartKeepAliveApps(); + static int32 TerminateApp(const char *bundleName); + + static int32 Invoke(IServerProxy *iProxy, int funcId, void *origin, IpcIo *req, IpcIo *reply); + + static AbilityInnerFeature *GetInstance() + { + static AbilityInnerFeature instance; + return &instance; + } + ~AbilityInnerFeature() = default; +private: + AbilityInnerFeature(); + + static int32 TerminateAppInvoke(const void *origin, IpcIo *req); + static int32 DumpAbilityInvoke(const void *origin, IpcIo *req); + + static const char *GetFeatureName(Feature *feature); + static void OnFeatureInitialize(Feature *feature, Service *parent, Identity identity); + static void OnFeatureStop(Feature *feature, Identity identity); + static BOOL OnFeatureMessage(Feature *feature, Request *request); + +private: + Identity identity_; + static InvokeFunc invokeFuncList[COMMAND_END - INNER_BEGIN]; + DISALLOW_COPY_AND_MOVE(AbilityInnerFeature); +}; + +typedef struct { + INHERIT_IUNKNOWNENTRY(AmsInnerInterface); + AbilityInnerFeature *ams; +} AbilityInnerFeatureImpl; +} // namespace OHOS +#endif // OHOS_ABILITYMANAGERSERVICE_INNER_FEATURE_H diff --git a/services/abilitymgr_lite/include/ability_list.h b/services/abilitymgr_lite/include/ability_list.h new file mode 100644 index 0000000..02d7f8d --- /dev/null +++ b/services/abilitymgr_lite/include/ability_list.h @@ -0,0 +1,38 @@ +/* + * Copyright (c) 2020 Huawei Device Co., Ltd. + * 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 OHOS_ABILITY_LIST_H +#define OHOS_ABILITY_LIST_H + +#include "ability_record.h" +#include "utils_list.h" + +namespace OHOS { +class AbilityList { +public: + AbilityList() = default; + ~AbilityList() = default; + + void Add(AbilityRecord *abilityRecord); + AbilityRecord *Get(uint16_t token) const; + AbilityRecord *Get(const char *bundleName) const; + void Erase(uint16_t token); + +private: + List abilityList_ {}; +}; +} // namespace OHOS + +#endif // OHOS_ABILITY_LIST_H \ No newline at end of file diff --git a/services/abilitymgr_lite/include/ability_message_id.h b/services/abilitymgr_lite/include/ability_message_id.h new file mode 100644 index 0000000..3ab67cb --- /dev/null +++ b/services/abilitymgr_lite/include/ability_message_id.h @@ -0,0 +1,69 @@ +/* + * Copyright (c) 2020 Huawei Device Co., Ltd. + * 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 OHOS_ABILITY_MESSAGE_ID_H +#define OHOS_ABILITY_MESSAGE_ID_H + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif +#endif + +enum AmsMsgType { +#ifndef OHOS_APPEXECFWK_BMS_BUNDLEMANAGER + AMS_SERVICE_INITED = 0x1000, + AMS_START_ABILITY, + AMS_TERMINATE_ABILITY, + AMS_ONSTART, + AMS_ONACTIVE, + AMS_ONBACKGROUND, + AMS_ONDESTROY, + AMS_SENDMESSAGE, + AMS_REGISTER, + AMS_UNREGISTER, + + AMS_START_CHECK_REQUEST, + AMS_START_CHECK_RESPONSE, + + /* msgId used to communicated with Launcher */ + LAUNCHER_SCHEDULE_ACTIVE, + LAUNCHER_SCHEDULE_BACKGROUND, + // The above value is for watch gt, don't change the order +#else + AMS_SERVICE_INITED = 0, + AMS_START_ABILITY, + AMS_TERMINATE_ABILITY, + + AMS_ATTACH_BUNDLE, + AMS_TRANSACTION_DONE, + + AMS_CONNECT_ABILITY, + AMS_CONNECT_ABILITY_DONE, + AMS_DISCONNECT_ABILITY, + AMS_DISCONNECT_ABILITY_DONE, + AMS_TERMINATE_SERVICE, + AMS_TERMINATE_APP, + AMS_RESTART_APP, + AMS_DUMP_ABILITY, +#endif +}; + +#ifdef __cplusplus +#if __cplusplus +} +#endif +#endif +#endif // OHOS_ABILITY_MESSAGE_ID_H diff --git a/services/abilitymgr_lite/include/ability_mgr_context.h b/services/abilitymgr_lite/include/ability_mgr_context.h new file mode 100644 index 0000000..7655723 --- /dev/null +++ b/services/abilitymgr_lite/include/ability_mgr_context.h @@ -0,0 +1,41 @@ +/* + * Copyright (c) 2020 Huawei Device Co., Ltd. + * 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 OHOS_ABILITY_MGR_CONTEXT_H +#define OHOS_ABILITY_MGR_CONTEXT_H + +#include "ability_mission_stack.h" +#include "ability_connect_mission.h" + +namespace OHOS { +class AbilityMgrContext { +public: + AbilityMgrContext(); + ~AbilityMgrContext(); + + const AbilityMissionStack *GetLauncherMissionStacks() const; + const AbilityMissionStack *GetDefaultMissionStacks() const; + const AbilityMissionStack *GetTopMissionStacks() const; + const AbilityMissionStack *GetTargetMissionStack(const char *bundleName) const; + const AbilityConnectMission *GetServiceConnects() const; + void SetTopMissionStacks(const AbilityMissionStack *stack); +private: + AbilityMissionStack *launcherMissionStacks_ { nullptr }; + AbilityMissionStack *defaultMissionStacks_ { nullptr }; + AbilityConnectMission *serviceConnects_ { nullptr }; + const AbilityMissionStack *topMissionStacks_ { nullptr }; +}; +} // namespace OHOS +#endif // OHOS_ABILITY_MGR_CONTEXT_H diff --git a/services/abilitymgr_lite/include/ability_mgr_feature.h b/services/abilitymgr_lite/include/ability_mgr_feature.h new file mode 100755 index 0000000..12b574c --- /dev/null +++ b/services/abilitymgr_lite/include/ability_mgr_feature.h @@ -0,0 +1,79 @@ +/* + * Copyright (c) 2020 Huawei Device Co., Ltd. + * 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 OHOS_ABILITYMANAGERSERVICE_FEATURE_H +#define OHOS_ABILITYMANAGERSERVICE_FEATURE_H + +#include "ability_mgr_handler.h" +#include "ability_service_interface.h" +#include "feature.h" +#include "iproxy_client.h" +#include "iunknown.h" +#include "nocopyable.h" + +namespace OHOS { +typedef int32 (*InvokeFunc)(const void *origin, IpcIo *req); + +class AbilityMgrFeature : public Feature { +public: + static int32 StartAbility(const Want *want); + static int32 TerminateAbility(uint64_t token); + static int32 ConnectAbility(const Want *want, SvcIdentity *svc, uint64_t token); + static int32 DisconnectAbility(SvcIdentity *svc, uint64_t token); + static int32 StopAbility(const Want *want); + + static int32 Invoke(IServerProxy *iProxy, int funcId, void *origin, IpcIo *req, IpcIo *reply); + + static int32 AppDeathNotify(const IpcContext* context, void *ipcMsg, IpcIo *data, void *arg); + static AbilityMgrFeature *GetInstance() + { + static AbilityMgrFeature instance; + return &instance; + } + ~AbilityMgrFeature() = default; +private: + AbilityMgrFeature(); + static int32 StartAbilityInner(const Want *want, pid_t callingUid); + static int32 ConnectAbilityInner(const Want *want, SvcIdentity *svc, uint64_t token, pid_t callingUid); + static int32 StopAbilityInner(const Want *want, pid_t callingUid); + static int32 StartAbilityInvoke(const void *origin, IpcIo *req); + static int32 TerminateAbilityInvoke(const void *origin, IpcIo *req); + static int32 ConnectAbilityInvoke(const void *origin, IpcIo *req); + static int32 DisconnectAbilityInvoke(const void *origin, IpcIo *req); + static int32 StopAbilityInvoke(const void *origin, IpcIo *req); + + static int32 AbilityTransactionDoneInvoke(const void *origin, IpcIo *req); + static int32 AttachBundleInvoke(const void *origin, IpcIo *req); + static int32 ConnectAbilityDoneInvoke(const void *origin, IpcIo *req); + static int32 DisconnectAbilityDoneInvoke(const void *origin, IpcIo *req); + static int32 RestartApp(const char *bundleName); + + static const char *GetFeatureName(Feature *feature); + static void OnFeatureInitialize(Feature *feature, Service *parent, Identity identity); + static void OnFeatureStop(Feature *feature, Identity identity); + static BOOL OnFeatureMessage(Feature *feature, Request *request); + +private: + Identity identity_; + static InvokeFunc invokeFuncList[INNER_BEGIN]; + DISALLOW_COPY_AND_MOVE(AbilityMgrFeature); +}; + +typedef struct { + INHERIT_IUNKNOWNENTRY(AmsInterface); + AbilityMgrFeature *ams; +} AbilityMgrFeatureImpl; +} // namespace OHOS +#endif // OHOS_ABILITYMANAGERSERVICE_FEATURE_H diff --git a/services/abilitymgr_lite/include/ability_mgr_handler.h b/services/abilitymgr_lite/include/ability_mgr_handler.h new file mode 100644 index 0000000..91b3a19 --- /dev/null +++ b/services/abilitymgr_lite/include/ability_mgr_handler.h @@ -0,0 +1,63 @@ +/* + * Copyright (c) 2020 Huawei Device Co., Ltd. + * 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 OHOS_ABILITY_MANAGER_SERVICE_IMPL_H +#define OHOS_ABILITY_MANAGER_SERVICE_IMPL_H + +#include "ability_connect_trans_param.h" +#include "ability_worker.h" +#include "client/ability_dump_client.h" +#include "client/bundlems_client.h" +#include "message.h" +#include "nocopyable.h" + +namespace OHOS { +class AbilityMgrHandler : public NoCopyable { +public: + static AbilityMgrHandler &GetInstance() + { + static AbilityMgrHandler instance; + return instance; + } + ~AbilityMgrHandler() = default; + void Init(); + void ServiceMsgProcess(const Request& request); +private: + AbilityMgrHandler() = default; + void OnServiceInited(); + void StartKeepAliveApps(); + void StartKeepAliveApp(const BundleInfo &bundleInfo); + void StartLauncher(); + int StartAbility(const Want *want, pid_t callingUid); + void AttachBundle(AbilityThreadClient *client); + void TerminateAbility(const uint64_t *token); + void AbilityTransaction(TransactionState *state); + void TerminateApp(const char *bundleName); + void RestartApp(const char *bundleName); + + int ConnectAbility(AbilityConnectTransParam *transParam); + void DisconnectAbility(AbilityConnectTransParam *transParam); + void ConnectAbilityDone(AbilityConnectTransParam *transParam); + void DisconnectAbilityDone(const uint64_t *token); + void TerminateService(Want *want, pid_t callingUid); + void StartAbilityCallback(const Want *want, int code); + void DumpAbility(const AbilityDumpClient *client); + void ConnectAbilityCallback(AbilityConnectTransParam *transParam, int code); + + AbilityWorker abilityWorker_; + BundleMsClient bundleMsClient_; +}; +} // namespace OHOS +#endif // OHOS_ABILITY_MANAGER_SERVICE_IMPL_H diff --git a/services/abilitymgr_lite/include/ability_mgr_service.h b/services/abilitymgr_lite/include/ability_mgr_service.h new file mode 100755 index 0000000..fdba479 --- /dev/null +++ b/services/abilitymgr_lite/include/ability_mgr_service.h @@ -0,0 +1,46 @@ +/* + * Copyright (c) 2020 Huawei Device Co., Ltd. + * 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 OHOS_ABILITYMGRSERVICE_SERVICE_H +#define OHOS_ABILITYMGRSERVICE_SERVICE_H + +#include "service.h" + +#include "nocopyable.h" + +namespace OHOS { +class AbilityMgrService : public Service { +public: + static AbilityMgrService *GetInstance() + { + static AbilityMgrService instance; + return &instance; + } + ~AbilityMgrService() = default; + const Identity *GetIdentity(); + +private: + AbilityMgrService(); + static const char *GetServiceName(Service *service); + static BOOL ServiceInitialize(Service *service, Identity identity); + static TaskConfig GetServiceTaskConfig(Service *service); + static BOOL ServiceMessageHandle(Service *service, Request *request); + +private: + Identity identity_; + DISALLOW_COPY_AND_MOVE(AbilityMgrService); +}; +} // namespace OHOS +#endif // OHOS_ABILITYMGRSERVICE_SERVICE_H diff --git a/services/abilitymgr_lite/include/ability_mgr_slite_feature.h b/services/abilitymgr_lite/include/ability_mgr_slite_feature.h new file mode 100755 index 0000000..9a37fd1 --- /dev/null +++ b/services/abilitymgr_lite/include/ability_mgr_slite_feature.h @@ -0,0 +1,57 @@ +/* + * Copyright (c) 2021 Huawei Device Co., Ltd. + * 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 OHOS_ABILITYMANAGERSERVICE_SLITE_FEATURE_H +#define OHOS_ABILITYMANAGERSERVICE_SLITE_FEATURE_H + +#include "ability_service.h" +#include "ability_service_interface.h" +#include "feature.h" +#include "iproxy_client.h" +#include "iunknown.h" +#include "nocopyable.h" + +namespace OHOS { +class AbilityMgrSliteFeature : public Feature { +public: + static int32 StartAbility(const Want *want); + static int32 TerminateAbility(uint64_t token); + static int32 SchedulerLifecycleDone(uint64_t token, int state); + + static AbilityMgrSliteFeature *GetInstance() + { + static AbilityMgrSliteFeature instance; + return &instance; + } + ~AbilityMgrSliteFeature() = default; +private: + AbilityMgrSliteFeature(); + static const char *GetFeatureName(Feature *feature); + static void OnFeatureInitialize(Feature *feature, Service *parent, Identity identity); + static void OnFeatureStop(Feature *feature, Identity identity); + static BOOL OnFeatureMessage(Feature *feature, Request *request); + +private: + Identity identity_; + AbilityService *abilityService_; + DISALLOW_COPY_AND_MOVE(AbilityMgrSliteFeature); +}; + +typedef struct { + INHERIT_IUNKNOWNENTRY(AmsSliteInterface); + AbilityMgrSliteFeature *ams; +} AbilityMgrSliteFeatureImpl; +} // namespace OHOS +#endif // OHOS_ABILITYMANAGERSERVICE_SLITE_FEATURE_H diff --git a/services/abilitymgr_lite/include/ability_mission_record.h b/services/abilitymgr_lite/include/ability_mission_record.h new file mode 100644 index 0000000..b3e3f06 --- /dev/null +++ b/services/abilitymgr_lite/include/ability_mission_record.h @@ -0,0 +1,55 @@ +/* + * Copyright (c) 2020 Huawei Device Co., Ltd. + * 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 OHOS_ABILITY_MISSION_RECORD_H +#define OHOS_ABILITY_MISSION_RECORD_H + +#include + +#include "ability_connect_mission.h" +#include "page_ability_record.h" + +namespace OHOS { +class AbilityMissionStack; +class AbilityMissionRecord { +public: + AbilityMissionRecord(AbilityMissionStack *missionStack, const char *bundleName); + ~AbilityMissionRecord(); + bool IsEmpty() const; + bool IsSameMissionRecord(const char *bundleName) const; + void SetMissionStack(AbilityMissionStack *missionStack); + const AbilityMissionStack *GetMissionStack() const; + const PageAbilityRecord *GetTopPageAbility() const; + const PageAbilityRecord *GetBottomPageAbility() const; + PageAbilityRecord *FindPageAbility(uint64_t token) const; + PageAbilityRecord *FindPageAbility(const Want &want) const; + PageAbilityRecord *GetPrevPageAbility(const PageAbilityRecord ¤t) const; + void PushPageAbility(PageAbilityRecord &abilityRecord); + void RemovePageAbility(const PageAbilityRecord &target); + void ClearPageAbility(); + void ClearPageAbility(AbilityConnectMission *connectMission); + void SetPrevMissionRecord(const AbilityMissionRecord *missionRecord); + const AbilityMissionRecord *GetPrevMissionRecord() const; +#ifdef OHOS_DEBUG + AbilityMsStatus DumpMissionRecord() const; +#endif +private: + AbilityMissionStack *abilityMissionStack_ { nullptr }; + std::list pageAbilityRecords_; + const AbilityMissionRecord *prevMissionRecord_ { nullptr }; + const char *bundleName_ { nullptr }; +}; +} // namespace OHOS +#endif // OHOS_ABILITY_MISSION_RECORD_H diff --git a/services/abilitymgr_lite/include/ability_mission_stack.h b/services/abilitymgr_lite/include/ability_mission_stack.h new file mode 100644 index 0000000..c3a0f7c --- /dev/null +++ b/services/abilitymgr_lite/include/ability_mission_stack.h @@ -0,0 +1,54 @@ +/* + * Copyright (c) 2020 Huawei Device Co., Ltd. + * 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 OHOS_ABILITY_MISSION_STACK_H +#define OHOS_ABILITY_MISSION_STACK_H + +#include + +#include "ability_connect_mission.h" +#include "ability_mission_record.h" + +namespace OHOS { +typedef enum { + LAUNCHER, + DEFAULT, +} StackType; +class AbilityMissionStack { +public: + explicit AbilityMissionStack(StackType type); + ~AbilityMissionStack(); + StackType GetStackType() const; + // MissionRecord + void PushTopMissionRecord(AbilityMissionRecord &missionRecord); + void MoveMissionRecordToTop(AbilityMissionRecord &missionRecord); + AbilityMissionRecord *GetTargetMissionRecord(const char *bundleName) const; + const AbilityMissionRecord *GetTopMissionRecord() const; + void RemoveMissionRecord(AbilityMissionRecord &missionRecord); + void RemoveMissionRecord(AbilityConnectMission *connectMission, const char *bundleName); + bool IsTopMissionRecord(const char *bundleName) const; + // PageAbilityRecord + PageAbilityRecord *FindPageAbility(uint64_t token) const; + PageAbilityRecord *FindPageAbility(const Want &want) const; + const PageAbilityRecord *GetTopPageAbility() const; +#ifdef OHOS_DEBUG + AbilityMsStatus DumpMissionStack() const; +#endif +private: + std::list missionRecords_; + StackType stackType_; +}; +} // namespace OHOS +#endif // OHOS_ABILITY_MISSION_STACK_H diff --git a/services/abilitymgr_lite/include/ability_record.h b/services/abilitymgr_lite/include/ability_record.h new file mode 100755 index 0000000..f52d325 --- /dev/null +++ b/services/abilitymgr_lite/include/ability_record.h @@ -0,0 +1,165 @@ +/* + * Copyright (c) 2020 Huawei Device Co., Ltd. + * 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 OHOS_ABILITY_RECORD_H +#define OHOS_ABILITY_RECORD_H + +#ifdef APP_PLATFORM_WATCHGT +#include "cmsis_os.h" +#endif +#include "ability_info.h" + +namespace OHOS { +class JsAppHost; + +constexpr int FAIL_CALLBACK_ERRORCODE = 200; + +/* States-feedback from launcher to AMS */ +typedef enum { + SCHEDULE_INITED, + SCHEDULE_INACTIVE, + SCHEDULE_ACTIVE, + SCHEDULE_BACKGROUND, + SCHEDULE_STOP +} AbilityState; + +typedef enum { + STATE_JS_RUNNING, + STATE_NATIVE_RUNNING, + STATE_JS_JUMP_NATIVE, + STATE_NATIVE_JUMP_JS, + STATE_JS_JUMP_JS, +} AppState; + +class AbilityRecord { +public: + AbilityRecord(); + ~AbilityRecord(); + + void SetAppName(const char *appName); + const char *GetAppName() const + { + return appName_; + } + + void SetAppPath(const char *appPath); + const char *GetAppPath() const + { + return appPath_; + } + + void SetAppData(const void *appData, uint16_t dataLength); + const void *GetAppData() const + { + return appData_; + } + + void SetAbilityInfo(const AbilityInfo abilityInfo) + { + abilityInfo_ = abilityInfo; + } + + AbilityInfo GetAbilityInfo() const + { + return abilityInfo_; + } + + uint16_t GetDataLength() const + { + return dataLength_; + } + + void SetState(const AbilityState state) + { + state_ = state; + } + + AbilityState GetState() const + { + return state_; + } + + bool IsAttached() const + { + return state_ != SCHEDULE_STOP; + } + + void SetToken(uint16_t token) + { + token_ = token; + } + uint16_t GetToken() const + { + return token_; + } + + void SetTaskId(UINT32 taskId) + { + taskId_ = taskId; + } + + UINT32 GetTaskId() const + { + return taskId_; + } + + void SetTerminated(bool isTerminated) + { + isTerminated_ = isTerminated; + } + + bool IsTerminated() const + { + return isTerminated_; + } + + void SetMessageQueueId(const osMessageQueueId_t jsAppQueueId) + { + jsAppQueueId_ = jsAppQueueId; + } + + const osMessageQueueId_t& GetMessageQueueId() const + { + return jsAppQueueId_; + } + + void SetJsAppHost(const JsAppHost *jsAppHost) + { + jsAppHost_ = const_cast(jsAppHost); + } + + const JsAppHost *GetJsAppHost() const + { + return jsAppHost_; + } + + static void CopyAbilityRecord(AbilityRecord &abilityRecord, AbilityRecord &newAbilityRecord); + +private: + char *appName_ { nullptr }; + char *appPath_ { nullptr }; + AbilityInfo abilityInfo_; + void *appData_ { nullptr }; + uint16_t dataLength_ { 0 }; + AbilityState state_ { SCHEDULE_STOP }; + uint16_t token_ { 0 }; + UINT32 taskId_ { 0 }; + osMessageQueueId_t jsAppQueueId_ { nullptr }; + JsAppHost *jsAppHost_ { nullptr }; + bool isTerminated_ = false; +}; +} // namespace OHOS + +#endif // OHOS_ABILITY_RECORD_H diff --git a/services/abilitymgr_lite/include/ability_service.h b/services/abilitymgr_lite/include/ability_service.h new file mode 100755 index 0000000..02e9a34 --- /dev/null +++ b/services/abilitymgr_lite/include/ability_service.h @@ -0,0 +1,77 @@ +/* + * Copyright (c) 2020 Huawei Device Co., Ltd. + * 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 OHOS_ABILITY_SERVICE_H +#define OHOS_ABILITY_SERVICE_H + +#include + +#include "ability_list.h" +#include "ability_record.h" +#include "ability_stack.h" +#include "adapter.h" +#include "js_app_host.h" +#include "nocopyable.h" +#include "want.h" +#include "slite_ability.h" + +namespace OHOS { +struct AbilitySvcInfo { + char *bundleName; + char *path; + void *data; + uint16_t dataLength; +}; + +class AbilityService : public NoCopyable { +public: + static AbilityService& GetInstance() + { + static AbilityService instance; + return instance; + } + ~AbilityService() override; + int32_t StartAbility(const Want *want); + int32_t TerminateAbility(uint16_t token); + int32_t SchedulerLifecycleDone(uint64_t token, int32_t state); + void setNativeAbility(const SliteAbility *ability); + void StartLauncher(); + void CleanWant(); + Want *want_ = nullptr; + +private: + static uint16_t GenerateToken(); + AbilityService(); + int32_t StartAbility(AbilitySvcInfo *info); + int32_t PreCheckStartAbility(const char *bundleName, const char *path, const void *data, uint16_t dataLength); + bool CheckResponse(const char *bundleName); + int32_t SchedulerLifecycle(uint64_t token, int32_t state); + int32_t SchedulerLifecycleInner(const AbilityRecord *record, int32_t state); + void SchedulerAbilityLifecycle(SliteAbility *ability, const Want &want, int32_t state); + int32_t CreateAppTask(AbilityRecord *record); + void OnActiveDone(uint16_t token); + void OnBackgroundDone(uint16_t token); + void OnDestroyDone(uint16_t token); + void DeleteRecordInfo(uint16_t token); + bool SendMsgToJsAbility(int32_t msgId, const AbilityRecord *record); + void SetAbilityState(uint64_t token, int32_t state); + void UpdataRecord(AbilitySvcInfo *info); + + uint16_t pendingToken_ { 0 }; + AbilityList abilityList_ {}; + AbilityStack abilityStack_ {}; +}; +} // namespace OHOS +#endif // OHOS_ABILITY_SERVICE_H diff --git a/services/abilitymgr_lite/include/ability_stack.h b/services/abilitymgr_lite/include/ability_stack.h new file mode 100755 index 0000000..f5df036 --- /dev/null +++ b/services/abilitymgr_lite/include/ability_stack.h @@ -0,0 +1,38 @@ +/* + * Copyright (c) 2020 Huawei Device Co., Ltd. + * 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 OHOS_ABILITY_STACK_H +#define OHOS_ABILITY_STACK_H + +#include "ability_record.h" +#include "utils_list.h" +#include + +namespace OHOS { +class AbilityStack { +public: + AbilityStack() = default; + ~AbilityStack() = default; + + const AbilityRecord *GetTopAbility() const; + int GetAllAbilities(AbilityRecord **abilityRecords); + void PushAbility(AbilityRecord *record); + void PopAbility(); + +private: + List abilityStack_ {}; +}; +} // namespace OHOS +#endif // OHOS_ABILITY_STACK_H diff --git a/services/abilitymgr_lite/include/ability_stack_manager.h b/services/abilitymgr_lite/include/ability_stack_manager.h new file mode 100644 index 0000000..f7fa0a9 --- /dev/null +++ b/services/abilitymgr_lite/include/ability_stack_manager.h @@ -0,0 +1,58 @@ +/* + * Copyright (c) 2020 Huawei Device Co., Ltd. + * 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 OHOS_ABILITY_STACK_MANAGER_H +#define OHOS_ABILITY_STACK_MANAGER_H + +#include + +#include "ability_mission_stack.h" +#include "ability_mgr_context.h" +#include "ability_info.h" +#include "bundle_info.h" +#include "nocopyable.h" +#include "want.h" + +namespace OHOS { +class AbilityStackManager : public NoCopyable { +public: + static AbilityStackManager &GetInstance() + { + static AbilityStackManager instance; + return instance; + }; + ~AbilityStackManager() = default; + + PageAbilityRecord *GeneratePageAbility(const AbilityInfo &target, + const Want &want, const PageAbilityRecord *topAbility, AbilityMgrContext &amsContext) const; + PageAbilityRecord *FindPageAbility(const AbilityMgrContext &amsContext, uint64_t token) const; + const PageAbilityRecord *FindPageAbility(const AbilityMgrContext &amsContext, const Want &want) const; + const PageAbilityRecord *GetTopPageAbility(const AbilityMgrContext &amsContext) const; + const PageAbilityRecord *GetPrevPageAbility(const AbilityMgrContext &amsContext, + const PageAbilityRecord ¤t) const; + void RemovePageAbility(const PageAbilityRecord &target, AbilityMgrContext &amsContext); + bool ExistAppInStack(const AbilityInfo &target, AbilityMgrContext &amsContext) const; + void ClearAbilityStack(const char *bundleName, AbilityMgrContext &amsContext) const; +#ifdef OHOS_DEBUG + AbilityMsStatus DumpAllAbilityRecord(const AbilityMgrContext &amsContext) const; +#endif + PageAbilityRecord *FindServiceAbility(const AbilityMgrContext &amsContext, uint64_t token) const; + PageAbilityRecord *FindServiceAbility(const AbilityMgrContext &amsContext, const char *bundleName, + const char *abilityName) const; +private: + AbilityStackManager() = default; +}; +} // namespace OHOS +#endif // OHOS_ABILITY_STACK_MANAGER_H diff --git a/services/abilitymgr_lite/include/ability_worker.h b/services/abilitymgr_lite/include/ability_worker.h new file mode 100644 index 0000000..3a644cc --- /dev/null +++ b/services/abilitymgr_lite/include/ability_worker.h @@ -0,0 +1,49 @@ +/* + * Copyright (c) 2020 Huawei Device Co., Ltd. + * 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 OHOS_ABILITY_WORKER_H +#define OHOS_ABILITY_WORKER_H + +#include "ability_connect_trans_param.h" +#include "ability_mgr_context.h" +#include "client/ability_thread_client.h" +#include "client/ability_dump_client.h" + +namespace OHOS { +class AbilityWorker { +public: + AbilityWorker(); + ~AbilityWorker(); + + AbilityMsStatus StartAbility(const Want &want, const AbilityInfo &target, const BundleInfo &bundleInfo, pid_t uid); + AbilityMsStatus AttachBundle(const AbilityThreadClient &client); + AbilityMsStatus TerminateAbility(uint64_t token); + AbilityMsStatus AbilityTransaction(const TransactionState &state); + AbilityMsStatus TerminateApp(const char *bundleName); + AbilityMsStatus RestartApp(const BundleInfo &bundleInfo); + AbilityMsStatus DumpAbility(const AbilityDumpClient &client); + + AbilityMsStatus TerminateService(const AbilityInfo &target, const BundleInfo &bundleInfo, pid_t callingUid); + AbilityMsStatus ConnectAbility(const AbilityConnectTransParam &connectParam, const AbilityInfo &target, + const BundleInfo &bundleInfo); + AbilityMsStatus DisconnectAbility(const SvcIdentity &identity, uint64_t token); + AbilityMsStatus ConnectAbilityDone(const SvcIdentity &identity, uint64_t token); + AbilityMsStatus DisconnectAbilityDone(uint64_t token); + +private: + AbilityMgrContext *abilityMgrContext_ { nullptr }; +}; +} // namespace OHOS +#endif // OHOS_ABILITY_WORKER_H diff --git a/services/abilitymgr_lite/include/app_manager.h b/services/abilitymgr_lite/include/app_manager.h new file mode 100644 index 0000000..fd8821b --- /dev/null +++ b/services/abilitymgr_lite/include/app_manager.h @@ -0,0 +1,47 @@ +/* + * Copyright (c) 2020 Huawei Device Co., Ltd. + * 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 FOUNDATION_APP_MANAGER_H +#define FOUNDATION_APP_MANAGER_H + +#include + +#include "app_record.h" +#include "bundle_info.h" +#include "client/app_spawn_client.h" +#include "nocopyable.h" + +namespace OHOS { +class AppManager : public NoCopyable { +public: + static AppManager &GetInstance() + { + static AppManager instance; + return instance; + } + ~AppManager() = default; + AppRecord *StartAppProcess(const BundleInfo &bundleInfo); + AbilityMsStatus TerminateAppProcess(const char *bundleName); + const AppRecord *GetAppRecordByToken(uint64_t token, pid_t callingPid); + AppRecord *GetAppRecordByBundleName(const char *bundleName); + void RemoveAppRecord(const AppRecord &appRecord); + void RemoveAppRecord(const char *bundleName); +private: + AppManager() = default; + AppSpawnClient spawnClient_; + std::vector appRecords_; +}; +} // namespace OHOS +#endif // FOUNDATION_APP_MANAGER_H diff --git a/services/abilitymgr_lite/include/app_record.h b/services/abilitymgr_lite/include/app_record.h new file mode 100644 index 0000000..8a47451 --- /dev/null +++ b/services/abilitymgr_lite/include/app_record.h @@ -0,0 +1,60 @@ +/* + * Copyright (c) 2020 Huawei Device Co., Ltd. + * 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 OHOS_APP_RECORD_H +#define OHOS_APP_RECORD_H + +#include "bundle_info.h" +#include "client/ability_thread_client.h" + +namespace OHOS { +class PageAbilityRecord; +class AppRecord { +public: + AppRecord(const BundleInfo& bundleInfo, uint64_t identityId); + ~AppRecord(); + + void SetPid(pid_t pid); + pid_t GetPid() const; + uint64_t GetIdentityId() const; + const BundleInfo &GetBundleInfo() const; + + AbilityMsStatus LoadPermission() const; + void UnloadPermission() const; + AbilityMsStatus QueryAppCapability(const char *bundleName, uint32_t **caps, uint32_t *capNums); + AbilityMsStatus SetAbilityThreadClient(const AbilityThreadClient &client); + AbilityMsStatus AbilityTransaction(const TransactionState &state, + const Want &want, AbilityType abilityType) const; + AbilityMsStatus AppInitTransaction() const; + AbilityMsStatus AppExitTransaction() const; + AbilityMsStatus DumpAbilityTransaction(const Want &want, uint64_t token) const; + void SetPendingAbility(PageAbilityRecord *abilityRecord); + AbilityMsStatus LaunchPendingAbility(); + + AbilityMsStatus ConnectTransaction(const Want &want, uint64_t token) const; + AbilityMsStatus DisconnectTransaction(const Want &want, uint64_t token) const; + AbilityMsStatus ConnectDoneTransaction(const Want &want, const SvcIdentity &serviceSid, + const SvcIdentity &connectSid) const; + AbilityMsStatus DisconnectDoneTransaction(const Want &want, const SvcIdentity &connectSid) const; + void ClearPendingAbility(PageAbilityRecord *abilityRecord); +private: + pid_t pid_ { 0 }; + uint64_t identityId_ { 0 }; + BundleInfo bundleInfo_ {}; + AbilityThreadClient *abilityThreadClient_ { nullptr }; + PageAbilityRecord *pendingAbilityRecord_ { nullptr }; +}; +} // namespace OHOS +#endif // OHOS_APP_RECORD_H diff --git a/services/abilitymgr_lite/include/client/ability_dump_client.h b/services/abilitymgr_lite/include/client/ability_dump_client.h new file mode 100755 index 0000000..6783363 --- /dev/null +++ b/services/abilitymgr_lite/include/client/ability_dump_client.h @@ -0,0 +1,35 @@ +/* + * Copyright (c) 2020 Huawei Device Co., Ltd. + * 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 OHOS_DUMP_ABILITY_CLIENT_H +#define OHOS_DUMP_ABILITY_CLIENT_H + +#include "liteipc_adapter.h" +#include "util/abilityms_status.h" +#include "want.h" + +namespace OHOS { +class AbilityDumpClient { +public: + explicit AbilityDumpClient(const Want &want); + ~AbilityDumpClient(); + + const Want &GetWant() const; + AbilityMsStatus AbilityDumpTransaction(const char *info) const; +private: + Want want_ = {}; +}; +} // namespace OHOS +#endif // OHOS_DUMP_ABILITY_CLIENT_H diff --git a/services/abilitymgr_lite/include/client/ability_thread_client.h b/services/abilitymgr_lite/include/client/ability_thread_client.h new file mode 100755 index 0000000..5b3f4b2 --- /dev/null +++ b/services/abilitymgr_lite/include/client/ability_thread_client.h @@ -0,0 +1,64 @@ +/* + * Copyright (c) 2020 Huawei Device Co., Ltd. + * 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 OHOS_ABILITY_THREAD_CLIENT_H +#define OHOS_ABILITY_THREAD_CLIENT_H + +#include "bundle_info.h" +#include "liteipc_adapter.h" +#include "util/abilityms_status.h" +#include "want.h" + +namespace OHOS { +typedef struct { + uint64_t token; + int32_t state; +} TransactionState; + +typedef struct { + char *bundleName; + SvcIdentity svcIdentity; +} AppInfo; + +class AbilityRecord; +class AbilityThreadClient { +public: + AbilityThreadClient(uint64_t token, pid_t callingPid, const SvcIdentity &svcIdentity, IpcMsgHandler handler); + AbilityThreadClient(const AbilityThreadClient &client); + ~AbilityThreadClient(); + + AbilityMsStatus Initialize(const char *bundleName); + uint64_t GetToken() const; + pid_t GetPid() const; + const SvcIdentity &GetSvcIdentity() const; + AbilityMsStatus AbilityTransaction(const TransactionState &state, const Want &want, AbilityType abilityType) const; + AbilityMsStatus AppInitTransaction(const BundleInfo &bundleInfo); + AbilityMsStatus AppExitTransaction(); + AbilityMsStatus ConnectAbility(const Want &want, uint64_t token) const; + AbilityMsStatus DisconnectAbility(const Want &want, uint64_t token) const; + AbilityMsStatus ConnectAbilityDone(const Want &want, const SvcIdentity &serviceSid, + const SvcIdentity &connectSid) const; + AbilityMsStatus DisconnectAbilityDone(const Want &want, const SvcIdentity &connectSid) const; + AbilityMsStatus DumpAbilityTransaction(const Want &want, uint64_t token); +private: + uint64_t token_ = -1; + pid_t pid_ = -1; + uint32_t cbid_ = -1; + const SvcIdentity svcIdentity_; + const IpcMsgHandler deathHandler_; + static const int MAX_OBJECTS = 2; +}; +} // namespace OHOS +#endif // OHOS_ABILITY_THREAD_CLIENT_H diff --git a/services/abilitymgr_lite/include/client/app_spawn_client.h b/services/abilitymgr_lite/include/client/app_spawn_client.h new file mode 100644 index 0000000..a8e3f5c --- /dev/null +++ b/services/abilitymgr_lite/include/client/app_spawn_client.h @@ -0,0 +1,35 @@ +/* + * Copyright (c) 2020 Huawei Device Co., Ltd. + * 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 OHOS_APP_SPAWN_CLIENT_H +#define OHOS_APP_SPAWN_CLIENT_H + +#include "app_record.h" +#include "iproxy_client.h" +#include "util/abilityms_status.h" + +namespace OHOS { +class AppSpawnClient { +public: + AppSpawnClient() = default; + ~AppSpawnClient() = default; + AbilityMsStatus SpawnProcess(AppRecord &appRecord); + AbilityMsStatus CallingInnerSpawnProcess(char *spawnMessage, AppRecord &appRecord); +private: + AbilityMsStatus Initialize(); + IClientProxy *spawnClient_ { nullptr }; +}; +} +#endif // OHOS_APP_SPAWN_CLIENT_H diff --git a/services/abilitymgr_lite/include/client/bundlems_client.h b/services/abilitymgr_lite/include/client/bundlems_client.h new file mode 100644 index 0000000..7ac37cd --- /dev/null +++ b/services/abilitymgr_lite/include/client/bundlems_client.h @@ -0,0 +1,37 @@ +/* + * Copyright (c) 2020 Huawei Device Co., Ltd. + * 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 OHOS_BUNDLEMS_CLIENT_H +#define OHOS_BUNDLEMS_CLIENT_H + +#include "bundle_inner_interface.h" +#include "util/abilityms_status.h" + +namespace OHOS { +class BundleMsClient { +public: + BundleMsClient() = default; + ~BundleMsClient(); + AbilityMsStatus Initialize(); + + AbilityMsStatus QueryAbilityInfo(const Want *want, AbilityInfo *result) const; + AbilityMsStatus QueryBundleInfo(const char* bundleName, BundleInfo *bundleInfo) const; + AbilityMsStatus QueryKeepAliveBundleInfos(BundleInfo **bundleInfos, int32_t *len) const; + +private: + BmsServerProxy *bmsServerProxy_ { nullptr }; +}; +} +#endif // OHOS_BUNDLEMS_CLIENT_H diff --git a/services/abilitymgr_lite/include/client/wms_client.h b/services/abilitymgr_lite/include/client/wms_client.h new file mode 100644 index 0000000..dfbe301 --- /dev/null +++ b/services/abilitymgr_lite/include/client/wms_client.h @@ -0,0 +1,29 @@ +/* + * Copyright (c) 2020 Huawei Device Co., Ltd. + * 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 OHOS_WMS_CLIENT_H +#define OHOS_WMS_CLIENT_H + +namespace OHOS { +class WMSClient { +public: + WMSClient() = default; + ~WMSClient() = default; +#ifdef ABILITY_WINDOW_SUPPORT + static void WaitUntilWmsReady(); +#endif +}; +} +#endif // OHOS_WMS_CLIENT_H diff --git a/services/abilitymgr_lite/include/js_app_host.h b/services/abilitymgr_lite/include/js_app_host.h new file mode 100755 index 0000000..bcd1bb3 --- /dev/null +++ b/services/abilitymgr_lite/include/js_app_host.h @@ -0,0 +1,57 @@ +/* + * Copyright (c) 2020 Huawei Device Co., Ltd. + * 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 OHOS_JS_APP_HOST_H +#define OHOS_JS_APP_HOST_H + +#include "cmsis_os2.h" +#include "js_ability.h" +#include "js_async_work.h" + +namespace OHOS { +class JsAppHost { +public: + JsAppHost(); + ~JsAppHost(); + + static void JsAppTaskHandler(uint32_t uwArg); + + void SetMessageQueueId(const osMessageQueueId_t jsAppQueueId) + { + jsAppQueueId_ = jsAppQueueId; + ACELite::JsAsyncWork::SetAppQueueHandler(reinterpret_cast(jsAppQueueId)); + } + + const osMessageQueueId_t &GetMessageQueueId() const + { + return jsAppQueueId_; + } + + void ForceDestroy() const; + +private: + void OnActive(uint16_t token, const char *bundleName, const char *path); + void OnBackground(uint16_t token); + void OnDestroy(uint16_t token); + void BackPressed(); + void SendMsgToAbilityService(uint16_t token, int32_t id); + void HandleTickEvent(); + + ACELite::JSAbility *jsAbility_ = nullptr; + osMessageQueueId_t jsAppQueueId_ = {nullptr}; + bool isBackground_ = false; +}; +} // namespace OHOS +#endif // OHOS_JS_APP_HOST_H diff --git a/services/abilitymgr_lite/include/page_ability_record.h b/services/abilitymgr_lite/include/page_ability_record.h new file mode 100755 index 0000000..55f4308 --- /dev/null +++ b/services/abilitymgr_lite/include/page_ability_record.h @@ -0,0 +1,120 @@ +/* + * Copyright (c) 2020 Huawei Device Co., Ltd. + * 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 OHOS_ABILITY_RECORD_NEW_H +#define OHOS_ABILITY_RECORD_NEW_H + +#include + +#include "ability_connect_record.h" +#include "ability_state.h" +#include "app_record.h" +#include "serializer.h" + +namespace OHOS { +class AbilityConnectMission; +class AbilityMissionRecord; +class PageAbilityRecord { +public: + PageAbilityRecord(const AbilityInfo &abilityInfo, const Want &want); + ~PageAbilityRecord(); + + // AbilityInfo + const AbilityInfo& GetAbilityInfo() const; + bool IsLauncherAbility() const; + void SetCurrentState(State state); + State GetCurrentState() const; + uint64_t GetToken() const; + + // Util + bool IsSamePageAbility(const PageAbilityRecord &target) const; + bool IsSamePageAbility(const Want &want) const; + bool IsSamePageAbility(const char *bundleName) const; + bool IsBottomPageAbility() const; + + // BundleInfo + const BundleInfo& GetBundleInfo() const; + void SetBundleInfo(const BundleInfo &bundleInfo); + + // LifeCycle + AbilityMsStatus StartAbility(); + AbilityMsStatus ActiveAbility(); + AbilityMsStatus InactiveAbility() const; + AbilityMsStatus ToBackgroundAbility() const; + AbilityMsStatus StopAbility() const; + AbilityMsStatus ExitApp(); + + // MissionRecord + void SetMissionRecord(AbilityMissionRecord *missionRecord); + const AbilityMissionRecord *GetMissionRecord() const; + + // Getter and Setter next and prev ability + void SetNextPageAbility(PageAbilityRecord *next); + const PageAbilityRecord *GetNextPageAbility() const; + void SetPrevPageAbility(PageAbilityRecord *prev); + const PageAbilityRecord *GetPrevPageAbility() const; + + // connect service ability + void SetConnectMission(AbilityConnectMission *connectMission); + const AbilityConnectMission *GetConnectMission() const; + void SetServiceSid(const SvcIdentity& serviceSid); + const SvcIdentity GetServiceSid() const; + ConnectStatus GetConnectStatus() const; + void SetConnectStatus(ConnectStatus connectStatus); + void SetStartDone(bool startDone); + AbilityConnectRecord *GetConnectRecord(const SvcIdentity &serviceSid) const; + void pushConnectRecord(AbilityConnectRecord *connectRecord); + void RemoveConnectRecord(const SvcIdentity &serviceSid); + bool IsPerformStop() const; + AbilityConnectRecord *GetConnectRecord(const SvcIdentity &serviceSid, uint64_t abilityToken) const; + + AbilityMsStatus StartService(); + AbilityMsStatus ConnectAbility(); + AbilityMsStatus DisconnectAbility(const SvcIdentity &connectSid); + AbilityMsStatus ConnectAbilityDone(); + AbilityMsStatus DisconnectAbilityDone(); + AbilityMsStatus ForceStopServiceAbility(); + AbilityMsStatus StopAbilityDone(); + void RemoveConnectRecordByPageToken(uint64_t token); + + // Dump +#ifdef OHOS_DEBUG + AbilityMsStatus DumpAbilityRecord() const; +#endif + AbilityMsStatus DumpAbilitySlice(const Want &want) const; +private: + void Initialize(); + + AbilityMissionRecord *missionRecord_ { nullptr }; + PageAbilityRecord *nextPageAbility_ { nullptr }; + PageAbilityRecord *prevPageAbility_ { nullptr }; + + AppRecord *appRecord_ { nullptr }; + AbilityInfo abilityInfo_ = {}; + BundleInfo bundleInfo_ = {}; + Want want_ = {}; + State currentState_ = STATE_UNINITIALIZED; + uint64_t token_ { 0 }; + + bool startDone_ = false; + SvcIdentity serviceSid_ = { 0, 0 }; + ConnectStatus connectStatus_ = ConnectStatus::INIT; + bool forceStop_ = false; + + AbilityConnectMission *connectMission_ { nullptr }; + std::list connectRecords_; +}; +} +#endif // OHOS_ABILITY_RECORD_NEW_H diff --git a/services/abilitymgr_lite/include/task/ability_activate_task.h b/services/abilitymgr_lite/include/task/ability_activate_task.h new file mode 100644 index 0000000..e174e43 --- /dev/null +++ b/services/abilitymgr_lite/include/task/ability_activate_task.h @@ -0,0 +1,36 @@ +/* + * Copyright (c) 2020 Huawei Device Co., Ltd. + * 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 OHOS_ABILITY_ACTIVATE_TASK_H +#define OHOS_ABILITY_ACTIVATE_TASK_H + +#include "ability_task.h" + +namespace OHOS { +class AbilityMgrContext; + +class AbilityActivateTask : public AbilityTask { +public: + AbilityActivateTask(AbilityMgrContext *context, uint64_t token); + ~AbilityActivateTask() override = default; + + AbilityMsStatus Execute() override; + +private: + uint64_t token_; +}; +} // namespace OHOS + +#endif // OHOS_ABILITY_ACTIVATE_TASK_H diff --git a/services/abilitymgr_lite/include/task/ability_attach_task.h b/services/abilitymgr_lite/include/task/ability_attach_task.h new file mode 100644 index 0000000..fe16d1f --- /dev/null +++ b/services/abilitymgr_lite/include/task/ability_attach_task.h @@ -0,0 +1,33 @@ +/* + * Copyright (c) 2020 Huawei Device Co., Ltd. + * 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 OHOS_ABILITY_ATTACH_TASK_H +#define OHOS_ABILITY_ATTACH_TASK_H + +#include "ability_task.h" + +namespace OHOS { +class AbilityMgrContext; +class AbilityAttachTask : public AbilityTask { +public: + explicit AbilityAttachTask(const AbilityThreadClient *client); + ~AbilityAttachTask() override; + + AbilityMsStatus Execute() override; +private: + const AbilityThreadClient *client_ { nullptr }; +}; +} // namespace OHOS +#endif // OHOS_ABILITY_ATTACH_TASK_H diff --git a/services/abilitymgr_lite/include/task/ability_background_task.h b/services/abilitymgr_lite/include/task/ability_background_task.h new file mode 100644 index 0000000..f2fe33e --- /dev/null +++ b/services/abilitymgr_lite/include/task/ability_background_task.h @@ -0,0 +1,36 @@ +/* + Copyright (c) 2020 Huawei Device Co., Ltd. + * 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 OHOS_ABILITY_BACKGROUND_TASK_H +#define OHOS_ABILITY_BACKGROUND_TASK_H + +#include "ability_task.h" + +namespace OHOS { +class AbilityMgrContext; + +class AbilityBackgroundTask : public AbilityTask { +public: + AbilityBackgroundTask(AbilityMgrContext *context, uint64_t token); + ~AbilityBackgroundTask() override = default; + + AbilityMsStatus Execute() override; + +private: + uint64_t token_; +}; +} // namespace OHOS + +#endif // OHOS_ABILITY_BACKGROUND_TASK_H diff --git a/services/abilitymgr_lite/include/task/ability_connect_done_task.h b/services/abilitymgr_lite/include/task/ability_connect_done_task.h new file mode 100644 index 0000000..c12af18 --- /dev/null +++ b/services/abilitymgr_lite/include/task/ability_connect_done_task.h @@ -0,0 +1,37 @@ +/* + * Copyright (c) 2020 Huawei Device Co., Ltd. + * 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 OHOS_ABILITY_CONNECT_DONE_TASK_H +#define OHOS_ABILITY_CONNECT_DONE_TASK_H + +#include "ability_task.h" + +namespace OHOS { +class AbilityMgrContext; + +class AbilityConnectDoneTask : public AbilityTask { +public: + AbilityConnectDoneTask(AbilityMgrContext *context, const SvcIdentity &serviceSid, uint64_t token); + AbilityConnectDoneTask() = delete; + ~AbilityConnectDoneTask() override = default; + + AbilityMsStatus Execute() override; +private: + SvcIdentity serviceSid_; + uint64_t token_; +}; +} // namespace OHOS + +#endif // OHOS_ABILITY_CONNECT_DONE_TASK_H diff --git a/services/abilitymgr_lite/include/task/ability_connect_task.h b/services/abilitymgr_lite/include/task/ability_connect_task.h new file mode 100644 index 0000000..5218a67 --- /dev/null +++ b/services/abilitymgr_lite/include/task/ability_connect_task.h @@ -0,0 +1,39 @@ +/* + * Copyright (c) 2020 Huawei Device Co., Ltd. + * 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 OHOS_ABILITY_CONNECT_TASK_H +#define OHOS_ABILITY_CONNECT_TASK_H + +#include "ability_task.h" + +namespace OHOS { +class AbilityMgrContext; + +class AbilityConnectTask : public AbilityTask { +public: + AbilityConnectTask(AbilityMgrContext *context, const Want &want, const SvcIdentity &identity, uint64_t token); + ~AbilityConnectTask() override = default; + + AbilityMsStatus Execute() override; +private: + AbilityMsStatus PerformConnectTask(PageAbilityRecord *service); + + Want want_; + SvcIdentity connectSid_; + uint64_t token_; +}; +} // namespace OHOS + +#endif // OHOS_ABILITY_CONNECT_TASK_H diff --git a/services/abilitymgr_lite/include/task/ability_disconnect_done_task.h b/services/abilitymgr_lite/include/task/ability_disconnect_done_task.h new file mode 100644 index 0000000..7d98a4f --- /dev/null +++ b/services/abilitymgr_lite/include/task/ability_disconnect_done_task.h @@ -0,0 +1,35 @@ +/* + * Copyright (c) 2020 Huawei Device Co., Ltd. + * 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 OHOS_ABILITY_DISCONNECT_DONE_TASK_H +#define OHOS_ABILITY_DISCONNECT_DONE_TASK_H + +#include "ability_task.h" + +namespace OHOS { +class AbilityMgrContext; + +class AbilityDisconnectDoneTask : public AbilityTask { +public: + AbilityDisconnectDoneTask(AbilityMgrContext *context, uint64_t token); + ~AbilityDisconnectDoneTask() override = default; + + AbilityMsStatus Execute() override; +private: + uint64_t token_; +}; +} // namespace OHOS + +#endif // OHOS_ABILITY_DISCONNECT_DONE_TASK_H diff --git a/services/abilitymgr_lite/include/task/ability_disconnect_task.h b/services/abilitymgr_lite/include/task/ability_disconnect_task.h new file mode 100644 index 0000000..b11c1ba --- /dev/null +++ b/services/abilitymgr_lite/include/task/ability_disconnect_task.h @@ -0,0 +1,36 @@ +/* + * Copyright (c) 2020 Huawei Device Co., Ltd. + * 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 OHOS_ABILITY_DISCONNECT_TASK_H +#define OHOS_ABILITY_DISCONNECT_TASK_H + +#include "ability_task.h" + +namespace OHOS { +class AbilityMgrContext; + +class AbilityDisconnectTask : public AbilityTask { +public: + AbilityDisconnectTask(AbilityMgrContext *context, const SvcIdentity &identity, uint64_t token); + ~AbilityDisconnectTask() override = default; + + AbilityMsStatus Execute() override; +private: + SvcIdentity identity_; + uint64_t token_; +}; +} // namespace OHOS + +#endif // OHOS_ABILITY_DISCONNECT_TASK_H diff --git a/services/abilitymgr_lite/include/task/ability_dump_task.h b/services/abilitymgr_lite/include/task/ability_dump_task.h new file mode 100644 index 0000000..c392031 --- /dev/null +++ b/services/abilitymgr_lite/include/task/ability_dump_task.h @@ -0,0 +1,34 @@ +/* + Copyright (c) 2020 Huawei Device Co., Ltd. + * 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 OHOS_ABILITY_DUMP_TASK_H +#define OHOS_ABILITY_DUMP_TASK_H + +#include "ability_task.h" +#include "ability_mgr_context.h" +#include "client/ability_dump_client.h" + +namespace OHOS { +class AbilityDumpTask : public AbilityTask { +public: + AbilityDumpTask(AbilityMgrContext *context, const AbilityDumpClient *client); + ~AbilityDumpTask() override = default; + + AbilityMsStatus Execute() override; +private: + const AbilityDumpClient *client_ { nullptr }; +}; +} // namespace OHOS +#endif // OHOS_ABILITY_DUMP_TASK_H diff --git a/services/abilitymgr_lite/include/task/ability_inactivate_task.h b/services/abilitymgr_lite/include/task/ability_inactivate_task.h new file mode 100644 index 0000000..fb78cf9 --- /dev/null +++ b/services/abilitymgr_lite/include/task/ability_inactivate_task.h @@ -0,0 +1,34 @@ +/* + * Copyright (c) 2020 Huawei Device Co., Ltd. + * 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 OHOS_ABILITY_INACTIVATE_TASK_H +#define OHOS_ABILITY_INACTIVATE_TASK_H + +#include "ability_task.h" + +namespace OHOS { +class AbilityMgrContext; +class AbilityInactivateTask : public AbilityTask { +public: + AbilityInactivateTask(AbilityMgrContext *context, uint64_t token); + ~AbilityInactivateTask() override = default; + + AbilityMsStatus Execute() override; + +private: + uint64_t token_; +}; +} // namespace OHOS +#endif // OHOS_ABILITY_INACTIVATE_TASK_H diff --git a/services/abilitymgr_lite/include/task/ability_start_task.h b/services/abilitymgr_lite/include/task/ability_start_task.h new file mode 100644 index 0000000..746ad71 --- /dev/null +++ b/services/abilitymgr_lite/include/task/ability_start_task.h @@ -0,0 +1,45 @@ +/* + * Copyright (c) 2020 Huawei Device Co., Ltd. + * 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 OHOS_ABILITY_START_TASK_H +#define OHOS_ABILITY_START_TASK_H + +#include "ability_task.h" +#include "ability_info.h" +#include "want.h" + +namespace OHOS { +class AbilityMgrContext; + +class AbilityStartTask : public AbilityTask { +public: + AbilityStartTask(AbilityMgrContext *context, const Want *want, + const AbilityInfo *target, const BundleInfo *bundleInfo); + ~AbilityStartTask() override; + + AbilityMsStatus Execute() override; + void SetWaitConnect(bool waitConnect); + +private: + AbilityMsStatus StartService(); + + const Want *want_ {}; + const AbilityInfo *target_ {}; + const BundleInfo *bundleInfo_ {}; + bool waitConnect_ = false; +}; +} // namespace OHOS + +#endif // OHOS_ABILITY_START_TASK_H diff --git a/services/abilitymgr_lite/include/task/ability_stop_task.h b/services/abilitymgr_lite/include/task/ability_stop_task.h new file mode 100644 index 0000000..2c5b587 --- /dev/null +++ b/services/abilitymgr_lite/include/task/ability_stop_task.h @@ -0,0 +1,34 @@ +/* + Copyright (c) 2020 Huawei Device Co., Ltd. + * 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 OHOS_ABILITY_STOP_TASK_H +#define OHOS_ABILITY_STOP_TASK_H + +#include "ability_task.h" + +namespace OHOS { +class AbilityMgrContext; +class AbilityStopTask : public AbilityTask { +public: + AbilityStopTask(AbilityMgrContext *context, uint64_t token); + ~AbilityStopTask() override = default; + + AbilityMsStatus Execute() override; + +private: + uint64_t token_; +}; +} // namespace OHOS +#endif // OHOS_ABILITY_STOP_TASK_H diff --git a/services/abilitymgr_lite/include/task/ability_task.h b/services/abilitymgr_lite/include/task/ability_task.h new file mode 100644 index 0000000..61597a0 --- /dev/null +++ b/services/abilitymgr_lite/include/task/ability_task.h @@ -0,0 +1,42 @@ +/* + * Copyright (c) 2020 Huawei Device Co., Ltd. + * 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 OHOS_ABILITY_TASK_H +#define OHOS_ABILITY_TASK_H + +#include "ability_stack_manager.h" +#include "util/abilityms_status.h" +#include "util/abilityms_log.h" + +namespace OHOS { +class AbilityTask { +public: + AbilityTask() = default; + explicit AbilityTask(AbilityMgrContext *context) : abilityMgrContext_(context) + { + } + virtual ~AbilityTask() + { + abilityMgrContext_ = nullptr; + } + + virtual AbilityMsStatus Execute() = 0; + +protected: + AbilityMgrContext *abilityMgrContext_ { nullptr }; +}; +} // OHOS + +#endif // OHOS_ABILITY_TASK_H diff --git a/services/abilitymgr_lite/include/task/ability_terminate_service_task.h b/services/abilitymgr_lite/include/task/ability_terminate_service_task.h new file mode 100644 index 0000000..17db72a --- /dev/null +++ b/services/abilitymgr_lite/include/task/ability_terminate_service_task.h @@ -0,0 +1,35 @@ +/* + * Copyright (c) 2020 Huawei Device Co., Ltd. + * 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 OHOS_ABILITY_TERMINATE_SERVICE_TASK_H +#define OHOS_ABILITY_TERMINATE_SERVICE_TASK_H + +#include "ability_task.h" + +namespace OHOS { +class AbilityMgrContext; + +class AbilityTerminateServiceTask : public AbilityTask { +public: + AbilityTerminateServiceTask(AbilityMgrContext *context, const AbilityInfo *target); + ~AbilityTerminateServiceTask() override; + + AbilityMsStatus Execute() override; +private: + const AbilityInfo *target_ { nullptr }; +}; +} // namespace OHOS + +#endif // OHOS_ABILITY_TERMINATE_SERVICE_TASK_H diff --git a/services/abilitymgr_lite/include/task/ability_terminate_task.h b/services/abilitymgr_lite/include/task/ability_terminate_task.h new file mode 100644 index 0000000..b5a0787 --- /dev/null +++ b/services/abilitymgr_lite/include/task/ability_terminate_task.h @@ -0,0 +1,35 @@ +/* + * Copyright (c) 2020 Huawei Device Co., Ltd. + * 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 OHOS_ABILITY_TERMINATE_TASK_H +#define OHOS_ABILITY_TERMINATE_TASK_H + +#include "ability_task.h" + +namespace OHOS { +class AbilityMgrContext; + +class AbilityTerminateTask : public AbilityTask { +public: + AbilityTerminateTask(AbilityMgrContext *context, uint64_t token); + ~AbilityTerminateTask() override = default; + + AbilityMsStatus Execute() override; + +private: + uint64_t token_; +}; +} // namespace OHOS +#endif // OHOS_ABILITY_TERMINATE_TASK_H diff --git a/services/abilitymgr_lite/include/task/app_restart_task.h b/services/abilitymgr_lite/include/task/app_restart_task.h new file mode 100644 index 0000000..677a426 --- /dev/null +++ b/services/abilitymgr_lite/include/task/app_restart_task.h @@ -0,0 +1,35 @@ +/* + * Copyright (c) 2020 Huawei Device Co., Ltd. + * 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 OHOS_APP_RESTART_TASK_H +#define OHOS_APP_RESTART_TASK_H + +#include "ability_task.h" +#include "bundle_info.h" + +namespace OHOS { +class AbilityMgrContext; + +class AppRestartTask : public AbilityTask { +public: + AppRestartTask(AbilityMgrContext *context, const BundleInfo *bundleInfo); + ~AppRestartTask() override = default; + + AbilityMsStatus Execute() override; +private: + const BundleInfo *bundleInfo_ { nullptr }; +}; +} // namespace OHOS +#endif // OHOS_APP_RESTART_TASK_H diff --git a/services/abilitymgr_lite/include/task/app_terminate_task.h b/services/abilitymgr_lite/include/task/app_terminate_task.h new file mode 100644 index 0000000..660b317 --- /dev/null +++ b/services/abilitymgr_lite/include/task/app_terminate_task.h @@ -0,0 +1,34 @@ +/* + * Copyright (c) 2020 Huawei Device Co., Ltd. + * 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 OHOS_APP_TERMINATE_TASK_H +#define OHOS_APP_TERMINATE_TASK_H + +#include "ability_task.h" + +namespace OHOS { +class AbilityMgrContext; + +class AppTerminateTask : public AbilityTask { +public: + AppTerminateTask(AbilityMgrContext *context, const char *bundleName); + ~AppTerminateTask() override = default; + + AbilityMsStatus Execute() override; +private: + const char *bundleName_ { nullptr }; +}; +} // namespace OHOS +#endif // OHOS_APP_TERMINATE_TASK_H diff --git a/services/abilitymgr_lite/include/util/abilityms_helper.h b/services/abilitymgr_lite/include/util/abilityms_helper.h new file mode 100755 index 0000000..d72c5b2 --- /dev/null +++ b/services/abilitymgr_lite/include/util/abilityms_helper.h @@ -0,0 +1,43 @@ +/* + * Copyright (c) 2020 Huawei Device Co., Ltd. + * 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 OHOS_ABILITY_HELPER_H +#define OHOS_ABILITY_HELPER_H + +#include + +#include "abilityms_log.h" +#include "abilityms_status.h" +#include "ability_state.h" +#include "bundle_info.h" +#include "want.h" + +namespace OHOS { +class AbilityMsHelper { +public: + static bool IsLauncherAbility(const char *bundleName); + static bool IsAceAbility(const char *abilityName); + static AbilityMsStatus SetLauncherWant(Want &want); + static AbilityMsStatus SetKeepAliveWant(const BundleInfo &bundleInfo, Want &want); +#ifdef OHOS_DEBUG + static std::string AbilityStateToString(State state); +#endif + static bool IsLegalBundleName(const char *bundleName); + static bool CheckVisiblePermission(pid_t callingUid, pid_t targetUid, bool isVisible); + + static const pid_t SYSTEM_UID = 0; +}; +} +#endif // OHOS_ABILITY_HELPER_H diff --git a/services/abilitymgr_lite/include/util/abilityms_log.h b/services/abilitymgr_lite/include/util/abilityms_log.h new file mode 100755 index 0000000..d16a590 --- /dev/null +++ b/services/abilitymgr_lite/include/util/abilityms_log.h @@ -0,0 +1,91 @@ +/* + * Copyright (c) 2020 Huawei Device Co., Ltd. + * 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 OHOS_LOGGING_H +#define OHOS_LOGGING_H + +#ifndef APP_PLATFORM_WATCHGT +#include "log.h" +#endif + +namespace OHOS { +#undef LOG_TAG +#define LOG_TAG "abilityms" +#undef LOG_DOMAIN +#define LOG_DOMAIN 0xD001300 + +#ifdef APP_PLATFORM_WATCHGT +#ifndef HILOG_DEBUG +#define HILOG_DEBUG(mod, format, ...) +#endif +#ifndef HILOG_ERROR +#define HILOG_ERROR(mod, format, ...) +#endif +#ifndef HILOG_FATAL +#define HILOG_FATAL(mod, format, ...) +#endif +#ifndef HILOG_INFO +#define HILOG_INFO(mod, format, ...) +#endif +#ifndef HILOG_WARN +#define HILOG_WARN(mod, format, ...) +#endif +#ifndef HILOG_RACE +#define HILOG_RACE(mod, format, ...) +#endif +#define PRINTD(name, fmt, ...) +#define PRINTI(name, fmt, ...) +#define PRINTW(name, fmt, ...) +#define PRINTE(name, fmt, ...) +#else +#ifdef OHOS_DEBUG +#define PRINTD(name, fmt, ...) HILOG_DEBUG(LOG_DOMAIN, "%{public}s::%{public}s(%{public}d): " fmt, \ + name, __FUNCTION__, __LINE__, ##__VA_ARGS__) +#else +#define PRINTD(name, fmt, ...) +#endif +#define PRINTI(name, fmt, ...) HILOG_INFO(LOG_DOMAIN, "%{public}s::%{public}s(%{public}d): " fmt, \ + name, __FUNCTION__, __LINE__, ##__VA_ARGS__) +#define PRINTW(name, fmt, ...) HILOG_WARN(LOG_DOMAIN, "%{public}s::%{public}s(%{public}d): " fmt, \ + name, __FUNCTION__, __LINE__, ##__VA_ARGS__) +#define PRINTE(name, fmt, ...) HILOG_ERROR(LOG_DOMAIN, "%{public}s::%{public}s(%{public}d): " fmt, \ + name, __FUNCTION__, __LINE__, ##__VA_ARGS__) +#endif + +#define CHECK_NULLPTR_RETURN_PTR(point, name, fmt) \ + do { \ + if (point == nullptr) { \ + PRINTE(name, fmt); \ + return nullptr; \ + } \ + } while (0) + +#define CHECK_NULLPTR_RETURN(point, name, fmt) \ + do { \ + if (point == nullptr) { \ + PRINTE(name, fmt); \ + return; \ + } \ + } while (0) + +#define CHECK_NULLPTR_RETURN_CODE(point, name, fmt, code) \ + do { \ + if (point == nullptr) { \ + PRINTE(name, fmt); \ + return code; \ + } \ + } while (0) +} // namespace OHOS +#endif // OHOS_LOGGING_H diff --git a/services/abilitymgr_lite/include/util/abilityms_status.h b/services/abilitymgr_lite/include/util/abilityms_status.h new file mode 100644 index 0000000..5d26e2c --- /dev/null +++ b/services/abilitymgr_lite/include/util/abilityms_status.h @@ -0,0 +1,167 @@ +/* + * Copyright (c) 2020 Huawei Device Co., Ltd. + * 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 OHOS_ABILITYMS_STATUS_H +#define OHOS_ABILITYMS_STATUS_H + +#include + +namespace OHOS { +class AbilityMsStatus { +public: + AbilityMsStatus() : code_(OK) {} + ~AbilityMsStatus() = default; + static AbilityMsStatus Ok() + { + return AbilityMsStatus(); + } + + static AbilityMsStatus BmsQueryStatus(const char *msg) + { + return AbilityMsStatus(BMS_QUERY_NOT_FOUND, nullptr, msg); + } + + static AbilityMsStatus AppTransanctStatus(const char *msg) + { + return AbilityMsStatus(APP_TRANSACT_ERROR, nullptr, msg); + } + + static AbilityMsStatus TaskStatus(const char *key, const char *msg) + { + return AbilityMsStatus(ABILITY_TASK_ERROR, key, msg); + } + + static AbilityMsStatus LifeCycleStatus(const char *msg) + { + return AbilityMsStatus(LIFE_CYCLE_ILLEGAL, nullptr, msg); + } + + static AbilityMsStatus ProcessStatus(const char *msg) + { + return AbilityMsStatus(PROCESS_ERROR, nullptr, msg); + } + + static AbilityMsStatus NoActiveAbilityStatus(const char *key, const char *msg) + { + return AbilityMsStatus(NO_ACTIVE_ABILITY, key, msg); + } + + static AbilityMsStatus HelpStatus(const char *msg) + { + return AbilityMsStatus(ABILITY_HELP_ERROR, nullptr, msg); + } + + static AbilityMsStatus DumpStatus(const char *msg) + { + return AbilityMsStatus(ABILITY_DUMP, nullptr, msg); + } + + static AbilityMsStatus PermissionStatus(const char *msg) + { + return AbilityMsStatus(PERMISSION_DENIED, nullptr, msg); + } + + static AbilityMsStatus AppCapabilitiesStatus(const char *msg) + { + return AbilityMsStatus(QUERY_APP_CAPS, nullptr, msg); + } + + void DumpAppend(const AbilityMsStatus &status) + { + if (code_ == ABILITY_DUMP) { + state_ += status.state_; + } + } + + void DumpAppend(const char *msg) + { + if (code_ == ABILITY_DUMP) { + state_ += msg; + } + } + + const char *Dump() const + { + if (code_ == ABILITY_DUMP) { + return state_.c_str(); + } + return ""; + } + + bool IsOk() const + { + return code_ == OK; + } + + bool IsNoActiveAbility() const + { + return code_ == NO_ACTIVE_ABILITY; + } + + bool IsProcessError() const + { + return code_ == PROCESS_ERROR; + } + + bool IsTransactError() const + { + return code_ == APP_TRANSACT_ERROR; + } + + void LogStatus() const; +private: + enum StatusCode { + OK = 0, + BMS_QUERY_NOT_FOUND, + PERMISSION_DENIED, + ABILITY_TASK_ERROR, + APP_TRANSACT_ERROR, + LIFE_CYCLE_ILLEGAL, + PROCESS_ERROR, + NO_ACTIVE_ABILITY, + ABILITY_HELP_ERROR, + ABILITY_DUMP, + QUERY_APP_CAPS, + }; + AbilityMsStatus(StatusCode code, const char *key, const char *msg); + StatusCode code_ = OK; + std::string state_; + std::string key_; +}; + +#define CHECK_RESULT_LOG_CODE(status, code) \ + do { \ + if (!status.IsOk()) { \ + status.LogStatus(); \ + return code; \ + } \ + } while (0) + +#define CHECK_RESULT_LOG(status) \ + do { \ + if (!status.IsOk()) { \ + status.LogStatus(); \ + return; \ + } \ + } while (0) + +#define CHECK_RESULT(status) \ + do { \ + if (!status.IsOk()) { \ + return status; \ + } \ + } while (0) +} +#endif // OHOS_ABILITY_CONST_H diff --git a/services/abilitymgr_lite/src/ability_connect_mission.cpp b/services/abilitymgr_lite/src/ability_connect_mission.cpp new file mode 100644 index 0000000..065aaae --- /dev/null +++ b/services/abilitymgr_lite/src/ability_connect_mission.cpp @@ -0,0 +1,154 @@ +/* + * Copyright (c) 2020 Huawei Device Co., Ltd. + * 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 "ability_connect_mission.h" + +#include + +#include "util/abilityms_log.h" + +namespace OHOS { +AbilityConnectMission::~AbilityConnectMission() +{ + for (auto iterator = serviceRecords_.begin(); iterator != serviceRecords_.end(); ++iterator) { + auto record = *iterator; + delete record; + } + serviceRecords_.clear(); + PRINTD("AbilityConnectMission", "Constructor"); +} + +void AbilityConnectMission::PushServiceRecord(PageAbilityRecord &abilityRecord) +{ + serviceRecords_.emplace_back(&abilityRecord); +} + +PageAbilityRecord *AbilityConnectMission::FindServiceRecord(uint64_t token) const +{ + for (const auto record : serviceRecords_) { + if (record != nullptr && record->GetToken() == token) { + return record; + } + } + return nullptr; +} + +PageAbilityRecord *AbilityConnectMission::FindServiceRecord(const char *bundleName, const char *abilityName) const +{ + CHECK_NULLPTR_RETURN_PTR(bundleName, "AbilityConnectMission", "invalid argument"); + CHECK_NULLPTR_RETURN_PTR(abilityName, "AbilityConnectMission", "invalid argument"); + for (const auto record : serviceRecords_) { + if (record != nullptr) { + const char *recordBundleName = record->GetAbilityInfo().bundleName; + const char *recordAbilityName = record->GetAbilityInfo().name; + if (recordBundleName == nullptr || recordAbilityName == nullptr) { + continue; + } + if (strcmp(recordBundleName, bundleName) == 0 && strcmp(recordAbilityName, abilityName) == 0) { + return record; + } + } + } + return nullptr; +} + +PageAbilityRecord *AbilityConnectMission::FindServiceRecord(const SvcIdentity &connectSid, uint64_t abilityToken) const +{ + for (const auto record : serviceRecords_) { + if (record != nullptr && record->GetConnectRecord(connectSid, abilityToken) != nullptr) { + return record; + } + } + return nullptr; +} + +void AbilityConnectMission::RemoveServiceRecord(uint64_t token) +{ + for (auto iterator = serviceRecords_.begin(); iterator != serviceRecords_.end();) { + auto record = *iterator; + if (record != nullptr && record->GetToken() == token) { + iterator = serviceRecords_.erase(iterator); + delete record; + } else { + ++iterator; + } + } +} + +void AbilityConnectMission::RemoveServiceRecord(const char *bundleName) +{ + CHECK_NULLPTR_RETURN(bundleName, "AbilityConnectMission", "invalid argument"); + for (auto iterator = serviceRecords_.begin(); iterator != serviceRecords_.end();) { + auto record = *iterator; + if (record != nullptr && record->IsSamePageAbility(bundleName)) { + AbilityMsStatus status = record->StopAbilityDone(); + if (!status.IsOk()) { + PRINTW("RemoveServiceRecord", "service disconnectDoneTransaction failed"); + } + iterator = serviceRecords_.erase(iterator); + delete record; + } else { + ++iterator; + } + } +} + +int32_t AbilityConnectMission::CountServiceInApp(const char *bundleName) +{ + if (bundleName == nullptr) { + return 0; + } + int32_t retVal = 0; + for (const auto record : serviceRecords_) { + if (record == nullptr) { + continue; + } + if (record->GetAbilityInfo().bundleName != nullptr && + strcmp(record->GetAbilityInfo().bundleName, bundleName) == 0) { + retVal++; + } + } + return retVal; +} + +#ifdef OHOS_DEBUG +AbilityMsStatus AbilityConnectMission::DumpConnectMission() const +{ + if (serviceRecords_.empty()) { + return AbilityMsStatus::DumpStatus(""); + } + std::string connectInfo = "ConnectMission: \n"; + AbilityMsStatus result = AbilityMsStatus::DumpStatus(connectInfo.c_str()); + for (const auto target : serviceRecords_) { + if (target != nullptr) { + result.DumpAppend(target->DumpAbilityRecord()); + } + } + return result; +} +#endif + +void AbilityConnectMission::RemoveConnectRecordByPageToken(uint64_t token, const char *bundleName) +{ + CHECK_NULLPTR_RETURN(bundleName, "AbilityConnectMission", "invalid argument"); + for (auto iterator = serviceRecords_.begin(); iterator != serviceRecords_.end(); ++iterator) { + auto record = *iterator; + if (record != nullptr && record->GetAbilityInfo().bundleName != nullptr && + strcmp(record->GetAbilityInfo().bundleName, bundleName) != 0) { + record->RemoveConnectRecordByPageToken(token); + } + } +} +} // namespace OHOS diff --git a/services/abilitymgr_lite/src/ability_inner_feature.cpp b/services/abilitymgr_lite/src/ability_inner_feature.cpp new file mode 100644 index 0000000..3ef6460 --- /dev/null +++ b/services/abilitymgr_lite/src/ability_inner_feature.cpp @@ -0,0 +1,180 @@ +/* + * Copyright (c) 2020 Huawei Device Co., Ltd. + * 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 "ability_inner_feature.h" + +#include "ability_connect_trans_param.h" +#include "ability_errors.h" +#include "ability_info.h" +#include "ability_message_id.h" +#include "ability_mgr_handler.h" +#include "ability_service_interface.h" +#include "adapter.h" +#include "ohos_init.h" +#include "iproxy_client.h" +#include "samgr_lite.h" +#include "securec.h" +#include "util/abilityms_helper.h" +#include "utils.h" +#include "want_utils.h" + +namespace OHOS { +AbilityInnerFeatureImpl g_amsInnerImpl = { + SERVER_IPROXY_IMPL_BEGIN, + .Invoke = AbilityInnerFeature::Invoke, + .StartKeepAliveApps = AbilityInnerFeature::StartKeepAliveApps, + .TerminateApp = AbilityInnerFeature::TerminateApp, + IPROXY_END +}; + +InvokeFunc AbilityInnerFeature::invokeFuncList[COMMAND_END - INNER_BEGIN] { + AbilityInnerFeature::TerminateAppInvoke, + AbilityInnerFeature::DumpAbilityInvoke, +}; + +static void Init() +{ + SamgrLite *samgrLite = SAMGR_GetInstance(); + CHECK_NULLPTR_RETURN(samgrLite, "AbilityInnerFeature", "get samgr error"); + BOOL result = samgrLite->RegisterFeature(AMS_SERVICE, AbilityInnerFeature::GetInstance()); + if (result == FALSE) { + PRINTE("AbilityInnerFeature", "ams register feature failure"); + return; + } + g_amsInnerImpl.ams = AbilityInnerFeature::GetInstance(); + auto publicApi = GET_IUNKNOWN(g_amsInnerImpl); + CHECK_NULLPTR_RETURN(publicApi, "AbilityMgrFeatureLite", "publicApi is nullptr"); + BOOL apiResult = samgrLite->RegisterFeatureApi(AMS_SERVICE, AMS_INNER_FEATURE, publicApi); + PRINTI("AbilityInnerFeature", "ams inner feature init %{public}s", apiResult ? "success" : "failure"); +} +SYSEX_FEATURE_INIT(Init); + +AbilityInnerFeature::AbilityInnerFeature() : Feature(), identity_() +{ + this->Feature::GetName = AbilityInnerFeature::GetFeatureName; + this->Feature::OnInitialize = AbilityInnerFeature::OnFeatureInitialize; + this->Feature::OnStop = AbilityInnerFeature::OnFeatureStop; + this->Feature::OnMessage = AbilityInnerFeature::OnFeatureMessage; +} + +int32 AbilityInnerFeature::Invoke(IServerProxy *iProxy, int funcId, void *origin, IpcIo *req, IpcIo *reply) +{ + PRINTI("AbilityInnerFeature", "ams invoke called"); + if (req == nullptr) { + return EC_INVALID; + } + if (funcId >= INNER_BEGIN && funcId < COMMAND_END) { + return invokeFuncList[funcId - INNER_BEGIN](origin, req); + } + return COMMAND_ERROR; +} + +const char *AbilityInnerFeature::GetFeatureName(Feature *feature) +{ + (void) feature; + return AMS_INNER_FEATURE; +} + +void AbilityInnerFeature::OnFeatureInitialize(Feature *feature, Service *parent, Identity identity) +{ + CHECK_NULLPTR_RETURN(feature, "AbilityInnerFeature", "initialize fail"); + (static_cast(feature))->identity_ = identity; +} + +void AbilityInnerFeature::OnFeatureStop(Feature *feature, Identity identity) +{ + (void) feature; + (void) identity; +} + +BOOL AbilityInnerFeature::OnFeatureMessage(Feature *feature, Request *request) +{ + if (feature == nullptr || request == nullptr) { + return FALSE; + } + + AbilityMgrHandler::GetInstance().ServiceMsgProcess(*request); + return TRUE; +} + +int32 AbilityInnerFeature::TerminateAppInvoke(const void *origin, IpcIo *req) +{ + size_t len = 0; + char *bundleName = reinterpret_cast(IpcIoPopString(req, &len)); + if (bundleName == nullptr || len == 0) { + PRINTE("AbilityInnerFeature", "bundleName is null"); + return EC_INVALID; + } + return TerminateApp(bundleName); +} + +int32 AbilityInnerFeature::StartKeepAliveApps() +{ + Request request = { + .msgId = AMS_SERVICE_INITED, + }; + return SAMGR_SendRequest(&(GetInstance()->identity_), &request, nullptr); +} + +int32 AbilityInnerFeature::TerminateApp(const char *bundleName) +{ + if (!AbilityMsHelper::IsLegalBundleName(bundleName)) { + return EC_INVALID; + } + + char *name = Utils::Strdup(bundleName); + if (name == nullptr) { + return EC_NOMEMORY; + } + Request request = { + .msgId = AMS_TERMINATE_APP, + .len = 0, + .data = reinterpret_cast(name), + }; + int32 propRet = SAMGR_SendRequest(&(GetInstance()->identity_), &request, nullptr); + if (propRet != EC_SUCCESS) { + PRINTE("AbilityInnerFeature", "send request failure"); + AdapterFree(name); + return EC_COMMU; + } + return EC_SUCCESS; +} + +int32 AbilityInnerFeature::DumpAbilityInvoke(const void *origin, IpcIo *req) +{ + Want want = { nullptr, nullptr, nullptr, 0 }; + if (!DeserializeWant(&want, req) || (want.sid == nullptr)) { + ClearWant(&want); + return EC_FAILURE; + } +#ifdef __LINUX__ + BinderAcquire(want.sid->ipcContext, want.sid->handle); +#endif + auto client = new AbilityDumpClient(want); + ClearWant(&want); + Request request = { + .msgId = AMS_DUMP_ABILITY, + .len = 0, + .data = reinterpret_cast(client), + }; + int32 propRet = SAMGR_SendRequest(&(GetInstance()->identity_), &request, nullptr); + if (propRet != EC_SUCCESS) { + PRINTE("AbilityInnerFeature", "send request failure"); + delete client; + return EC_COMMU; + } + return EC_SUCCESS; +} +} // namespace OHOS diff --git a/services/abilitymgr_lite/src/ability_list.cpp b/services/abilitymgr_lite/src/ability_list.cpp new file mode 100644 index 0000000..54bae57 --- /dev/null +++ b/services/abilitymgr_lite/src/ability_list.cpp @@ -0,0 +1,81 @@ +/* + * Copyright (c) 2020 Huawei Device Co., Ltd. + * 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 "ability_list.h" + +#include + +#include "ability_record.h" + +namespace OHOS { +void AbilityList::Add(AbilityRecord *abilityRecord) +{ + if (abilityRecord == nullptr) { + return; + } + + if (Get(abilityRecord->GetToken()) == nullptr) { + abilityList_.PushBack(abilityRecord); + } +} + +AbilityRecord *AbilityList::Get(uint16_t token) const +{ + for (auto node = abilityList_.Begin(); node != abilityList_.End(); node = node->next_) { + AbilityRecord *record = node->value_; + if (record == nullptr) { + continue; + } + if (record->GetToken() == token) { + return record; + } + } + + return nullptr; +} + +AbilityRecord *AbilityList::Get(const char *bundleName) const +{ + if (bundleName == nullptr) { + return nullptr; + } + + for (auto node = abilityList_.Begin(); node != abilityList_.End(); node = node->next_) { + AbilityRecord *record = node->value_; + if (record == nullptr || record->GetAppName() == nullptr) { + continue; + } + if (strcmp(bundleName, record->GetAppName()) == 0) { + return record; + } + } + + return nullptr; +} + +void AbilityList::Erase(uint16_t token) +{ + for (auto node = abilityList_.Begin(); node != abilityList_.End(); node = node->next_) { + AbilityRecord *record = node->value_; + if (record == nullptr) { + continue; + } + if (record->GetToken() == token) { + abilityList_.Remove(node); + return; + } + } +} +} // namespace OHOS diff --git a/services/abilitymgr_lite/src/ability_mgr_context.cpp b/services/abilitymgr_lite/src/ability_mgr_context.cpp new file mode 100755 index 0000000..6825f8d --- /dev/null +++ b/services/abilitymgr_lite/src/ability_mgr_context.cpp @@ -0,0 +1,71 @@ +/* + * Copyright (c) 2020 Huawei Device Co., Ltd. + * 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 "ability_mgr_context.h" +#include "ability_mission_stack.h" +#include "util/abilityms_helper.h" + +namespace OHOS { +AbilityMgrContext::AbilityMgrContext() +{ + launcherMissionStacks_ = new AbilityMissionStack(LAUNCHER); + defaultMissionStacks_ = new AbilityMissionStack(DEFAULT); + serviceConnects_ = new AbilityConnectMission(); +} + +AbilityMgrContext::~AbilityMgrContext() +{ + delete launcherMissionStacks_; + launcherMissionStacks_ = nullptr; + delete defaultMissionStacks_; + defaultMissionStacks_ = nullptr; + delete serviceConnects_; + serviceConnects_ = nullptr; + topMissionStacks_ = nullptr; +} + +const AbilityMissionStack *AbilityMgrContext::GetLauncherMissionStacks() const +{ + return launcherMissionStacks_; +} + +const AbilityMissionStack *AbilityMgrContext::GetDefaultMissionStacks() const +{ + return defaultMissionStacks_; +} + +const AbilityMissionStack *AbilityMgrContext::GetTopMissionStacks() const +{ + return topMissionStacks_; +} + +const AbilityMissionStack *AbilityMgrContext::GetTargetMissionStack(const char *bundleName) const +{ + if (AbilityMsHelper::IsLauncherAbility(bundleName)) { + return launcherMissionStacks_; + } + return defaultMissionStacks_; +} + +void AbilityMgrContext::SetTopMissionStacks(const AbilityMissionStack *stack) +{ + topMissionStacks_ = stack; +} + +const AbilityConnectMission *AbilityMgrContext::GetServiceConnects() const +{ + return serviceConnects_; +} +} // namespace OHOS diff --git a/services/abilitymgr_lite/src/ability_mgr_feature.cpp b/services/abilitymgr_lite/src/ability_mgr_feature.cpp new file mode 100644 index 0000000..482be5a --- /dev/null +++ b/services/abilitymgr_lite/src/ability_mgr_feature.cpp @@ -0,0 +1,504 @@ +/* + * Copyright (c) 2020 Huawei Device Co., Ltd. + * 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 "ability_mgr_feature.h" + +#include "ability_connect_trans_param.h" +#include "ability_errors.h" +#include "ability_info.h" +#include "ability_message_id.h" +#include "ability_mgr_handler.h" +#include "ability_service_interface.h" +#include "adapter.h" +#include "ohos_init.h" +#include "iproxy_client.h" +#include "samgr_lite.h" +#include "securec.h" +#include "util/abilityms_helper.h" +#include "utils.h" +#include "want_utils.h" + +namespace OHOS { +AbilityMgrFeatureImpl g_amsImpl = { + SERVER_IPROXY_IMPL_BEGIN, + .Invoke = AbilityMgrFeature::Invoke, + .StartAbility = AbilityMgrFeature::StartAbility, + .TerminateAbility = AbilityMgrFeature::TerminateAbility, + .ConnectAbility = AbilityMgrFeature::ConnectAbility, + .DisconnectAbility = AbilityMgrFeature::DisconnectAbility, + .StopAbility = AbilityMgrFeature::StopAbility, + IPROXY_END +}; + +InvokeFunc AbilityMgrFeature::invokeFuncList[INNER_BEGIN] { + AbilityMgrFeature::StartAbilityInvoke, + AbilityMgrFeature::TerminateAbilityInvoke, + AbilityMgrFeature::AttachBundleInvoke, + AbilityMgrFeature::ConnectAbilityInvoke, + AbilityMgrFeature::ConnectAbilityDoneInvoke, + AbilityMgrFeature::DisconnectAbilityInvoke, + AbilityMgrFeature::DisconnectAbilityDoneInvoke, + AbilityMgrFeature::AbilityTransactionDoneInvoke, + AbilityMgrFeature::StopAbilityInvoke, +}; + +static void Init() +{ + SamgrLite *samgrLite = SAMGR_GetInstance(); + CHECK_NULLPTR_RETURN(samgrLite, "AbilityMgrFeature", "get samgr error"); + BOOL result = samgrLite->RegisterFeature(AMS_SERVICE, AbilityMgrFeature::GetInstance()); + if (result == FALSE) { + PRINTE("AbilityMgrFeature", "ams register feature failure"); + return; + } + g_amsImpl.ams = AbilityMgrFeature::GetInstance(); + auto publicApi = GET_IUNKNOWN(g_amsImpl); + CHECK_NULLPTR_RETURN(publicApi, "AbilityMgrFeatureLite", "publicApi is nullptr"); + BOOL apiResult = samgrLite->RegisterFeatureApi(AMS_SERVICE, AMS_FEATURE, publicApi); + PRINTI("AbilityMgrFeature", "ams feature init %{public}s", apiResult ? "success" : "failure"); +} +SYSEX_FEATURE_INIT(Init); + +AbilityMgrFeature::AbilityMgrFeature() : Feature(), identity_() +{ + this->Feature::GetName = AbilityMgrFeature::GetFeatureName; + this->Feature::OnInitialize = AbilityMgrFeature::OnFeatureInitialize; + this->Feature::OnStop = AbilityMgrFeature::OnFeatureStop; + this->Feature::OnMessage = AbilityMgrFeature::OnFeatureMessage; +} + +int32 AbilityMgrFeature::Invoke(IServerProxy *iProxy, int funcId, void *origin, IpcIo *req, IpcIo *reply) +{ + PRINTI("AbilityMgrFeature", "ams invoke called"); + if (req == nullptr) { + return EC_INVALID; + } + if (funcId >= START_ABILITY && funcId < INNER_BEGIN) { + return invokeFuncList[funcId](origin, req); + } + return COMMAND_ERROR; +} + +const char *AbilityMgrFeature::GetFeatureName(Feature *feature) +{ + (void) feature; + return AMS_FEATURE; +} + +void AbilityMgrFeature::OnFeatureInitialize(Feature *feature, Service *parent, Identity identity) +{ + CHECK_NULLPTR_RETURN(feature, "AbilityMgrFeature", "initialize fail"); + (static_cast(feature))->identity_ = identity; + AbilityMgrHandler::GetInstance().Init(); +} + +void AbilityMgrFeature::OnFeatureStop(Feature *feature, Identity identity) +{ + (void) feature; + (void) identity; +} + +BOOL AbilityMgrFeature::OnFeatureMessage(Feature *feature, Request *request) +{ + if (feature == nullptr || request == nullptr) { + return FALSE; + } + + AbilityMgrHandler::GetInstance().ServiceMsgProcess(*request); + return TRUE; +} + +int32 AbilityMgrFeature::StartAbilityInvoke(const void *origin, IpcIo *req) +{ + pid_t uid = GetCallingUid(origin); + if (uid < 0) { + PRINTE("AbilityMgrFeature", "invalid uid argument"); + return EC_INVALID; + } + Want want = { nullptr, nullptr, nullptr, 0 }; + if (!DeserializeWant(&want, req)) { + return EC_FAILURE; + } + int retVal = StartAbilityInner(&want, uid); + ClearWant(&want); + return retVal; +} + +int32 AbilityMgrFeature::StartAbility(const Want *want) +{ + return StartAbilityInner(want, -1); +} + +int32 AbilityMgrFeature::StartAbilityInner(const Want *want, pid_t callingUid) +{ + if (want == nullptr || want->element == nullptr) { + PRINTE("AbilityMgrFeature", "invalid argument"); + return EC_INVALID; + } + Want *data = new Want(); + if (memset_s(data, sizeof(Want), 0, sizeof(Want)) != EOK) { + PRINTE("AbilityMgrFeature", "memory alloc error"); + delete data; + return EC_NOMEMORY; + } + SetWantElement(data, *(want->element)); + SetWantData(data, want->data, want->dataLength); + if (want->sid != nullptr) { + SetWantSvcIdentity(data, *(want->sid)); + } + Request request = { + .msgId = AMS_START_ABILITY, + .len = 0, + .data = reinterpret_cast(data), + .msgValue = static_cast(callingUid), + }; + int32 propRet = SAMGR_SendRequest(&(GetInstance()->identity_), &request, nullptr); + if (propRet != EC_SUCCESS) { + PRINTE("AbilityMgrFeature", "send request failure"); + ClearWant(data); + delete data; + return EC_COMMU; + } + return EC_SUCCESS; +} + +int32 AbilityMgrFeature::TerminateAbilityInvoke(const void *origin, IpcIo *req) +{ + uint64_t token = IpcIoPopUint64(req); + return TerminateAbility(token); +} + +int32 AbilityMgrFeature::TerminateAbility(uint64_t token) +{ + uint64_t *terminateToken = new uint64_t; + *terminateToken = token; + Request request = { + .msgId = AMS_TERMINATE_ABILITY, + .len = 0, + .data = reinterpret_cast(terminateToken), + }; + int32 propRet = SAMGR_SendRequest(&(GetInstance()->identity_), &request, nullptr); + if (propRet != EC_SUCCESS) { + PRINTE("AbilityMgrFeature", "send request failure"); + delete terminateToken; + return EC_COMMU; + } + return EC_SUCCESS; +} + +int32 AbilityMgrFeature::AbilityTransactionDoneInvoke(const void *origin, IpcIo *req) +{ + uint64_t token = IpcIoPopUint64(req); + int32 state = IpcIoPopInt32(req); + TransactionState *transactionState = new TransactionState(); + transactionState->token = token; + transactionState->state = state; + Request request = { + .msgId = AMS_TRANSACTION_DONE, + .len = 0, + .data = reinterpret_cast(transactionState), + }; + int32 propRet = SAMGR_SendRequest(&(GetInstance()->identity_), &request, nullptr); + if (propRet != EC_SUCCESS) { + PRINTE("AbilityMgrFeature", "send request failure"); + delete transactionState; + return EC_COMMU; + } + return EC_SUCCESS; +} + +int32 AbilityMgrFeature::AttachBundleInvoke(const void *origin, IpcIo *req) +{ + uint64_t token = IpcIoPopUint64(req); + SvcIdentity *svcIdentity = IpcIoPopSvc(req); + if (svcIdentity == nullptr) { + return EC_INVALID; + } +#ifdef __LINUX__ + pid_t callingPid = IpcIoPopUint64(req); +#else + pid_t callingPid = GetCallingPid(origin); +#endif + if (callingPid < 0) { +#ifdef __LINUX__ + AdapterFree(svcIdentity); + svcIdentity = nullptr; +#endif + PRINTE("AbilityMgrFeature", "invalid pid argument"); + return EC_INVALID; + } + + auto client = new AbilityThreadClient(token, callingPid, + *svcIdentity, &AbilityMgrFeature::AppDeathNotify); +#ifdef __LINUX__ + BinderAcquire(svcIdentity->ipcContext, svcIdentity->handle); + AdapterFree(svcIdentity); + svcIdentity = nullptr; +#endif + Request request = { + .msgId = AMS_ATTACH_BUNDLE, + .len = 0, + .data = reinterpret_cast(client), + }; + int32 propRet = SAMGR_SendRequest(&(GetInstance()->identity_), &request, nullptr); + if (propRet != EC_SUCCESS) { + PRINTE("AbilityMgrFeature", "send request failure"); + delete client; + return EC_COMMU; + } + return EC_SUCCESS; +} + +int32 AbilityMgrFeature::ConnectAbilityInvoke(const void *origin, IpcIo *req) +{ + pid_t uid = GetCallingUid(origin); + if (uid < 0) { + PRINTE("AbilityMgrFeature", "invalid uid argument"); + return EC_INVALID; + } + uint64_t token = IpcIoPopUint64(req); + SvcIdentity* sid = IpcIoPopSvc(req); + Want want = { nullptr, nullptr, nullptr, 0 }; + if (!DeserializeWant(&want, req)) { +#ifdef __LINUX__ + AdapterFree(sid); + sid = nullptr; +#endif + return EC_FAILURE; + } + int32 retVal = ConnectAbilityInner(&want, sid, token, uid); +#ifdef __LINUX__ + AdapterFree(sid); + sid = nullptr; +#endif + ClearWant(&want); + return retVal; +} + +int32 AbilityMgrFeature::ConnectAbility(const Want *want, SvcIdentity *svc, uint64_t token) +{ + return ConnectAbilityInner(want, svc, token, -1); +} + +int32 AbilityMgrFeature::ConnectAbilityInner(const Want *want, SvcIdentity *svc, uint64_t token, pid_t callingUid) +{ + if (want == nullptr || want->element == nullptr || svc == nullptr) { + return EC_INVALID; + } + Want *data = new Want(); + if (memset_s(data, sizeof(Want), 0, sizeof(Want)) != EOK) { + delete data; + PRINTE("AbilityMgrFeature", "memory alloc error"); + return EC_NOMEMORY; + } + SetWantElement(data, *(want->element)); + SetWantData(data, want->data, want->dataLength); + if (want->sid != nullptr) { + SetWantSvcIdentity(data, *(want->sid)); + } +#ifdef __LINUX__ + BinderAcquire(svc->ipcContext, svc->handle); +#endif + auto transParam = new AbilityConnectTransParam(data, *svc, token); + transParam->SetCallingUid(callingUid); + Request request = { + .msgId = AMS_CONNECT_ABILITY, + .len = 0, + .data = reinterpret_cast(transParam), + }; + int32 propRet = SAMGR_SendRequest(&(GetInstance()->identity_), &request, nullptr); + if (propRet != EC_SUCCESS) { + PRINTE("AbilityMgrFeature", "connect ability send request failure"); + delete transParam; + return EC_COMMU; + } + return EC_SUCCESS; +} + +int32 AbilityMgrFeature::DisconnectAbilityInvoke(const void *origin, IpcIo *req) +{ + uint64_t token = IpcIoPopUint64(req); + SvcIdentity *sid = IpcIoPopSvc(req); + return DisconnectAbility(sid, token); +} + +int32 AbilityMgrFeature::DisconnectAbility(SvcIdentity *svc, uint64_t token) +{ + if (svc == nullptr) { + return EC_INVALID; + } + auto transParam = new AbilityConnectTransParam(nullptr, *svc, token); +#ifdef __LINUX__ + AdapterFree(svc); + svc = nullptr; +#endif + Request request = { + .msgId = AMS_DISCONNECT_ABILITY, + .len = 0, + .data = reinterpret_cast(transParam), + }; + int32 propRet = SAMGR_SendRequest(&(GetInstance()->identity_), &request, nullptr); + if (propRet != EC_SUCCESS) { + PRINTE("AbilityMgrFeature", "disconnect ability send request failure"); + delete transParam; + return EC_COMMU; + } + return EC_SUCCESS; +} + +int32 AbilityMgrFeature::ConnectAbilityDoneInvoke(const void *origin, IpcIo *req) +{ + uint64_t token = IpcIoPopUint64(req); + SvcIdentity *sid = IpcIoPopSvc(req); + if (sid == nullptr) { + return EC_INVALID; + } + auto transParam = new AbilityConnectTransParam(nullptr, *sid, token); +#ifdef __LINUX__ + BinderAcquire(sid->ipcContext, sid->handle); + AdapterFree(sid); + sid = nullptr; +#endif + Request request = { + .msgId = AMS_CONNECT_ABILITY_DONE, + .len = 0, + .data = reinterpret_cast(transParam), + }; + int32 propRet = SAMGR_SendRequest(&(GetInstance()->identity_), &request, nullptr); + if (propRet != EC_SUCCESS) { + PRINTE("AbilityMgrFeature", "connect ability done send request failure"); + delete transParam; + return EC_COMMU; + } + return EC_SUCCESS; +} + +int32 AbilityMgrFeature::DisconnectAbilityDoneInvoke(const void *origin, IpcIo *req) +{ + uint64_t *disconnectToken = new uint64_t; + *disconnectToken = IpcIoPopUint64(req); + Request request = { + .msgId = AMS_DISCONNECT_ABILITY_DONE, + .len = 0, + .data = reinterpret_cast(disconnectToken), + }; + int32 propRet = SAMGR_SendRequest(&(GetInstance()->identity_), &request, nullptr); + if (propRet != EC_SUCCESS) { + PRINTE("AbilityMgrFeature", "disconnect ability done send request failure"); + delete disconnectToken; + return EC_COMMU; + } + return EC_SUCCESS; +} + +int32 AbilityMgrFeature::StopAbilityInvoke(const void *origin, IpcIo *req) +{ + pid_t uid = GetCallingUid(origin); + if (uid < 0) { + PRINTE("AbilityMgrFeature", "invalid uid argument"); + return EC_INVALID; + } + Want want = { nullptr, nullptr, nullptr, 0 }; + if (!DeserializeWant(&want, req)) { + return EC_FAILURE; + } + int retVal = StopAbilityInner(&want, uid); + ClearWant(&want); + return retVal; +} + +int32 AbilityMgrFeature::StopAbility(const Want *want) +{ + return StopAbilityInner(want, -1); +} + +int32 AbilityMgrFeature::StopAbilityInner(const Want *want, pid_t callingUid) +{ + if (want == nullptr || want->element == nullptr) { + PRINTE("AbilityMgrFeature", "invalid argument"); + return EC_INVALID; + } + Want *data = new Want(); + if (memset_s(data, sizeof(Want), 0, sizeof(Want)) != EOK) { + PRINTE("AbilityMgrFeature", "memory alloc error"); + delete data; + return EC_NOMEMORY; + } + SetWantElement(data, *(want->element)); + SetWantData(data, want->data, want->dataLength); + if (want->sid != nullptr) { + SetWantSvcIdentity(data, *(want->sid)); + } + Request request = { + .msgId = AMS_TERMINATE_SERVICE, + .len = 0, + .data = reinterpret_cast(data), + .msgValue = static_cast(callingUid), + }; + int32 propRet = SAMGR_SendRequest(&(GetInstance()->identity_), &request, nullptr); + if (propRet != EC_SUCCESS) { + PRINTE("AbilityMgrFeature", "send request failure"); + ClearWant(data); + delete data; + return EC_COMMU; + } + return EC_SUCCESS; +} + +int32 AbilityMgrFeature::RestartApp(const char *bundleName) +{ + if (!AbilityMsHelper::IsLegalBundleName(bundleName)) { + return EC_INVALID; + } + char *name = Utils::Strdup(bundleName); + if (name == nullptr) { + return EC_NOMEMORY; + } + Request request = { + .msgId = AMS_RESTART_APP, + .len = 0, + .data = reinterpret_cast(name), + }; + int32 propRet = SAMGR_SendRequest(&(GetInstance()->identity_), &request, nullptr); + if (propRet != EC_SUCCESS) { + PRINTE("AbilityMgrFeature", "send request failure"); + AdapterFree(name); + return EC_COMMU; + } + return EC_SUCCESS; +} + +int32 AbilityMgrFeature::AppDeathNotify(const IpcContext* context, void *ipcMsg, IpcIo *data, void *arg) +{ + FreeBuffer(nullptr, ipcMsg); + AppInfo *appInfo = reinterpret_cast(arg); + if (appInfo == nullptr) { + return EC_INVALID; + } +#ifdef __LINUX__ + BinderRelease(appInfo->svcIdentity.ipcContext, appInfo->svcIdentity.handle); +#endif + if (!AbilityMsHelper::IsLegalBundleName(appInfo->bundleName)) { + AdapterFree(appInfo->bundleName); + delete appInfo; + return EC_INVALID; + } + PRINTE("AbilityMgrFeature", "%s AppDeathNotify called", appInfo->bundleName); + int32 ret = RestartApp(appInfo->bundleName); + AdapterFree(appInfo->bundleName); + delete appInfo; + return ret; +} +} // namespace OHOS diff --git a/services/abilitymgr_lite/src/ability_mgr_handler.cpp b/services/abilitymgr_lite/src/ability_mgr_handler.cpp new file mode 100644 index 0000000..84900fa --- /dev/null +++ b/services/abilitymgr_lite/src/ability_mgr_handler.cpp @@ -0,0 +1,378 @@ +/* + * Copyright (c) 2020 Huawei Device Co., Ltd. + * 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 "ability_mgr_handler.h" + +#include "ability_kit_command.h" +#include "ability_message_id.h" +#include "adapter.h" +#include "app_manager.h" +#include "bundle_info.h" +#include "bundle_manager.h" +#ifdef ABILITY_WINDOW_SUPPORT +#include "client/wms_client.h" +#endif +#include "element_name_utils.h" +#include "iproxy_client.h" +#include "util/abilityms_helper.h" + +namespace OHOS { +void AbilityMgrHandler::Init() +{ + AbilityMsStatus status = bundleMsClient_.Initialize(); + CHECK_RESULT_LOG(status); +} + +void AbilityMgrHandler::ServiceMsgProcess(const Request &request) +{ + switch (request.msgId) { + case AMS_SERVICE_INITED: { + OnServiceInited(); + break; + } + case AMS_START_ABILITY: { + Want *want = reinterpret_cast(request.data); + pid_t uid = request.msgValue; + int ret = StartAbility(want, uid); + StartAbilityCallback(want, ret); + ClearWant(want); + delete want; + break; + } + case AMS_TERMINATE_ABILITY: { + TerminateAbility(reinterpret_cast(request.data)); + break; + } + case AMS_ATTACH_BUNDLE: { + AttachBundle(reinterpret_cast(request.data)); + break; + } + case AMS_TRANSACTION_DONE: { + AbilityTransaction(reinterpret_cast(request.data)); + break; + } + case AMS_CONNECT_ABILITY: { + auto transParam = reinterpret_cast(request.data); + int ret = ConnectAbility(transParam); + ConnectAbilityCallback(transParam, ret); + delete transParam; + break; + } + case AMS_CONNECT_ABILITY_DONE: { + auto transParam = reinterpret_cast(request.data); + ConnectAbilityDone(transParam); + delete transParam; + break; + } + case AMS_DISCONNECT_ABILITY: { + auto transParam = reinterpret_cast(request.data); + DisconnectAbility(transParam); + delete transParam; + break; + } + case AMS_DISCONNECT_ABILITY_DONE: { + DisconnectAbilityDone(reinterpret_cast(request.data)); + break; + } + case AMS_TERMINATE_SERVICE: { + Want *want = reinterpret_cast(request.data); + pid_t uid = request.msgValue; + TerminateService(want, uid); + ClearWant(want); + delete want; + break; + } + case AMS_TERMINATE_APP: { + char *bundleName = reinterpret_cast(request.data); + TerminateApp(bundleName); + AdapterFree(bundleName); + break; + } + case AMS_DUMP_ABILITY: { + DumpAbility(reinterpret_cast(request.data)); + break; + } + case AMS_RESTART_APP: { + char *bundleName = reinterpret_cast(request.data); + RestartApp(bundleName); + AdapterFree(bundleName); + break; + } + default: { + PRINTI("AbilityMgrHandler", "unknown msgId"); + break; + } + } +} + +void AbilityMgrHandler::OnServiceInited() +{ + PRINTD("AbilityMgrHandler", "start"); + StartKeepAliveApps(); +} + +void AbilityMgrHandler::StartKeepAliveApps() +{ + int32_t len = 0; + BundleInfo *bundleInfos = nullptr; + AbilityMsStatus status = bundleMsClient_.QueryKeepAliveBundleInfos(&bundleInfos, &len); + CHECK_RESULT_LOG(status); + CHECK_NULLPTR_RETURN(bundleInfos, "AbilityMgrHandler", "bundleInfos is nullptr"); +#ifdef ABILITY_WINDOW_SUPPORT + if (len > 0) { + // Start keep-alive apps until wms is ready. + WMSClient::WaitUntilWmsReady(); + } +#endif + for (int32_t i = 0; i < len; ++i) { + if (AbilityMsHelper::IsLauncherAbility(bundleInfos[i].bundleName)) { +#ifdef ABILITY_WINDOW_SUPPORT + StartLauncher(); +#endif + } else { + StartKeepAliveApp(bundleInfos[i]); + } + } + for (int32_t i = 0; i < len; ++i) { + ClearBundleInfo(&(bundleInfos[i])); + } + AdapterFree(bundleInfos); +} + +void AbilityMgrHandler::StartKeepAliveApp(const BundleInfo &bundleInfo) +{ + PRINTD("AbilityMgrHandler", "start"); + Want want = {}; + AbilityMsStatus status = AbilityMsHelper::SetKeepAliveWant(bundleInfo, want); + CHECK_RESULT_LOG(status); + StartAbility(&want, AbilityMsHelper::SYSTEM_UID); + ClearWant(&want); +} + +void AbilityMgrHandler::StartLauncher() +{ + PRINTD("AbilityMgrHandler", "start"); + // Create Launcher Want, + Want want = {}; + AbilityMsStatus status = AbilityMsHelper::SetLauncherWant(want); + CHECK_RESULT_LOG(status); + + StartAbility(&want, AbilityMsHelper::SYSTEM_UID); + ClearWant(&want); +} + +int AbilityMgrHandler::StartAbility(const Want *want, pid_t callingUid) +{ + PRINTD("AbilityMgrHandler", "start"); + CHECK_NULLPTR_RETURN_CODE(want, "AbilityMgrHandler", "invalid argument", EC_FAILURE); + CHECK_NULLPTR_RETURN_CODE(want->element, "AbilityMgrHandler", "invalid argument", EC_FAILURE); + + // Qurey BundleInfo note: bundleInfo not need clear + BundleInfo bundleInfo = {}; + AbilityMsStatus status = bundleMsClient_.QueryBundleInfo(want->element->bundleName, &bundleInfo); + CHECK_RESULT_LOG_CODE(status, EC_INVALID); + + // Query AbilityInfo + AbilityInfo target = {}; + status = bundleMsClient_.QueryAbilityInfo(want, &target); + CHECK_RESULT_LOG_CODE(status, EC_INVALID); + + status = abilityWorker_.StartAbility(*want, target, bundleInfo, callingUid); + ClearAbilityInfo(&target); + CHECK_RESULT_LOG_CODE(status, EC_COMMU); + + return EC_SUCCESS; +} + +void AbilityMgrHandler::AttachBundle(AbilityThreadClient *client) +{ + PRINTD("AbilityMgrHandler", "start"); + CHECK_NULLPTR_RETURN(client, "AbilityMgrHandler", "invalid augument"); + AbilityMsStatus status = abilityWorker_.AttachBundle(*client); + delete client; + CHECK_RESULT_LOG(status); +} + +void AbilityMgrHandler::TerminateAbility(const uint64_t *token) +{ + PRINTD("AbilityMgrHandler", "start"); + CHECK_NULLPTR_RETURN(token, "AbilityMgrHandler", "invalid argument"); + AbilityMsStatus status = abilityWorker_.TerminateAbility(*token); + delete token; + CHECK_RESULT_LOG(status); +} + +void AbilityMgrHandler::AbilityTransaction(TransactionState *state) +{ + PRINTD("AbilityMgrHandler", "start"); + CHECK_NULLPTR_RETURN(state, "AbilityMgrHandler", "invalid argument"); + AbilityMsStatus status = abilityWorker_.AbilityTransaction(*state); + delete state; + if (status.IsNoActiveAbility()) { + status.LogStatus(); + StartLauncher(); + } else { + CHECK_RESULT_LOG(status); + } +} + +void AbilityMgrHandler::TerminateApp(const char *bundleName) +{ + PRINTD("AbilityMgrHandler", "start"); + CHECK_NULLPTR_RETURN(bundleName, "AbilityMgrHandler", "invalid argument"); + AbilityMsStatus status = abilityWorker_.TerminateApp(bundleName); + CHECK_RESULT_LOG(status); +} + +void AbilityMgrHandler::RestartApp(const char *bundleName) +{ + PRINTD("AbilityMgrHandler", "start %{public}s", bundleName); + CHECK_NULLPTR_RETURN(bundleName, "AbilityMgrHandler", "invalid argument"); + // Qurey BundleInfo + BundleInfo bundleInfo = {}; + AbilityMsStatus status = bundleMsClient_.QueryBundleInfo(bundleName, &bundleInfo); + if (!status.IsOk()) { + status.LogStatus(); + return; + } + status = abilityWorker_.RestartApp(bundleInfo); + if (status.IsNoActiveAbility()) { + status.LogStatus(); + StartLauncher(); + } + if (!AbilityMsHelper::IsLauncherAbility(bundleInfo.bundleName) && bundleInfo.isSystemApp + && bundleInfo.isKeepAlive) { + StartKeepAliveApp(bundleInfo); + } + CHECK_RESULT_LOG(status); +} + +int AbilityMgrHandler::ConnectAbility(AbilityConnectTransParam *transParam) +{ + PRINTD("AbilityMgrHandler", "connect"); + CHECK_NULLPTR_RETURN_CODE(transParam, "AbilityMgrHandler", "invalid argument", EC_FAILURE); + const Want *want = transParam->GetWant(); + CHECK_NULLPTR_RETURN_CODE(want, "AbilityMgrHandler", "invalid argument", EC_FAILURE); + CHECK_NULLPTR_RETURN_CODE(want->element, "AbilityMgrHandler", "invalid argument", EC_FAILURE); + // Qurey BundleInfo note: bundleInfo not need clear + BundleInfo bundleInfo = {}; + AbilityMsStatus status = bundleMsClient_.QueryBundleInfo(want->element->bundleName, &bundleInfo); + CHECK_RESULT_LOG_CODE(status, EC_INVALID); + + // Query AbilityInfo + AbilityInfo target = {}; + status = bundleMsClient_.QueryAbilityInfo(want, &target); + CHECK_RESULT_LOG_CODE(status, EC_INVALID); + + status = abilityWorker_.ConnectAbility(*transParam, target, bundleInfo); + ClearAbilityInfo(&target); + CHECK_RESULT_LOG_CODE(status, EC_COMMU); + return EC_SUCCESS; +} + +void AbilityMgrHandler::DisconnectAbility(AbilityConnectTransParam *transParam) +{ + PRINTD("AbilityMgrHandler", "disconnect"); + CHECK_NULLPTR_RETURN(transParam, "AbilityMgrHandler", "invalid argument"); + const SvcIdentity sid = transParam->GetSvcIdentity(); + uint64_t token = transParam->GetToken(); + AbilityMsStatus status = abilityWorker_.DisconnectAbility(sid, token); + CHECK_RESULT_LOG(status); +} + +void AbilityMgrHandler::ConnectAbilityDone(AbilityConnectTransParam *transParam) +{ + PRINTD("AbilityMgrHandler", "connectDone"); + CHECK_NULLPTR_RETURN(transParam, "AbilityMgrHandler", "invalid argument"); + const SvcIdentity sid = transParam->GetSvcIdentity(); + uint64_t token = transParam->GetToken(); + AbilityMsStatus status = abilityWorker_.ConnectAbilityDone(sid, token); + CHECK_RESULT_LOG(status); +} + +void AbilityMgrHandler::DisconnectAbilityDone(const uint64_t *token) +{ + PRINTD("AbilityMgrHandler", "disconnectDone"); + CHECK_NULLPTR_RETURN(token, "AbilityMgrHandler", "invalid argument: token"); + AbilityMsStatus status = abilityWorker_.DisconnectAbilityDone(*token); + delete token; + CHECK_RESULT_LOG(status); +} + +void AbilityMgrHandler::TerminateService(Want *want, pid_t callingUid) +{ + PRINTD("AbilityMgrHandler", "terminateService"); + CHECK_NULLPTR_RETURN(want, "AbilityMgrHandler", "invalid argument"); + CHECK_NULLPTR_RETURN(want->element, "AbilityMgrHandler", "invalid argument"); + + // Qurey BundleInfo note: bundleInfo not need clear + BundleInfo bundleInfo = {}; + AbilityMsStatus status = bundleMsClient_.QueryBundleInfo(want->element->bundleName, &bundleInfo); + CHECK_RESULT_LOG(status); + + // Query AbilityInfo + AbilityInfo target = {}; + status = bundleMsClient_.QueryAbilityInfo(want, &target); + CHECK_RESULT_LOG(status); + status = abilityWorker_.TerminateService(target, bundleInfo, callingUid); + ClearAbilityInfo(&target); + CHECK_RESULT_LOG(status); +} + +void AbilityMgrHandler::StartAbilityCallback(const Want *want, int code) +{ + if ((want == nullptr) || (want->sid == nullptr) || (code == EC_SUCCESS)) { + return; + } + PRINTI("AbilityMgrHandler", "start ability failed callback"); + IpcIo io; + char data[IPC_IO_DATA_MAX]; + IpcIoInit(&io, data, IPC_IO_DATA_MAX, 0); + if (!SerializeElement(&io, want->element)) { + return; + } + IpcIoPushInt32(&io, code); + if (Transact(nullptr, *(want->sid), SCHEDULER_APP_INIT, &io, nullptr, LITEIPC_FLAG_ONEWAY, nullptr) != LITEIPC_OK) { + PRINTE("AbilityMgrHandler", "start ability callback failed, ipc error"); + } +} + +void AbilityMgrHandler::DumpAbility(const AbilityDumpClient *client) +{ + PRINTD("AbilityMgrHandler", "start"); + CHECK_NULLPTR_RETURN(client, "AbilityMgrHandler", "invalid argument"); + AbilityMsStatus status = abilityWorker_.DumpAbility(*client); +#ifdef __LINUX__ + BinderRelease(client->GetWant().sid->ipcContext, client->GetWant().sid->handle); +#endif + delete client; + CHECK_RESULT_LOG(status); +} + +void AbilityMgrHandler::ConnectAbilityCallback(AbilityConnectTransParam *transParam, int code) +{ + if (transParam == nullptr || code == EC_SUCCESS) { + return; + } + PRINTI("AbilityMgrHandler", "connect ability failed"); + if (Transact(nullptr, transParam->GetSvcIdentity(), SCHEDULER_ABILITY_CONNECT_FAIL, nullptr, nullptr, + LITEIPC_FLAG_ONEWAY, nullptr) != LITEIPC_OK) { + PRINTE("AbilityMgrHandler", "connect ability callback failed, ipc error"); + } +#ifdef __LINUX__ + BinderRelease(transParam->GetSvcIdentity().ipcContext, transParam->GetSvcIdentity().handle); +#endif +} +} // namespace OHOS diff --git a/services/abilitymgr_lite/src/ability_mgr_service.cpp b/services/abilitymgr_lite/src/ability_mgr_service.cpp new file mode 100755 index 0000000..08fd2ff --- /dev/null +++ b/services/abilitymgr_lite/src/ability_mgr_service.cpp @@ -0,0 +1,103 @@ +/* + * Copyright (c) 2020 Huawei Device Co., Ltd. + * 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 "ability_mgr_service.h" + +#include "ability_errors.h" +#ifdef APP_PLATFORM_WATCHGT +#include "ability_service.h" +#endif +#include "ability_service_interface.h" +#include "adapter.h" +#include "ohos_init.h" +#include "samgr_lite.h" +#include "util/abilityms_log.h" + +namespace OHOS { +#ifndef APP_PLATFORM_WATCHGT +const int STACK_SIZE = 0x800; +#else +const int STACK_SIZE = 0xE00; +#endif +const int QUEUE_SIZE = 20; +const int BYTE_OFFSET = 8; + +AbilityMgrService::AbilityMgrService() : Service(), identity_() +{ + this->Service::GetName = AbilityMgrService::GetServiceName; + this->Service::Initialize = AbilityMgrService::ServiceInitialize; + this->Service::MessageHandle = AbilityMgrService::ServiceMessageHandle; + this->Service::GetTaskConfig = AbilityMgrService::GetServiceTaskConfig; +} + +static void Init() +{ + SamgrLite *sm = SAMGR_GetInstance(); + CHECK_NULLPTR_RETURN(sm, "AbilityManagerService", "get samgr error"); + BOOL result = sm->RegisterService(AbilityMgrService::GetInstance()); + PRINTI("AbilityManagerService", "ams starts %{public}s", result ? "successfully" : "unsuccessfully"); +} +SYSEX_SERVICE_INIT(Init); + +const char *AbilityMgrService::GetServiceName(Service *service) +{ + (void)service; + return AMS_SERVICE; +} + +const Identity *AbilityMgrService::GetIdentity() +{ + return &identity_; +} + +BOOL AbilityMgrService::ServiceInitialize(Service *service, Identity identity) +{ + if (service == nullptr) { + return FALSE; + } + AbilityMgrService *abilityManagerService = static_cast(service); + abilityManagerService->identity_ = identity; + return TRUE; +} + +BOOL AbilityMgrService::ServiceMessageHandle(Service *service, Request *request) +{ + if (request == nullptr) { + return FALSE; + } +#ifdef APP_PLATFORM_WATCHGT + int ret = ERR_OK; + if (request->msgId == START_ABILITY) { + ret = AbilityService::GetInstance().StartAbility(AbilityService::GetInstance().want_); + AbilityService::GetInstance().CleanWant(); + } else if (request->msgId == ABILITY_TRANSACTION_DONE) { + int token = request->msgValue & 0xFF; + int state = (request->msgValue >> BYTE_OFFSET) & 0xFF; + ret = AbilityService::GetInstance().SchedulerLifecycleDone(token, state); + } else if (request->msgId == TERMINATE_ABILITY) { + ret = AbilityService::GetInstance().TerminateAbility(request->msgValue); + } + return ret == ERR_OK; +#else + return TRUE; +#endif +} + +TaskConfig AbilityMgrService::GetServiceTaskConfig(Service *service) +{ + TaskConfig config = {LEVEL_HIGH, PRI_NORMAL, STACK_SIZE, QUEUE_SIZE, SINGLE_TASK}; + return config; +} +} // namespace OHOS diff --git a/services/abilitymgr_lite/src/ability_mgr_slite_feature.cpp b/services/abilitymgr_lite/src/ability_mgr_slite_feature.cpp new file mode 100755 index 0000000..12bff89 --- /dev/null +++ b/services/abilitymgr_lite/src/ability_mgr_slite_feature.cpp @@ -0,0 +1,108 @@ +/* + * Copyright (c) 2020 Huawei Device Co., Ltd. + * 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 "ability_mgr_slite_feature.h" + +#include "ability_errors.h" +#include "ability_info.h" +#include "ability_message_id.h" +#include "ability_service_interface.h" +#include "abilityms_log.h" +#include "adapter.h" +#include "ohos_init.h" +#include "samgr_lite.h" +#include "securec.h" +#include "utils.h" +#include "want_utils.h" + +namespace OHOS { +AbilityMgrSliteFeatureImpl g_amsSliteImpl = { + DEFAULT_IUNKNOWN_ENTRY_BEGIN, + .StartAbility = AbilityMgrSliteFeature::StartAbility, + .TerminateAbility = AbilityMgrSliteFeature::TerminateAbility, + .SchedulerLifecycleDone = AbilityMgrSliteFeature::SchedulerLifecycleDone, + DEFAULT_IUNKNOWN_ENTRY_END +}; + +static void Init() +{ + SamgrLite *samgrLite = SAMGR_GetInstance(); + CHECK_NULLPTR_RETURN(samgrLite, "AbilityMgrSliteFeature", "get samgr error"); + BOOL result = samgrLite->RegisterFeature(AMS_SERVICE, AbilityMgrSliteFeature::GetInstance()); + if (result == FALSE) { + PRINTE("AbilityMgrSliteFeature", "ams register feature failure"); + return; + } + g_amsSliteImpl.ams = AbilityMgrSliteFeature::GetInstance(); + auto publicApi = GET_IUNKNOWN(g_amsSliteImpl); + CHECK_NULLPTR_RETURN(publicApi, "AbilityMgrSliteFeatureLite", "publicApi is nullptr"); + BOOL apiResult = samgrLite->RegisterFeatureApi(AMS_SERVICE, AMS_SLITE_FEATURE, publicApi); + PRINTI("AbilityMgrSliteFeature", "ams feature init %{public}s", apiResult ? "success" : "failure"); +} +SYSEX_FEATURE_INIT(Init); + +AbilityMgrSliteFeature::AbilityMgrSliteFeature() : Feature(), identity_() +{ + this->Feature::GetName = AbilityMgrSliteFeature::GetFeatureName; + this->Feature::OnInitialize = AbilityMgrSliteFeature::OnFeatureInitialize; + this->Feature::OnStop = AbilityMgrSliteFeature::OnFeatureStop; + this->Feature::OnMessage = AbilityMgrSliteFeature::OnFeatureMessage; +} + +const char *AbilityMgrSliteFeature::GetFeatureName(Feature *feature) +{ + (void) feature; + return AMS_SLITE_FEATURE; +} + +void AbilityMgrSliteFeature::OnFeatureInitialize(Feature *feature, Service *parent, Identity identity) +{ + CHECK_NULLPTR_RETURN(feature, "AbilityMgrSliteFeature", "initialize fail"); + (static_cast(feature))->identity_ = identity; + AbilityService::GetInstance().StartLauncher(); +} + +void AbilityMgrSliteFeature::OnFeatureStop(Feature *feature, Identity identity) +{ + (void) feature; + (void) identity; +} + +BOOL AbilityMgrSliteFeature::OnFeatureMessage(Feature *feature, Request *request) +{ + if (feature == nullptr || request == nullptr) { + return FALSE; + } + return TRUE; +} + +int32_t AbilityMgrSliteFeature::StartAbility(const Want *want) +{ + int32_t ret = AbilityService::GetInstance().StartAbility(want); + ClearWant(const_cast(want)); + return ret; +} + +int32_t AbilityMgrSliteFeature::TerminateAbility(uint64_t token) +{ + uint16_t slitToken = token & 0xFFFF; + return AbilityService::GetInstance().TerminateAbility(slitToken); +} + +int32_t AbilityMgrSliteFeature::SchedulerLifecycleDone(uint64_t token, int state) +{ + return AbilityService::GetInstance().SchedulerLifecycleDone(token, state); +} +} // namespace OHOS diff --git a/services/abilitymgr_lite/src/ability_mission_record.cpp b/services/abilitymgr_lite/src/ability_mission_record.cpp new file mode 100644 index 0000000..1f86087 --- /dev/null +++ b/services/abilitymgr_lite/src/ability_mission_record.cpp @@ -0,0 +1,186 @@ +/* + * Copyright (c) 2020 Huawei Device Co., Ltd. + * 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 "ability_mission_record.h" + +#include "adapter.h" +#include "util/abilityms_log.h" +#include "utils.h" + +namespace OHOS { +AbilityMissionRecord::AbilityMissionRecord(AbilityMissionStack* missionStack, const char *bundleName) + : abilityMissionStack_(missionStack) +{ + if (bundleName != nullptr) { + bundleName_ = Utils::Strdup(bundleName); + } + PRINTD("AbilityMissionRecord", "Constructor"); +} + +AbilityMissionRecord::~AbilityMissionRecord() +{ + abilityMissionStack_ = nullptr; + ClearPageAbility(); + AdapterFree(bundleName_); + PRINTD("AbilityMissionRecord", "Destructor"); +} + +bool AbilityMissionRecord::IsEmpty() const +{ + return pageAbilityRecords_.empty(); +} + +bool AbilityMissionRecord::IsSameMissionRecord(const char *bundleName) const +{ + if (bundleName == nullptr || bundleName_ == nullptr) { + return false; + } + if (strcmp(bundleName, bundleName_) == 0) { + return true; + } + return false; +} + +void AbilityMissionRecord::SetMissionStack(AbilityMissionStack *missionStack) +{ + abilityMissionStack_ = missionStack; +} + +const AbilityMissionStack *AbilityMissionRecord::GetMissionStack() const +{ + return abilityMissionStack_; +} + +const PageAbilityRecord *AbilityMissionRecord::GetTopPageAbility() const +{ + return pageAbilityRecords_.back(); +} + +const PageAbilityRecord *AbilityMissionRecord::GetBottomPageAbility() const +{ + return pageAbilityRecords_.front(); +} + +PageAbilityRecord *AbilityMissionRecord::FindPageAbility(uint64_t token) const +{ + for (auto iterator = pageAbilityRecords_.begin(); iterator != pageAbilityRecords_.end(); ++iterator) { + PageAbilityRecord *record = *iterator; + if (record != nullptr && record->GetToken() == token) { + return record; + } + } + return nullptr; +} + +PageAbilityRecord *AbilityMissionRecord::FindPageAbility(const Want &want) const +{ + for (auto iterator = pageAbilityRecords_.begin(); iterator != pageAbilityRecords_.end(); ++iterator) { + PageAbilityRecord *record = *iterator; + if (record != nullptr && record->IsSamePageAbility(want)) { + return record; + } + } + return nullptr; +} + +PageAbilityRecord *AbilityMissionRecord::GetPrevPageAbility(const PageAbilityRecord ¤t) const +{ + for (auto iterator = pageAbilityRecords_.begin(); iterator != pageAbilityRecords_.end(); ++iterator) { + PageAbilityRecord *record = *iterator; + if (record != nullptr && record->IsSamePageAbility(current)) { + if (iterator == pageAbilityRecords_.begin()) { + return nullptr; + } + return *(--iterator); + } + } + return nullptr; +} + +void AbilityMissionRecord::PushPageAbility(PageAbilityRecord &abilityRecord) +{ + abilityRecord.SetMissionRecord(this); + pageAbilityRecords_.emplace_back(&abilityRecord); +} + +void AbilityMissionRecord::RemovePageAbility(const PageAbilityRecord &target) +{ + auto iterator = pageAbilityRecords_.begin(); + while (iterator != pageAbilityRecords_.end()) { + PageAbilityRecord *oldRecord = *iterator; + if (oldRecord != nullptr && oldRecord->IsSamePageAbility(target)) { + break; + } + ++iterator; + } + + // remove from current to top of stack + while (iterator != pageAbilityRecords_.end()) { + PageAbilityRecord* oldRecord = *iterator; + iterator = pageAbilityRecords_.erase(iterator); + delete oldRecord; + } +} + +void AbilityMissionRecord::ClearPageAbility() +{ + for (auto iterator = pageAbilityRecords_.begin(); iterator != pageAbilityRecords_.end();) { + PageAbilityRecord *abilityRecord = *iterator; + iterator = pageAbilityRecords_.erase(iterator); + delete abilityRecord; + } +} + +void AbilityMissionRecord::ClearPageAbility(AbilityConnectMission *connectMission) +{ + for (auto iterator = pageAbilityRecords_.begin(); iterator != pageAbilityRecords_.end();) { + PageAbilityRecord *abilityRecord = *iterator; + iterator = pageAbilityRecords_.erase(iterator); + if (connectMission != nullptr) { + connectMission->RemoveConnectRecordByPageToken(abilityRecord->GetToken(), bundleName_); + } + delete abilityRecord; + } +} + +void AbilityMissionRecord::SetPrevMissionRecord(const AbilityMissionRecord *missionRecord) +{ + prevMissionRecord_ = missionRecord; +} + +const AbilityMissionRecord *AbilityMissionRecord::GetPrevMissionRecord() const +{ + return prevMissionRecord_; +} + +#ifdef OHOS_DEBUG +AbilityMsStatus AbilityMissionRecord::DumpMissionRecord() const +{ + std::string missionInfo = " MissionRecord: "; + if (bundleName_ != nullptr) { + missionInfo.append(bundleName_); + } + missionInfo.append("\n"); + AbilityMsStatus result = AbilityMsStatus::DumpStatus(missionInfo.c_str()); + for (auto iterator = pageAbilityRecords_.rbegin(); iterator != pageAbilityRecords_.rend(); ++iterator) { + PageAbilityRecord *target = *iterator; + if (target != nullptr) { + result.DumpAppend(target->DumpAbilityRecord()); + } + } + return result; +} +#endif +} // namespace OHOS diff --git a/services/abilitymgr_lite/src/ability_mission_stack.cpp b/services/abilitymgr_lite/src/ability_mission_stack.cpp new file mode 100644 index 0000000..06c8a6d --- /dev/null +++ b/services/abilitymgr_lite/src/ability_mission_stack.cpp @@ -0,0 +1,151 @@ +/* + * Copyright (c) 2020 Huawei Device Co., Ltd. + * 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 "ability_mission_stack.h" + +#include "util/abilityms_log.h" + +namespace OHOS { +AbilityMissionStack::AbilityMissionStack(StackType type) + : stackType_(type) +{ +} + +AbilityMissionStack::~AbilityMissionStack() +{ + for (auto iterator = missionRecords_.begin(); iterator != missionRecords_.end();) { + AbilityMissionRecord *missionRecord = *iterator; + iterator = missionRecords_.erase(iterator); + delete missionRecord; + } +} + +StackType AbilityMissionStack::GetStackType() const +{ + return stackType_; +} + +void AbilityMissionStack::PushTopMissionRecord(AbilityMissionRecord &missionRecord) +{ + missionRecord.SetMissionStack(this); + missionRecords_.emplace_back(&missionRecord); +} + +void AbilityMissionStack::MoveMissionRecordToTop(AbilityMissionRecord &missionRecord) +{ + if (missionRecords_.back() != &missionRecord) { + missionRecords_.remove(&missionRecord); + missionRecords_.emplace_back(&missionRecord); + } +} + +void AbilityMissionStack::RemoveMissionRecord(AbilityMissionRecord &missionRecord) +{ + missionRecords_.remove(&missionRecord); + // clear prev mission record + for (const auto currentMission : missionRecords_) { + if (currentMission != nullptr && currentMission->GetPrevMissionRecord() == &missionRecord) { + currentMission->SetPrevMissionRecord(nullptr); + } + } +} + +void AbilityMissionStack::RemoveMissionRecord(AbilityConnectMission *connectMission, const char *bundleName) +{ + AbilityMissionRecord *missionRecord = GetTargetMissionRecord(bundleName); + CHECK_NULLPTR_RETURN(missionRecord, "AbilityMissionStack", "missionRecord is null"); + missionRecord->ClearPageAbility(connectMission); + RemoveMissionRecord(*missionRecord); + delete missionRecord; +} + +bool AbilityMissionStack::IsTopMissionRecord(const char *bundleName) const +{ + if (bundleName == nullptr) { + return false; + } + AbilityMissionRecord *topMissionRecord = missionRecords_.back(); + if (topMissionRecord != nullptr) { + return topMissionRecord->IsSameMissionRecord(bundleName); + } + return false; +} + +AbilityMissionRecord *AbilityMissionStack::GetTargetMissionRecord(const char *bundleName) const +{ + CHECK_NULLPTR_RETURN_PTR(bundleName, "AbilityMissionStack", "invalid argument"); + for (const auto missionRecord : missionRecords_) { + if (missionRecord != nullptr && missionRecord->IsSameMissionRecord(bundleName)) { + return missionRecord; + } + } + return nullptr; +} + +const AbilityMissionRecord *AbilityMissionStack::GetTopMissionRecord() const +{ + return missionRecords_.back(); +} + +PageAbilityRecord *AbilityMissionStack::FindPageAbility(uint64_t token) const +{ + for (const auto missionRecord : missionRecords_) { + if (missionRecord == nullptr) { + continue; + } + PageAbilityRecord *record = missionRecord->FindPageAbility(token); + if (record != nullptr) { + return record; + } + } + return nullptr; +} + +PageAbilityRecord *AbilityMissionStack::FindPageAbility(const Want &want) const +{ + CHECK_NULLPTR_RETURN_PTR(want.element, "AbilityMissionStack", "invalid argument"); + AbilityMissionRecord *missionRecord = GetTargetMissionRecord(want.element->bundleName); + if (missionRecord != nullptr) { + return missionRecord->FindPageAbility(want); + } + return nullptr; +} + +const PageAbilityRecord *AbilityMissionStack::GetTopPageAbility() const +{ + if (!missionRecords_.empty()) { + return missionRecords_.back()->GetTopPageAbility(); + } + return nullptr; +} + +#ifdef OHOS_DEBUG +AbilityMsStatus AbilityMissionStack::DumpMissionStack() const +{ + if (missionRecords_.size() <= 0) { + return AbilityMsStatus::DumpStatus(""); + } + std::string stackType = (stackType_ == LAUNCHER) ? "launcher\n" : "default\n"; + std::string stackInfo = "MissionStack Type: " + stackType; + AbilityMsStatus result = AbilityMsStatus::DumpStatus(stackInfo.c_str()); + for (const auto missionRecord : missionRecords_) { + if (missionRecord != nullptr) { + result.DumpAppend(missionRecord->DumpMissionRecord()); + } + } + return result; +} +#endif +} // namespace OHOS diff --git a/services/abilitymgr_lite/src/ability_record.cpp b/services/abilitymgr_lite/src/ability_record.cpp new file mode 100755 index 0000000..5a1125a --- /dev/null +++ b/services/abilitymgr_lite/src/ability_record.cpp @@ -0,0 +1,67 @@ +/* + * Copyright (c) 2020 Huawei Device Co., Ltd. + * 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 "ability_record.h" + +#include "adapter.h" +#include "securec.h" +#include "utils.h" + +namespace OHOS { +AbilityRecord::AbilityRecord() + : abilityInfo_() +{ +} + +AbilityRecord::~AbilityRecord() +{ + AdapterFree(appName_); + AdapterFree(appPath_); + AdapterFree(appData_); +} + +void AbilityRecord::SetAppName(const char *bundleName) +{ + AdapterFree(appName_); + appName_ = Utils::Strdup(bundleName); +} + +void AbilityRecord::SetAppPath(const char *appPath) +{ + AdapterFree(appPath_); + appPath_ = Utils::Strdup(appPath); +} + +void AbilityRecord::SetAppData(const void *appData, uint16_t dataLength) +{ + AdapterFree(appData_); + appData_ = Utils::Memdup(appData, dataLength); + if (appData == nullptr) { + dataLength_ = 0; + return; + } + dataLength_ = dataLength; +} + +void AbilityRecord::CopyAbilityRecord(AbilityRecord &abilityRecord, AbilityRecord &newAbilityRecord) +{ + newAbilityRecord.SetAppName(abilityRecord.GetAppName()); + newAbilityRecord.SetAppPath(abilityRecord.GetAppPath()); + newAbilityRecord.SetAppData(abilityRecord.GetAppData(), abilityRecord.GetDataLength()); + newAbilityRecord.SetState(abilityRecord.GetState()); + newAbilityRecord.SetToken(abilityRecord.GetToken()); + newAbilityRecord.SetTaskId(abilityRecord.GetTaskId()); +} +} // namespace OHOS diff --git a/services/abilitymgr_lite/src/ability_service.cpp b/services/abilitymgr_lite/src/ability_service.cpp new file mode 100755 index 0000000..f6004fe --- /dev/null +++ b/services/abilitymgr_lite/src/ability_service.cpp @@ -0,0 +1,564 @@ +/* + * Copyright (c) 2020 Huawei Device Co., Ltd. + * 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 "ability_service.h" + +#include "ability_errors.h" +#include "ability_list.h" +#include "ability_message_id.h" +#include "ability_mgr_service.h" +#include "ability_mgr_slite_feature.h" +#include "ability_record.h" +#include "ability_stack.h" +#include "ability_state.h" +#include "abilityms_log.h" +#include "bundle_manager.h" +#include "cmsis_os.h" +#include "js_app_host.h" +#include "los_task.h" +#include "slite_ability.h" +#include "utils.h" +#include "want.h" + +using namespace OHOS::ACELite; + +namespace OHOS { +constexpr char LAUNCHER_BUNDLE_NAME[] = "com.huawei.launcher"; +constexpr uint16_t LAUNCHER_TOKEN = 0; +constexpr int32_t QUEUE_LENGTH = 32; +constexpr int32_t SIZE_COEFFICIENT = 12; +constexpr int32_t TASK_STACK_SIZE = 0x400 * SIZE_COEFFICIENT; +constexpr int32_t APP_TASK_PRI = 25; +SliteAbility *g_NativeAbility = nullptr; +AbilityMgrService *g_AbilityService = nullptr; +AbilityMgrSliteFeature *g_AbilityFeature = nullptr; + +AbilityService::AbilityService() +{ +} + +AbilityService::~AbilityService() +{ + DeleteRecordInfo(LAUNCHER_TOKEN); +} + +void AbilityService::StartLauncher() +{ + auto record = new AbilityRecord(); + record->SetAppName(LAUNCHER_BUNDLE_NAME); + record->SetToken(LAUNCHER_TOKEN); + record->SetState(SCHEDULE_ACTIVE); + abilityList_.Add(record); + abilityStack_.PushAbility(record); + (void) SchedulerLifecycleInner(record, STATE_ACTIVE); +} + +void AbilityService::CleanWant() +{ + ClearWant(want_); + AdapterFree(want_); +} + +int32_t AbilityService::StartAbility(const Want *want) +{ + if (want == nullptr || want->element == nullptr) { + HILOG_ERROR(HILOG_MODULE_AAFWK, "Ability Service wanted element is null"); + return PARAM_NULL_ERROR; + } + char *bundleName = want->element->bundleName; + if (bundleName == nullptr) { + HILOG_ERROR(HILOG_MODULE_AAFWK, "Ability Service wanted bundleName is null"); + return PARAM_NULL_ERROR; + } + + // TODO Ѿǰֱ̨ӷ + AbilitySvcInfo *info = + static_cast(AdapterMalloc(sizeof(AbilitySvcInfo))); + if (info == nullptr) { + HILOG_ERROR(HILOG_MODULE_AAFWK, "Ability Service AbilitySvcInfo is null"); + return PARAM_NULL_ERROR; + } + // TODO ʼinfo + + // װinfoϢ + // + if (strcmp(bundleName, LAUNCHER_BUNDLE_NAME) == 0) { + info->bundleName = Utils::Strdup(bundleName); + info->path = nullptr; + } else { + // JSӦ + AbilityInfo abilityInfo = { nullptr, nullptr }; + QueryAbilityInfo(want, &abilityInfo); + if ((abilityInfo.bundleName == nullptr) || (strlen(abilityInfo.bundleName) == 0) || + (abilityInfo.srcPath == nullptr) || (strlen(abilityInfo.srcPath) == 0)) { + APP_ERRCODE_EXTRA(EXCE_ACE_APP_START, EXCE_ACE_APP_START_UNKNOWN_BUNDLE_INFO); + ClearAbilityInfo(&abilityInfo); + AdapterFree(info); + HILOG_ERROR(HILOG_MODULE_AAFWK, "Ability Service returned bundleInfo is not valid"); + return PARAM_NULL_ERROR; + } + info->bundleName = OHOS::Utils::Strdup(abilityInfo.bundleName); + info->path = OHOS::Utils::Strdup(abilityInfo.srcPath); + ClearAbilityInfo(&abilityInfo); + } + + info->data = OHOS::Utils::Memdup(want->data, want->dataLength); + info->dataLength = want->dataLength; + auto ret = StartAbility(info); + AdapterFree(info->bundleName); + AdapterFree(info->path); + AdapterFree(info->data); + AdapterFree(info); + return ERR_OK; +} + +void AbilityService::UpdataRecord(AbilitySvcInfo *info) +{ + if (info == nullptr) { + return; + } + AbilityRecord *record = abilityList_.Get(info->bundleName); + if (record == nullptr) { + return; + } + if (record->GetToken() != LAUNCHER_TOKEN) { + return; + } + record->SetAppData(info->data, info->dataLength); +} + +int32_t AbilityService::StartAbility(AbilitySvcInfo *info) +{ + if ((info == nullptr) || (info->bundleName == nullptr) || (strlen(info->bundleName) == 0)) { + return PARAM_NULL_ERROR; + } + HILOG_INFO(HILOG_MODULE_AAFWK, "StartAbility"); + + auto topRecord = abilityStack_.GetTopAbility(); + if ((topRecord == nullptr) || (topRecord->GetAppName() == nullptr)) { + HILOG_ERROR(HILOG_MODULE_AAFWK, "StartAbility top null."); + return PARAM_NULL_ERROR; + } + uint16_t topToken = topRecord->GetToken(); + // + if (strcmp(info->bundleName, LAUNCHER_BUNDLE_NAME) == 0) { + UpdataRecord(info); + // Top棬JSӦҲں̨ + if (topToken != LAUNCHER_TOKEN && topRecord->GetState() != SCHEDULE_BACKGROUND) { + HILOG_INFO(HILOG_MODULE_AAFWK, "Change Js app to background."); + (void) SchedulerLifecycleInner(topRecord, STATE_BACKGROUND); + } else { + // TODO Ƿ֪ͨLauncher TOP棬top棬jsں̨ + (void) SchedulerLifecycle(LAUNCHER_TOKEN, STATE_ACTIVE); + } + return ERR_OK; + } + // TODO CheckǷ + if (!CheckResponse(info->bundleName)) { + return -1; + } + + // jsTOPjsӦãѾtask + if (topRecord->IsAttached() && topRecord->GetToken() != LAUNCHER_TOKEN) { + // ֮ǰͬһӦ tocheck + if (strcmp(info->bundleName, topRecord->GetAppName()) == 0) { + if (topRecord->GetState() == SCHEDULE_BACKGROUND) { + HILOG_INFO(HILOG_MODULE_AAFWK, "StartAbility Resume app when background."); + (void) SchedulerLifecycle(LAUNCHER_TOKEN, STATE_BACKGROUND); + return ERR_OK; + } + HILOG_INFO(HILOG_MODULE_AAFWK, "Js app already started or starting."); + } else { + // TODO ֮ǰjsӦòһӦ JS2JSҪȰ֮ǰJS˳ + return ERR_OK; + } + } + + // application has not been launched and then to check priority and permission. + return PreCheckStartAbility(info->bundleName, info->path, info->data, info->dataLength); +} + +int32_t AbilityService::TerminateAbility(uint16_t token) +{ + HILOG_INFO(HILOG_MODULE_AAFWK, "TerminateAbility [%u]", token); + AbilityRecord *topRecord = const_cast(abilityStack_.GetTopAbility()); + if (topRecord == nullptr) { + APP_ERRCODE_EXTRA(EXCE_ACE_APP_START, EXCE_ACE_APP_STOP_NO_ABILITY_RUNNING); + return PARAM_NULL_ERROR; + } + uint16_t topToken = topRecord->GetToken(); + // TODO CHECK terminate ,Ƿиó + if (token == LAUNCHER_TOKEN) { + // ǰjsں̨, ˺̨jsߵǰ̨ + if (topToken != token && topRecord->GetState() == SCHEDULE_BACKGROUND) { + HILOG_INFO(HILOG_MODULE_AAFWK, "Resume Js app [%u]", topToken); + return SchedulerLifecycle(LAUNCHER_TOKEN, STATE_BACKGROUND); + } + return ERR_OK; + } + + // TODO CHECKǷиó + if (token != topToken) { + APP_ERRCODE_EXTRA(EXCE_ACE_APP_START, EXCE_ACE_APP_STOP_UNKNOWN_ABILITY_TOKEN); + DeleteRecordInfo(token); + return -1; + } + topRecord->SetTerminated(true); + // TerminateAbility TOPjs + return SchedulerLifecycleInner(topRecord, STATE_BACKGROUND); +} + +int32_t AbilityService::PreCheckStartAbility( + const char *bundleName, const char *path, const void *data, uint16_t dataLength) +{ + if (path == nullptr) { + HILOG_ERROR(HILOG_MODULE_AAFWK, "PreCheckStartAbility path is null."); + return PARAM_NULL_ERROR; + } + auto curRecord = abilityList_.Get(bundleName); + if (curRecord != nullptr) { + // ǰѾǰ̨ + if (curRecord->GetState() == SCHEDULE_ACTIVE) { + HILOG_ERROR(HILOG_MODULE_AAFWK, "PreCheckStartAbility cur state active."); + } else if (curRecord->GetState() == SCHEDULE_BACKGROUND) { + // jsں̨Ƚߵ̨ + SchedulerLifecycle(LAUNCHER_TOKEN, STATE_BACKGROUND); + } + return ERR_OK; + } + auto record = new AbilityRecord(); + record->SetToken(GenerateToken()); + record->SetAppName(bundleName); + record->SetAppPath(path); + record->SetAppData(data, dataLength); + record->SetState(SCHEDULE_STOP); + abilityList_.Add(record); + // APP TASK + if (CreateAppTask(record) != ERR_OK) { + HILOG_ERROR(HILOG_MODULE_AAFWK, "CheckResponse CreateAppTask fail"); + abilityList_.Erase(record->GetToken()); + delete record; + return CREATE_APPTASK_ERROR; + } + return ERR_OK; +} + +bool AbilityService::CheckResponse(const char *bundleName) +{ + return true; +} + +int32_t AbilityService::CreateAppTask(AbilityRecord *record) +{ + if ((record == nullptr) || (record->GetAppName() == nullptr)) { + return PARAM_NULL_ERROR; + } + + HILOG_INFO(HILOG_MODULE_AAFWK, "CreateAppTask."); + LOS_TaskLock(); + TSK_INIT_PARAM_S stTskInitParam; + stTskInitParam.pfnTaskEntry = (TSK_ENTRY_FUNC)(JsAppHost::JsAppTaskHandler); + stTskInitParam.uwStackSize = TASK_STACK_SIZE; + stTskInitParam.usTaskPrio = OS_TASK_PRIORITY_LOWEST - APP_TASK_PRI; + stTskInitParam.pcName = const_cast("AppTask"); + stTskInitParam.uwResved = 0; + auto jsAppHost = new JsAppHost(); + stTskInitParam.uwArg = reinterpret_cast((uintptr_t)jsAppHost); + UINT32 appTaskId = 0; + UINT32 res = LOS_TaskCreate(&appTaskId, &stTskInitParam); + if (res != LOS_OK) { + APP_ERRCODE_EXTRA(EXCE_ACE_APP_START, EXCE_ACE_APP_START_CREATE_TSAK_FAILED); + delete jsAppHost; + LOS_TaskUnlock(); + return CREATE_APPTASK_ERROR; + } + osMessageQueueId_t jsAppQueueId = osMessageQueueNew(QUEUE_LENGTH, sizeof(AbilityInnerMsg), nullptr); + jsAppHost->SetMessageQueueId(jsAppQueueId); + LOS_TaskUnlock(); + + record->SetTaskId(appTaskId); + record->SetMessageQueueId(jsAppQueueId); + record->SetJsAppHost(jsAppHost); + + // LoadPermissions(record->GetAppName(), appTaskId) + record->SetState(SCHEDULE_INACTIVE); + // TODO SchedulerLifecycle֮ + abilityStack_.PushAbility(record); + APP_EVENT(MT_ACE_APP_START); + if (SchedulerLifecycle(LAUNCHER_TOKEN, STATE_BACKGROUND) != 0) { + APP_ERRCODE_EXTRA(EXCE_ACE_APP_START, EXCE_ACE_APP_START_LAUNCHER_EXIT_FAILED); + HILOG_INFO(HILOG_MODULE_AAFWK, "CreateAppTask Fail to hide launcher"); + abilityStack_.PopAbility(); + return SCHEDULER_LIFECYCLE_ERROR; + } + return ERR_OK; +} + +uint16_t AbilityService::GenerateToken() +{ + static uint16_t token = LAUNCHER_TOKEN; + if (token == UINT16_MAX - 1) { + token = LAUNCHER_TOKEN; + } + return ++token; +} + +void AbilityService::DeleteRecordInfo(uint16_t token) +{ + AbilityRecord *record = abilityList_.Get(token); + if (record == nullptr) { + return; + } + if (token != LAUNCHER_TOKEN) { + if (record->IsAttached()) { + UINT32 taskId = record->GetTaskId(); + // UnLoadPermissions(taskId) + LOS_TaskDelete(taskId); + osMessageQueueId_t jsAppQueueId = record->GetMessageQueueId(); + osMessageQueueDelete(jsAppQueueId); + auto jsAppHost = const_cast(record->GetJsAppHost()); + delete jsAppHost; + // free all JS native memory after exiting it + // CleanTaskMem(taskId) + } + // record app info event when stop app + RecordAbiityInfoEvt(record->GetAppName()); + } + abilityList_.Erase(token); + delete record; +} + +void AbilityService::OnActiveDone(uint16_t token) +{ + HILOG_INFO(HILOG_MODULE_AAFWK, "OnActiveDone [%u]", token); + SetAbilityState(token, SCHEDULE_ACTIVE); + auto topRecord = const_cast(abilityStack_.GetTopAbility()); + if (topRecord == nullptr) { + return; + } + if (token == LAUNCHER_TOKEN) { + // 漤JS״̬Ϊ̨˳JS + if (topRecord->GetToken() != LAUNCHER_TOKEN) { + if (topRecord->GetState() != SCHEDULE_BACKGROUND) { + APP_ERRCODE_EXTRA(EXCE_ACE_APP_START, EXCE_ACE_APP_START_LAUNCHER_EXIT_FAILED); + HILOG_ERROR(HILOG_MODULE_AAFWK, "Active launcher js bg fail"); + abilityStack_.PopAbility(); + DeleteRecordInfo(topRecord->GetToken()); + } else if (topRecord->IsTerminated()) { + (void) SchedulerLifecycleInner(topRecord, STATE_UNINITIALIZED); + } + } + return; + } + // js + if (topRecord->GetToken() == token) { + APP_EVENT(MT_ACE_APP_ACTIVE); + } +} + +void AbilityService::OnBackgroundDone(uint16_t token) +{ + HILOG_INFO(HILOG_MODULE_AAFWK, "OnBackgroundDone [%u]", token); + SetAbilityState(token, SCHEDULE_BACKGROUND); + auto topRecord = const_cast(abilityStack_.GetTopAbility()); + if (topRecord == nullptr) { + return; + } + // JSߵ̨LAUNCHER + if (token != LAUNCHER_TOKEN) { + if (topRecord->GetToken() == token) { + APP_EVENT(MT_ACE_APP_BACKGROUND); + topRecord->SetTerminated(true); + (void) SchedulerLifecycle(LAUNCHER_TOKEN, STATE_ACTIVE); + } + return; + } + // launcherߵ̨ + if (topRecord->GetToken() != LAUNCHER_TOKEN) { + (void) SchedulerLifecycleInner(topRecord, STATE_ACTIVE); + } else { + // TODO CHECKû + HILOG_WARN(HILOG_MODULE_AAFWK, "Js app exit, but has no js app."); + } +} + +void AbilityService::OnDestroyDone(uint16_t token) +{ + HILOG_INFO(HILOG_MODULE_AAFWK, "OnDestroyDone [%u]", token); + SetAbilityState(token, SCHEDULE_STOP); + // 治destroy + if (token == LAUNCHER_TOKEN) { + return; + } + auto topRecord = abilityStack_.GetTopAbility(); + if ((topRecord == nullptr) || (topRecord->GetToken() != token)) { + DeleteRecordInfo(token); + return; + } + APP_EVENT(MT_ACE_APP_STOP); + abilityStack_.PopAbility(); + DeleteRecordInfo(token); + + // JSҪijֱӼ + if (pendingToken_ == 0) { + (void) SchedulerLifecycle(LAUNCHER_TOKEN, STATE_ACTIVE); + return; + } + + // JS2JS + auto record = abilityList_.Get(pendingToken_); + if (CreateAppTask(record) != ERR_OK) { + abilityList_.Erase(pendingToken_); + delete record; + (void) SchedulerLifecycle(LAUNCHER_TOKEN, STATE_ACTIVE); + } + pendingToken_ = 0; +} + +int32_t AbilityService::SchedulerLifecycle(uint64_t token, int32_t state) +{ + AbilityRecord *record = abilityList_.Get(token); + if (record == nullptr) { + return PARAM_NULL_ERROR; + } + return SchedulerLifecycleInner(record, state); +} + +void AbilityService::SetAbilityState(uint64_t token, int32_t state) +{ + AbilityRecord *record = abilityList_.Get(token); + if (record == nullptr) { + return; + } + record->SetState((AbilityState) state); +} + +int32_t AbilityService::SchedulerLifecycleInner(const AbilityRecord *record, int32_t state) +{ + if (record == nullptr) { + return PARAM_NULL_ERROR; + } + // ֪ͨӦabilityӦ + if (record->GetToken() != LAUNCHER_TOKEN) { // jsӦ + (void) SendMsgToJsAbility(state, record); + return ERR_OK; + } + // native ӦãȡnativeabilityӦ + if (g_NativeAbility == nullptr) { + return PARAM_NULL_ERROR; + } + // wantڴ棬ڷͷ + Want *info = static_cast(AdapterMalloc(sizeof(Want))); + if (info == nullptr) { + return MEMORY_MALLOC_ERROR; + } + info->element = nullptr; + info->data = nullptr; + info->dataLength = 0; + + ElementName elementName = {}; + SetElementBundleName(&elementName, LAUNCHER_BUNDLE_NAME); + SetWantElement(info, elementName); + ClearElement(&elementName); + SetWantData(info, record->GetAppData(), record->GetDataLength()); + SchedulerAbilityLifecycle(g_NativeAbility, *info, state); + ClearWant(info); + return ERR_OK; +} + +void AbilityService::SchedulerAbilityLifecycle(SliteAbility *ability, const Want &want, int32_t state) +{ + if (ability == nullptr) { + return; + } + switch (state) { + case STATE_ACTIVE: { + ability->OnActive(want); + break; + } + case STATE_BACKGROUND: { + ability->OnBackground(); + break; + } + default: { + break; + } + } + return; +} + +int32_t AbilityService::SchedulerLifecycleDone(uint64_t token, int32_t state) +{ + switch (state) { + case STATE_ACTIVE: { + OnActiveDone(token); + break; + } + case STATE_BACKGROUND: { + OnBackgroundDone(token); + break; + } + case STATE_UNINITIALIZED: { // TODO DESTROY + OnDestroyDone(token); + break; + } + default: { + break; + } + } + return ERR_OK; +} + +bool AbilityService::SendMsgToJsAbility(int32_t state, const AbilityRecord *record) +{ + if (record == nullptr) { + return false; + } + + AbilityInnerMsg innerMsg; + if (state == STATE_ACTIVE) { + innerMsg.msgId = ACTIVE; + } else if (state == STATE_BACKGROUND) { + innerMsg.msgId = BACKGROUND; + } else if (state == STATE_UNINITIALIZED) { + innerMsg.msgId = DESTORY; + } else { + innerMsg.msgId = (AbilityMsgId) state; + } + innerMsg.bundleName = record->GetAppName(); + innerMsg.token = record->GetToken(); + innerMsg.path = record->GetAppPath(); + innerMsg.data = const_cast(record->GetAppData()); + innerMsg.dataLength = record->GetDataLength(); + osMessageQueueId_t appQueueId = record->GetMessageQueueId(); + osStatus_t ret = osMessageQueuePut(appQueueId, static_cast(&innerMsg), 0, 0); + return ret == osOK; +} + +void AbilityService::setNativeAbility(const SliteAbility *ability) +{ + g_AbilityFeature = AbilityMgrSliteFeature::GetInstance(); + g_AbilityService = AbilityMgrService::GetInstance(); + g_NativeAbility = const_cast(ability); +} +} // namespace OHOS + +extern "C" { +int InstallNativeAbility(const AbilityInfo *abilityInfo, const OHOS::SliteAbility *ability) +{ + OHOS::AbilityService::GetInstance().setNativeAbility(ability); + return ERR_OK; +} +} \ No newline at end of file diff --git a/services/abilitymgr_lite/src/ability_stack.cpp b/services/abilitymgr_lite/src/ability_stack.cpp new file mode 100644 index 0000000..f78d095 --- /dev/null +++ b/services/abilitymgr_lite/src/ability_stack.cpp @@ -0,0 +1,61 @@ +/* + * Copyright (c) 2020 Huawei Device Co., Ltd. + * 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 "ability_stack.h" + +#include "ability_record.h" + +namespace OHOS { +const AbilityRecord *AbilityStack::GetTopAbility() const +{ + if (abilityStack_.Size() != 0) { + return abilityStack_.Front(); + } + return nullptr; +} + +int AbilityStack::GetAllAbilities(AbilityRecord **abilityRecords) +{ + int size = abilityStack_.Size(); + if (size == 0) { + *abilityRecords = nullptr; + return 0; + } + + auto ars = new AbilityRecord[size]; + *abilityRecords = ars; + for (auto node = abilityStack_.Begin(); node != abilityStack_.End(); node = node->next_) { + if (node->value_ == nullptr) { + continue; + } + AbilityRecord::CopyAbilityRecord(*(node->value_), *ars); + ars++; + } + + return size; +} + +void AbilityStack::PushAbility(AbilityRecord *record) +{ + if (record != nullptr) { + abilityStack_.PushFront(record); + } +} + +void AbilityStack::PopAbility() +{ + abilityStack_.PopFront(); +} +} // namespace OHOS \ No newline at end of file diff --git a/services/abilitymgr_lite/src/ability_stack_manager.cpp b/services/abilitymgr_lite/src/ability_stack_manager.cpp new file mode 100644 index 0000000..404211d --- /dev/null +++ b/services/abilitymgr_lite/src/ability_stack_manager.cpp @@ -0,0 +1,237 @@ +/* + * Copyright (c) 2020 Huawei Device Co., Ltd. + * 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 "ability_stack_manager.h" + +#include "util/abilityms_helper.h" + +namespace OHOS { +PageAbilityRecord *AbilityStackManager::GeneratePageAbility(const AbilityInfo &target, + const Want &want, const PageAbilityRecord *topAbility, AbilityMgrContext &amsContext) const +{ + CHECK_NULLPTR_RETURN_PTR(target.name, "AbilityStackManager", "target ability name is nullptr"); + auto stack = const_cast(amsContext.GetTargetMissionStack(target.bundleName)); + CHECK_NULLPTR_RETURN_PTR(stack, "AbilityStackManager", "missionStack is nullptr"); + + PageAbilityRecord *targetAbility = nullptr; + AbilityMissionRecord *targetMission = stack->GetTargetMissionRecord(target.bundleName); + auto topMissionRecord = stack->GetTopMissionRecord(); + /* launcher -> default or default -> launcher */ + if (topAbility == nullptr || AbilityMsHelper::IsAceAbility(target.name) || + (!topAbility->IsLauncherAbility() && AbilityMsHelper::IsLauncherAbility(target.bundleName)) || + (topAbility->IsLauncherAbility() && !AbilityMsHelper::IsLauncherAbility(target.bundleName))) { + // Get the mission record of the current bundleName + PRINTD("AbilityStackManager", "launcher jumps to default or default jumps to launcher"); + if (targetMission == nullptr) { + targetMission = new AbilityMissionRecord(stack, target.bundleName); + targetAbility = new PageAbilityRecord(target, want); + targetMission->PushPageAbility(*targetAbility); + stack->PushTopMissionRecord(*targetMission); + } else { + targetAbility = const_cast(targetMission->GetTopPageAbility()); + stack->MoveMissionRecordToTop(*targetMission); + } + } else { + PRINTD("AbilityStackManager", "default application jumps to another default"); + if (targetMission == nullptr) { + targetMission = new AbilityMissionRecord(stack, target.bundleName); + stack->PushTopMissionRecord(*targetMission); + } else { + stack->MoveMissionRecordToTop(*targetMission); + } + targetAbility = new PageAbilityRecord(target, want); + targetMission->PushPageAbility(*targetAbility); + } + + // default jumps to default, then return to default + if (topAbility != nullptr && !topAbility->IsLauncherAbility() && + targetAbility != nullptr && !targetAbility->IsLauncherAbility()) { + if (targetMission != nullptr && topMissionRecord != nullptr && targetMission != topMissionRecord) { + targetMission->SetPrevMissionRecord(topMissionRecord); + } + } + + amsContext.SetTopMissionStacks(stack); + return targetAbility; +} + +const PageAbilityRecord *AbilityStackManager::GetTopPageAbility(const AbilityMgrContext &amsContext) const +{ + const AbilityMissionStack *topMissionStack = amsContext.GetTopMissionStacks(); + CHECK_NULLPTR_RETURN_PTR(topMissionStack, "AbilityStackManager", "topMissionStack is nullptr"); + return topMissionStack->GetTopPageAbility(); +} + +void AbilityStackManager::RemovePageAbility(const PageAbilityRecord &target, AbilityMgrContext &amsContext) +{ + AbilityMissionRecord *missionRecord = const_cast(target.GetMissionRecord()); + CHECK_NULLPTR_RETURN(missionRecord, "AbilityStackManager", "missionRecord is nullptr"); + missionRecord->RemovePageAbility(target); + // Current mission reocrd is empty + if (missionRecord->IsEmpty()) { + AbilityMissionStack *stack = const_cast(missionRecord->GetMissionStack()); + if (stack != nullptr) { + stack->RemoveMissionRecord(*missionRecord); + } + auto prevMissionRecord = const_cast(missionRecord->GetPrevMissionRecord()); + if (stack != nullptr && prevMissionRecord != nullptr) { + stack->MoveMissionRecordToTop(*prevMissionRecord); + } else { + amsContext.SetTopMissionStacks(amsContext.GetLauncherMissionStacks()); + } + delete missionRecord; + } +} + +void AbilityStackManager::ClearAbilityStack(const char *bundleName, AbilityMgrContext &amsContext) const +{ + CHECK_NULLPTR_RETURN(bundleName, "AbilityStackManager", "invalid argument"); + AbilityConnectMission *connectMission = const_cast(amsContext.GetServiceConnects()); + if (connectMission != nullptr) { + connectMission->RemoveServiceRecord(bundleName); + } + // get target mission record + auto missionStack = const_cast(amsContext.GetTargetMissionStack(bundleName)); + CHECK_NULLPTR_RETURN(missionStack, "AbilityStackManager", "missionStack is nullptr"); + AbilityMissionRecord *missionRecord = missionStack->GetTargetMissionRecord(bundleName); + if (missionRecord != nullptr) { + // if default application jumps to another default, return prev application + auto prevMissionRecord = const_cast(missionRecord->GetPrevMissionRecord()); + if (prevMissionRecord != nullptr) { + missionStack->MoveMissionRecordToTop(*prevMissionRecord); + } else { + // return launcher application + const AbilityMissionStack *topMissionStack = amsContext.GetTopMissionStacks(); + if (topMissionStack != nullptr && topMissionStack->IsTopMissionRecord(bundleName)) { + amsContext.SetTopMissionStacks(amsContext.GetLauncherMissionStacks()); + } + } + } + + missionStack->RemoveMissionRecord(connectMission, bundleName); +} + +PageAbilityRecord *AbilityStackManager::FindPageAbility(const AbilityMgrContext &amsContext, uint64_t token) const +{ + PageAbilityRecord *record = nullptr; + const AbilityMissionStack *stack = amsContext.GetDefaultMissionStacks(); + if (stack != nullptr) { + record = stack->FindPageAbility(token); + if (record != nullptr) { + return record; + } + } + stack = amsContext.GetLauncherMissionStacks(); + if (stack != nullptr) { + record = stack->FindPageAbility(token); + } + + // find service ability + if (record == nullptr) { + auto serviceConnects = amsContext.GetServiceConnects(); + if (serviceConnects != nullptr) { + record = serviceConnects->FindServiceRecord(token); + } + } + return record; +} + +const PageAbilityRecord *AbilityStackManager::FindPageAbility(const AbilityMgrContext &amsContext, + const Want &want) const +{ + CHECK_NULLPTR_RETURN_PTR(want.element, "AbilityStackManager", "element is nullptr"); + auto missionStack = amsContext.GetTargetMissionStack(want.element->bundleName); + CHECK_NULLPTR_RETURN_PTR(missionStack, "AbilityStackManager", "target mission stack is nullptr"); + PageAbilityRecord *record = missionStack->FindPageAbility(want); + if (record != nullptr) { + return record; + } + const AbilityConnectMission *connectMission = amsContext.GetServiceConnects(); + CHECK_NULLPTR_RETURN_PTR(connectMission, "AbilityStackManager", "service connect is nullptr"); + return connectMission->FindServiceRecord(want.element->bundleName, want.element->abilityName); +} + +const PageAbilityRecord *AbilityStackManager::GetPrevPageAbility(const AbilityMgrContext &amsContext, + const PageAbilityRecord ¤t) const +{ + AbilityMissionRecord *currentMission = const_cast(current.GetMissionRecord()); + if (currentMission != nullptr) { + PageAbilityRecord *prevAbility = currentMission->GetPrevPageAbility(current); + if (prevAbility != nullptr) { + return prevAbility; + } else { + auto prevMission = currentMission->GetPrevMissionRecord(); + if (prevMission != nullptr) { + return prevMission->GetTopPageAbility(); + } + } + } + auto launcherStack = amsContext.GetLauncherMissionStacks(); + CHECK_NULLPTR_RETURN_PTR(launcherStack, "AbilityStackManager", "launcherStack is nullptr"); + return launcherStack->GetTopPageAbility(); +} + +bool AbilityStackManager::ExistAppInStack(const AbilityInfo &target, AbilityMgrContext &amsContext) const +{ + auto stack = amsContext.GetTargetMissionStack(target.bundleName); + if (stack == nullptr) { + return false; + } + AbilityMissionRecord *targetMission = stack->GetTargetMissionRecord(target.bundleName); + return targetMission != nullptr; +} + +#ifdef OHOS_DEBUG +AbilityMsStatus AbilityStackManager::DumpAllAbilityRecord(const AbilityMgrContext &amsContext) const +{ + AbilityMsStatus result = AbilityMsStatus::DumpStatus(""); + const AbilityMissionStack *stack = amsContext.GetTopMissionStacks(); + if (stack != nullptr) { + result.DumpAppend(stack->DumpMissionStack()); + if (stack->GetStackType() == LAUNCHER) { + stack = amsContext.GetDefaultMissionStacks(); + if (stack != nullptr) { + result.DumpAppend(stack->DumpMissionStack()); + } + } else if (stack->GetStackType() == DEFAULT) { + stack = amsContext.GetLauncherMissionStacks(); + if (stack != nullptr) { + result.DumpAppend(stack->DumpMissionStack()); + } + } + } + const AbilityConnectMission *mission = amsContext.GetServiceConnects(); + if (mission != nullptr) { + result.DumpAppend(mission->DumpConnectMission()); + } + return result; +} +#endif + +PageAbilityRecord *AbilityStackManager::FindServiceAbility(const AbilityMgrContext &amsContext, uint64_t token) const +{ + auto serviceConnects = amsContext.GetServiceConnects(); + CHECK_NULLPTR_RETURN_PTR(serviceConnects, "AbilityStackManager", "serviceConnects is nullptr"); + return serviceConnects->FindServiceRecord(token); +} + +PageAbilityRecord *AbilityStackManager::FindServiceAbility(const AbilityMgrContext &amsContext, + const char *bundleName, const char *abilityName) const +{ + auto serviceConnects = amsContext.GetServiceConnects(); + CHECK_NULLPTR_RETURN_PTR(serviceConnects, "AbilityStackManager", "serviceConnects is nullptr"); + return serviceConnects->FindServiceRecord(bundleName, abilityName); +} +} diff --git a/services/abilitymgr_lite/src/ability_worker.cpp b/services/abilitymgr_lite/src/ability_worker.cpp new file mode 100644 index 0000000..b3fb42e --- /dev/null +++ b/services/abilitymgr_lite/src/ability_worker.cpp @@ -0,0 +1,184 @@ +/* + * Copyright (c) 2020 Huawei Device Co., Ltd. + * 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 "ability_worker.h" + +#define __STDC_FORMAT_MACROS +#include + +#include "ability_activate_task.h" +#include "ability_attach_task.h" +#include "ability_background_task.h" +#include "ability_connect_done_task.h" +#include "ability_connect_task.h" +#include "ability_disconnect_done_task.h" +#include "ability_disconnect_task.h" +#include "ability_dump_task.h" +#include "ability_inactivate_task.h" +#include "ability_start_task.h" +#include "ability_stop_task.h" +#include "ability_terminate_service_task.h" +#include "ability_terminate_task.h" +#include "app_restart_task.h" +#include "app_terminate_task.h" +#include "util/abilityms_helper.h" + +namespace OHOS { +AbilityWorker::AbilityWorker() +{ + abilityMgrContext_ = new AbilityMgrContext(); +} + +AbilityWorker::~AbilityWorker() +{ + delete abilityMgrContext_; + abilityMgrContext_ = nullptr; +} + +AbilityMsStatus AbilityWorker::StartAbility(const Want &want, const AbilityInfo &target, + const BundleInfo &bundleInfo, pid_t callingUid) +{ + if (!AbilityMsHelper::CheckVisiblePermission(callingUid, bundleInfo.uid, target.isVisible)) { + return AbilityMsStatus::PermissionStatus("start ability visible is false"); + } + AbilityStartTask startTask(abilityMgrContext_, &want, &target, &bundleInfo); + return startTask.Execute(); +} + +AbilityMsStatus AbilityWorker::AttachBundle(const AbilityThreadClient &client) +{ + PRINTD("AbilityWorker", "app token(%{private}" PRIu64 ")", client.GetToken()); + AbilityAttachTask attachTask(&client); + return attachTask.Execute(); +} + +AbilityMsStatus AbilityWorker::TerminateAbility(uint64_t token) +{ + PRINTD("AbilityWorker", "ability token(%{private}" PRIu64 ")", token); + AbilityTerminateTask terminateTask(abilityMgrContext_, token); + return terminateTask.Execute(); +} + +AbilityMsStatus AbilityWorker::TerminateService(const AbilityInfo &target, const BundleInfo &bundleInfo, + pid_t callingUid) +{ + if (!AbilityMsHelper::CheckVisiblePermission(callingUid, bundleInfo.uid, target.isVisible)) { + return AbilityMsStatus::PermissionStatus("terminate service visible is false"); + } + AbilityTerminateServiceTask terminateServiceTask(abilityMgrContext_, &target); + return terminateServiceTask.Execute(); +} + +AbilityMsStatus AbilityWorker::AbilityTransaction(const TransactionState &state) +{ + PRINTD("AbilityWorker", "ability token(%{private}" PRIu64 "), state(%{public}d)", state.token, state.state); + AbilityTask *task = nullptr; + switch (state.state) { + case STATE_BACKGROUND: + task = new AbilityBackgroundTask(abilityMgrContext_, state.token); + break; + case STATE_INACTIVE: + task = new AbilityInactivateTask(abilityMgrContext_, state.token); + break; + case STATE_ACTIVE: + task = new AbilityActivateTask(abilityMgrContext_, state.token); + break; + case STATE_INITIAL: + task = new AbilityStopTask(abilityMgrContext_, state.token); + break; + default: + break; + } + AbilityMsStatus status = (task != nullptr) ? task->Execute() : AbilityMsStatus(); + delete task; + return status; +} + +AbilityMsStatus AbilityWorker::TerminateApp(const char *bundleName) +{ + AppTerminateTask appTerminateTask(abilityMgrContext_, bundleName); + return appTerminateTask.Execute(); +} + +AbilityMsStatus AbilityWorker::RestartApp(const BundleInfo &bundleInfo) +{ + AppRestartTask restartTask(abilityMgrContext_, &bundleInfo); + return restartTask.Execute(); +} + +AbilityMsStatus AbilityWorker::ConnectAbility(const AbilityConnectTransParam &connectParam, + const AbilityInfo &target, const BundleInfo &bundleInfo) +{ + if (!AbilityMsHelper::CheckVisiblePermission(connectParam.GetCallingUid(), bundleInfo.uid, target.isVisible)) { + return AbilityMsStatus::PermissionStatus("connect ability visibale is false"); + } + if (abilityMgrContext_ == nullptr) { + return AbilityMsStatus::TaskStatus("connect", "invalid argument"); + } + auto serviceConnects = abilityMgrContext_->GetServiceConnects(); + if (serviceConnects == nullptr) { + return AbilityMsStatus::TaskStatus("connect", "invalid argument"); + } + if (connectParam.GetWant() == nullptr || connectParam.GetWant()->element == nullptr) { + return AbilityMsStatus::TaskStatus("connect", "invalid argument"); + } + char *bundleName = connectParam.GetWant()->element->bundleName; + char *abilityName = connectParam.GetWant()->element->abilityName; + auto abilityRecord = serviceConnects->FindServiceRecord(bundleName, abilityName); + if (abilityRecord == nullptr) { + PRINTD("AbilityWorker", "ability start first"); + AbilityStartTask startTask(abilityMgrContext_, connectParam.GetWant(), &target, &bundleInfo); + startTask.SetWaitConnect(true); + AbilityMsStatus status = startTask.Execute(); + if (!status.IsOk()) { + return status; + } + } else { + PRINTD("AbilityWorker", "ability has started"); + } + abilityRecord = serviceConnects->FindServiceRecord(bundleName, abilityName); + if (abilityRecord == nullptr) { + return AbilityMsStatus::TaskStatus("connect", "generate ability record failure"); + } + AbilityConnectTask connectTask(abilityMgrContext_, *connectParam.GetWant(), + connectParam.GetSvcIdentity(), connectParam.GetToken()); + AbilityMsStatus status = connectTask.Execute(); + return status; +} + +AbilityMsStatus AbilityWorker::DisconnectAbility(const SvcIdentity &identity, uint64_t token) +{ + AbilityDisconnectTask disconnectTask(abilityMgrContext_, identity, token); + return disconnectTask.Execute(); +} + +AbilityMsStatus AbilityWorker::ConnectAbilityDone(const SvcIdentity &identity, uint64_t token) +{ + AbilityConnectDoneTask connectDoneTask(abilityMgrContext_, identity, token); + return connectDoneTask.Execute(); +} + +AbilityMsStatus AbilityWorker::DisconnectAbilityDone(uint64_t token) +{ + AbilityDisconnectDoneTask connectDoneTask(abilityMgrContext_, token); + return connectDoneTask.Execute(); +} + +AbilityMsStatus AbilityWorker::DumpAbility(const AbilityDumpClient &client) +{ + AbilityDumpTask dumpTask(abilityMgrContext_, &client); + return dumpTask.Execute(); +} +} // namespace OHOS diff --git a/services/abilitymgr_lite/src/app_manager.cpp b/services/abilitymgr_lite/src/app_manager.cpp new file mode 100644 index 0000000..b3d275f --- /dev/null +++ b/services/abilitymgr_lite/src/app_manager.cpp @@ -0,0 +1,112 @@ +/* + * Copyright (c) 2020 Huawei Device Co., Ltd. + * 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_manager.h" + +#define __STDC_FORMAT_MACROS +#include +#include + +#include "token_generate.h" +#include "util/abilityms_log.h" + +namespace OHOS { +AppRecord *AppManager::StartAppProcess(const BundleInfo &bundleInfo) +{ + CHECK_NULLPTR_RETURN_PTR(bundleInfo.bundleName, "AppManager", "invalid argument"); + AppRecord *appRecord = GetAppRecordByBundleName(bundleInfo.bundleName); + if (appRecord != nullptr) { + PRINTI("AppManager", "%{public}s AppRecord is already exist", bundleInfo.bundleName); + return appRecord; + } + uint64_t token = TokenGenerate::GenerateToken(); + appRecord = new AppRecord(bundleInfo, token); + AbilityMsStatus status = spawnClient_.SpawnProcess(*appRecord); + if (!status.IsOk()) { + status.LogStatus(); + delete appRecord; + return nullptr; + } + PRINTD("AppManager", "start app name:%{public}s, token: %{private}" PRIu64, + appRecord->GetBundleInfo().bundleName, token); + appRecords_.emplace_back(appRecord); + return appRecord; +} + +void AppManager::RemoveAppRecord(const AppRecord &appRecord) +{ + for (auto iterator = appRecords_.begin(); iterator != appRecords_.end();) { + AppRecord *current = *iterator; + if (current != nullptr && current->GetIdentityId() == appRecord.GetIdentityId()) { + PRINTD("AppManager", "remove process %{private}" PRIu64, current->GetIdentityId()); + current->UnloadPermission(); + iterator = appRecords_.erase(iterator); + delete current; + } else { + ++iterator; + } + } +} + +AbilityMsStatus AppManager::TerminateAppProcess(const char *bundleName) +{ + AppRecord *current = GetAppRecordByBundleName(bundleName); + if (current == nullptr) { + PRINTI("AppManager", "app record is not find"); + return AbilityMsStatus::Ok(); + } + // exit app process + return current->AppExitTransaction(); +} + +void AppManager::RemoveAppRecord(const char *bundleName) +{ + CHECK_NULLPTR_RETURN(bundleName, "AppManager", "start"); + for (auto iterator = appRecords_.cbegin(); iterator != appRecords_.cend();) { + const AppRecord *current = *iterator; + if (current != nullptr && current->GetBundleInfo().bundleName != nullptr && + (strcmp(current->GetBundleInfo().bundleName, bundleName) == 0)) { + PRINTD("AppManager", "remove process name:%{public}s", bundleName); + current->UnloadPermission(); + iterator = appRecords_.erase(iterator); + delete current; + } else { + ++iterator; + } + } +} + +const AppRecord *AppManager::GetAppRecordByToken(uint64_t token, pid_t pid) +{ + for (const auto &appRecord : appRecords_) { + if (appRecord != nullptr && appRecord->GetIdentityId() == token && appRecord->GetPid() == pid) { + return appRecord; + } + } + return nullptr; +} + +AppRecord *AppManager::GetAppRecordByBundleName(const char *bundleName) +{ + CHECK_NULLPTR_RETURN_PTR(bundleName, "AppManager", "invalid argument"); + for (const auto &appRecord : appRecords_) { + if (appRecord != nullptr && appRecord->GetBundleInfo().bundleName != nullptr && + (strcmp(appRecord->GetBundleInfo().bundleName, bundleName) == 0)) { + return appRecord; + } + } + return nullptr; +} +} diff --git a/services/abilitymgr_lite/src/app_record.cpp b/services/abilitymgr_lite/src/app_record.cpp new file mode 100755 index 0000000..e264561 --- /dev/null +++ b/services/abilitymgr_lite/src/app_record.cpp @@ -0,0 +1,183 @@ +/* + * Copyright (c) 2020 Huawei Device Co., Ltd. + * 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_record.h" + +#include "adapter.h" +#include "bundle_info_utils.h" +#include "page_ability_record.h" +#include "pms.h" +#include "securec.h" +#include "utils.h" + +namespace OHOS { +AppRecord::AppRecord(const BundleInfo &bundleInfo, uint64_t identityId) + : identityId_(identityId) +{ + BundleInfoUtils::CopyBundleInfo(0, &bundleInfo_, bundleInfo); +} + +AppRecord::~AppRecord() +{ + ClearBundleInfo(&bundleInfo_); + delete abilityThreadClient_; +} + +void AppRecord::SetPid(const pid_t pid) +{ + pid_ = pid; +} + +pid_t AppRecord::GetPid() const +{ + return pid_; +} + +uint64_t AppRecord::GetIdentityId() const +{ + return identityId_; +} + +const BundleInfo &AppRecord::GetBundleInfo() const +{ + return bundleInfo_; +} + +AbilityMsStatus AppRecord::LoadPermission() const +{ + int ret = LoadPermissions(bundleInfo_.bundleName, bundleInfo_.uid); + if (ret != PERM_ERRORCODE_SUCCESS) { + AppExitTransaction(); + std::string errorMsg = "load application permission ret = " + std::to_string(ret); + return AbilityMsStatus::PermissionStatus(errorMsg.c_str()); + } + return AbilityMsStatus::Ok(); +} + +void AppRecord::UnloadPermission() const +{ + UnLoadPermissions(bundleInfo_.uid); +} + +AbilityMsStatus AppRecord::QueryAppCapability(const char *bundleName, uint32_t **caps, uint32_t *capNums) +{ + int ret = QueryAppCapabilities(bundleName, caps, capNums); + if (ret == PERM_ERRORCODE_SUCCESS || ret == PERM_ERRORCODE_FILE_NOT_EXIST) { + return AbilityMsStatus::Ok(); + } + std::string errorMsg = "query application permission ret = " + std::to_string(ret); + return AbilityMsStatus::AppCapabilitiesStatus(errorMsg.c_str()); +} + +AbilityMsStatus AppRecord::SetAbilityThreadClient(const AbilityThreadClient &client) +{ + abilityThreadClient_ = new AbilityThreadClient(client); + return abilityThreadClient_->Initialize(bundleInfo_.bundleName); +} + +AbilityMsStatus AppRecord::AbilityTransaction(const TransactionState &state, + const Want &want, AbilityType abilityType) const +{ + if (abilityThreadClient_ != nullptr) { + return abilityThreadClient_->AbilityTransaction(state, want, abilityType); + } + return AbilityMsStatus::AppTransanctStatus("life cycle ability thread client not exsit"); +} + +AbilityMsStatus AppRecord::AppInitTransaction() const +{ + if (abilityThreadClient_ != nullptr) { + return abilityThreadClient_->AppInitTransaction(bundleInfo_); + } + return AbilityMsStatus::AppTransanctStatus("app init ability thread client not exsit"); +} + +AbilityMsStatus AppRecord::AppExitTransaction() const +{ + if (abilityThreadClient_ != nullptr) { + return abilityThreadClient_->AppExitTransaction(); + } + return AbilityMsStatus::AppTransanctStatus("app exit ability thread client not exsit"); +} + +AbilityMsStatus AppRecord::DumpAbilityTransaction(const Want &want, uint64_t token) const +{ + if (abilityThreadClient_ != nullptr) { + return abilityThreadClient_->DumpAbilityTransaction(want, token); + } + return AbilityMsStatus::AppTransanctStatus("dump ability ability thread client not exsit"); +} + +void AppRecord::SetPendingAbility(PageAbilityRecord *abilityRecord) +{ + pendingAbilityRecord_ = abilityRecord; +} + +AbilityMsStatus AppRecord::LaunchPendingAbility() +{ + if (pendingAbilityRecord_ != nullptr) { + AbilityMsStatus status; + if (pendingAbilityRecord_->GetAbilityInfo().abilityType == AbilityType::SERVICE) { + status = pendingAbilityRecord_->InactiveAbility(); + } else { + status = pendingAbilityRecord_->ActiveAbility(); + } + // MissionRecord release AbilityRecord + pendingAbilityRecord_ = nullptr; + return status; + } + return AbilityMsStatus::LifeCycleStatus("pending ability not exsit"); +} + +AbilityMsStatus AppRecord::ConnectTransaction(const Want &want, uint64_t token) const +{ + if (abilityThreadClient_ != nullptr) { + return abilityThreadClient_->ConnectAbility(want, token); + } + return AbilityMsStatus::TaskStatus("connectAbility", "app exit ability thread client not exsit"); +} + +AbilityMsStatus AppRecord::DisconnectTransaction(const Want &want, uint64_t token) const +{ + if (abilityThreadClient_ != nullptr) { + return abilityThreadClient_->DisconnectAbility(want, token); + } + return AbilityMsStatus::TaskStatus("disconnectAbility", "app exit ability thread client not exsit"); +} + +AbilityMsStatus AppRecord::ConnectDoneTransaction(const Want &want, const SvcIdentity &serviceSid, + const SvcIdentity &connectSid) const +{ + if (abilityThreadClient_ != nullptr) { + return abilityThreadClient_->ConnectAbilityDone(want, serviceSid, connectSid); + } + return AbilityMsStatus::TaskStatus("connectAbilityDone", "app exit ability thread client not exsit"); +} + +AbilityMsStatus AppRecord::DisconnectDoneTransaction(const Want &want, const SvcIdentity &connectSid) const +{ + if (abilityThreadClient_ != nullptr) { + return abilityThreadClient_->DisconnectAbilityDone(want, connectSid); + } + return AbilityMsStatus::TaskStatus("disconnectAbilityDone", "app exit ability thread client not exsit"); +} + +void AppRecord::ClearPendingAbility(PageAbilityRecord *abilityRecord) +{ + if (pendingAbilityRecord_ != nullptr && pendingAbilityRecord_ == abilityRecord) { + pendingAbilityRecord_ = nullptr; + } +} +} // namespace OHOS diff --git a/services/abilitymgr_lite/src/client/ability_dump_client.cpp b/services/abilitymgr_lite/src/client/ability_dump_client.cpp new file mode 100644 index 0000000..6527feb --- /dev/null +++ b/services/abilitymgr_lite/src/client/ability_dump_client.cpp @@ -0,0 +1,72 @@ +/* + * Copyright (c) 2020 Huawei Device Co., Ltd. + * 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 "client/ability_dump_client.h" + +#include "ability_kit_command.h" +#include "liteipc_adapter.h" +#include "securec.h" +#include "util/abilityms_log.h" + +namespace OHOS { +AbilityDumpClient::AbilityDumpClient(const Want &want) +{ + if (want.element != nullptr) { + SetWantElement(&want_, *(want.element)); + } + if (want.data != nullptr) { + SetWantData(&want_, want.data, want.dataLength); + } + if (want.sid != nullptr) { + SetWantSvcIdentity(&want_, *(want.sid)); + } +} +AbilityDumpClient::~AbilityDumpClient() +{ + ClearWant(&want_); +} + +const Want &AbilityDumpClient::GetWant() const +{ + return want_; +} + +AbilityMsStatus AbilityDumpClient::AbilityDumpTransaction(const char *info) const +{ + if (want_.sid == nullptr) { + return AbilityMsStatus::DumpStatus("null SvcIdentity"); + } + PRINTD("AbilityThreadClient", "start"); + if (info == nullptr) { + info = ""; + } + IpcIo req; + char data[IPC_IO_DATA_MAX]; + IpcIoInit(&req, data, IPC_IO_DATA_MAX, 1); +#ifdef __LINUX__ + IpcIoPushString(&req, info); +#else + BuffPtr buffPtr; + buffPtr.buff = const_cast(info); + buffPtr.buffSz = strlen(info) + 1; + IpcIoPushDataBuff(&req, &buffPtr); +#endif + if (Transact(nullptr, *(want_.sid), SCHEDULER_DUMP_ABILITY, &req, nullptr, + LITEIPC_FLAG_ONEWAY, nullptr) != LITEIPC_OK) { + return AbilityMsStatus::AppTransanctStatus("dump ability ipc error"); + } + return AbilityMsStatus::Ok(); +} +} diff --git a/services/abilitymgr_lite/src/client/ability_thread_client.cpp b/services/abilitymgr_lite/src/client/ability_thread_client.cpp new file mode 100644 index 0000000..4d01aaa --- /dev/null +++ b/services/abilitymgr_lite/src/client/ability_thread_client.cpp @@ -0,0 +1,241 @@ +/* + * Copyright (c) 2020 Huawei Device Co., Ltd. + * 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 "client/ability_thread_client.h" + +#define __STDC_FORMAT_MACROS +#include + +#include "ability_kit_command.h" +#include "adapter.h" +#include "app_manager.h" +#include "app_record.h" +#include "client/bundlems_client.h" +#include "element_name_utils.h" +#include "liteipc_adapter.h" +#include "securec.h" +#include "serializer.h" +#include "util/abilityms_helper.h" +#include "utils.h" +#include "want_utils.h" + +namespace OHOS { +const int MAX_MODULE_SIZE = 16; +AbilityThreadClient::AbilityThreadClient(uint64_t token, pid_t pid, const SvcIdentity &svcIdentity, + IpcMsgHandler handler) : token_(token), pid_(pid), svcIdentity_(svcIdentity), deathHandler_(handler) +{ +} + +AbilityThreadClient::AbilityThreadClient(const AbilityThreadClient &client) + : token_(client.token_), pid_(client.pid_), svcIdentity_(client.svcIdentity_), deathHandler_(client.deathHandler_) +{ +} + +AbilityThreadClient::~AbilityThreadClient() +{ + UnregisterDeathCallback(svcIdentity_, cbid_); +} + +AbilityMsStatus AbilityThreadClient::Initialize(const char *bundleName) +{ + if (bundleName == nullptr) { + return AbilityMsStatus::AppTransanctStatus("bundleName is null"); + } + AppInfo *appInfo = new AppInfo(); + appInfo->bundleName = Utils::Strdup(bundleName); + if (appInfo->bundleName == nullptr) { + delete appInfo; + return AbilityMsStatus::AppTransanctStatus("memory alloc fail"); + } + appInfo->svcIdentity = svcIdentity_; + if (RegisterDeathCallback(nullptr, svcIdentity_, deathHandler_, appInfo, &cbid_) != LITEIPC_OK) { + AdapterFree(appInfo->bundleName); + delete appInfo; + return AbilityMsStatus::AppTransanctStatus("register death callback ipc error"); + } + PRINTD("AbilityThreadClient", "token(%{private}" PRIu64 ") bundleName(%{public}s) success", + token_, appInfo->bundleName); + return AbilityMsStatus::Ok(); +} + +uint64_t AbilityThreadClient::GetToken() const +{ + return token_; +} + +pid_t AbilityThreadClient::GetPid() const +{ + return pid_; +} + +const SvcIdentity& AbilityThreadClient::GetSvcIdentity() const +{ + return svcIdentity_; +} + +AbilityMsStatus AbilityThreadClient::AbilityTransaction(const TransactionState &state, + const Want &want, AbilityType abilityType) const +{ + PRINTD("AbilityThreadClient", "start"); + IpcIo req; + char data[IPC_IO_DATA_MAX]; + IpcIoInit(&req, data, IPC_IO_DATA_MAX, MAX_OBJECTS); + IpcIoPushInt32(&req, state.state); + IpcIoPushUint64(&req, state.token); + IpcIoPushInt32(&req, abilityType); + if (!SerializeWant(&req, &want)) { + return AbilityMsStatus::AppTransanctStatus("SerializeWant failed"); + } + int32_t ret = Transact(nullptr, svcIdentity_, SCHEDULER_ABILITY_LIFECYCLE, &req, + nullptr, LITEIPC_FLAG_ONEWAY, nullptr); + if (ret != LITEIPC_OK) { + return AbilityMsStatus::AppTransanctStatus("lifecycle ipc error"); + } + return AbilityMsStatus::Ok(); +} + +AbilityMsStatus AbilityThreadClient::AppInitTransaction(const BundleInfo &bundleInfo) +{ + PRINTD("AbilityThreadClient", "start"); + if (bundleInfo.bundleName == nullptr || bundleInfo.codePath == nullptr || + bundleInfo.numOfModule > MAX_MODULE_SIZE) { + return AbilityMsStatus::AppTransanctStatus("app init invalid argument"); + } + IpcIo req; + char data[IPC_IO_DATA_MAX]; + IpcIoInit(&req, data, IPC_IO_DATA_MAX, 0); + IpcIoPushString(&req, bundleInfo.bundleName); + IpcIoPushString(&req, bundleInfo.codePath); + IpcIoPushString(&req, bundleInfo.dataPath); + IpcIoPushBool(&req, bundleInfo.isNativeApp); + // transact moduleName + IpcIoPushInt32(&req, bundleInfo.numOfModule); + for (int i = 0; i < bundleInfo.numOfModule; i++) { + if (bundleInfo.moduleInfos[i].moduleName != nullptr) { + IpcIoPushString(&req, bundleInfo.moduleInfos[i].moduleName); + } + } + uintptr_t ptr; + if (Transact(nullptr, svcIdentity_, SCHEDULER_APP_INIT, &req, + nullptr, LITEIPC_FLAG_DEFAULT, &ptr) != LITEIPC_OK) { + return AbilityMsStatus::AppTransanctStatus("app init ipc error"); + } + FreeBuffer(nullptr, reinterpret_cast(ptr)); + return AbilityMsStatus::Ok(); +} + +AbilityMsStatus AbilityThreadClient::AppExitTransaction() +{ + PRINTD("AbilityThreadClient", "start"); + if (Transact(nullptr, svcIdentity_, SCHEDULER_APP_EXIT, nullptr, + nullptr, LITEIPC_FLAG_ONEWAY, nullptr) != LITEIPC_OK) { + return AbilityMsStatus::AppTransanctStatus("app exit ipc error"); + } + return AbilityMsStatus::Ok(); +} + +AbilityMsStatus AbilityThreadClient::ConnectAbility(const Want &want, uint64_t token) const +{ + PRINTD("AbilityThreadClient", "connect"); + IpcIo req; + char data[IPC_IO_DATA_MAX]; + IpcIoInit(&req, data, IPC_IO_DATA_MAX, MAX_OBJECTS); + IpcIoPushUint64(&req, token); + if (!SerializeWant(&req, &want)) { + return AbilityMsStatus::TaskStatus("connectAbility", "SerializeWant failed"); + } + if (Transact(nullptr, svcIdentity_, SCHEDULER_ABILITY_CONNECT, &req, + nullptr, LITEIPC_FLAG_ONEWAY, nullptr) != LITEIPC_OK) { + return AbilityMsStatus::TaskStatus("connectAbility", "connectAbility exit ipc error"); + } + return AbilityMsStatus::Ok(); +} + +AbilityMsStatus AbilityThreadClient::DisconnectAbility(const Want &want, uint64_t token) const +{ + PRINTD("AbilityThreadClient", "disconnect"); + IpcIo req; + char data[IPC_IO_DATA_MAX]; + IpcIoInit(&req, data, IPC_IO_DATA_MAX, MAX_OBJECTS); + IpcIoPushUint64(&req, token); + if (!SerializeWant(&req, &want)) { + return AbilityMsStatus::TaskStatus("disconnectAbility", "SerializeWant failed"); + } + if (Transact(nullptr, svcIdentity_, SCHEDULER_ABILITY_DISCONNECT, &req, nullptr, + LITEIPC_FLAG_ONEWAY, nullptr) != LITEIPC_OK) { + return AbilityMsStatus::TaskStatus("disconnectAbility", "disconnectAbility exit ipc error"); + } + return AbilityMsStatus::Ok(); +} + +AbilityMsStatus AbilityThreadClient::ConnectAbilityDone(const Want &want, const SvcIdentity &serviceSid, + const SvcIdentity &connectSid) const +{ + PRINTD("AbilityThreadClient", "connectDone"); + IpcIo req; + char data[IPC_IO_DATA_MAX]; + IpcIoInit(&req, data, IPC_IO_DATA_MAX, 1); + IpcIoPushSvc(&req, &serviceSid); + if (!SerializeElement(&req, want.element)) { + return AbilityMsStatus::TaskStatus("connectAbilityDone", "SerializeElement failed"); + } + + if (Transact(nullptr, connectSid, SCHEDULER_ABILITY_CONNECT, &req, nullptr, + LITEIPC_FLAG_ONEWAY, nullptr) != LITEIPC_OK) { + return AbilityMsStatus::TaskStatus("connectAbilityDone", "connectAbilityDone ipc error"); + } + return AbilityMsStatus::Ok(); +} + +AbilityMsStatus AbilityThreadClient::DisconnectAbilityDone(const Want &want, const SvcIdentity &connectSid) const +{ + PRINTD("AbilityThreadClient", "disconnectDone"); + IpcIo req; + char data[IPC_IO_DATA_MAX]; + IpcIoInit(&req, data, IPC_IO_DATA_MAX, 0); + if (!SerializeElement(&req, want.element)) { + return AbilityMsStatus::TaskStatus("DisconnectAbilityDone", "SerializeElement failed"); + } + + if (Transact(nullptr, connectSid, SCHEDULER_ABILITY_DISCONNECT, &req, + nullptr, LITEIPC_FLAG_ONEWAY, nullptr) != LITEIPC_OK) { +#ifdef __LINUX__ + BinderRelease(connectSid.ipcContext, connectSid.handle); +#endif + return AbilityMsStatus::TaskStatus("disconnectAbilityDone", "disconnectAbilityDone ipc error"); + } +#ifdef __LINUX__ + BinderRelease(connectSid.ipcContext, connectSid.handle); +#endif + return AbilityMsStatus::Ok(); +} + +AbilityMsStatus AbilityThreadClient::DumpAbilityTransaction(const Want &want, uint64_t token) +{ + PRINTD("AbilityThreadClient", "start"); + IpcIo req; + char data[IPC_IO_DATA_MAX]; + IpcIoInit(&req, data, IPC_IO_DATA_MAX, MAX_OBJECTS); + if (!SerializeWant(&req, &want)) { + return AbilityMsStatus::TaskStatus("dumpAbility", "SerializeWant failed"); + } + IpcIoPushUint64(&req, token); + if (Transact(nullptr, svcIdentity_, SCHEDULER_DUMP_ABILITY, &req, + nullptr, LITEIPC_FLAG_ONEWAY, nullptr) != LITEIPC_OK) { + return AbilityMsStatus::AppTransanctStatus("dump ability ipc error"); + } + return AbilityMsStatus::Ok(); +} +} diff --git a/services/abilitymgr_lite/src/client/app_spawn_client.cpp b/services/abilitymgr_lite/src/client/app_spawn_client.cpp new file mode 100644 index 0000000..47f373f --- /dev/null +++ b/services/abilitymgr_lite/src/client/app_spawn_client.cpp @@ -0,0 +1,157 @@ +/* + * Copyright (c) 2020 Huawei Device Co., Ltd. + * 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 "client/app_spawn_client.h" + +#include "appspawn_service.h" +#include "cJSON.h" +#include "ohos_errno.h" +#include "liteipc_adapter.h" +#include "samgr_lite.h" +#include "securec.h" +#include "util/abilityms_log.h" + +namespace OHOS { +const unsigned long SLEEP_TIMES = 200000; +const int RETRY_TIMES_MAX = 30; + +static int Notify(IOwner owner, int code, IpcIo *reply) +{ + if (reply == nullptr || owner == nullptr) { + return EC_INVALID; + } + int64_t *result = reinterpret_cast(owner); + *result = IpcIoPopInt64(reply); + return EC_SUCCESS; +} + +AbilityMsStatus AppSpawnClient::Initialize() +{ + while (spawnClient_ == nullptr) { + IUnknown *iUnknown = SAMGR_GetInstance()->GetDefaultFeatureApi(APPSPAWN_SERVICE_NAME); + if (iUnknown == nullptr) { + PRINTW("AppSpawnClient", "get default feature api fail, again try"); + usleep(SLEEP_TIMES); // sleep 200ms + continue; + } + int result = iUnknown->QueryInterface(iUnknown, CLIENT_PROXY_VER, (void **)(&spawnClient_)); + if (result != EC_SUCCESS || spawnClient_ == nullptr) { + PRINTW("AppSpawnClient", "get app spawn client fail"); + usleep(SLEEP_TIMES); // sleep 200ms + continue; + } + } + return AbilityMsStatus::Ok(); +} + +void static InnerFreeDataBuff(void *ptr) +{ + if (ptr != nullptr) { + cJSON_free(ptr); + } +} + +AbilityMsStatus AppSpawnClient::CallingInnerSpawnProcess(char *spawnMessage, AppRecord &appRecord) +{ + if (spawnMessage == nullptr) { + return AbilityMsStatus::ProcessStatus("CallingInnerSpawnProcess spawnMessage is nullptr"); + } + if (spawnClient_ == nullptr) { + AbilityMsStatus status = Initialize(); + if (!status.IsOk()) { + cJSON_free(spawnMessage); + return AbilityMsStatus::ProcessStatus("CallingInnerSpawnProcess Initialize unsuccessfully"); + } + } + + IpcIo request; + char data[IPC_IO_DATA_MAX]; +#ifdef __LINUX__ + IpcIoInit(&request, data, IPC_IO_DATA_MAX, 0); + IpcIoPushString(&request, spawnMessage); +#else + IpcIoInit(&request, data, IPC_IO_DATA_MAX, 1); + BuffPtr dataBuff = { + .buffSz = strlen(spawnMessage) + 1, // include \0 + .buff = spawnMessage, + }; + IpcIoPushDataBuffWithFree(&request, &dataBuff, InnerFreeDataBuff); +#endif + pid_t pid = -1; + int result = spawnClient_->Invoke(spawnClient_, ID_CALL_CREATE_SERVICE, &request, &pid, Notify); + int retry = 0; + while (result != EC_SUCCESS && retry < RETRY_TIMES_MAX) { + ++retry; + PRINTI("AppManager", "invoke fail: %{public}d, retry times: %{public}d", result, retry); + usleep(SLEEP_TIMES); // sleep 200ms if invoke fail. + result = spawnClient_->Invoke(spawnClient_, ID_CALL_CREATE_SERVICE, &request, &pid, Notify); + } + if (result != EC_SUCCESS) { + return AbilityMsStatus::ProcessStatus("spawn process fail"); + } + appRecord.SetPid(pid); + return AbilityMsStatus::Ok(); +} + +AbilityMsStatus AppSpawnClient::SpawnProcess(AppRecord &appRecord) +{ + char *innerBundleName = appRecord.GetBundleInfo().bundleName; + if (innerBundleName == nullptr) { + return AbilityMsStatus::ProcessStatus("invalid argument"); + } + + cJSON *root = cJSON_CreateObject(); + if (root == nullptr) { + return AbilityMsStatus::ProcessStatus("SpawnProcess create fail"); + } + cJSON_AddStringToObject(root, "bundleName", innerBundleName); + std::string identityId = std::to_string(appRecord.GetIdentityId()); + cJSON_AddStringToObject(root, "identityID", identityId.c_str()); + cJSON_AddNumberToObject(root, "uID", appRecord.GetBundleInfo().uid); + cJSON_AddNumberToObject(root, "gID", appRecord.GetBundleInfo().gid); + + cJSON *caps = cJSON_AddArrayToObject(root, "capability"); + if (caps == nullptr) { + cJSON_Delete(root); + return AbilityMsStatus::ProcessStatus("SpawnProcess create array unsuccessfully"); + } + + uint32_t *capabilities = nullptr; + uint32_t capNums = 0; + AbilityMsStatus status = appRecord.QueryAppCapability(innerBundleName, &capabilities, &capNums); + if (!status.IsOk()) { + cJSON_Delete(root); + return AbilityMsStatus::ProcessStatus("SpawnProcess QueryAppCapability unsuccessfully"); + } + if ((capabilities != nullptr) && (capNums != 0)) { + for (int32_t i = 0; i < capNums; ++i) { + cJSON *item = cJSON_CreateNumber(capabilities[i]); + if ((item == nullptr) || !cJSON_AddItemToArray(caps, item)) { + free(capabilities); + capabilities = nullptr; + cJSON_Delete(item); + cJSON_Delete(root); + return AbilityMsStatus::ProcessStatus("SpawnProcess add item to array unsuccessfully"); + } + } + free(capabilities); + capabilities = nullptr; + } + char *spawnMessage = cJSON_PrintUnformatted(root); + cJSON_Delete(root); + + return CallingInnerSpawnProcess(spawnMessage, appRecord); +} +} // namespace OHOS diff --git a/services/abilitymgr_lite/src/client/bundlems_client.cpp b/services/abilitymgr_lite/src/client/bundlems_client.cpp new file mode 100644 index 0000000..c0a2710 --- /dev/null +++ b/services/abilitymgr_lite/src/client/bundlems_client.cpp @@ -0,0 +1,73 @@ +/* + * Copyright (c) 2020 Huawei Device Co., Ltd. + * 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 "client/bundlems_client.h" + +#include "appexecfwk_errors.h" +#include "samgr_lite.h" + +namespace OHOS { +BundleMsClient::~BundleMsClient() +{ + bmsServerProxy_ = nullptr; +} + +AbilityMsStatus BundleMsClient::Initialize() +{ + IUnknown *iUnknown = SAMGR_GetInstance()->GetFeatureApi(BMS_SERVICE, BMS_FEATURE); + if (iUnknown == nullptr) { + return AbilityMsStatus::BmsQueryStatus("get bms feature api failure"); + } + int result = iUnknown->QueryInterface(iUnknown, DEFAULT_VERSION, (void **) &bmsServerProxy_); + if (result != 0 || bmsServerProxy_ == nullptr) { + return AbilityMsStatus::BmsQueryStatus("get bms interface failure"); + } + return AbilityMsStatus::Ok(); +} + +AbilityMsStatus BundleMsClient::QueryAbilityInfo(const Want *want, AbilityInfo *result) const +{ + if (bmsServerProxy_ == nullptr) { + return AbilityMsStatus::BmsQueryStatus("bms server proxy is nullptr"); + } + if (bmsServerProxy_->QueryAbilityInfo(want, result) != ERR_OK) { + ClearAbilityInfo(result); + return AbilityMsStatus::BmsQueryStatus("query ability info failure"); + } + return AbilityMsStatus::Ok(); +} + +AbilityMsStatus BundleMsClient::QueryBundleInfo(const char* bundleName, BundleInfo *bundleInfo) const +{ + if (bmsServerProxy_ == nullptr) { + return AbilityMsStatus::BmsQueryStatus("bms service proxy is nullptr"); + } + if (bmsServerProxy_->GetBundleInfo(bundleName, 1, bundleInfo) != ERR_OK) { + return AbilityMsStatus::BmsQueryStatus("query bundle info failure"); + } + return AbilityMsStatus::Ok(); +} + +AbilityMsStatus BundleMsClient::QueryKeepAliveBundleInfos(BundleInfo **bundleInfos, int32_t *len) const +{ + if (bmsServerProxy_ == nullptr) { + return AbilityMsStatus::BmsQueryStatus("bms service proxy is nullptr"); + } + if (bmsServerProxy_->QueryKeepAliveBundleInfos(bundleInfos, len) != ERR_OK) { + return AbilityMsStatus::BmsQueryStatus("query keep alive bundle info failure"); + } + return AbilityMsStatus::Ok(); +} +} // namespace OHOS diff --git a/services/abilitymgr_lite/src/client/wms_client.cpp b/services/abilitymgr_lite/src/client/wms_client.cpp new file mode 100755 index 0000000..1e5c16d --- /dev/null +++ b/services/abilitymgr_lite/src/client/wms_client.cpp @@ -0,0 +1,53 @@ +/* + * Copyright (c) 2020 Huawei Device Co., Ltd. + * 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 "client/wms_client.h" + +#include "ohos_errno.h" +#include "iproxy_client.h" +#ifdef ABILITY_WINDOW_SUPPORT +#include "lite_wm_type.h" +#endif +#include "liteipc_adapter.h" +#include "samgr_lite.h" +#include "util/abilityms_log.h" + +namespace OHOS { +#ifdef ABILITY_WINDOW_SUPPORT +namespace { + const unsigned long RETRY_SLEEP_TIMES = 200000; // sleep 200ms +} + +void WMSClient::WaitUntilWmsReady() +{ + PRINTI("WMSClient", "wait for window manager service start"); + IClientProxy *wmsProxy = nullptr; + while (wmsProxy == nullptr) { + IUnknown *iUnknown = SAMGR_GetInstance()->GetDefaultFeatureApi(SERVICE_NAME); + if (iUnknown == nullptr) { + usleep(RETRY_SLEEP_TIMES); + continue; + } + int result = iUnknown->QueryInterface(iUnknown, CLIENT_PROXY_VER, (void **)(&wmsProxy)); + if (result != EC_SUCCESS || wmsProxy == nullptr) { + usleep(RETRY_SLEEP_TIMES); + continue; + } + } + PRINTI("WMSClient", "get window manager service proxy success"); + wmsProxy->Release(reinterpret_cast(wmsProxy)); +} +#endif +} // namespace OHOS diff --git a/services/abilitymgr_lite/src/js_app_host.cpp b/services/abilitymgr_lite/src/js_app_host.cpp new file mode 100755 index 0000000..836e52f --- /dev/null +++ b/services/abilitymgr_lite/src/js_app_host.cpp @@ -0,0 +1,149 @@ +/* + * Copyright (c) 2020 Huawei Device Co., Ltd. + * 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 "js_app_host.h" + +#include "ability_manager_inner.h" +#include "ability_message_id.h" +#include "ability_state.h" +#include "adapter.h" + +using namespace OHOS::ACELite; + +namespace OHOS { +JsAppHost::JsAppHost() +{ +} + +JsAppHost::~JsAppHost() +{ + if (jsAbility_ != nullptr) { + delete jsAbility_; + } +} + +void JsAppHost::JsAppTaskHandler(uint32_t uwArg) +{ + auto jsappHost = reinterpret_cast((uintptr_t)uwArg); + if (jsappHost == nullptr) { + return; + } + + osMessageQueueId_t appQueueId = jsappHost->GetMessageQueueId(); + if (appQueueId == nullptr) { + return; + } + + for (;;) { + AbilityInnerMsg innerMsg; + uint8_t prio = 0; + osStatus_t ret = osMessageQueueGet(appQueueId, &innerMsg, &prio, osWaitForever); + if (ret != osOK) { + return; + } + // work_begin(MC_MAIL_EXTERN_APP) + switch ((uint32_t)innerMsg.msgId) { + case ACTIVE: + jsappHost->OnActive(innerMsg.token, innerMsg.bundleName, innerMsg.path); + break; + case BACKGROUND: + jsappHost->OnBackground(innerMsg.token); + break; + case DESTORY: + // cleanup the message queue id to present any new async message + JsAsyncWork::SetAppQueueHandler(nullptr); + jsappHost->OnDestroy(innerMsg.token); + // work_end(MC_MAIL_EXTERN_APP) + return; // here exit the loop, and abort all messages afterwards + case BACKPRESSED: + jsappHost->BackPressed(); + break; + case ASYNCWORK: { + AsyncWork* work = reinterpret_cast(innerMsg.data); + JsAsyncWork::ExecuteAsyncWork(work); + break; + } + case TE_EVENT: + jsappHost->HandleTickEvent(); + break; + default: + break; + } + // work_end(MC_MAIL_EXTERN_APP) + } +} + +void JsAppHost::OnActive(uint16_t token, const char *bundleName, const char *path) +{ + if (jsAbility_ == nullptr) { + jsAbility_ = new ACELite::JSAbility(); + if (jsAbility_ == nullptr) { + return; + } + jsAbility_->Launch(const_cast(path), bundleName, token); + } + jsAbility_->Show(); + isBackground_ = false; + SendMsgToAbilityService(token, STATE_ACTIVE); +} + +void JsAppHost::OnBackground(uint16_t token) +{ + if (jsAbility_ != nullptr) { + isBackground_ = true; + jsAbility_->Hide(); + SendMsgToAbilityService(token, STATE_BACKGROUND); + } +} + +void JsAppHost::OnDestroy(uint16_t token) +{ + if (jsAbility_ != nullptr) { + // the TE owner will be JS application after JS application start up except for it's lying in background, + // call render once to make sure the last TE message is processed properly + if (!isBackground_) { + jsAbility_->HandleRenderTick(); + } + jsAbility_->TransferToDestroy(); + } + SendMsgToAbilityService(token, STATE_UNINITIALIZED); +} + +void JsAppHost::BackPressed() +{ + if (jsAbility_ != nullptr) { + jsAbility_->BackPressed(); + } +} + +void JsAppHost::ForceDestroy() const +{ + if (jsAbility_ != nullptr) { + jsAbility_->ForceDestroy(); + } +} + +void JsAppHost::HandleTickEvent() +{ + if (jsAbility_ != nullptr) { + jsAbility_->HandleRenderTick(); + } +} + +void JsAppHost::SendMsgToAbilityService(uint16_t token, int32_t id) +{ + SchedulerLifecycleDone(token, id); +} +} // namespace OHOS diff --git a/services/abilitymgr_lite/src/page_ability_record.cpp b/services/abilitymgr_lite/src/page_ability_record.cpp new file mode 100644 index 0000000..3673af1 --- /dev/null +++ b/services/abilitymgr_lite/src/page_ability_record.cpp @@ -0,0 +1,485 @@ +/* + * Copyright (c) 2020 Huawei Device Co., Ltd. + * 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 "page_ability_record.h" + +#include "ability_connect_mission.h" +#include "ability_info_utils.h" +#include "ability_mission_record.h" +#include "adapter.h" +#include "app_manager.h" +#include "bundle_info_utils.h" +#include "securec.h" +#include "token_generate.h" +#include "util/abilityms_helper.h" + +namespace OHOS { +PageAbilityRecord::PageAbilityRecord(const AbilityInfo &abilityInfo, const Want &want) +{ + if (want.element != nullptr) { + SetWantElement(&want_, *(want.element)); + } + if (want.data != nullptr) { + SetWantData(&want_, want.data, want.dataLength); + } + if (want.sid != nullptr) { + SetWantSvcIdentity(&want_, *(want.sid)); + } + AbilityInfoUtils::CopyAbilityInfo(&abilityInfo_, abilityInfo); + Initialize(); + PRINTD("PageAbilityRecord", "Constructor"); +} + +PageAbilityRecord::~PageAbilityRecord() +{ + if (appRecord_ != nullptr) { + appRecord_->ClearPendingAbility(this); + appRecord_ = nullptr; + } + ClearWant(&want_); + ClearAbilityInfo(&abilityInfo_); + ClearBundleInfo(&bundleInfo_); + missionRecord_ = nullptr; + prevPageAbility_ = nullptr; + nextPageAbility_ = nullptr; + + for (auto iterator = connectRecords_.begin(); iterator != connectRecords_.end(); ++iterator) { + auto record = *iterator; + delete record; + } + connectRecords_.clear(); + PRINTD("AbilityRecord", "Destructor"); +} + +void PageAbilityRecord::Initialize() +{ + token_ = TokenGenerate::GenerateToken(); + appRecord_ = AppManager::GetInstance().GetAppRecordByBundleName(abilityInfo_.bundleName); +} + +const AbilityInfo& PageAbilityRecord::GetAbilityInfo() const +{ + return abilityInfo_; +} + +const BundleInfo& PageAbilityRecord::GetBundleInfo() const +{ + return bundleInfo_; +} + +void PageAbilityRecord::SetBundleInfo(const BundleInfo &bundleInfo) +{ + if (memset_s(&bundleInfo_, sizeof(BundleInfo), 0, sizeof(BundleInfo)) == EOK) { + BundleInfoUtils::CopyBundleInfo(0, &bundleInfo_, bundleInfo); + } +} + +bool PageAbilityRecord::IsSamePageAbility(const PageAbilityRecord &target) const +{ + return token_ == target.GetToken(); +} + +bool PageAbilityRecord::IsSamePageAbility(const Want &want) const +{ + if (want.element == nullptr || want.element->bundleName == nullptr || want.element->abilityName == nullptr) { + return false; + } + if (abilityInfo_.bundleName == nullptr || abilityInfo_.name == nullptr) { + return false; + } + if (strcmp(abilityInfo_.bundleName, want.element->bundleName) == 0 && + strcmp(abilityInfo_.name, want.element->abilityName) == 0) { + return true; + } + return false; +} + +bool PageAbilityRecord::IsSamePageAbility(const char *bundleName) const +{ + if (bundleName == nullptr || abilityInfo_.bundleName == nullptr) { + return false; + } + return strcmp(bundleName, abilityInfo_.bundleName) == 0; +} + +bool PageAbilityRecord::IsBottomPageAbility() const +{ + if (missionRecord_ != nullptr) { + const PageAbilityRecord *bottomAbililty = missionRecord_->GetBottomPageAbility(); + if (bottomAbililty != nullptr && bottomAbililty->GetToken() == token_) { + return true; + } + } + return false; +} + +ConnectStatus PageAbilityRecord::GetConnectStatus() const +{ + return connectStatus_; +} + +bool PageAbilityRecord::IsPerformStop() const +{ + return connectStatus_ == ConnectStatus::STOPPING || connectStatus_ == ConnectStatus::STOPPED; +} + +void PageAbilityRecord::SetConnectStatus(ConnectStatus connectStatus) +{ + connectStatus_ = connectStatus; +} + +void PageAbilityRecord::SetStartDone(bool startDone) +{ + startDone_ = startDone; +} + +uint64_t PageAbilityRecord::GetToken() const +{ + return token_; +} + +void PageAbilityRecord::SetCurrentState(State state) +{ + currentState_ = state; +} + +State PageAbilityRecord::GetCurrentState() const +{ + return currentState_; +} + +void PageAbilityRecord::SetMissionRecord(AbilityMissionRecord *missionRecord) +{ + missionRecord_ = missionRecord; +} + +const AbilityMissionRecord *PageAbilityRecord::GetMissionRecord() const +{ + return missionRecord_; +} + +void PageAbilityRecord::SetNextPageAbility(PageAbilityRecord *next) +{ + nextPageAbility_ = next; +} + +const PageAbilityRecord *PageAbilityRecord::GetNextPageAbility() const +{ + return nextPageAbility_; +} + +void PageAbilityRecord::SetPrevPageAbility(PageAbilityRecord *prev) +{ + prevPageAbility_ = prev; +} + +const PageAbilityRecord *PageAbilityRecord::GetPrevPageAbility() const +{ + return prevPageAbility_; +} + +void PageAbilityRecord::SetConnectMission(AbilityConnectMission *connectMission) +{ + connectMission_ = connectMission; +} + +const AbilityConnectMission *PageAbilityRecord::GetConnectMission() const +{ + return connectMission_; +} + +void PageAbilityRecord::SetServiceSid(const SvcIdentity &serviceSid) +{ + serviceSid_ = serviceSid; +} + +const SvcIdentity PageAbilityRecord::GetServiceSid() const +{ + return serviceSid_; +} + +AbilityConnectRecord *PageAbilityRecord::GetConnectRecord(const SvcIdentity &serviceSid) const +{ + for (const auto record : connectRecords_) { + if (record != nullptr && record->GetConnectSid().handle == serviceSid.handle && + record->GetConnectSid().token == serviceSid.token) { + return record; + } + } + return nullptr; +} + +void PageAbilityRecord::pushConnectRecord(AbilityConnectRecord *connectRecord) +{ + connectRecords_.emplace_back(connectRecord); +} + +void PageAbilityRecord::RemoveConnectRecord(const SvcIdentity &serviceSid) +{ + for (auto iterator = connectRecords_.begin(); iterator != connectRecords_.end(); ++iterator) { + auto record = *iterator; + if (record != nullptr && record->GetConnectSid().handle == serviceSid.handle && + record->GetConnectSid().token == serviceSid.token) { + connectRecords_.erase(iterator); + delete record; + return; + } + } +} + +bool PageAbilityRecord::IsLauncherAbility() const +{ + return AbilityMsHelper::IsLauncherAbility(abilityInfo_.bundleName); +} + +AbilityMsStatus PageAbilityRecord::StartAbility() +{ + if (appRecord_ == nullptr) { + // If process is not exist, start process. + appRecord_ = AppManager::GetInstance().StartAppProcess(bundleInfo_); + if (appRecord_ == nullptr) { + return AbilityMsStatus::ProcessStatus("start app process fail"); + } + appRecord_->SetPendingAbility(this); + return AbilityMsStatus::Ok(); + } + return ActiveAbility(); +} + +AbilityMsStatus PageAbilityRecord::StartService() +{ + if (appRecord_ == nullptr) { + // If process is not exist, start process. + appRecord_ = AppManager::GetInstance().StartAppProcess(bundleInfo_); + if (appRecord_ == nullptr) { + return AbilityMsStatus::ProcessStatus("start app process fail"); + } + appRecord_->SetPendingAbility(this); + return AbilityMsStatus::Ok(); + } + return InactiveAbility(); +} + +AbilityMsStatus PageAbilityRecord::ActiveAbility() +{ + if (currentState_ == STATE_ACTIVE) { + return AbilityMsStatus::LifeCycleStatus("current state is already active when active"); + } + if (appRecord_ == nullptr) { + return AbilityMsStatus::AppTransanctStatus("app record not exsit"); + } + TransactionState state = {token_, STATE_ACTIVE}; + auto status = appRecord_->AbilityTransaction(state, want_, abilityInfo_.abilityType); + AdapterFree(want_.sid); + return status; +} + +AbilityMsStatus PageAbilityRecord::InactiveAbility() const +{ + if (currentState_ != STATE_ACTIVE && abilityInfo_.abilityType != AbilityType::SERVICE) { + return AbilityMsStatus::LifeCycleStatus("current state is not active when inactive"); + } + if (appRecord_ == nullptr) { + return AbilityMsStatus::AppTransanctStatus("app record not exsit"); + } + TransactionState state = {token_, STATE_INACTIVE}; + return appRecord_->AbilityTransaction(state, want_, abilityInfo_.abilityType); +} + +AbilityMsStatus PageAbilityRecord::ToBackgroundAbility() const +{ + if (currentState_ != STATE_INACTIVE) { + return AbilityMsStatus::LifeCycleStatus("current state is not inactive when background"); + } + if (appRecord_ == nullptr) { + return AbilityMsStatus::AppTransanctStatus("app record not exsit"); + } + TransactionState state = {token_, STATE_BACKGROUND}; + return appRecord_->AbilityTransaction(state, want_, abilityInfo_.abilityType); +} + +AbilityMsStatus PageAbilityRecord::StopAbility() const +{ + if (currentState_ != STATE_INACTIVE) { + return AbilityMsStatus::LifeCycleStatus("current state is not inactive when stop"); + } + if (appRecord_ == nullptr) { + return AbilityMsStatus::AppTransanctStatus("app record not exsit"); + } + TransactionState state = {token_, STATE_INITIAL}; + return appRecord_->AbilityTransaction(state, want_, abilityInfo_.abilityType); +} + +AbilityMsStatus PageAbilityRecord::ExitApp() +{ + if (appRecord_ == nullptr) { + return AbilityMsStatus::AppTransanctStatus("app record not exsit"); + } + AbilityMsStatus status = appRecord_->AppExitTransaction(); + if (status.IsOk()) { + AppManager::GetInstance().RemoveAppRecord(*appRecord_); + appRecord_ = nullptr; + } + return status; +} + +AbilityMsStatus PageAbilityRecord::ConnectAbility() +{ + if (appRecord_ == nullptr) { + return AbilityMsStatus::TaskStatus("connectAbility, ", "app record not exsit"); + } + return appRecord_->ConnectTransaction(want_, token_); +} + +AbilityMsStatus PageAbilityRecord::DisconnectAbility(const SvcIdentity &connectSid) +{ + if (appRecord_ == nullptr) { + return AbilityMsStatus::TaskStatus("disconnectAbility, ", "app record not exsit"); + } + RemoveConnectRecord(connectSid); + + if (connectStatus_ == ConnectStatus::DISCONNECT || connectStatus_ == ConnectStatus::DISCONNECTING) { + PRINTW("disconnectAbility", "service is disconnecting"); + return AbilityMsStatus::Ok(); + } + if (IsPerformStop()) { + PRINTW("disconnectAbility", "service is stopping"); + return AbilityMsStatus::Ok(); + } + if (connectRecords_.empty()) { + SetConnectStatus(ConnectStatus::DISCONNECTING); + return appRecord_->DisconnectTransaction(want_, token_); + } + return AbilityMsStatus::Ok(); +} + +AbilityMsStatus PageAbilityRecord::ConnectAbilityDone() +{ + if (appRecord_ == nullptr) { + return AbilityMsStatus::TaskStatus("connectAbilityDone, ", "app record not exsit"); + } + for (auto record : connectRecords_) { + if (record != nullptr && record->GetStatus() == ConnectStatus::CONNECTING) { + record->SetStatus(ConnectStatus::CONNECTED); + appRecord_->ConnectDoneTransaction(want_, serviceSid_, record->GetConnectSid()); + } + } + return AbilityMsStatus::Ok(); +} + +AbilityMsStatus PageAbilityRecord::DisconnectAbilityDone() +{ + if (appRecord_ == nullptr) { + return AbilityMsStatus::TaskStatus("disconnectAbilityDone, ", "app record not exsit"); + } + if (startDone_) { + SetConnectStatus(ConnectStatus::INIT); + } else { + SetConnectStatus(ConnectStatus::DISCONNECT); + } + if ((connectRecords_.empty() && !startDone_) || forceStop_) { + SetConnectStatus(ConnectStatus::STOPPING); + TransactionState state = {token_, STATE_INITIAL}; + return appRecord_->AbilityTransaction(state, want_, abilityInfo_.abilityType); + } + return AbilityMsStatus::Ok(); +} + +AbilityMsStatus PageAbilityRecord::ForceStopServiceAbility() +{ + if (appRecord_ == nullptr) { + return AbilityMsStatus::TaskStatus("terminateService, ", "app record not exsit"); + } + forceStop_ = true; + if (IsPerformStop()) { + return AbilityMsStatus::TaskStatus("terminateService", "service is stopping"); + } + if (connectStatus_ == ConnectStatus::DISCONNECTING) { + return AbilityMsStatus::TaskStatus("terminateService", "service is disconnecting"); + } + if (connectStatus_ == ConnectStatus::DISCONNECT || connectRecords_.empty()) { + SetConnectStatus(ConnectStatus::STOPPING); + TransactionState state = {token_, STATE_INITIAL}; + return appRecord_->AbilityTransaction(state, want_, abilityInfo_.abilityType); + } else { + SetConnectStatus(ConnectStatus::DISCONNECTING); + return appRecord_->DisconnectTransaction(want_, token_); + } +} + +AbilityMsStatus PageAbilityRecord::StopAbilityDone() +{ + if (appRecord_ == nullptr) { + return AbilityMsStatus::TaskStatus("disconnectAbilityDone, ", "app record not exsit"); + } + SetConnectStatus(ConnectStatus::STOPPED); + for (const auto record : connectRecords_) { + if (record != nullptr) { + appRecord_->DisconnectDoneTransaction(want_, record->GetConnectSid()); + } + } + return AbilityMsStatus::Ok(); +} + +#ifdef OHOS_DEBUG +AbilityMsStatus PageAbilityRecord::DumpAbilityRecord() const +{ + std::string launcherMode = (abilityInfo_.launchMode == STANDARD) ? "standard" : "singleton"; + std::string result = "\tAbilityRecord:" + std::to_string(token_) + "\n" + "\t stat:" + AbilityMsHelper::AbilityStateToString(currentState_) + " launchMode:" + launcherMode + "\n" + "\t bundleName:" + abilityInfo_.bundleName + " abilityName:" + abilityInfo_.name + "\n" + "\t codePath:" + bundleInfo_.codePath + " dataPath:" + bundleInfo_.dataPath + "\n"; + return AbilityMsStatus::DumpStatus(result.c_str()); +} +#endif + +AbilityMsStatus PageAbilityRecord::DumpAbilitySlice(const Want &want) const +{ + if (appRecord_ == nullptr) { + return AbilityMsStatus::TaskStatus("DumpAbility, ", "app record not exsit"); + } + return appRecord_->DumpAbilityTransaction(want, token_); +} + +void PageAbilityRecord::RemoveConnectRecordByPageToken(uint64_t token) +{ + if (connectRecords_.empty()) { + return; + } + for (auto iterator = connectRecords_.begin(); iterator != connectRecords_.end();) { + auto record = *iterator; + if (record != nullptr && record->GetAbilityToken() == token) { + iterator = connectRecords_.erase(iterator); + delete record; + } else { + ++iterator; + } + } + if (connectRecords_.empty() && !startDone_) { + StopAbility(); + } +} + +AbilityConnectRecord *PageAbilityRecord::GetConnectRecord(const SvcIdentity &serviceSid, uint64_t abilityToken) const +{ + for (const auto record : connectRecords_) { + if (record != nullptr && record->GetConnectSid().handle == serviceSid.handle && + record->GetConnectSid().token == serviceSid.token && record->GetAbilityToken() == abilityToken) { + return record; + } + } + return nullptr; +} +} diff --git a/services/abilitymgr_lite/src/task/ability_activate_task.cpp b/services/abilitymgr_lite/src/task/ability_activate_task.cpp new file mode 100644 index 0000000..8b498bf --- /dev/null +++ b/services/abilitymgr_lite/src/task/ability_activate_task.cpp @@ -0,0 +1,55 @@ +/* + * Copyright (c) 2020 Huawei Device Co., Ltd. + * 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 "ability_activate_task.h" + +namespace OHOS { +AbilityActivateTask::AbilityActivateTask(AbilityMgrContext *context, uint64_t token) + : AbilityTask(context), token_(token) +{ +} + +AbilityMsStatus AbilityActivateTask::Execute() +{ + PRINTD("AbilityActivateTask", "start"); + if (abilityMgrContext_ == nullptr) { + return AbilityMsStatus::TaskStatus("activate", "invalid argument"); + } + AbilityStackManager &stackManager = AbilityStackManager::GetInstance(); + PageAbilityRecord *activeAbility = stackManager.FindPageAbility(*abilityMgrContext_, token_); + if (activeAbility == nullptr) { + return AbilityMsStatus::TaskStatus("activate", "ability record not found"); + } + activeAbility->SetCurrentState(STATE_ACTIVE); + auto prevAbility = const_cast(activeAbility->GetPrevPageAbility()); + AbilityMsStatus status = AbilityMsStatus::Ok(); + if (activeAbility->GetAbilityInfo().abilityType == AbilityType::SERVICE) { + return status; + } + if (prevAbility != nullptr) { + status = prevAbility->ToBackgroundAbility(); + activeAbility->SetPrevPageAbility(nullptr); + PRINTD("AbilityActivateTask", "prev ability is not nullptr, to background"); + } else { + auto nextAbility = const_cast(activeAbility->GetNextPageAbility()); + if (nextAbility != nullptr) { + status = nextAbility->StopAbility(); + activeAbility->SetNextPageAbility(nullptr); + PRINTD("AbilityActivateTask", "next ability is not nullptr, to stop"); + } + } + return status; +} +} // namespace OHOS diff --git a/services/abilitymgr_lite/src/task/ability_attach_task.cpp b/services/abilitymgr_lite/src/task/ability_attach_task.cpp new file mode 100644 index 0000000..34461b7 --- /dev/null +++ b/services/abilitymgr_lite/src/task/ability_attach_task.cpp @@ -0,0 +1,61 @@ +/* + * Copyright (c) 2020 Huawei Device Co., Ltd. + * 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 "ability_attach_task.h" + +#include "app_manager.h" + +namespace OHOS { +AbilityAttachTask::AbilityAttachTask(const AbilityThreadClient *client) + : client_(client) +{ +} + +AbilityAttachTask::~AbilityAttachTask() +{ + client_ = nullptr; +} + +AbilityMsStatus AbilityAttachTask::Execute() +{ + PRINTD("AbilityAttachTask", "start"); + if (client_ == nullptr) { + return AbilityMsStatus::TaskStatus("Attach", "invalid argument"); + } + // step1: Get app record by token. + auto appRecord = const_cast(AppManager::GetInstance().GetAppRecordByToken( + client_->GetToken(), client_->GetPid())); + if (appRecord == nullptr) { + return AbilityMsStatus::TaskStatus("Attach", "appRecord not found"); + } + // step2: Save ability thread client. + AbilityMsStatus status = appRecord->SetAbilityThreadClient(*client_); + CHECK_RESULT(status); + + // step3: Load permission + status = appRecord->LoadPermission(); + if (!status.IsOk()) { + AppManager::GetInstance().RemoveAppRecord(*appRecord); + return status; + } + + // step4: Init app + status = appRecord->AppInitTransaction(); + CHECK_RESULT(status); + + // step5: Launch pending ability. + return appRecord->LaunchPendingAbility(); +} +} // namespace OHOS diff --git a/services/abilitymgr_lite/src/task/ability_background_task.cpp b/services/abilitymgr_lite/src/task/ability_background_task.cpp new file mode 100644 index 0000000..c880e7a --- /dev/null +++ b/services/abilitymgr_lite/src/task/ability_background_task.cpp @@ -0,0 +1,38 @@ +/* + * Copyright (c) 2020 Huawei Device Co., Ltd. + * 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 "ability_background_task.h" + +namespace OHOS { +AbilityBackgroundTask::AbilityBackgroundTask(AbilityMgrContext *context, uint64_t token) + : AbilityTask(context), token_(token) +{ +} + +AbilityMsStatus AbilityBackgroundTask::Execute() +{ + PRINTD("AbilityBackgroundTask", "start"); + if (abilityMgrContext_ == nullptr) { + return AbilityMsStatus::TaskStatus("background", "invalid argument"); + } + AbilityStackManager &stackManager = AbilityStackManager::GetInstance(); + PageAbilityRecord *backgroundAbility = stackManager.FindPageAbility(*abilityMgrContext_, token_); + if (backgroundAbility == nullptr) { + return AbilityMsStatus::TaskStatus("background", "ability record not find"); + } + backgroundAbility->SetCurrentState(STATE_BACKGROUND); + return AbilityMsStatus::Ok(); +} +} // namespace OHOS diff --git a/services/abilitymgr_lite/src/task/ability_connect_done_task.cpp b/services/abilitymgr_lite/src/task/ability_connect_done_task.cpp new file mode 100644 index 0000000..19a740c --- /dev/null +++ b/services/abilitymgr_lite/src/task/ability_connect_done_task.cpp @@ -0,0 +1,43 @@ +/* + * Copyright (c) 2020 Huawei Device Co., Ltd. + * 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 "ability_connect_done_task.h" + +namespace OHOS { +AbilityConnectDoneTask::AbilityConnectDoneTask(AbilityMgrContext *context, const SvcIdentity &serviceSid, + uint64_t token) : AbilityTask(context), serviceSid_(serviceSid), token_(token) +{ +} + +AbilityMsStatus AbilityConnectDoneTask::Execute() +{ + PRINTD("AbilityConnectDoneTask", "start"); + if (abilityMgrContext_ == nullptr) { + return AbilityMsStatus::TaskStatus("connectTaskDone", "invalid argument"); + } + AbilityStackManager &stackManager = AbilityStackManager::GetInstance(); + PageAbilityRecord *service = stackManager.FindServiceAbility(*abilityMgrContext_, token_); + if (service == nullptr) { + return AbilityMsStatus::TaskStatus("connectTaskDone", "service ability dose not exists"); + } + if (service->IsPerformStop()) { + return AbilityMsStatus::TaskStatus("connectTaskDone", "service is stopping"); + } + service->SetServiceSid(serviceSid_); + AbilityMsStatus status = service->ConnectAbilityDone(); + service->SetConnectStatus(ConnectStatus::CONNECTED); + return status; +} +} // namespace OHOS diff --git a/services/abilitymgr_lite/src/task/ability_connect_task.cpp b/services/abilitymgr_lite/src/task/ability_connect_task.cpp new file mode 100644 index 0000000..bf7a393 --- /dev/null +++ b/services/abilitymgr_lite/src/task/ability_connect_task.cpp @@ -0,0 +1,87 @@ +/* + * Copyright (c) 2020 Huawei Device Co., Ltd. + * 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 "ability_connect_task.h" + +#include "ability_connect_record.h" +#include "utils.h" + +namespace OHOS { +AbilityConnectTask::AbilityConnectTask(AbilityMgrContext *context, const Want &want, const SvcIdentity& identity, + uint64_t token) : AbilityTask(context), want_(want), connectSid_(identity), token_(token) +{ +} + +AbilityMsStatus AbilityConnectTask::Execute() +{ + PRINTD("AbilityConnectTask", "start"); + if (abilityMgrContext_ == nullptr || want_.element == nullptr) { + return AbilityMsStatus::TaskStatus("connectTask", "invalid argument"); + } + AbilityStackManager &stackManager = AbilityStackManager::GetInstance(); + PageAbilityRecord *service = stackManager.FindServiceAbility(*abilityMgrContext_, + want_.element->bundleName, want_.element->abilityName); + if (service == nullptr) { + return AbilityMsStatus::TaskStatus("connectTask", "service ability does not exists"); + } + if (service->IsPerformStop()) { + return AbilityMsStatus::TaskStatus("connectTask", "service has stopped"); + } + return PerformConnectTask(service); +} + +AbilityMsStatus AbilityConnectTask::PerformConnectTask(PageAbilityRecord *service) +{ + ConnectStatus serviceConnectStatus = service->GetConnectStatus(); + if (serviceConnectStatus == ConnectStatus::DISCONNECTING || serviceConnectStatus == ConnectStatus::DISCONNECT || + serviceConnectStatus == ConnectStatus::STOPPING || serviceConnectStatus == ConnectStatus::STOPPED) { + PRINTW("AbilityConnectTask", "service status has disconnected"); + return AbilityMsStatus::TaskStatus("AbilityConnectTask", "service status has disconnected"); + } + auto connectRecord = service->GetConnectRecord(connectSid_); + if (connectRecord == nullptr) { + connectRecord = new AbilityConnectRecord(connectSid_, token_); + connectRecord->SetStatus(ConnectStatus::CONNECTING); + service->pushConnectRecord(connectRecord); + } + AbilityMsStatus abilityMsStatus = AbilityMsStatus::Ok(); + switch (serviceConnectStatus) { + case ConnectStatus::INIT: { + if (service->GetCurrentState() == STATE_UNINITIALIZED) { + PRINTI("AbilityConnectTask", "service status is initializing, waiting connecting"); + service->SetConnectStatus(ConnectStatus::WAIT_CONNECT); + } else { + PRINTI("AbilityConnectTask", "service status is init, connection is connecting"); + service->SetConnectStatus(ConnectStatus::CONNECTING); + abilityMsStatus = service->ConnectAbility(); + } + break; + } + case ConnectStatus::CONNECTED: + { + if (connectRecord->GetStatus() == ConnectStatus::CONNECTING) { + PRINTI("AbilityConnectTask", "service status has connected, connection is connecting"); + abilityMsStatus = service->ConnectAbilityDone(); + } else { + PRINTI("AbilityConnectTask", "connection has connected"); + } + break; + } + default: + break; + } + return abilityMsStatus; +} +} // namespace OHOS diff --git a/services/abilitymgr_lite/src/task/ability_disconnect_done_task.cpp b/services/abilitymgr_lite/src/task/ability_disconnect_done_task.cpp new file mode 100644 index 0000000..f095050 --- /dev/null +++ b/services/abilitymgr_lite/src/task/ability_disconnect_done_task.cpp @@ -0,0 +1,40 @@ +/* + * Copyright (c) 2020 Huawei Device Co., Ltd. + * 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 "ability_disconnect_done_task.h" + +namespace OHOS { +AbilityDisconnectDoneTask::AbilityDisconnectDoneTask(AbilityMgrContext *context, uint64_t token) + : AbilityTask(context), token_(token) +{ +} + +AbilityMsStatus AbilityDisconnectDoneTask::Execute() +{ + PRINTD("AbilityDisconnectDoneTask", "start"); + if (abilityMgrContext_ == nullptr) { + return AbilityMsStatus::TaskStatus("disconnectTaskDone", "invalid argument"); + } + AbilityStackManager &stackManager = AbilityStackManager::GetInstance(); + PageAbilityRecord *service = stackManager.FindServiceAbility(*abilityMgrContext_, token_); + if (service == nullptr) { + return AbilityMsStatus::TaskStatus("disconnectTaskDone", "service ability does not exists"); + } + if (service->IsPerformStop()) { + return AbilityMsStatus::TaskStatus("disconnectTaskDone", "service is stopping"); + } + return service->DisconnectAbilityDone(); +} +} // namespace OHOS diff --git a/services/abilitymgr_lite/src/task/ability_disconnect_task.cpp b/services/abilitymgr_lite/src/task/ability_disconnect_task.cpp new file mode 100644 index 0000000..34e89c3 --- /dev/null +++ b/services/abilitymgr_lite/src/task/ability_disconnect_task.cpp @@ -0,0 +1,40 @@ +/* + * Copyright (c) 2020 Huawei Device Co., Ltd. + * 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 "ability_disconnect_task.h" + +namespace OHOS { +AbilityDisconnectTask::AbilityDisconnectTask(AbilityMgrContext *context, const SvcIdentity &identity, + uint64_t token) : AbilityTask(context), identity_(identity), token_(token) +{ +} + +AbilityMsStatus AbilityDisconnectTask::Execute() +{ + PRINTD("AbilityDisconnectTask", "start"); + if (abilityMgrContext_ == nullptr) { + return AbilityMsStatus::TaskStatus("disconnectTask", "invalid argument"); + } + auto serviceConnects = abilityMgrContext_->GetServiceConnects(); + if (serviceConnects == nullptr) { + return AbilityMsStatus::TaskStatus("disconnectTask", "invalid argument"); + } + auto service = serviceConnects->FindServiceRecord(identity_, token_); + if (service == nullptr) { + return AbilityMsStatus::TaskStatus("disconnectTask", "service is not exists"); + } + return service->DisconnectAbility(identity_); +} +} // namespace OHOS diff --git a/services/abilitymgr_lite/src/task/ability_dump_task.cpp b/services/abilitymgr_lite/src/task/ability_dump_task.cpp new file mode 100644 index 0000000..5a0e7cf --- /dev/null +++ b/services/abilitymgr_lite/src/task/ability_dump_task.cpp @@ -0,0 +1,49 @@ +/* + * Copyright (c) 2020 Huawei Device Co., Ltd. + * 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 "ability_dump_task.h" + +namespace OHOS { +AbilityDumpTask::AbilityDumpTask(AbilityMgrContext *context, const AbilityDumpClient *client) + : AbilityTask(context), client_(client) +{ +} + +AbilityMsStatus AbilityDumpTask::Execute() +{ + PRINTD("AbilityDumpTask", "start"); + if (abilityMgrContext_ == nullptr || client_ == nullptr) { + return AbilityMsStatus::TaskStatus("dump", "invalid argument"); + } + AbilityStackManager &stackManager = AbilityStackManager::GetInstance(); + if (client_->GetWant().element != nullptr) { + // If query target ability + const PageAbilityRecord *targetAbility = + stackManager.FindPageAbility(*abilityMgrContext_, client_->GetWant()); + if (targetAbility == nullptr) { + return client_->AbilityDumpTransaction("Ability not found\n"); + } + return targetAbility->DumpAbilitySlice(client_->GetWant()); + } else { + // Query all ability +#ifdef OHOS_DEBUG + AbilityMsStatus status = stackManager.DumpAllAbilityRecord(*abilityMgrContext_); + return client_->AbilityDumpTransaction(status.Dump()); +#else + return client_->AbilityDumpTransaction("Dump is not available in release\n"); +#endif + } +} +} // namespace OHOS diff --git a/services/abilitymgr_lite/src/task/ability_inactivate_task.cpp b/services/abilitymgr_lite/src/task/ability_inactivate_task.cpp new file mode 100644 index 0000000..7703682 --- /dev/null +++ b/services/abilitymgr_lite/src/task/ability_inactivate_task.cpp @@ -0,0 +1,64 @@ +/* + * Copyright (c) 2020 Huawei Device Co., Ltd. + * 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 "ability_inactivate_task.h" + +namespace OHOS { +AbilityInactivateTask::AbilityInactivateTask(AbilityMgrContext *context, uint64_t token) + : AbilityTask(context), token_(token) +{ +} + +AbilityMsStatus AbilityInactivateTask::Execute() +{ + PRINTD("AbilityInactivateTask", "start"); + if (abilityMgrContext_ == nullptr) { + return AbilityMsStatus::TaskStatus("inactivate", "invalid argument"); + } + AbilityStackManager &stackManager = AbilityStackManager::GetInstance(); + PageAbilityRecord *inactiveAbility = stackManager.FindPageAbility(*abilityMgrContext_, token_); + if (inactiveAbility == nullptr) { + return AbilityMsStatus::TaskStatus("inactivate", "ability record not found"); + } + inactiveAbility->SetCurrentState(STATE_INACTIVE); + PageAbilityRecord *nextAbility = const_cast(inactiveAbility->GetNextPageAbility()); + AbilityMsStatus status = AbilityMsStatus::Ok(); + if (inactiveAbility->GetAbilityInfo().abilityType == AbilityType::SERVICE) { + if (inactiveAbility->GetConnectStatus() == ConnectStatus::WAIT_CONNECT) { + PRINTD("AbilityInactivateTask", "perform connect"); + inactiveAbility->SetConnectStatus(ConnectStatus::CONNECTING); + return inactiveAbility->ConnectAbility(); + } + return status; + } + if (nextAbility != nullptr) { + status = nextAbility->StartAbility(); + inactiveAbility->SetNextPageAbility(nullptr); + PRINTD("AbilityInactivateTask", "next ability is not nullptr, active"); + } else { + PageAbilityRecord *prevAbility = const_cast( + stackManager.GetPrevPageAbility(*abilityMgrContext_, *inactiveAbility)); + if (prevAbility != nullptr) { + status = prevAbility->ActiveAbility(); + prevAbility->SetNextPageAbility(inactiveAbility); + PRINTD("AbilityInactivateTask", "prev ability is not nullptr, active"); + } else { + inactiveAbility->StopAbility(); + status = AbilityMsStatus::NoActiveAbilityStatus("inactivate", "start launcher"); + } + } + return status; +} +} // namespace OHOS diff --git a/services/abilitymgr_lite/src/task/ability_start_task.cpp b/services/abilitymgr_lite/src/task/ability_start_task.cpp new file mode 100644 index 0000000..0062b0f --- /dev/null +++ b/services/abilitymgr_lite/src/task/ability_start_task.cpp @@ -0,0 +1,110 @@ +/* + * Copyright (c) 2020 Huawei Device Co., Ltd. + * 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 "ability_start_task.h" + +#include "ability_stack_manager.h" + +namespace OHOS { +AbilityStartTask::AbilityStartTask(AbilityMgrContext *context, const Want *want, + const AbilityInfo *target, const BundleInfo *bundleInfo) + : AbilityTask(context), want_(want), target_(target), bundleInfo_(bundleInfo) +{ +} + +AbilityStartTask::~AbilityStartTask() +{ + want_ = nullptr; + target_ = nullptr; + bundleInfo_ = nullptr; +} + +void AbilityStartTask::SetWaitConnect(bool waitConnect) +{ + waitConnect_ = waitConnect; +} + +AbilityMsStatus AbilityStartTask::Execute() +{ + PRINTD("AbilityStartTask", "start"); + if (abilityMgrContext_ == nullptr || want_ == nullptr || + target_ == nullptr || bundleInfo_ == nullptr) { + return AbilityMsStatus::TaskStatus("start", "invalid argument"); + } + if (target_->abilityType == AbilityType::SERVICE) { + return StartService(); + } + AbilityStackManager &stackManager = AbilityStackManager::GetInstance(); + // Step1: Get current top ability record. + PageAbilityRecord *topAbility = const_cast( + stackManager.GetTopPageAbility(*abilityMgrContext_)); + // Step2: Generate target ability record. + PageAbilityRecord *targetAbility = stackManager.GeneratePageAbility( + *target_, *want_, topAbility, *abilityMgrContext_); + if (targetAbility == nullptr || targetAbility == topAbility) { + return AbilityMsStatus::TaskStatus("start", "generate ability record failure"); + } + targetAbility->SetBundleInfo(*bundleInfo_); + if (topAbility != nullptr) { + // step3:If topAbility is not nullptr, inactive top ability. + PRINTD("AbilityStartTask", "topAbility is not nullptr, first inactive"); + AbilityMsStatus status = topAbility->InactiveAbility(); + if (status.IsOk()) { + topAbility->SetNextPageAbility(targetAbility); + targetAbility->SetPrevPageAbility(topAbility); + } else { + stackManager.RemovePageAbility(*targetAbility, *abilityMgrContext_); + } + return status; + } + // step4: Start ability. + PRINTD("AbilityStartTask", "topAbility is nullptr or not active"); + AbilityMsStatus status = targetAbility->StartAbility(); + if (status.IsProcessError() || status.IsTransactError()) { + // Clean page ability record if failure + stackManager.RemovePageAbility(*targetAbility, *abilityMgrContext_); + } + return status; +} + +AbilityMsStatus AbilityStartTask::StartService() +{ + PRINTD("AbilityStartTask", "start service"); + auto connectMission = const_cast(abilityMgrContext_->GetServiceConnects()); + if (connectMission == nullptr) { + return AbilityMsStatus::TaskStatus("start", "invalid argument"); + } + auto service = connectMission->FindServiceRecord(target_->bundleName, target_->name); + if (service != nullptr) { + return AbilityMsStatus::TaskStatus("start", "service ability exists"); + } + auto targetAbility = new PageAbilityRecord(*target_, *want_); + targetAbility->SetBundleInfo(*bundleInfo_); + if (waitConnect_) { + targetAbility->SetStartDone(false); + targetAbility->SetConnectStatus(ConnectStatus::WAIT_CONNECT); + } else { + targetAbility->SetStartDone(true); + } + connectMission->PushServiceRecord(*targetAbility); + targetAbility->SetConnectMission(connectMission); + AbilityMsStatus status = targetAbility->StartService(); + if (status.IsProcessError() || status.IsTransactError()) { + // Clean service ability record if failure + connectMission->RemoveServiceRecord(targetAbility->GetToken()); + } + return status; +} +} // namespace OHOS diff --git a/services/abilitymgr_lite/src/task/ability_stop_task.cpp b/services/abilitymgr_lite/src/task/ability_stop_task.cpp new file mode 100644 index 0000000..e3a17d4 --- /dev/null +++ b/services/abilitymgr_lite/src/task/ability_stop_task.cpp @@ -0,0 +1,67 @@ +/* + * Copyright (c) 2020 Huawei Device Co., Ltd. + * 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 "ability_stop_task.h" + +namespace OHOS { +AbilityStopTask::AbilityStopTask(AbilityMgrContext *context, uint64_t token) + : AbilityTask(context), token_(token) +{ +} + +AbilityMsStatus AbilityStopTask::Execute() +{ + PRINTD("AbilityStopTask", "start"); + if (abilityMgrContext_ == nullptr) { + return AbilityMsStatus::TaskStatus("stop", "invalid argument"); + } + AbilityStackManager &stackManager = AbilityStackManager::GetInstance(); + // Step 1: Find stop ability record. + PageAbilityRecord *stopAbility = stackManager.FindPageAbility(*abilityMgrContext_, token_); + if (stopAbility == nullptr) { + return AbilityMsStatus::TaskStatus("stop", "ability record not found"); + } + auto serviceConnects = const_cast(abilityMgrContext_->GetServiceConnects()); + if (serviceConnects == nullptr) { + return AbilityMsStatus::TaskStatus("stop", "invalid argument"); + } + stopAbility->SetCurrentState(STATE_INITIAL); + if (stopAbility->GetAbilityInfo().abilityType == AbilityType::SERVICE) { + if (stopAbility->GetConnectStatus() == ConnectStatus::STOPPED) { + return AbilityMsStatus::TaskStatus("stop", "service has stopped"); + } + AbilityMsStatus status = stopAbility->StopAbilityDone(); + bool existsPage = stackManager.ExistAppInStack(stopAbility->GetAbilityInfo(), *abilityMgrContext_); + int32_t count = serviceConnects->CountServiceInApp(stopAbility->GetAbilityInfo().bundleName); + if (!existsPage && count == 1) { + PRINTI("AbilityStopTask", "exit app"); + status = stopAbility->ExitApp(); + } + serviceConnects->RemoveServiceRecord(token_); + return status; + } else { + // Step 2: Ability is bottom in MissionRecord + AbilityMsStatus status = AbilityMsStatus::Ok(); + if (stopAbility->IsBottomPageAbility() && + serviceConnects->CountServiceInApp(stopAbility->GetAbilityInfo().bundleName) == 0) { + // exit process + status = stopAbility->ExitApp(); + } + // Step 3: Delete ability from stack + stackManager.RemovePageAbility(*stopAbility, *abilityMgrContext_); + return status; + } +} +} // namespace OHOS diff --git a/services/abilitymgr_lite/src/task/ability_terminate_service_task.cpp b/services/abilitymgr_lite/src/task/ability_terminate_service_task.cpp new file mode 100644 index 0000000..f472566 --- /dev/null +++ b/services/abilitymgr_lite/src/task/ability_terminate_service_task.cpp @@ -0,0 +1,52 @@ +/* + * Copyright (c) 2020 Huawei Device Co., Ltd. + * 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 "ability_terminate_service_task.h" + +#include "ability_stack_manager.h" + +namespace OHOS { +AbilityTerminateServiceTask::AbilityTerminateServiceTask(AbilityMgrContext *context, const AbilityInfo *target) + : AbilityTask(context), target_(target) +{ +} + +AbilityTerminateServiceTask::~AbilityTerminateServiceTask() +{ + target_ = nullptr; +} + +AbilityMsStatus AbilityTerminateServiceTask::Execute() +{ + PRINTD("AbilityTerminateServiceTask", "start"); + if (abilityMgrContext_ == nullptr || target_ == nullptr) { + return AbilityMsStatus::TaskStatus("terminateService", "invalid argument"); + } + auto serviceConnects = abilityMgrContext_->GetServiceConnects(); + if (serviceConnects == nullptr) { + return AbilityMsStatus::TaskStatus("terminateService", "invalid argument"); + } + auto service = serviceConnects->FindServiceRecord(target_->bundleName, target_->name); + if (service == nullptr) { + return AbilityMsStatus::TaskStatus("terminateService", "service does not exists"); + } + if (service->GetCurrentState() == STATE_UNINITIALIZED) { + uint64_t token = service->GetToken(); + const_cast(serviceConnects)->RemoveServiceRecord(token); + return AbilityMsStatus::Ok(); + } + return service->ForceStopServiceAbility(); +} +} // namespace OHOS diff --git a/services/abilitymgr_lite/src/task/ability_terminate_task.cpp b/services/abilitymgr_lite/src/task/ability_terminate_task.cpp new file mode 100644 index 0000000..2ea2429 --- /dev/null +++ b/services/abilitymgr_lite/src/task/ability_terminate_task.cpp @@ -0,0 +1,45 @@ +/* + * Copyright (c) 2020 Huawei Device Co., Ltd. + * 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 "ability_terminate_task.h" + +#include "ability_stack_manager.h" + +namespace OHOS { +AbilityTerminateTask::AbilityTerminateTask(AbilityMgrContext *context, uint64_t token) + : AbilityTask(context), token_(token) +{ +} + +AbilityMsStatus AbilityTerminateTask::Execute() +{ + PRINTD("AbilityTerminateTask", "start"); + if (abilityMgrContext_ == nullptr) { + return AbilityMsStatus::TaskStatus("ability terminate", "invalid argument"); + } + // Step1: Get ability record from stack + AbilityStackManager &stackManager = AbilityStackManager::GetInstance(); + PageAbilityRecord *terminateAbility = stackManager.FindPageAbility(*abilityMgrContext_, token_); + if (terminateAbility == nullptr) { + return AbilityMsStatus::TaskStatus("ability terminate", "ability record not find"); + } + if (terminateAbility->GetAbilityInfo().abilityType == AbilityType::SERVICE) { + return terminateAbility->ForceStopServiceAbility(); + } else { + // Step2: Inactive ability record + return terminateAbility->InactiveAbility(); + } +} +} // namespace OHOS diff --git a/services/abilitymgr_lite/src/task/app_restart_task.cpp b/services/abilitymgr_lite/src/task/app_restart_task.cpp new file mode 100644 index 0000000..d59803b --- /dev/null +++ b/services/abilitymgr_lite/src/task/app_restart_task.cpp @@ -0,0 +1,52 @@ +/* + * Copyright (c) 2020 Huawei Device Co., Ltd. + * 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_restart_task.h" + +#include "ability_stack_manager.h" +#include "app_manager.h" +#include "util/abilityms_helper.h" + +namespace OHOS { +AppRestartTask::AppRestartTask(AbilityMgrContext *context, const BundleInfo *bundleInfo) + : AbilityTask(context), bundleInfo_(bundleInfo) +{ +} + +AbilityMsStatus AppRestartTask::Execute() +{ + PRINTD("AppRestartTask", "start"); + if (abilityMgrContext_ == nullptr || bundleInfo_ == nullptr || bundleInfo_->bundleName == nullptr) { + return AbilityMsStatus::TaskStatus("app terminate", "invalid argument"); + } + + // Step1: Clear app MissionStack and AbilityRecord + AbilityStackManager &stackManager = AbilityStackManager::GetInstance(); + stackManager.ClearAbilityStack(bundleInfo_->bundleName, *abilityMgrContext_); + + // Step2: Remove app record + AppManager::GetInstance().RemoveAppRecord(bundleInfo_->bundleName); + + // Step3: Get top page ability + auto topRecord = const_cast(stackManager.GetTopPageAbility(*abilityMgrContext_)); + if (topRecord == nullptr) { + return AbilityMsStatus::NoActiveAbilityStatus("restart app", "start launcher"); + } else { + // Step4: Active top ability + topRecord->ActiveAbility(); + } + return AbilityMsStatus::Ok(); +} +} // namespace OHOS diff --git a/services/abilitymgr_lite/src/task/app_terminate_task.cpp b/services/abilitymgr_lite/src/task/app_terminate_task.cpp new file mode 100644 index 0000000..505b793 --- /dev/null +++ b/services/abilitymgr_lite/src/task/app_terminate_task.cpp @@ -0,0 +1,52 @@ +/* + * Copyright (c) 2020 Huawei Device Co., Ltd. + * 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_terminate_task.h" + +#include "ability_stack_manager.h" +#include "app_manager.h" + +namespace OHOS { +AppTerminateTask::AppTerminateTask(AbilityMgrContext *context, const char *bundleName) + : AbilityTask(context), bundleName_(bundleName) +{ +} + +AbilityMsStatus AppTerminateTask::Execute() +{ + PRINTD("AppTerminateTask", "start"); + if (abilityMgrContext_ == nullptr || bundleName_ == nullptr) { + return AbilityMsStatus::TaskStatus("app terminate", "invalid argument"); + } + + // Step1: Stop process + AbilityMsStatus status = AppManager::GetInstance().TerminateAppProcess(bundleName_); + CHECK_RESULT(status); + + // Step2: Clear app MissionStack and AbilityRecord + AbilityStackManager &stackManager = AbilityStackManager::GetInstance(); + stackManager.ClearAbilityStack(bundleName_, *abilityMgrContext_); + + // Step3: Remove App Record + AppManager::GetInstance().RemoveAppRecord(bundleName_); + + // Step4: Active top ability + auto topRecord = const_cast(stackManager.GetTopPageAbility(*abilityMgrContext_)); + if (topRecord != nullptr) { + topRecord->ActiveAbility(); + } + return AbilityMsStatus::Ok(); +} +} // namespace OHOS diff --git a/services/abilitymgr_lite/src/util/abilityms_helper.cpp b/services/abilitymgr_lite/src/util/abilityms_helper.cpp new file mode 100755 index 0000000..71eb383 --- /dev/null +++ b/services/abilitymgr_lite/src/util/abilityms_helper.cpp @@ -0,0 +1,146 @@ +/* + * Copyright (c) 2020 Huawei Device Co., Ltd. + * 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 "util/abilityms_helper.h" + +#include + +#include "adapter.h" +#include "bundle_inner_interface.h" +#include "bundle_manager.h" +#include "iproxy_client.h" +#include "samgr_lite.h" + +namespace OHOS { +const char * const LAUNCHER_BUNDLE_NAME = "com.huawei.launcher"; +const char * const LAUNCHER_ABILITY_NAME = "MainAbility"; +const char * const ACE_ABILITY_NAME = "AceAbility"; +const int MAX_BUNDLE_NAME_SIZE = 128; + +bool AbilityMsHelper::IsLauncherAbility(const char *bundleName) +{ + if (bundleName == nullptr) { + PRINTW("AbilityMsHelper", "bundleName is null"); + return false; + } + return strcmp(LAUNCHER_BUNDLE_NAME, bundleName) == 0; +} + +bool AbilityMsHelper::IsAceAbility(const char *abilityName) +{ + if (abilityName == nullptr) { + PRINTW("AbilityMsHelper", "abilityName is null"); + return false; + } + return strcmp(ACE_ABILITY_NAME, abilityName) == 0; +} + +AbilityMsStatus AbilityMsHelper::SetLauncherWant(Want &want) +{ + ElementName elementName = {}; + SetElementAbilityName(&elementName, LAUNCHER_ABILITY_NAME); + SetElementBundleName(&elementName, LAUNCHER_BUNDLE_NAME); + + SetWantElement(&want, elementName); + ClearElement(&elementName); + return AbilityMsStatus::Ok(); +} + +AbilityMsStatus AbilityMsHelper::SetKeepAliveWant(const BundleInfo &bundleInfo, Want &want) +{ + if (bundleInfo.numOfAbility <= 0) { + return AbilityMsStatus::HelpStatus("no ability exist"); + } + ElementName elementName = {}; + if (bundleInfo.abilityInfos[0].name == nullptr) { + return AbilityMsStatus::HelpStatus("abilityName is null"); + } + if (bundleInfo.bundleName == nullptr) { + return AbilityMsStatus::HelpStatus("bundleName is null"); + } + SetElementAbilityName(&elementName, bundleInfo.abilityInfos[0].name); + SetElementBundleName(&elementName, bundleInfo.bundleName); + + SetWantElement(&want, elementName); + ClearElement(&elementName); + return AbilityMsStatus::Ok(); +} + +#ifdef OHOS_DEBUG +std::string AbilityMsHelper::AbilityStateToString(State state) +{ + std::string result; + switch (state) { + case STATE_UNINITIALIZED: + result = "uninitialized"; + break; + case STATE_INITIAL: + result = "initial"; + break; + case STATE_INACTIVE: + result = "inactive"; + break; + case STATE_ACTIVE: + result = "active"; + break; + case STATE_BACKGROUND: + result = "background"; + break; + default: + break; + } + return result; +} +#endif + +bool AbilityMsHelper::IsLegalBundleName(const char *bundleName) +{ + if (bundleName == nullptr) { + return false; + } + int len = strlen(bundleName); + if (len <= 0 || len > MAX_BUNDLE_NAME_SIZE) { + return false; + } + return true; +} + +bool AbilityMsHelper::CheckVisiblePermission(pid_t callingUid, pid_t targetUid, bool isVisible) +{ + if (callingUid == SYSTEM_UID) { + return true; + } + if (isVisible || callingUid == targetUid) { + return true; + } + IUnknown *iUnknown = SAMGR_GetInstance()->GetFeatureApi(BMS_SERVICE, BMS_FEATURE); + if (iUnknown == nullptr) { + return false; + } + BmsServerProxy *bmsServerProxy = nullptr; + int result = iUnknown->QueryInterface(iUnknown, DEFAULT_VERSION, (void **) &bmsServerProxy); + if (result != 0 || bmsServerProxy == nullptr) { + return false; + } + char *bundleName = nullptr; + uint8_t ret = bmsServerProxy->GetBundleNameForUid(callingUid, &bundleName); + if (ret == 0 && IsLauncherAbility(bundleName)) { + AdapterFree(bundleName); + return true; + } + AdapterFree(bundleName); + return false; +} +} diff --git a/services/abilitymgr_lite/src/util/abilityms_status.cpp b/services/abilitymgr_lite/src/util/abilityms_status.cpp new file mode 100644 index 0000000..5aa976f --- /dev/null +++ b/services/abilitymgr_lite/src/util/abilityms_status.cpp @@ -0,0 +1,69 @@ +/* + * Copyright (c) 2020 Huawei Device Co., Ltd. + * 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 "util/abilityms_status.h" + +#include "util/abilityms_log.h" + +namespace OHOS { +AbilityMsStatus::AbilityMsStatus(StatusCode code, const char *key, const char *msg) +{ + code_ = code; + if (key != nullptr) { + key_ = key; + } + if (msg != nullptr) { + state_ = msg; + } +} + +void AbilityMsStatus::LogStatus() const +{ + std::string result; + switch (code_) { + case OK: + result = "success: "; + break; + case PERMISSION_DENIED: + result = "permission denied: "; + break; + case BMS_QUERY_NOT_FOUND: + result = "bms query not found: "; + break; + case ABILITY_TASK_ERROR: + result = "task " + key_ + " exec failure: "; + break; + case APP_TRANSACT_ERROR: + result = "app transanct failure: "; + break; + case LIFE_CYCLE_ILLEGAL: + result = "life cycle illegal: "; + break; + case PROCESS_ERROR: + result = "process exception: "; + break; + case NO_ACTIVE_ABILITY: + result = "no active ability when " + key_ + ": "; + break; + case ABILITY_HELP_ERROR: + result = "help failure: "; + break; + default: + break; + } + result += state_; + HILOG_ERROR(LOG_DOMAIN, "%s", result.c_str()); +} +} diff --git a/services/abilitymgr_lite/tools/BUILD.gn b/services/abilitymgr_lite/tools/BUILD.gn new file mode 100755 index 0000000..6280e90 --- /dev/null +++ b/services/abilitymgr_lite/tools/BUILD.gn @@ -0,0 +1,81 @@ +# Copyright (c) 2020 Huawei Device Co., Ltd. +# 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. +import("//build/lite/config/component/lite_component.gni") +import("//build/lite/config/subsystem/aafwk/config.gni") + +lite_component("tools_lite") { + features = [ ":aa" ] +} + +generate_notice_file("tools_lite_notice_file") { + module_name = "tools_lite" + module_source_dir_list = [ + "//third_party/bounds_checking_function", + "//third_party/cJSON", + ] +} + +executable("aa") { + sources = [ + "src/ability_tool.cpp", + "src/main.cpp", + ] + + cflags = [ "-Wall" ] + cflags_cc = cflags + + ldflags = [ + "-lstdc++", + "-lpthread", + "-ldl", + ] + + deps = [ + "${aafwk_lite_path}/frameworks/abilitymgr_lite:aafwk_abilityManager_lite", + "${appexecfwk_lite_path}/frameworks/bundle_lite:bundle", + "//base/hiviewdfx/hilog_lite/frameworks/featured:hilog_shared", + "//build/lite/config/component/cJSON:cjson_shared", + "//foundation/communication/ipc_lite:liteipc_adapter", + "//foundation/distributedschedule/samgr_lite/samgr:samgr", + "//utils/native/lite/kv_store:kv_store", + ] + + if (enable_ohos_appexecfwk_feature_ability == true) { + deps += [ + "//foundation/graphic/surface", + "//foundation/graphic/ui:lite_ui", + "//foundation/graphic/utils:lite_graphic_utils", + ] + } + include_dirs = [ + "include", + "${aafwk_lite_path}/interfaces/kits/ability_lite", + "${aafwk_lite_path}/interfaces/kits/want_lite", + "${aafwk_lite_path}/interfaces/innerkits/abilitymgr_lite", + "${aafwk_lite_path}/frameworks/abilitymgr_lite/include", + "${aafwk_lite_path}/frameworks/want_lite/include", + "${appexecfwk_lite_path}/utils/bundle_lite", + "${appexecfwk_lite_path}/interfaces/kits/bundle_lite", + "//foundation/communication/ipc_lite/interfaces/kits", + "//foundation/distributedschedule/samgr_lite/interfaces/kits/registry", + "//foundation/distributedschedule/samgr_lite/interfaces/kits/samgr", + "//kernel/liteos_a/kernel/include", + "//kernel/liteos_a/kernel/common", + "//third_party/bounds_checking_function/include", + "//third_party/cJSON", + "//utils/native/lite/include", + ] + + defines = [ "OHOS_APPEXECFWK_BMS_BUNDLEMANAGER" ] + output_dir = "$root_out_dir/dev_tools" +} diff --git a/services/abilitymgr_lite/tools/LICENSE b/services/abilitymgr_lite/tools/LICENSE new file mode 100755 index 0000000..4a45986 --- /dev/null +++ b/services/abilitymgr_lite/tools/LICENSE @@ -0,0 +1,177 @@ + + 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 \ No newline at end of file diff --git a/services/abilitymgr_lite/tools/README.md b/services/abilitymgr_lite/tools/README.md new file mode 100755 index 0000000..49e2a5d --- /dev/null +++ b/services/abilitymgr_lite/tools/README.md @@ -0,0 +1,24 @@ +# AMS command line tool + +## Introduction + +This module allows users to submit instructions to the AMS through text lines. + +## Features + +- Start ability +- Stop service ability +- Dump ability +- Terminate application + +## Directions + +``` +├── BUILD.gn +├── include +│   └── ability_tool.h +├── README.md +└── src + ├── ability_tool.cpp + └── main.cpp +``` \ No newline at end of file diff --git a/services/abilitymgr_lite/tools/include/ability_tool.h b/services/abilitymgr_lite/tools/include/ability_tool.h new file mode 100755 index 0000000..d2e0aad --- /dev/null +++ b/services/abilitymgr_lite/tools/include/ability_tool.h @@ -0,0 +1,51 @@ +/* + * Copyright (c) 2020 Huawei Device Co., Ltd. + * 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 OHOS_ABILITY_TOOL_H +#define OHOS_ABILITY_TOOL_H + +#include +#include "liteipc_adapter.h" +#include "want.h" + +namespace OHOS { +class AbilityTool { +public: + AbilityTool() = default; + ~AbilityTool(); + bool SetBundleName(const char *bundleName); + bool SetAbilityName(const char *className); + void SetExtra(const char *extra); + bool SetCommand(const char *command); + bool RunCommand(); + void SetDumpAll(); + +private: + Want* BuildWant(); + bool InnerStartAbility(); + bool InnerStopAbility(); + bool TerminateApp(IClientProxy *proxy) const; + bool Dump(IClientProxy *proxy); + static int32_t AaCallback(const IpcContext* context, void *ipcMsg, IpcIo *data, void *arg); + + ElementName elementName_ { nullptr, nullptr, nullptr }; + char *extra_ { nullptr }; + char *command_ { nullptr }; + bool dumpAll_ { false }; + SvcIdentity identity_ {}; + static const int MAX_OBJECTS = 2; +}; +} // namespace OHOS +#endif // OHOS_ABILITY_TOOL_H diff --git a/services/abilitymgr_lite/tools/src/ability_tool.cpp b/services/abilitymgr_lite/tools/src/ability_tool.cpp new file mode 100755 index 0000000..310d169 --- /dev/null +++ b/services/abilitymgr_lite/tools/src/ability_tool.cpp @@ -0,0 +1,310 @@ +/* + * Copyright (c) 2020 Huawei Device Co., Ltd. + * 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 "ability_tool.h" + +#include +#include +#include +#include +#include +#include +#include + +#include "ability_errors.h" +#include "ability_kit_command.h" +#include "ability_manager.h" +#include "ability_service_interface.h" +#include "adapter.h" +#include "want_utils.h" + +namespace OHOS { +namespace { +constexpr int WAIT_TIMEOUT = 30; // 5 second +constexpr int MAX_BUFFER_SIZE_PER = 1024; // 1024 byte +constexpr char CMD_START_ABILITY[] = "start"; +constexpr char CMD_STOP_ABILITY[] = "stopability"; +constexpr char CMD_TERMINATE_APP[] = "terminate"; +constexpr char CMD_DUMP_ABILITY[] = "dump"; +} // namespace + +static sem_t g_sem; + +AbilityTool::~AbilityTool() +{ + ClearElement(&elementName_); + UnregisterIpcCallback(identity_); +} + +bool AbilityTool::SetBundleName(const char *bundleName) +{ + if (bundleName == nullptr || strlen(bundleName) == 0) { + return false; + } + SetElementBundleName(&elementName_, bundleName); + return true; +} + +bool AbilityTool::SetAbilityName(const char *abilityName) +{ + if (abilityName == nullptr || strlen(abilityName) == 0) { + return false; + } + SetElementAbilityName(&elementName_, abilityName); + return true; +} + +void AbilityTool::SetExtra(const char *extra) +{ + extra_ = const_cast(extra); +} + +bool AbilityTool::SetCommand(const char *command) +{ + if (command == nullptr) { + return false; + } + if (strcmp(command, CMD_START_ABILITY) != 0 && + strcmp(command, CMD_STOP_ABILITY) != 0 && + strcmp(command, CMD_TERMINATE_APP) != 0 && + strcmp(command, CMD_DUMP_ABILITY) != 0) { + return false; + } + printf("receive command: %s\n", command); + command_ = const_cast(command); + return true; +} + +void AbilityTool::SetDumpAll() +{ + dumpAll_ = true; +} + +bool AbilityTool::RunCommand() +{ + if (command_ == nullptr) { + printf("unknown command\n"); + return false; + } + IUnknown *iUnknown = SAMGR_GetInstance()->GetFeatureApi(AMS_SERVICE, AMS_INNER_FEATURE); + if (iUnknown == nullptr) { + printf("ams inner unknown is null\n"); + return false; + } + IClientProxy *innerProxy = nullptr; + (void)iUnknown->QueryInterface(iUnknown, CLIENT_PROXY_VER, (void **)&innerProxy); + if (innerProxy == nullptr) { + printf("ams inner feature is null\n"); + return false; + } + + if (RegisterIpcCallback(AbilityTool::AaCallback, 0, IPC_WAIT_FOREVER, &identity_, this) != 0) { + printf("registerIpcCallback failed\n"); + return false; + } + bool retVal = false; + if (strcmp(command_, CMD_START_ABILITY) == 0) { + retVal = InnerStartAbility(); + } else if (strcmp(command_, CMD_STOP_ABILITY) == 0) { + retVal = InnerStopAbility(); + } else if (strcmp(command_, CMD_TERMINATE_APP) == 0) { + retVal = TerminateApp(innerProxy); + } else if (strcmp(command_, CMD_DUMP_ABILITY) == 0) { + retVal = Dump(innerProxy); + } else { + printf("unknown command: %s\n", command_); + } + return retVal; +} + +Want* AbilityTool::BuildWant() +{ + Want *want = new Want(); + if (memset_s(want, sizeof(Want), 0, sizeof(Want)) != EOK) { + delete want; + return nullptr; + } + if (!dumpAll_) { + if (elementName_.abilityName == nullptr || strlen(elementName_.abilityName) == 0 || + elementName_.bundleName == nullptr || strlen(elementName_.bundleName) == 0) { + printf("ability name or bundle name is not entered\n"); + delete want; + return nullptr; + } + SetWantElement(want, elementName_); + } + if (strcmp(command_, CMD_DUMP_ABILITY) == 0) { + SetWantSvcIdentity(want, identity_); + } + if (extra_ != nullptr) { + SetWantData(want, extra_, strlen(extra_) + 1); + } + return want; +} + +bool AbilityTool::InnerStartAbility() +{ + Want *want = BuildWant(); + if (want == nullptr) { + return false; + } + int ret = StartAbility(want); + ClearWant(want); + delete want; + return ret == ERR_OK; +} + +bool AbilityTool::InnerStopAbility() +{ + Want *want = BuildWant(); + if (want == nullptr) { + return false; + } + int ret = StopAbility(want); + ClearWant(want); + delete want; + return ret == ERR_OK; +} + +bool AbilityTool::TerminateApp(IClientProxy *proxy) const +{ + if (proxy == nullptr) { + return false; + } + if (elementName_.bundleName == nullptr || strlen(elementName_.bundleName) == 0) { + printf("invalid argument\n"); + return false; + } + IpcIo req; + char data[IPC_IO_DATA_MAX]; + IpcIoInit(&req, data, IPC_IO_DATA_MAX, 0); + IpcIoPushString(&req, elementName_.bundleName); + return proxy->Invoke(proxy, TERMINATE_APP, &req, nullptr, nullptr) == EC_SUCCESS; +} + +bool AbilityTool::Dump(IClientProxy *proxy) +{ + if (proxy == nullptr) { + return false; + } + Want *want = BuildWant(); + if (want == nullptr) { + return false; + } + + IpcIo req; + char data[IPC_IO_DATA_MAX]; + IpcIoInit(&req, data, IPC_IO_DATA_MAX, MAX_OBJECTS); + if (!SerializeWant(&req, want)) { + printf("SerializeWant failed\n"); + ClearWant(want); + delete want; + return false; + } + ClearWant(want); + delete want; + if (proxy->Invoke(proxy, DUMP_ABILITY, &req, nullptr, nullptr) != EC_SUCCESS) { + printf("dumpAbility failed\n"); + return false; + } + if (sem_init(&g_sem, 0, 0)) { + printf("sem_init failed\n"); + return false; + } + printf("wait for callback\n"); + struct timespec ts = { 0, 0 }; + clock_gettime(CLOCK_REALTIME, &ts); + ts.tv_sec += WAIT_TIMEOUT; + sem_timedwait(&g_sem, &ts); + printf("sem exit\n"); + return true; +} + +int32_t AbilityTool::AaCallback(const IpcContext* context, void *ipcMsg, IpcIo *data, void *arg) +{ + printf("get ability info\n"); + if (ipcMsg == nullptr) { + printf("ams call back error, ipcMsg is null\n"); + return -1; + } + auto abilityTool = static_cast(arg); + if (abilityTool == nullptr) { + printf("ams call back error, abilityTool is null\n"); + FreeBuffer(nullptr, ipcMsg); + return -1; + } + + uint32_t funcId = 0; + GetCode(ipcMsg, &funcId); + uint32_t flag = 0; + GetFlag(ipcMsg, &flag); + switch (funcId) { + case SCHEDULER_APP_INIT: { + ElementName element = {}; + DeserializeElement(&element, data); + int ret = IpcIoPopInt32(data); + printf("ams call back, start %s.%s ret = %d\n", element.bundleName, element.abilityName, ret); + ClearElement(&element); + break; + } + case SCHEDULER_DUMP_ABILITY: { +#ifdef __LINUX__ + size_t len = 0; + char *result = reinterpret_cast(IpcIoPopString(data, &len)); +#else + BuffPtr *buff = IpcIoPopDataBuff(data); + if ((buff == nullptr) || (buff->buff == nullptr)) { + printf("ams call back error, buff is empty\n"); + if (flag == LITEIPC_FLAG_ONEWAY) { + FreeBuffer(nullptr, ipcMsg); + } + return false; + } + char *result = static_cast(buff->buff); + if ((buff->buffSz > 0) && (result[buff->buffSz - 1] != '\0')) { + printf("Wrong message format.\n}\n"); + FreeBuffer(nullptr, buff->buff); + break; + } + int len = strlen(result); +#endif + printf("dump ability info:\n"); + if (!abilityTool->dumpAll_) { + printf("[%s][%s]\n", abilityTool->elementName_.bundleName, abilityTool->elementName_.abilityName); + } + printf("{\n"); + for (int i = 0; i <= (len - 1) / MAX_BUFFER_SIZE_PER; i++) { + int start = MAX_BUFFER_SIZE_PER * i; + int size = (len - start) < MAX_BUFFER_SIZE_PER ? (len - start) : MAX_BUFFER_SIZE_PER; + printf("%-.*s", size, result + start); + } + printf("}\n"); +#ifndef __LINUX__ + FreeBuffer(nullptr, buff->buff); +#endif + break; + } + default: { + printf("ams call back error, funcId: %u\n", funcId); + break; + } + } + if (flag == LITEIPC_FLAG_ONEWAY) { + FreeBuffer(nullptr, ipcMsg); + } + sem_post(&g_sem); + return 0; +} +} // namespace OHOS diff --git a/services/abilitymgr_lite/tools/src/main.cpp b/services/abilitymgr_lite/tools/src/main.cpp new file mode 100755 index 0000000..7f8cc25 --- /dev/null +++ b/services/abilitymgr_lite/tools/src/main.cpp @@ -0,0 +1,108 @@ +/* + * Copyright (c) 2020 Huawei Device Co., Ltd. + * 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 +#include +#include + +#include "ability_tool.h" + +using OHOS::AbilityTool; + +static void PrintUsage() +{ + printf("Usage:\n"); + printf("aa start -p bundlename -n ability_name\n"); + printf("aa stopability -p bundlename -n ability_name\n"); + printf("aa terminate -p bundlename\n"); + printf("aa dump -p bundlename -n ability_name -e extra_option\n"); + printf("aa dump -a\n"); + printf("\n"); + printf("Options:\n"); + printf(" -h (--help) Show the help information. [eg: aa -h]\n"); + printf(" -p (--bundlename) Appoint the bundlename name. [eg: -p com.huawei]\n"); + printf(" -n (--abilityname) Appoint the ability name. [eg: -n MyAbility]\n"); + printf(" -a (--all) [Unnecessary]dump all ability info. [eg: -a]\n"); + printf(" -e (--extra) [Unnecessary]extra info when dump. [eg: -e]\n"); + printf("\n"); + printf("Commands:\n"); + printf("aa start Start the target ability.\n"); + printf("aa stopability Stop the target service ability.\n"); + printf("aa terminate Terminate the target app.\n"); + printf("aa dump Dump ability\n"); +} + +static void SetOptions(int argc, char *argv[], const option *options, AbilityTool &tool) +{ + const char *command = argv[1]; + int index = 0; + const char *optStr = "hap:n:e:"; + int para = 0; + while ((para = getopt_long(argc, argv, optStr, options, &index)) != -1) { + switch (para) { + case 'h': { + PrintUsage(); + exit(0); + } + case 'a': { + tool.SetDumpAll(); + break; + } + case 'p': { + tool.SetBundleName(optarg); + break; + } + case 'n': { + tool.SetAbilityName(optarg); + break; + } + case 'e': { + tool.SetExtra(optarg); + break; + } + default: + printf("Try 'aa -h' for more information.\n"); + exit(-1); + } + } + if (!tool.SetCommand(command)) { + printf("Unsupported this command. Try 'aa -h' for more information.\n"); + exit(-1); + } +} + +int main(int argc, char *argv[]) +{ + struct option options[] = { + {"help", no_argument, nullptr, 'h'}, + {"bundlename", required_argument, nullptr, 'p'}, + {"abilityname", required_argument, nullptr, 'n'}, + {"all", no_argument, nullptr, 'a'}, + {"extra", required_argument, nullptr, 'e'}, + {nullptr, no_argument, nullptr, 0}, + }; + + if (argc == 1) { + PrintUsage(); + exit(0); + } + AbilityTool tool = AbilityTool(); + SetOptions(argc, argv, options, tool); + bool ret = tool.RunCommand(); + if (!ret) { + printf("Failed to run the command. \n"); + } + exit(0); +}