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, ×);
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
GetAbilityAutoStartStateKey(const std::string & bundleName,const std::string & abilityName,int32_t accountId)238 std::string Utils::GetAbilityAutoStartStateKey(const std::string &bundleName, const std::string &abilityName,
239 int32_t accountId)
240 {
241 HILOG_DEBUG("bundle name(%{public}s) ability name(%{public}s) accountId(%{public}d)",
242 bundleName.c_str(), abilityName.c_str(), accountId);
243 return bundleName + "/" + abilityName + "/" + std::to_string(accountId);
244 }
245
SelectUsefulFromVecWithSameBundle(std::vector<std::string> & selectVec,std::vector<std::string> & cmpVec,bool & hasDif,const std::string & bundleName)246 void Utils::SelectUsefulFromVecWithSameBundle(std::vector<std::string> &selectVec, std::vector<std::string> &cmpVec,
247 bool &hasDif, const std::string &bundleName)
248 {
249 HILOG_DEBUG();
250 for (auto iter = selectVec.begin(); iter != selectVec.end();) {
251 if (iter->substr(0, iter->find("/")) != bundleName) {
252 ++iter;
253 continue;
254 }
255 auto it = cmpVec.begin();
256 for (; it != cmpVec.end(); ++it) {
257 if ((*it) == (*iter)) {
258 break;
259 }
260 }
261 if (it == cmpVec.end()) {
262 selectVec.erase(iter);
263 hasDif = true;
264 } else {
265 ++iter;
266 }
267 }
268 }
269
RecordUnavailableEvent(A11yUnavailableEvent event,A11yError errCode,const std::string & bundleName,const std::string & abilityName)270 void Utils::RecordUnavailableEvent(A11yUnavailableEvent event, A11yError errCode,
271 const std::string &bundleName, const std::string &abilityName)
272 {
273 if (!(errCode > A11yError::ERROR_NEED_REPORT_BASE && errCode < A11yError::ERROR_NEED_REPORT_END)) {
274 return;
275 }
276 std::ostringstream oss;
277 oss << "accessibility function is unavailable: " << "event: " << TransferUnavailableEventToString(event)
278 << ", errCode: " << static_cast<int32_t>(errCode)
279 << ", bundleName: " << bundleName << ", abilityName: " << abilityName << ";";
280 std::string info = oss.str();
281 HILOG_DEBUG("accessibility function is unavailable: %{public}s", info.c_str());
282 int32_t ret = HiSysEventWrite(
283 OHOS::HiviewDFX::HiSysEvent::Domain::ACCESSIBILITY,
284 "UNAVAILABLE",
285 OHOS::HiviewDFX::HiSysEvent::EventType::FAULT,
286 "MSG", info);
287 if (ret != 0) {
288 HILOG_ERROR("Write HiSysEvent error, ret:%{public}d", ret);
289 }
290 }
291
TransferUnavailableEventToString(A11yUnavailableEvent type)292 std::string Utils::TransferUnavailableEventToString(A11yUnavailableEvent type)
293 {
294 std::string event;
295 switch (type) {
296 case A11yUnavailableEvent::READ_EVENT:
297 event = "READ";
298 break;
299 case A11yUnavailableEvent::CONNECT_EVENT:
300 event = "CONNECT";
301 break;
302 case A11yUnavailableEvent::QUERY_EVENT:
303 event = "QUERY";
304 break;
305 default:
306 event = "UNDEFINE";
307 break;
308 }
309 return event;
310 }
311
RecordStartingA11yEvent(uint32_t flag)312 void Utils::RecordStartingA11yEvent(uint32_t flag)
313 {
314 std::ostringstream oss;
315 oss << "starting accessibility: " << "event: " << "system" << ", id: " << flag << ";";
316 HILOG_DEBUG("starting accessibility: %{public}s", oss.str().c_str());
317 int32_t ret = HiSysEventWrite(
318 OHOS::HiviewDFX::HiSysEvent::Domain::ACCESSIBILITY,
319 "STARTING_FUNCTION",
320 OHOS::HiviewDFX::HiSysEvent::EventType::BEHAVIOR,
321 "MSG", oss.str());
322 if (ret != 0) {
323 HILOG_ERROR("Write HiSysEvent error, ret:%{public}d", ret);
324 }
325 }
326
RecordStartingA11yEvent(const std::string & name)327 void Utils::RecordStartingA11yEvent(const std::string &name)
328 {
329 std::ostringstream oss;
330 oss << "starting accessibility: " << "event: " << "extension" << ", name: " << name << ";";
331 HILOG_DEBUG("starting accessibility: %{public}s", oss.str().c_str());
332 int32_t ret = HiSysEventWrite(
333 OHOS::HiviewDFX::HiSysEvent::Domain::ACCESSIBILITY,
334 "STARTING_FUNCTION",
335 OHOS::HiviewDFX::HiSysEvent::EventType::BEHAVIOR,
336 "MSG", oss.str());
337 if (ret != 0) {
338 HILOG_ERROR("Write HiSysEvent error, ret:%{public}d", ret);
339 }
340 }
341 } // namespace Accessibility
342 } // namespace OHOS