1 /*
2 * Copyright (c) 2023 Huawei Device Co., Ltd.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15
16 #include <ctime>
17
18 #include "system_event_wrapper.h"
19
20 #include "bundle_constants.h"
21 #include "common_event_manager.h"
22 #include "common_event_subscriber.h"
23 #include "common_event_support.h"
24
25 #include "asset_log.h"
26
27 namespace {
28 using namespace OHOS::AppExecFwk::Constants;
29 using namespace OHOS::EventFwk;
30
31 const char * const APP_ID = "appId";
32 const char * const APP_INDEX = "appIndex";
33 const char * const COMMON_EVENT_RESTORE_START = "usual.event.RESTORE_START";
34 const char * const COMMON_EVENT_USER_PIN_CREATED = "USER_PIN_CREATED_EVENT";
35 const char * const BUNDLE_NAME = "bundleName";
36 const char * const PERMISSION_MANAGE_USER_IDM = "ohos.permission.MANAGE_USER_IDM";
37 const char * const DEVELOPER_ID = "developerId";
38 const char * const GROUP_IDS = "assetAccessGroups";
39 const char * const OWNER_INFO_SEPARATOR = "_";
40 const char * const GROUP_SEPARATOR = ",";
41
ParseDeveloperId(const std::string & developerId,ConstAssetBlob & developerIdBlob)42 void ParseDeveloperId(const std::string &developerId, ConstAssetBlob &developerIdBlob)
43 {
44 if (!developerId.empty()) {
45 developerIdBlob = { .size = developerId.size(),
46 .data = reinterpret_cast<const uint8_t *>(developerId.c_str()) };
47 } else {
48 developerIdBlob = { .size = 0, .data = nullptr };
49 }
50 }
51
ParseGroupIds(const std::string & groupIds,std::vector<std::string> & groupIdStrs,std::vector<ConstAssetBlob> & groupIdBlobs,ConstAssetBlobArray & groupIdBlobArray)52 void ParseGroupIds(const std::string &groupIds, std::vector<std::string> &groupIdStrs,
53 std::vector<ConstAssetBlob> &groupIdBlobs, ConstAssetBlobArray &groupIdBlobArray)
54 {
55 if (!groupIds.empty()) {
56 size_t start = 0;
57 size_t end;
58 while ((end = groupIds.find(GROUP_SEPARATOR, start)) != std::string::npos) {
59 groupIdStrs.push_back(groupIds.substr(start, end - start));
60 start = ++end;
61 }
62 groupIdStrs.push_back(groupIds.substr(start, end));
63 for (const std::string &groupIdStr : groupIdStrs) {
64 groupIdBlobs.push_back({ .size = groupIdStr.size(),
65 .data = reinterpret_cast<const uint8_t *>(groupIdStr.c_str()) });
66 }
67 groupIdBlobArray = { .size = groupIdBlobs.size(),
68 .blob = reinterpret_cast<const ConstAssetBlob *>(&groupIdBlobs[0]) };
69 } else {
70 groupIdBlobArray = { .size = 0, .blob = nullptr };
71 }
72 }
73
HandlePackageRemoved(const OHOS::AAFwk::Want & want,bool isSandBoxApp,OnPackageRemoved onPackageRemoved)74 void HandlePackageRemoved(const OHOS::AAFwk::Want &want, bool isSandBoxApp, OnPackageRemoved onPackageRemoved)
75 {
76 int userId = want.GetIntParam(USER_ID, INVALID_USERID);
77 std::string appId = want.GetStringParam(APP_ID);
78 int appIndex = isSandBoxApp ? want.GetIntParam(SANDBOX_APP_INDEX, -1) : want.GetIntParam(APP_INDEX, -1);
79 if (appId.empty() || userId == INVALID_USERID || appIndex == -1) {
80 LOGE("[FATAL]Get removed owner info failed, userId=%{public}d, appId=%{public}s, appIndex=%{public}d",
81 userId, appId.c_str(), appIndex);
82 return;
83 }
84 std::string owner = appId + OWNER_INFO_SEPARATOR + std::to_string(appIndex);
85 ConstAssetBlob ownerBlob = { .size = owner.size(), .data = reinterpret_cast<const uint8_t *>(owner.c_str()) };
86
87 std::string bundleName = want.GetBundle();
88 ConstAssetBlob bundleNameBlob = { .size = bundleName.size(),
89 .data = reinterpret_cast<const uint8_t *>(bundleName.c_str()) };
90
91 std::string developerId = want.GetStringParam(DEVELOPER_ID);
92 ConstAssetBlob developerIdBlob;
93 ParseDeveloperId(developerId, developerIdBlob);
94 std::string groupIds = want.GetStringParam(GROUP_IDS);
95 std::vector<ConstAssetBlob> groupIdBlobs;
96 std::vector<std::string> groupIdStrs;
97 ConstAssetBlobArray groupIdBlobArray;
98 ParseGroupIds(groupIds, groupIdStrs, groupIdBlobs, groupIdBlobArray);
99
100 if (onPackageRemoved != nullptr) {
101 onPackageRemoved({ userId, appIndex, ownerBlob, developerIdBlob, groupIdBlobArray, bundleNameBlob });
102 }
103 LOGI("[INFO]Receive event: PACKAGE_REMOVED, userId=%{public}d, appId=%{public}s, appIndex=%{public}d", userId,
104 appId.c_str(), appIndex);
105 }
106
HandleAppRestore(const OHOS::AAFwk::Want & want,OnAppRestore onAppRestore)107 void HandleAppRestore(const OHOS::AAFwk::Want &want, OnAppRestore onAppRestore)
108 {
109 if (onAppRestore != nullptr) {
110 int userId = want.GetIntParam(USER_ID, INVALID_USERID);
111 std::string bundleName = want.GetStringParam(BUNDLE_NAME);
112
113 int appIndex = want.GetIntParam(SANDBOX_APP_INDEX, -1);
114 if (appIndex == -1) {
115 LOGI("[INFO]Get app restore info failed, default as index 0.");
116 appIndex = 0;
117 }
118
119 onAppRestore(userId, reinterpret_cast<const uint8_t *>(bundleName.c_str()), appIndex);
120 LOGI("[INFO]Receive event: RESTORE_START.");
121 }
122 }
123
124 class SystemEventHandler : public CommonEventSubscriber {
125 public:
SystemEventHandler(const CommonEventSubscribeInfo & subscribeInfo,const EventCallBack eventCallBack)126 explicit SystemEventHandler(const CommonEventSubscribeInfo &subscribeInfo, const EventCallBack eventCallBack)
127 : CommonEventSubscriber(subscribeInfo), eventCallBack(eventCallBack) {}
128 ~SystemEventHandler() = default;
OnReceiveEvent(const CommonEventData & data)129 void OnReceiveEvent(const CommonEventData &data) override
130 {
131 long startTime = std::clock();
132 auto want = data.GetWant();
133 std::string action = want.GetAction();
134 if (action == CommonEventSupport::COMMON_EVENT_PACKAGE_REMOVED) {
135 HandlePackageRemoved(want, false, this->eventCallBack.onPackageRemoved);
136 } else if (action == CommonEventSupport::COMMON_EVENT_SANDBOX_PACKAGE_REMOVED) {
137 HandlePackageRemoved(want, true, this->eventCallBack.onPackageRemoved);
138 } else if (action == CommonEventSupport::COMMON_EVENT_USER_REMOVED) {
139 int userId = data.GetCode();
140 if (this->eventCallBack.onUserRemoved != nullptr) {
141 this->eventCallBack.onUserRemoved(userId);
142 }
143 LOGI("[INFO] Receive event: USER_REMOVED, userId=%{public}d", userId);
144 } else if (action == CommonEventSupport::COMMON_EVENT_SCREEN_OFF) {
145 if (this->eventCallBack.onScreenOff != nullptr) {
146 this->eventCallBack.onScreenOff();
147 }
148 LOGI("[INFO]Receive event: SCREEN_OFF, start_time: %{public}ld", startTime);
149 } else if (action == CommonEventSupport::COMMON_EVENT_CHARGING) {
150 if (this->eventCallBack.onCharging != nullptr) {
151 this->eventCallBack.onCharging();
152 }
153 LOGI("[INFO]Receive event: CHARGING, start_time: %{public}ld", startTime);
154 } else if (action == COMMON_EVENT_RESTORE_START) {
155 HandleAppRestore(want, this->eventCallBack.onAppRestore);
156 } else if (action == CommonEventSupport::COMMON_EVENT_USER_UNLOCKED) {
157 if (this->eventCallBack.onUserUnlocked != nullptr) {
158 int userId = data.GetCode();
159 this->eventCallBack.onUserUnlocked(userId);
160 }
161 LOGI("[INFO]Receive event: USER_UNLOCKED, start_time: %{public}ld", startTime);
162 } else if (action == COMMON_EVENT_USER_PIN_CREATED) {
163 if (this->eventCallBack.onUserUnlocked != nullptr) {
164 int userId = data.GetCode();
165 this->eventCallBack.onUserUnlocked(userId);
166 }
167 LOGI("[INFO]Receive event: USER_PIN_CREATED_EVENT, start_time: %{public}ld", startTime);
168 } else {
169 LOGW("[WARNING]Receive unknown event: %{public}s", action.c_str());
170 }
171 }
172 private:
173 const EventCallBack eventCallBack;
174 };
175
176 std::shared_ptr<SystemEventHandler> g_eventHandler = nullptr;
177 std::shared_ptr<SystemEventHandler> g_pinEventHandler = nullptr;
SubscribePinEvent(const EventCallBack eventCallBack)178 bool SubscribePinEvent(const EventCallBack eventCallBack)
179 {
180 MatchingSkills matchingSkills;
181 matchingSkills.AddEvent(COMMON_EVENT_USER_PIN_CREATED);
182 CommonEventSubscribeInfo info(matchingSkills);
183 info.SetPermission(PERMISSION_MANAGE_USER_IDM);
184 if (g_pinEventHandler == nullptr) {
185 g_pinEventHandler = std::shared_ptr<SystemEventHandler>(
186 new (std::nothrow) SystemEventHandler(info, eventCallBack));
187 if (g_pinEventHandler == nullptr) {
188 LOGE("[FATAL]Asset pin event handler is nullptr.");
189 return false;
190 }
191 }
192
193 return CommonEventManager::SubscribeCommonEvent(g_pinEventHandler);
194 }
195
UnSubscribePinEvent(void)196 bool UnSubscribePinEvent(void)
197 {
198 if (g_pinEventHandler == nullptr) {
199 LOGW("Asset pin event handler is nullptr, no need to unsubscribe.");
200 return false;
201 }
202
203 bool res = CommonEventManager::UnSubscribeCommonEvent(g_pinEventHandler);
204 g_pinEventHandler = nullptr;
205 return res;
206 }
207
208 }
209
SubscribeSystemEvent(const EventCallBack eventCallBack)210 bool SubscribeSystemEvent(const EventCallBack eventCallBack)
211 {
212 bool ret = SubscribePinEvent(eventCallBack);
213 LOGI("Subscribe pin event result: %d", ret);
214
215 MatchingSkills matchingSkills;
216 matchingSkills.AddEvent(CommonEventSupport::COMMON_EVENT_PACKAGE_REMOVED);
217 matchingSkills.AddEvent(CommonEventSupport::COMMON_EVENT_SANDBOX_PACKAGE_REMOVED);
218 matchingSkills.AddEvent(CommonEventSupport::COMMON_EVENT_USER_REMOVED);
219 matchingSkills.AddEvent(CommonEventSupport::COMMON_EVENT_SCREEN_OFF);
220 matchingSkills.AddEvent(CommonEventSupport::COMMON_EVENT_CHARGING);
221 matchingSkills.AddEvent(CommonEventSupport::COMMON_EVENT_USER_UNLOCKED);
222 matchingSkills.AddEvent(COMMON_EVENT_RESTORE_START);
223 CommonEventSubscribeInfo info(matchingSkills);
224 if (g_eventHandler == nullptr) {
225 g_eventHandler = std::shared_ptr<SystemEventHandler>(
226 new (std::nothrow) SystemEventHandler(info, eventCallBack));
227 if (g_eventHandler == nullptr) {
228 LOGE("[FATAL]Asset system event handler is nullptr.");
229 return false;
230 }
231 }
232
233 return CommonEventManager::SubscribeCommonEvent(g_eventHandler);
234 }
235
UnSubscribeSystemEvent(void)236 bool UnSubscribeSystemEvent(void)
237 {
238 bool ret = UnSubscribePinEvent();
239 LOGI("UnSubscribe pin event result: %d", ret);
240
241 if (g_eventHandler == nullptr) {
242 LOGW("Asset system event handler is nullptr, no need to unsubscribe.");
243 return false;
244 }
245
246 bool res = CommonEventManager::UnSubscribeCommonEvent(g_eventHandler);
247 g_eventHandler = nullptr;
248 return res;
249 }
250