• 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 
24 namespace OHOS {
25 namespace Accessibility {
26 namespace {
27     const std::string KEY_ACCESSIBILITY_ABILITY_TYPES = "accessibilityAbilityTypes";
28     const std::string KEY_ACCESSIBILITY_CAPABILITIES = "accessibilityCapabilities";
29     const std::string KEY_SETTINGS_ABILITY = "settingsAbility";
30     const std::string KEY_ACCESSIBILITY_CAPABILITIES_RATIONALE = "accessibilityCapabilityRationale";
31     const std::string KEY_IS_IMPORTANT = "isImportant";
32 
33     // The json value of accessibilityAbility type
34     const std::string ACCESSIBILITY_ABILITY_TYPES_JSON_VALUE_SPOKEN = "spoken";
35     const std::string ACCESSIBILITY_ABILITY_TYPES_JSON_VALUE_HAPIC = "haptic";
36     const std::string ACCESSIBILITY_ABILITY_TYPES_JSON_VALUE_AUDIBLE = "audible";
37     const std::string ACCESSIBILITY_ABILITY_TYPES_JSON_VALUE_VISUAL = "visual";
38     const std::string ACCESSIBILITY_ABILITY_TYPES_JSON_VALUE_GENERIC = "generic";
39     const std::string ACCESSIBILITY_ABILITY_TYPES_JSON_VALUE_ALL = "all";
40 
41     // The json value of capabilities
42     const std::string CAPABILITIES_JSON_VALUE_RETRIEVE = "retrieve";
43     const std::string CAPABILITIES_JSON_VALUE_TOUCH_GUIDE = "touchGuide";
44     const std::string CAPABILITIES_JSON_VALUE_KEY_EVENT_OBSERVER = "keyEventObserver";
45     const std::string CAPABILITIES_JSON_VALUE_ZOOM = "zoom";
46     const std::string CAPABILITIES_JSON_VALUE_GESTURE = "gesture";
47 } // namespace
48 
49 class JsonUtils {
50 public:
GetStringFromJson(const nlohmann::json & json,const std::string & key,std::string & value)51     static bool GetStringFromJson(const nlohmann::json &json, const std::string &key, std::string &value)
52     {
53         HILOG_DEBUG("start.");
54         if (!json.is_object()) {
55             HILOG_ERROR("json is not object.");
56             return false;
57         }
58         if (json.find(key) != json.end() && json.at(key).is_string()) {
59             HILOG_DEBUG("Find key[%{public}s] successful.", key.c_str());
60             value = json.at(key).get<std::string>();
61         }
62         return true;
63     }
64 
GetStringVecFromJson(const nlohmann::json & json,const std::string & key,std::vector<std::string> & value)65     static bool GetStringVecFromJson(const nlohmann::json &json, const std::string &key,
66         std::vector<std::string> &value)
67     {
68         HILOG_DEBUG("start.");
69         if (!json.is_object()) {
70             HILOG_ERROR("json is not object.");
71             return false;
72         }
73         if (json.find(key) != json.end() && json.at(key).is_array()) {
74             HILOG_DEBUG("Find key[%{public}s] successful.", key.c_str());
75             value = json.at(key).get<std::vector<std::string>>();
76         }
77         return true;
78     }
79 
GetBoolFromJson(const nlohmann::json & json,const std::string & key,bool & value)80     static bool GetBoolFromJson(const nlohmann::json &json, const std::string &key, bool &value)
81     {
82         HILOG_DEBUG("start.");
83         if (!json.is_object()) {
84             HILOG_ERROR("json is not object.");
85             return false;
86         }
87         if (json.find(key) != json.end() && json.at(key).is_boolean()) {
88             HILOG_DEBUG("Find key[%{public}s] successful.", key.c_str());
89             value = json.at(key).get<bool>();
90         }
91         return true;
92     }
93 };
94 
95 class PraseVecUtils {
96 public:
ParseAbilityTypesFromVec(const std::vector<std::string> & abilities)97     static uint32_t ParseAbilityTypesFromVec(const std::vector<std::string> &abilities)
98     {
99         HILOG_DEBUG("start.");
100         uint32_t abilityTypes = 0;
101 
102         for (const auto &ability : abilities) {
103             if (ability == ACCESSIBILITY_ABILITY_TYPES_JSON_VALUE_SPOKEN) {
104                 abilityTypes |= AccessibilityAbilityTypes::ACCESSIBILITY_ABILITY_TYPE_SPOKEN;
105             }
106 
107             if (ability == ACCESSIBILITY_ABILITY_TYPES_JSON_VALUE_HAPIC) {
108                 abilityTypes |= AccessibilityAbilityTypes::ACCESSIBILITY_ABILITY_TYPE_HAPTIC;
109             }
110 
111             if (ability == ACCESSIBILITY_ABILITY_TYPES_JSON_VALUE_AUDIBLE) {
112                 abilityTypes |= AccessibilityAbilityTypes::ACCESSIBILITY_ABILITY_TYPE_AUDIBLE;
113             }
114 
115             if (ability == ACCESSIBILITY_ABILITY_TYPES_JSON_VALUE_VISUAL) {
116                 abilityTypes |= AccessibilityAbilityTypes::ACCESSIBILITY_ABILITY_TYPE_VISUAL;
117             }
118 
119             if (ability == ACCESSIBILITY_ABILITY_TYPES_JSON_VALUE_GENERIC) {
120                 abilityTypes |= AccessibilityAbilityTypes::ACCESSIBILITY_ABILITY_TYPE_GENERIC;
121             }
122 
123             if (ability == ACCESSIBILITY_ABILITY_TYPES_JSON_VALUE_ALL) {
124                 abilityTypes |= AccessibilityAbilityTypes::ACCESSIBILITY_ABILITY_TYPE_ALL;
125             }
126         }
127         return abilityTypes;
128     }
129 
ParseCapabilitiesFromVec(const std::vector<std::string> & capabilities)130     static uint32_t ParseCapabilitiesFromVec(const std::vector<std::string> &capabilities)
131     {
132         HILOG_DEBUG("start.");
133         uint32_t capabilitiesValue = 0;
134 
135         for (const auto &capability : capabilities) {
136             if (capability == CAPABILITIES_JSON_VALUE_RETRIEVE) {
137                 capabilitiesValue |= Capability::CAPABILITY_RETRIEVE;
138             }
139 
140             if (capability == CAPABILITIES_JSON_VALUE_TOUCH_GUIDE) {
141                 capabilitiesValue |= Capability::CAPABILITY_TOUCH_GUIDE;
142             }
143 
144             if (capability == CAPABILITIES_JSON_VALUE_KEY_EVENT_OBSERVER) {
145                 capabilitiesValue |= Capability::CAPABILITY_KEY_EVENT_OBSERVER;
146             }
147 
148             if (capability == CAPABILITIES_JSON_VALUE_ZOOM) {
149                 capabilitiesValue |= Capability::CAPABILITY_ZOOM;
150             }
151 
152             if (capability == CAPABILITIES_JSON_VALUE_GESTURE) {
153                 capabilitiesValue |= Capability::CAPABILITY_GESTURE;
154             }
155         }
156         return capabilitiesValue;
157     }
158 };
159 
Parse(const AppExecFwk::ExtensionAbilityInfo & abilityInfo,AccessibilityAbilityInitParams & initParams)160 void Utils::Parse(const AppExecFwk::ExtensionAbilityInfo &abilityInfo, AccessibilityAbilityInitParams &initParams)
161 {
162     HILOG_DEBUG("start.");
163     initParams.name = abilityInfo.name;
164     initParams.bundleName = abilityInfo.bundleName;
165     initParams.moduleName = abilityInfo.moduleName;
166     initParams.description = abilityInfo.description;
167 
168     std::vector<std::string> profileInfos;
169     std::string metadataName = "ohos.accessibleability";
170     AppExecFwk::BundleMgrClient bundleMgrClient;
171     bundleMgrClient.GetResConfigFile(abilityInfo, metadataName, profileInfos);
172     if (profileInfos.empty()) {
173         HILOG_ERROR("profileInfos is empty.");
174         return;
175     }
176 
177     nlohmann::json sourceJson = nlohmann::json::parse(profileInfos[0]);
178 
179     // accessibilityCapabilities
180     std::vector<std::string> capabilities;
181     if (!JsonUtils::GetStringVecFromJson(sourceJson, KEY_ACCESSIBILITY_CAPABILITIES, capabilities)) {
182         HILOG_ERROR("Get accessibilityCapabilities from json failed.");
183         return;
184     }
185     initParams.staticCapabilities = PraseVecUtils::ParseCapabilitiesFromVec(capabilities);
186 
187     // accessibilityAbilityTypes
188     std::vector<std::string> abilityTypes;
189     if (!JsonUtils::GetStringVecFromJson(sourceJson, KEY_ACCESSIBILITY_ABILITY_TYPES, abilityTypes)) {
190         HILOG_ERROR("Get accessibilityAbilityTypes from json failed.");
191         return;
192     }
193     initParams.abilityTypes = PraseVecUtils::ParseAbilityTypesFromVec(abilityTypes);
194 
195     // accessibilityCapabilityRationale
196     if (!JsonUtils::GetStringFromJson(sourceJson, KEY_ACCESSIBILITY_CAPABILITIES_RATIONALE, initParams.rationale)) {
197         HILOG_ERROR("Get accessibilityCapabilityRationale from json failed.");
198         return;
199     }
200 
201     // settingsAbility
202     if (!JsonUtils::GetStringFromJson(sourceJson, KEY_SETTINGS_ABILITY, initParams.settingsAbility)) {
203         HILOG_ERROR("Get settingsAbility from json failed.");
204         return;
205     }
206 
207     // isImportant
208     if (!JsonUtils::GetBoolFromJson(sourceJson, KEY_IS_IMPORTANT, initParams.isImportant)) {
209         HILOG_ERROR("Get isImportant from json failed.");
210         return;
211     }
212 }
213 
GetSystemTime()214 int64_t Utils::GetSystemTime()
215 {
216     HILOG_DEBUG("start.");
217 
218     struct timespec times = {0, 0};
219     clock_gettime(CLOCK_MONOTONIC, &times);
220     int64_t millisecond = static_cast<int64_t>(times.tv_sec * 1000 + times.tv_nsec / 1000000);
221 
222     return millisecond;
223 }
224 
GetUri(const OHOS::AppExecFwk::ElementName & elementName)225 std::string Utils::GetUri(const OHOS::AppExecFwk::ElementName &elementName)
226 {
227     HILOG_DEBUG("bundle name(%{public}s) ability name(%{public}s)",
228         elementName.GetBundleName().c_str(), elementName.GetAbilityName().c_str());
229     return elementName.GetBundleName() + "/" + elementName.GetAbilityName();
230 }
231 
GetUri(const std::string & bundleName,const std::string & abilityName)232 std::string Utils::GetUri(const std::string &bundleName, const std::string &abilityName)
233 {
234     HILOG_DEBUG("bundle name(%{public}s) ability name(%{public}s)", bundleName.c_str(), abilityName.c_str());
235     return bundleName + "/" + abilityName;
236 }
237 
RecordUnavailableEvent(A11yUnavailableEvent event,A11yError errCode,const std::string & bundleName,const std::string & abilityName)238 void Utils::RecordUnavailableEvent(A11yUnavailableEvent event, A11yError errCode,
239     const std::string &bundleName, const std::string &abilityName)
240 {
241     if (!(errCode > A11yError::ERROR_NEED_REPORT_BASE && errCode < A11yError::ERROR_NEED_REPORT_END)) {
242         return;
243     }
244     std::ostringstream oss;
245     oss << "accessibility function is unavailable: " << "event: " << TransferUnavailableEventToString(event)
246         << ", errCode: " << static_cast<int32_t>(errCode)
247         << ", bundleName: " << bundleName << ", abilityName: " << abilityName << ";";
248     std::string info = oss.str();
249     HILOG_DEBUG("accessibility function is unavailable: %{public}s", info.c_str());
250     int32_t ret = HiSysEventWrite(
251         OHOS::HiviewDFX::HiSysEvent::Domain::ACCESSIBILITY,
252         "UNAVAILABLE",
253         OHOS::HiviewDFX::HiSysEvent::EventType::FAULT,
254         "MSG", info);
255     if (ret != 0) {
256         HILOG_ERROR("Write HiSysEvent error, ret:%{public}d", ret);
257     }
258 }
259 
TransferUnavailableEventToString(A11yUnavailableEvent type)260 std::string Utils::TransferUnavailableEventToString(A11yUnavailableEvent type)
261 {
262     std::string event;
263     switch (type) {
264         case A11yUnavailableEvent::READ_EVENT:
265             event = "READ";
266             break;
267         case A11yUnavailableEvent::CONNECT_EVENT:
268             event = "CONNECT";
269             break;
270         case A11yUnavailableEvent::QUERY_EVENT:
271             event = "QUERY";
272             break;
273         default:
274             event = "UNDEFINE";
275             break;
276     }
277     return event;
278 }
279 
RecordStartingA11yEvent(uint32_t flag)280 void Utils::RecordStartingA11yEvent(uint32_t flag)
281 {
282     std::ostringstream oss;
283     oss << "starting accessibility: " << "event: " << "system" << ", id: " << flag << ";";
284     HILOG_DEBUG("starting accessibility: %{public}s", oss.str().c_str());
285     int32_t ret = HiSysEventWrite(
286         OHOS::HiviewDFX::HiSysEvent::Domain::ACCESSIBILITY,
287         "STARTING_FUNCTION",
288         OHOS::HiviewDFX::HiSysEvent::EventType::BEHAVIOR,
289         "MSG", oss.str());
290     if (ret != 0) {
291         HILOG_ERROR("Write HiSysEvent error, ret:%{public}d", ret);
292     }
293 }
294 
RecordStartingA11yEvent(const std::string & name)295 void Utils::RecordStartingA11yEvent(const std::string &name)
296 {
297     std::ostringstream oss;
298     oss << "starting accessibility: " << "event: " << "extension" << ", name: " << name << ";";
299     HILOG_DEBUG("starting accessibility: %{public}s", oss.str().c_str());
300     int32_t ret = HiSysEventWrite(
301         OHOS::HiviewDFX::HiSysEvent::Domain::ACCESSIBILITY,
302         "STARTING_FUNCTION",
303         OHOS::HiviewDFX::HiSysEvent::EventType::BEHAVIOR,
304         "MSG", oss.str());
305     if (ret != 0) {
306         HILOG_ERROR("Write HiSysEvent error, ret:%{public}d", ret);
307     }
308 }
309 } // namespace Accessibility
310 } // namespace OHOS