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
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