• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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, &times);
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