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
RecordOnRemoveSystemAbility(int32_t systemAbilityId,const std::string & bundleName,const std::string & abilityName)310 void Utils::RecordOnRemoveSystemAbility(int32_t systemAbilityId, const std::string &bundleName,
311 const std::string &abilityName)
312 {
313 std::ostringstream oss;
314 oss << "OnRemoveSystemAbility systemAbilityId is: " << systemAbilityId
315 << ", bundleName: " << bundleName << ", abilityName: " << abilityName << ";";
316 std::string info = oss.str();
317 HILOG_DEBUG("accessibility function is unavailable: %{public}s", info.c_str());
318 int32_t ret = HiSysEventWrite(
319 OHOS::HiviewDFX::HiSysEvent::Domain::ACCESSIBILITY,
320 "UNAVAILABLE",
321 OHOS::HiviewDFX::HiSysEvent::EventType::FAULT,
322 "MSG", info);
323 if (ret != 0) {
324 HILOG_ERROR("Write OnRemoveSystemAbility error, ret:%{public}d", ret);
325 }
326 }
327
RecordDatashareInteraction(A11yDatashareValueType type,const std::string & businessName,const std::string & bundleName,const std::string & abilityName)328 void Utils::RecordDatashareInteraction(A11yDatashareValueType type, const std::string &businessName,
329 const std::string &bundleName, const std::string &abilityName)
330 {
331 std::ostringstream oss;
332 oss << "datashare interaction failed, type is: " << static_cast<uint32_t>(type)
333 << ", businessName: " << businessName << ", bundleName: " << bundleName
334 << ", abilityName: " << abilityName << ";";
335 std::string info = oss.str();
336 HILOG_DEBUG("accessibility function is unavailable: %{public}s", info.c_str());
337 int32_t ret = HiSysEventWrite(
338 OHOS::HiviewDFX::HiSysEvent::Domain::ACCESSIBILITY,
339 "UNAVAILABLE",
340 OHOS::HiviewDFX::HiSysEvent::EventType::FAULT,
341 "MSG", info);
342 if (ret != 0) {
343 HILOG_ERROR("Write RecordDatashareInteraction error, ret:%{public}d", ret);
344 }
345 }
346
TransferUnavailableEventToString(A11yUnavailableEvent type)347 std::string Utils::TransferUnavailableEventToString(A11yUnavailableEvent type)
348 {
349 std::string event;
350 switch (type) {
351 case A11yUnavailableEvent::READ_EVENT:
352 event = "READ";
353 break;
354 case A11yUnavailableEvent::CONNECT_EVENT:
355 event = "CONNECT";
356 break;
357 case A11yUnavailableEvent::QUERY_EVENT:
358 event = "QUERY";
359 break;
360 default:
361 event = "UNDEFINE";
362 break;
363 }
364 return event;
365 }
366
RecordStartingA11yEvent(uint32_t flag)367 void Utils::RecordStartingA11yEvent(uint32_t flag)
368 {
369 std::ostringstream oss;
370 oss << "starting accessibility: " << "event: " << "system" << ", id: " << flag << ";";
371 HILOG_DEBUG("starting accessibility: %{public}s", oss.str().c_str());
372 int32_t ret = HiSysEventWrite(
373 OHOS::HiviewDFX::HiSysEvent::Domain::ACCESSIBILITY,
374 "STARTING_FUNCTION",
375 OHOS::HiviewDFX::HiSysEvent::EventType::BEHAVIOR,
376 "MSG", oss.str());
377 if (ret != 0) {
378 HILOG_ERROR("Write HiSysEvent error, ret:%{public}d", ret);
379 }
380 }
381
RecordStartingA11yEvent(const std::string & name)382 void Utils::RecordStartingA11yEvent(const std::string &name)
383 {
384 std::ostringstream oss;
385 oss << "starting accessibility: " << "event: " << "extension" << ", name: " << name << ";";
386 HILOG_DEBUG("starting accessibility: %{public}s", oss.str().c_str());
387 int32_t ret = HiSysEventWrite(
388 OHOS::HiviewDFX::HiSysEvent::Domain::ACCESSIBILITY,
389 "STARTING_FUNCTION",
390 OHOS::HiviewDFX::HiSysEvent::EventType::BEHAVIOR,
391 "MSG", oss.str());
392 if (ret != 0) {
393 HILOG_ERROR("Write HiSysEvent error, ret:%{public}d", ret);
394 }
395 }
396
RecordEnableShortkeyAbilityEvent(const std::string & name,const bool & enableState)397 void Utils::RecordEnableShortkeyAbilityEvent(const std::string &name, const bool &enableState)
398 {
399 std::string MSG_NAME = "enable single targets";
400 std::ostringstream oss;
401 std::string enableStateValue = enableState ? "on" : "off";
402 oss << "targets name: " << name.c_str() << ", state:" << enableStateValue.c_str() << ";";
403 HILOG_DEBUG("RecordEnableShortkeyAbilityEvent enable single targets: %{public}s, enableState: %{public}s",
404 name.c_str(), enableStateValue.c_str());
405 int32_t ret = HiSysEventWrite(
406 OHOS::HiviewDFX::HiSysEvent::Domain::ACCESSIBILITY_UE,
407 "ENABLE_SHORTKEY_ABILITY_SINGLE",
408 OHOS::HiviewDFX::HiSysEvent::EventType::BEHAVIOR,
409 "MSG_NAME", MSG_NAME, "MSG_VALUE", oss.str());
410 if (ret != 0) {
411 HILOG_ERROR("Write HiSysEvent RecordEnableShortkeyAbilityEvent error, ret:%{public}d", ret);
412 }
413 }
414
RecordOnZoomGestureEvent(const std::string & state)415 void Utils::RecordOnZoomGestureEvent(const std::string &state)
416 {
417 std::string MSG_NAME = "on zoom gesture state";
418 HILOG_DEBUG("starting RecordOnZoomGestureEvent on zoom gesture state: %{public}s", state.c_str());
419 int32_t ret = HiSysEventWrite(
420 OHOS::HiviewDFX::HiSysEvent::Domain::ACCESSIBILITY_UE,
421 "ZOOM_GESTURE_ACTION",
422 OHOS::HiviewDFX::HiSysEvent::EventType::BEHAVIOR,
423 "MSG_NAME", MSG_NAME, "MSG_VALUE", state);
424 if (ret != 0) {
425 HILOG_ERROR("Write HiSysEvent RecordOnZoomGestureEvent error, ret:%{public}d", ret);
426 }
427 }
428
VectorToString(const std::vector<std::string> & vectorVal,std::string & stringOut)429 void Utils::VectorToString(const std::vector<std::string> &vectorVal, std::string &stringOut)
430 {
431 HILOG_DEBUG();
432 int32_t i = 0;
433 for (auto& var : vectorVal) {
434 if (i > 0) {
435 stringOut = stringOut + ',';
436 }
437 stringOut = stringOut + var.c_str();
438 i++;
439 }
440 HILOG_DEBUG("stringOUT = %{public}s .", stringOut.c_str());
441 }
442
StringToVector(const std::string & stringIn,std::vector<std::string> & vectorResult)443 void Utils::StringToVector(const std::string &stringIn, std::vector<std::string> &vectorResult)
444 {
445 HILOG_DEBUG();
446 int32_t strLength = static_cast<int32_t>(stringIn.size());
447 std::vector<int32_t> position;
448
449 if (strLength <= 0 || strLength > STRING_LEN_MAX) {
450 return;
451 }
452
453 for (int32_t j = 0; j < strLength; j++) {
454 if (stringIn[j] == ',') {
455 position.push_back(j);
456 }
457 }
458
459 int32_t wrodCount = static_cast<int32_t>(position.size());
460 if (wrodCount == 0) {
461 vectorResult.push_back(stringIn);
462 } else {
463 int32_t startWrod = 0;
464 int32_t length = 0;
465 for (int32_t i = 0; i <= wrodCount; i++) {
466 if (i == 0) {
467 length = position[i];
468 vectorResult.push_back(stringIn.substr(startWrod, length)); // First string
469 } else if (i < wrodCount) {
470 startWrod = position[i - 1] + 1;
471 length = position[i] - position[i - 1] - 1;
472 vectorResult.push_back(stringIn.substr(startWrod, length)); // Second string to last-1 string
473 } else {
474 startWrod = position[i - 1] + 1;
475 length = strLength - position[i - 1] - 1;
476 vectorResult.push_back(stringIn.substr(startWrod, length)); // Last string
477 }
478 }
479 }
480 HILOG_DEBUG("strLength = %{public}d, wrodCount = %{public}d, stringIn : %{public}s",
481 strLength, wrodCount, stringIn.c_str());
482 for (auto& var : vectorResult) {
483 HILOG_DEBUG("vectorResult = %{public}s ", var.c_str());
484 }
485 }
486
GetUserIdByCallingUid()487 int32_t Utils::GetUserIdByCallingUid()
488 {
489 int32_t uid = IPCSkeleton::GetCallingUid();
490 if (uid <= INVALID_ID) {
491 return INVALID_USER_ID;
492 }
493 return (uid / BASE_USER_RANGE);
494 }
495 } // namespace Accessibility
496 } // namespace OHOS