1 /*
2 * Copyright (C) 2022 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 "utils.h"
17
18 #include <hisysevent.h>
19
20 #include "bundle_mgr_client.h"
21 #include "hilog_wrapper.h"
22 #include "nlohmann/json.hpp"
23 #include "ipc_skeleton.h"
24
25 namespace OHOS {
26 namespace Accessibility {
27 namespace {
28 const std::string KEY_ACCESSIBILITY_ABILITY_TYPES = "accessibilityAbilityTypes";
29 const std::string KEY_ACCESSIBILITY_CAPABILITIES = "accessibilityCapabilities";
30 const std::string KEY_SETTINGS_ABILITY = "settingsAbility";
31 const std::string KEY_ACCESSIBILITY_CAPABILITIES_RATIONALE = "accessibilityCapabilityRationale";
32 const std::string KEY_IS_IMPORTANT = "isImportant";
33 const std::string KEY_NEED_HIDE = "needHide";
34
35 // The json value of accessibilityAbility type
36 const std::string ACCESSIBILITY_ABILITY_TYPES_JSON_VALUE_SPOKEN = "spoken";
37 const std::string ACCESSIBILITY_ABILITY_TYPES_JSON_VALUE_HAPIC = "haptic";
38 const std::string ACCESSIBILITY_ABILITY_TYPES_JSON_VALUE_AUDIBLE = "audible";
39 const std::string ACCESSIBILITY_ABILITY_TYPES_JSON_VALUE_VISUAL = "visual";
40 const std::string ACCESSIBILITY_ABILITY_TYPES_JSON_VALUE_GENERIC = "generic";
41 const std::string ACCESSIBILITY_ABILITY_TYPES_JSON_VALUE_ALL = "all";
42
43 // The json value of capabilities
44 const std::string CAPABILITIES_JSON_VALUE_RETRIEVE = "retrieve";
45 const std::string CAPABILITIES_JSON_VALUE_TOUCH_GUIDE = "touchGuide";
46 const std::string CAPABILITIES_JSON_VALUE_KEY_EVENT_OBSERVER = "keyEventObserver";
47 const std::string CAPABILITIES_JSON_VALUE_ZOOM = "zoom";
48 const std::string CAPABILITIES_JSON_VALUE_GESTURE = "gesture";
49
50 const int32_t STRING_LEN_MAX = 10240;
51 constexpr int32_t BASE_USER_RANGE = 200000;
52 constexpr int32_t INVALID_ID = -1;
53 constexpr int32_t INVALID_USER_ID = -1;
54 } // namespace
55
56 class JsonUtils {
57 public:
GetStringFromJson(const nlohmann::json & json,const std::string & key,std::string & value)58 static bool GetStringFromJson(const nlohmann::json &json, const std::string &key, std::string &value)
59 {
60 HILOG_DEBUG("start.");
61 if (!json.is_object()) {
62 HILOG_ERROR("json is not object.");
63 return false;
64 }
65 if (json.find(key) != json.end() && json.at(key).is_string()) {
66 HILOG_DEBUG("Find key[%{public}s] successful.", key.c_str());
67 value = json.at(key).get<std::string>();
68 }
69 return true;
70 }
71
GetStringVecFromJson(const nlohmann::json & json,const std::string & key,std::vector<std::string> & value)72 static bool GetStringVecFromJson(const nlohmann::json &json, const std::string &key,
73 std::vector<std::string> &value)
74 {
75 HILOG_DEBUG("start.");
76 if (!json.is_object()) {
77 HILOG_ERROR("json is not object.");
78 return false;
79 }
80 if (json.find(key) != json.end() && json.at(key).is_array()) {
81 HILOG_DEBUG("Find key[%{public}s] successful.", key.c_str());
82 value = json.at(key).get<std::vector<std::string>>();
83 }
84 return true;
85 }
86
GetBoolFromJson(const nlohmann::json & json,const std::string & key,bool & value)87 static bool GetBoolFromJson(const nlohmann::json &json, const std::string &key, bool &value)
88 {
89 HILOG_DEBUG("start.");
90 if (!json.is_object()) {
91 HILOG_ERROR("json is not object.");
92 return false;
93 }
94 if (json.find(key) != json.end() && json.at(key).is_boolean()) {
95 HILOG_DEBUG("Find key[%{public}s] successful.", key.c_str());
96 value = json.at(key).get<bool>();
97 }
98 return true;
99 }
100 };
101
102 class PraseVecUtils {
103 public:
ParseAbilityTypesFromVec(const std::vector<std::string> & abilities)104 static uint32_t ParseAbilityTypesFromVec(const std::vector<std::string> &abilities)
105 {
106 HILOG_DEBUG("start.");
107 uint32_t abilityTypes = 0;
108
109 for (const auto &ability : abilities) {
110 if (ability == ACCESSIBILITY_ABILITY_TYPES_JSON_VALUE_SPOKEN) {
111 abilityTypes |= AccessibilityAbilityTypes::ACCESSIBILITY_ABILITY_TYPE_SPOKEN;
112 }
113
114 if (ability == ACCESSIBILITY_ABILITY_TYPES_JSON_VALUE_HAPIC) {
115 abilityTypes |= AccessibilityAbilityTypes::ACCESSIBILITY_ABILITY_TYPE_HAPTIC;
116 }
117
118 if (ability == ACCESSIBILITY_ABILITY_TYPES_JSON_VALUE_AUDIBLE) {
119 abilityTypes |= AccessibilityAbilityTypes::ACCESSIBILITY_ABILITY_TYPE_AUDIBLE;
120 }
121
122 if (ability == ACCESSIBILITY_ABILITY_TYPES_JSON_VALUE_VISUAL) {
123 abilityTypes |= AccessibilityAbilityTypes::ACCESSIBILITY_ABILITY_TYPE_VISUAL;
124 }
125
126 if (ability == ACCESSIBILITY_ABILITY_TYPES_JSON_VALUE_GENERIC) {
127 abilityTypes |= AccessibilityAbilityTypes::ACCESSIBILITY_ABILITY_TYPE_GENERIC;
128 }
129
130 if (ability == ACCESSIBILITY_ABILITY_TYPES_JSON_VALUE_ALL) {
131 abilityTypes |= AccessibilityAbilityTypes::ACCESSIBILITY_ABILITY_TYPE_ALL;
132 }
133 }
134 return abilityTypes;
135 }
136
ParseCapabilitiesFromVec(const std::vector<std::string> & capabilities)137 static uint32_t ParseCapabilitiesFromVec(const std::vector<std::string> &capabilities)
138 {
139 HILOG_DEBUG("start.");
140 uint32_t capabilitiesValue = 0;
141
142 for (const auto &capability : capabilities) {
143 if (capability == CAPABILITIES_JSON_VALUE_RETRIEVE) {
144 capabilitiesValue |= Capability::CAPABILITY_RETRIEVE;
145 }
146
147 if (capability == CAPABILITIES_JSON_VALUE_TOUCH_GUIDE) {
148 capabilitiesValue |= Capability::CAPABILITY_TOUCH_GUIDE;
149 }
150
151 if (capability == CAPABILITIES_JSON_VALUE_KEY_EVENT_OBSERVER) {
152 capabilitiesValue |= Capability::CAPABILITY_KEY_EVENT_OBSERVER;
153 }
154
155 if (capability == CAPABILITIES_JSON_VALUE_ZOOM) {
156 capabilitiesValue |= Capability::CAPABILITY_ZOOM;
157 }
158
159 if (capability == CAPABILITIES_JSON_VALUE_GESTURE) {
160 capabilitiesValue |= Capability::CAPABILITY_GESTURE;
161 }
162 }
163 return capabilitiesValue;
164 }
165 };
166
Parse(const AppExecFwk::ExtensionAbilityInfo & abilityInfo,AccessibilityAbilityInitParams & initParams)167 void Utils::Parse(const AppExecFwk::ExtensionAbilityInfo &abilityInfo, AccessibilityAbilityInitParams &initParams)
168 {
169 HILOG_DEBUG("start.");
170 initParams.name = abilityInfo.name;
171 initParams.bundleName = abilityInfo.bundleName;
172 initParams.moduleName = abilityInfo.moduleName;
173 initParams.description = abilityInfo.description;
174 initParams.label = abilityInfo.label;
175
176 std::vector<std::string> profileInfos;
177 std::string metadataName = "ohos.accessibleability";
178 AppExecFwk::BundleMgrClient bundleMgrClient;
179 bundleMgrClient.GetResConfigFile(abilityInfo, metadataName, profileInfos);
180 if (profileInfos.empty()) {
181 HILOG_ERROR("profileInfos is empty.");
182 return;
183 }
184
185 if (!nlohmann::json::accept(profileInfos[0])) {
186 HILOG_ERROR("profileInfos is not json format.");
187 return;
188 }
189 nlohmann::json sourceJson = nlohmann::json::parse(profileInfos[0]);
190
191 // accessibilityCapabilities
192 std::vector<std::string> capabilities;
193 if (!JsonUtils::GetStringVecFromJson(sourceJson, KEY_ACCESSIBILITY_CAPABILITIES, capabilities)) {
194 HILOG_ERROR("Get accessibilityCapabilities from json failed.");
195 return;
196 }
197 initParams.staticCapabilities = PraseVecUtils::ParseCapabilitiesFromVec(capabilities);
198
199 // accessibilityAbilityTypes
200 std::vector<std::string> abilityTypes;
201 if (!JsonUtils::GetStringVecFromJson(sourceJson, KEY_ACCESSIBILITY_ABILITY_TYPES, abilityTypes)) {
202 HILOG_ERROR("Get accessibilityAbilityTypes from json failed.");
203 return;
204 }
205 initParams.abilityTypes = PraseVecUtils::ParseAbilityTypesFromVec(abilityTypes);
206
207 // accessibilityCapabilityRationale
208 if (!JsonUtils::GetStringFromJson(sourceJson, KEY_ACCESSIBILITY_CAPABILITIES_RATIONALE, initParams.rationale)) {
209 HILOG_ERROR("Get accessibilityCapabilityRationale from json failed.");
210 return;
211 }
212
213 // settingsAbility
214 if (!JsonUtils::GetStringFromJson(sourceJson, KEY_SETTINGS_ABILITY, initParams.settingsAbility)) {
215 HILOG_ERROR("Get settingsAbility from json failed.");
216 return;
217 }
218
219 // isImportant
220 if (!JsonUtils::GetBoolFromJson(sourceJson, KEY_IS_IMPORTANT, initParams.isImportant)) {
221 HILOG_ERROR("Get isImportant from json failed.");
222 return;
223 }
224
225 // needHide
226 if (!JsonUtils::GetBoolFromJson(sourceJson, KEY_NEED_HIDE, initParams.needHide)) {
227 HILOG_ERROR("Get needHide from json failed.");
228 return;
229 }
230 }
231
GetSystemTime()232 int64_t Utils::GetSystemTime()
233 {
234 HILOG_DEBUG("start.");
235
236 struct timespec times = {0, 0};
237 clock_gettime(CLOCK_MONOTONIC, ×);
238 int64_t millisecond = static_cast<int64_t>(times.tv_sec * 1000 + times.tv_nsec / 1000000);
239
240 return millisecond;
241 }
242
GetUri(const OHOS::AppExecFwk::ElementName & elementName)243 std::string Utils::GetUri(const OHOS::AppExecFwk::ElementName &elementName)
244 {
245 HILOG_DEBUG("bundle name(%{public}s) ability name(%{public}s)",
246 elementName.GetBundleName().c_str(), elementName.GetAbilityName().c_str());
247 return elementName.GetBundleName() + "/" + elementName.GetAbilityName();
248 }
249
GetUri(const std::string & bundleName,const std::string & abilityName)250 std::string Utils::GetUri(const std::string &bundleName, const std::string &abilityName)
251 {
252 HILOG_DEBUG("bundle name(%{public}s) ability name(%{public}s)", bundleName.c_str(), abilityName.c_str());
253 return bundleName + "/" + abilityName;
254 }
255
GetAbilityAutoStartStateKey(const std::string & bundleName,const std::string & abilityName,int32_t accountId)256 std::string Utils::GetAbilityAutoStartStateKey(const std::string &bundleName, const std::string &abilityName,
257 int32_t accountId)
258 {
259 HILOG_DEBUG("bundle name(%{public}s) ability name(%{public}s) accountId(%{public}d)",
260 bundleName.c_str(), abilityName.c_str(), accountId);
261 return bundleName + "/" + abilityName + "/" + std::to_string(accountId);
262 }
263
SelectUsefulFromVecWithSameBundle(std::vector<std::string> & selectVec,std::vector<std::string> & cmpVec,bool & hasDif,const std::string & bundleName)264 void Utils::SelectUsefulFromVecWithSameBundle(std::vector<std::string> &selectVec, std::vector<std::string> &cmpVec,
265 bool &hasDif, const std::string &bundleName)
266 {
267 HILOG_DEBUG();
268 for (auto iter = selectVec.begin(); iter != selectVec.end();) {
269 if (iter->substr(0, iter->find("/")) != bundleName) {
270 ++iter;
271 continue;
272 }
273 auto it = cmpVec.begin();
274 for (; it != cmpVec.end(); ++it) {
275 if ((*it) == (*iter)) {
276 break;
277 }
278 }
279 if (it == cmpVec.end()) {
280 iter = selectVec.erase(iter);
281 hasDif = true;
282 } else {
283 ++iter;
284 }
285 }
286 }
287
RecordUnavailableEvent(A11yUnavailableEvent event,A11yError errCode,const std::string & bundleName,const std::string & abilityName)288 void Utils::RecordUnavailableEvent(A11yUnavailableEvent event, A11yError errCode,
289 const std::string &bundleName, const std::string &abilityName)
290 {
291 if (!(errCode > A11yError::ERROR_NEED_REPORT_BASE && errCode < A11yError::ERROR_NEED_REPORT_END)) {
292 return;
293 }
294 std::ostringstream oss;
295 oss << "accessibility function is unavailable: " << "event: " << TransferUnavailableEventToString(event)
296 << ", errCode: " << static_cast<int32_t>(errCode)
297 << ", bundleName: " << bundleName << ", abilityName: " << abilityName << ";";
298 std::string info = oss.str();
299 HILOG_DEBUG("accessibility function is unavailable: %{public}s", info.c_str());
300 int32_t ret = HiSysEventWrite(
301 OHOS::HiviewDFX::HiSysEvent::Domain::ACCESSIBILITY,
302 "UNAVAILABLE",
303 OHOS::HiviewDFX::HiSysEvent::EventType::FAULT,
304 "MSG", info);
305 if (ret != 0) {
306 HILOG_ERROR("Write HiSysEvent error, ret:%{public}d", ret);
307 }
308 }
309
TransferUnavailableEventToString(A11yUnavailableEvent type)310 std::string Utils::TransferUnavailableEventToString(A11yUnavailableEvent type)
311 {
312 std::string event;
313 switch (type) {
314 case A11yUnavailableEvent::READ_EVENT:
315 event = "READ";
316 break;
317 case A11yUnavailableEvent::CONNECT_EVENT:
318 event = "CONNECT";
319 break;
320 case A11yUnavailableEvent::QUERY_EVENT:
321 event = "QUERY";
322 break;
323 default:
324 event = "UNDEFINE";
325 break;
326 }
327 return event;
328 }
329
RecordStartingA11yEvent(uint32_t flag)330 void Utils::RecordStartingA11yEvent(uint32_t flag)
331 {
332 std::ostringstream oss;
333 oss << "starting accessibility: " << "event: " << "system" << ", id: " << flag << ";";
334 HILOG_DEBUG("starting accessibility: %{public}s", oss.str().c_str());
335 int32_t ret = HiSysEventWrite(
336 OHOS::HiviewDFX::HiSysEvent::Domain::ACCESSIBILITY,
337 "STARTING_FUNCTION",
338 OHOS::HiviewDFX::HiSysEvent::EventType::BEHAVIOR,
339 "MSG", oss.str());
340 if (ret != 0) {
341 HILOG_ERROR("Write HiSysEvent error, ret:%{public}d", ret);
342 }
343 }
344
RecordStartingA11yEvent(const std::string & name)345 void Utils::RecordStartingA11yEvent(const std::string &name)
346 {
347 std::ostringstream oss;
348 oss << "starting accessibility: " << "event: " << "extension" << ", name: " << name << ";";
349 HILOG_DEBUG("starting accessibility: %{public}s", oss.str().c_str());
350 int32_t ret = HiSysEventWrite(
351 OHOS::HiviewDFX::HiSysEvent::Domain::ACCESSIBILITY,
352 "STARTING_FUNCTION",
353 OHOS::HiviewDFX::HiSysEvent::EventType::BEHAVIOR,
354 "MSG", oss.str());
355 if (ret != 0) {
356 HILOG_ERROR("Write HiSysEvent error, ret:%{public}d", ret);
357 }
358 }
359
RecordEnableShortkeyAbilityEvent(const std::string & name)360 void Utils::RecordEnableShortkeyAbilityEvent(const std::string &name)
361 {
362 std::string MSG_NAME = "enable single targets";
363 HILOG_DEBUG("starting RecordEnableShortkeyAbilityEvent enable single targets: %{public}s", name.c_str());
364 int32_t ret = HiSysEventWrite(
365 OHOS::HiviewDFX::HiSysEvent::Domain::ACCESSIBILITY_UE,
366 "ENABLE_SHORTKEY_ABILITY_SINGLE",
367 OHOS::HiviewDFX::HiSysEvent::EventType::BEHAVIOR,
368 "MSG_NAME", MSG_NAME, "MSG_VALUE", name);
369 if (ret != 0) {
370 HILOG_ERROR("Write HiSysEvent RecordEnableShortkeyAbilityEvent error, ret:%{public}d", ret);
371 }
372 }
373
RecordOnZoomGestureEvent(const std::string & state)374 void Utils::RecordOnZoomGestureEvent(const std::string &state)
375 {
376 std::string MSG_NAME = "on zoom gesture state";
377 HILOG_DEBUG("starting RecordOnZoomGestureEvent on zoom gesture state: %{public}s", state.c_str());
378 int32_t ret = HiSysEventWrite(
379 OHOS::HiviewDFX::HiSysEvent::Domain::ACCESSIBILITY_UE,
380 "ZOOM_GESTURE_ACTION",
381 OHOS::HiviewDFX::HiSysEvent::EventType::BEHAVIOR,
382 "MSG_NAME", MSG_NAME, "MSG_VALUE", state);
383 if (ret != 0) {
384 HILOG_ERROR("Write HiSysEvent RecordOnZoomGestureEvent error, ret:%{public}d", ret);
385 }
386 }
387
VectorToString(const std::vector<std::string> & vectorVal,std::string & stringOut)388 void Utils::VectorToString(const std::vector<std::string> &vectorVal, std::string &stringOut)
389 {
390 HILOG_DEBUG();
391 int32_t i = 0;
392 for (auto& var : vectorVal) {
393 if (i > 0) {
394 stringOut = stringOut + ',';
395 }
396 stringOut = stringOut + var.c_str();
397 i++;
398 }
399 HILOG_DEBUG("stringOUT = %{public}s .", stringOut.c_str());
400 }
401
StringToVector(const std::string & stringIn,std::vector<std::string> & vectorResult)402 void Utils::StringToVector(const std::string &stringIn, std::vector<std::string> &vectorResult)
403 {
404 HILOG_DEBUG();
405 int32_t strLength = static_cast<int32_t>(stringIn.size());
406 std::vector<int32_t> position;
407
408 if (strLength <= 0 || strLength > STRING_LEN_MAX) {
409 return;
410 }
411
412 for (int32_t j = 0; j < strLength; j++) {
413 if (stringIn[j] == ',') {
414 position.push_back(j);
415 }
416 }
417
418 int32_t wrodCount = static_cast<int32_t>(position.size());
419 if (wrodCount == 0) {
420 vectorResult.push_back(stringIn);
421 } else {
422 int32_t startWrod = 0;
423 int32_t length = 0;
424 for (int32_t i = 0; i <= wrodCount; i++) {
425 if (i == 0) {
426 length = position[i];
427 vectorResult.push_back(stringIn.substr(startWrod, length)); // First string
428 } else if (i < wrodCount) {
429 startWrod = position[i - 1] + 1;
430 length = position[i] - position[i - 1] - 1;
431 vectorResult.push_back(stringIn.substr(startWrod, length)); // Second string to last-1 string
432 } else {
433 startWrod = position[i - 1] + 1;
434 length = strLength - position[i - 1] - 1;
435 vectorResult.push_back(stringIn.substr(startWrod, length)); // Last string
436 }
437 }
438 }
439 HILOG_DEBUG("strLength = %{public}d, wrodCount = %{public}d, stringIn : %{public}s",
440 strLength, wrodCount, stringIn.c_str());
441 for (auto& var : vectorResult) {
442 HILOG_DEBUG("vectorResult = %{public}s ", var.c_str());
443 }
444 }
445
GetUserIdByCallingUid()446 int32_t Utils::GetUserIdByCallingUid()
447 {
448 int32_t uid = IPCSkeleton::GetCallingUid();
449 if (uid <= INVALID_ID) {
450 return INVALID_USER_ID;
451 }
452 return (uid / BASE_USER_RANGE);
453 }
454 } // namespace Accessibility
455 } // namespace OHOS