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 "vibration_priority_manager.h"
17
18 #include <tokenid_kit.h>
19 #ifdef OHOS_BUILD_ENABLE_DO_NOT_DISTURB
20 #include <regex>
21 #endif // OHOS_BUILD_ENABLE_DO_NOT_DISTURB
22
23 #include "accesstoken_kit.h"
24 #ifdef HIVIEWDFX_HISYSEVENT_ENABLE
25 #include "hisysevent.h"
26 #endif // HIVIEWDFX_HISYSEVENT_ENABLE
27 #include "ipc_skeleton.h"
28 #include "iservice_registry.h"
29 #include "system_ability_definition.h"
30
31 #ifdef OHOS_BUILD_ENABLE_VIBRATOR_INPUT_METHOD
32 #include "bundle_mgr_client.h"
33 #include "os_account_manager.h"
34 #endif // OHOS_BUILD_ENABLE_VIBRATOR_INPUT_METHOD
35
36 #include "sensors_errors.h"
37
38 #undef LOG_TAG
39 #define LOG_TAG "VibrationPriorityManager"
40
41 namespace OHOS {
42 namespace Sensors {
43 using namespace OHOS::HiviewDFX;
44 #ifdef OHOS_BUILD_ENABLE_DO_NOT_DISTURB
45 const int32_t INVALID_USERID = 100;
46 const int32_t WHITE_LIST_MAX_COUNT = 100;
47 static int32_t g_currentUserId = INVALID_USERID;
48 static std::mutex g_settingMutex;
49 #endif // OHOS_BUILD_ENABLE_DO_NOT_DISTURB
50 namespace {
51 const std::string SETTING_COLUMN_KEYWORD = "KEYWORD";
52 const std::string SETTING_COLUMN_VALUE = "VALUE";
53 const std::string SETTING_FEEDBACK_KEY = "physic_navi_haptic_feedback_enabled";
54 const std::string SETTING_RINGER_MODE_KEY = "ringer_mode";
55 const std::string SETTING_URI_PROXY = "datashare:///com.ohos.settingsdata/entry/settingsdata/SETTINGSDATA?Proxy=true";
56 const std::string SCENEBOARD_BUNDLENAME = "com.ohos.sceneboard";
57 constexpr const char *SETTINGS_DATA_EXT_URI = "datashare:///com.ohos.settingsdata.DataAbility";
58 #ifdef OHOS_BUILD_ENABLE_DO_NOT_DISTURB
59 const std::string USER_SETTING_SECURE_URI_PROXY = "datashare:///com.ohos.settingsdata/entry/settingsdata/"
60 "USER_SETTINGSDATA_SECURE_##USERID##?Proxy=true";
61 const std::string DO_NOT_DISTURB_SWITCH = "focus_mode_enable";
62 const std::string DO_NOT_DISTURB_WHITE_LIST = "intelligent_scene_notification_white_list";
63 const std::string WHITE_LIST_KEY_BUNDLE = "bundle";
64 const std::string WHITE_LIST_KEY_UID = "uid";
65 constexpr const char *USERID_REPLACE = "##USERID##";
66 #endif // OHOS_BUILD_ENABLE_DO_NOT_DISTURB
67 #ifdef OHOS_BUILD_ENABLE_VIBRATOR_CROWN
68 const std::string SETTING_CROWN_FEEDBACK_KEY = "watch_crown_feedback_enabled";
69 const std::string SETTING_VIBRATE_INTENSITY_KEY = "vibration_intensity_index";
70 #endif
71 constexpr int32_t DECEM_BASE = 10;
72 constexpr int32_t DATA_SHARE_READY = 0;
73 constexpr int32_t DATA_SHARE_NOT_READY = 1055;
74 } // namespace
75
VibrationPriorityManager()76 VibrationPriorityManager::VibrationPriorityManager() {}
77
~VibrationPriorityManager()78 VibrationPriorityManager::~VibrationPriorityManager()
79 {
80 remoteObj_ = nullptr;
81 if (UnregisterObserver(observer_) != ERR_OK) {
82 MISC_HILOGE("UnregisterObserver failed");
83 }
84 #ifdef OHOS_BUILD_ENABLE_DO_NOT_DISTURB
85 if (UnregisterUserObserver() != ERR_OK) {
86 MISC_HILOGE("UnregisterUserObserver failed");
87 }
88 #endif // OHOS_BUILD_ENABLE_DO_NOT_DISTURB
89 }
90
Init()91 bool VibrationPriorityManager::Init()
92 {
93 auto sm = SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager();
94 if (sm == nullptr) {
95 MISC_HILOGE("sm cannot be nullptr");
96 return false;
97 }
98 remoteObj_ = sm->GetSystemAbility(MISCDEVICE_SERVICE_ABILITY_ID);
99 if (remoteObj_ == nullptr) {
100 MISC_HILOGE("GetSystemAbility return nullptr");
101 return false;
102 }
103 MiscDeviceObserver::UpdateFunc updateFunc = [&]() {
104 int32_t feedback = miscFeedback_;
105 if (GetIntValue(SETTING_FEEDBACK_KEY, feedback) != ERR_OK) {
106 MISC_HILOGE("Get feedback failed");
107 }
108 miscFeedback_ = feedback;
109 #ifdef HIVIEWDFX_HISYSEVENT_ENABLE
110 HiSysEventWrite(HiSysEvent::Domain::MISCDEVICE, "SWITCHES_TOGGLE",
111 HiSysEvent::EventType::BEHAVIOR, "SWITCH_TYPE", "feedback", "STATUS", feedback);
112 #endif // HIVIEWDFX_HISYSEVENT_ENABLE
113 MISC_HILOGI("feedback:%{public}d", feedback);
114 int32_t ringerMode = miscAudioRingerMode_;
115 if (GetIntValue(SETTING_RINGER_MODE_KEY, ringerMode) != ERR_OK) {
116 MISC_HILOGE("Get ringerMode failed");
117 }
118 miscAudioRingerMode_ = ringerMode;
119 #ifdef HIVIEWDFX_HISYSEVENT_ENABLE
120 HiSysEventWrite(HiSysEvent::Domain::MISCDEVICE, "SWITCHES_TOGGLE",
121 HiSysEvent::EventType::BEHAVIOR, "SWITCH_TYPE", "ringerMode", "STATUS", ringerMode);
122 #endif // HIVIEWDFX_HISYSEVENT_ENABLE
123 MISC_HILOGI("ringerMode:%{public}d", ringerMode);
124 #ifdef OHOS_BUILD_ENABLE_VIBRATOR_CROWN
125 MiscCrownIntensityFeedbackInit();
126 #endif
127 };
128 auto observer_ = CreateObserver(updateFunc);
129 if (observer_ == nullptr) {
130 MISC_HILOGE("observer is null");
131 return false;
132 }
133 if (RegisterObserver(observer_) != ERR_OK) {
134 MISC_HILOGE("RegisterObserver failed");
135 return false;
136 }
137 #ifdef OHOS_BUILD_ENABLE_DO_NOT_DISTURB
138 ReregisterCurrentUserObserver();
139 #endif // OHOS_BUILD_ENABLE_DO_NOT_DISTURB
140 return true;
141 }
142
143 #ifdef OHOS_BUILD_ENABLE_DO_NOT_DISTURB
InitDoNotDisturbData()144 void VibrationPriorityManager::InitDoNotDisturbData()
145 {
146 int32_t switchTemp = doNotDisturbSwitch_;
147 if (GetDoNotDisturbIntValue(DO_NOT_DISTURB_SWITCH, switchTemp) != ERR_OK) {
148 doNotDisturbSwitch_ = DONOTDISTURB_SWITCH_OFF;
149 MISC_HILOGE("Get doNotDisturbSwitch failed");
150 } else {
151 doNotDisturbSwitch_ = switchTemp;
152 MISC_HILOGI("doNotDisturbSwitch:%{public}d", switchTemp);
153 }
154 std::lock_guard<std::mutex> whiteListLock(whiteListMutex_);
155 if (doNotDisturbSwitch_ == DONOTDISTURB_SWITCH_ON) {
156 std::vector<WhiteListAppInfo> whiteListTemp;
157 int32_t whiteListRet = GetWhiteListValue(DO_NOT_DISTURB_WHITE_LIST, whiteListTemp);
158 if (whiteListRet != ERR_OK) {
159 doNotDisturbSwitch_ = DONOTDISTURB_SWITCH_OFF;
160 #ifdef HIVIEWDFX_HISYSEVENT_ENABLE
161 HiSysEventWrite(HiSysEvent::Domain::MISCDEVICE, "DATASHARE_EXCEPTION", HiSysEvent::EventType::FAULT,
162 "PKG_NAME", "GetWhiteListValue", "ERROR_CODE", whiteListRet);
163 #endif // HIVIEWDFX_HISYSEVENT_ENABLE
164 MISC_HILOGE("Get doNotDisturbWhiteList failed");
165 } else {
166 int32_t whiteListSize = static_cast<int32_t>(whiteListTemp.size());
167 if (whiteListSize == 0) {
168 doNotDisturbWhiteList_.clear();
169 #ifdef HIVIEWDFX_HISYSEVENT_ENABLE
170 HiSysEventWrite(HiSysEvent::Domain::MISCDEVICE, "WHITELIST_COUNT_EXCEPTION",
171 HiSysEvent::EventType::FAULT, "PKG_NAME", "InitDoNotDisturbData", "ACTUAL_COUNT", whiteListSize);
172 #endif // HIVIEWDFX_HISYSEVENT_ENABLE
173 } else if (whiteListSize > WHITE_LIST_MAX_COUNT) {
174 doNotDisturbWhiteList_.clear();
175 doNotDisturbWhiteList_.assign(whiteListTemp.begin(), whiteListTemp.begin() + WHITE_LIST_MAX_COUNT);
176 #ifdef HIVIEWDFX_HISYSEVENT_ENABLE
177 HiSysEventWrite(HiSysEvent::Domain::MISCDEVICE, "WHITELIST_COUNT_EXCEPTION",
178 HiSysEvent::EventType::FAULT, "PKG_NAME", "InitDoNotDisturbData", "ACTUAL_COUNT", whiteListSize);
179 #endif // HIVIEWDFX_HISYSEVENT_ENABLE
180 MISC_HILOGW("whiteListTemp size:%{public}d", whiteListSize);
181 } else {
182 doNotDisturbWhiteList_ = whiteListTemp;
183 }
184 MISC_HILOGI("doNotDisturbWhiteList size:%{public}d", static_cast<int32_t>(doNotDisturbWhiteList_.size()));
185 }
186 } else if (doNotDisturbSwitch_ == DONOTDISTURB_SWITCH_OFF) {
187 doNotDisturbWhiteList_.clear();
188 MISC_HILOGD("clear doNotDisturbWhiteList_, DoNotDisturbSwitch:%{public}d",
189 static_cast<int32_t>(doNotDisturbSwitch_));
190 } else {
191 MISC_HILOGW("DoNotDisturbSwitch invalid, DoNotDisturbSwitch:%{public}d",
192 static_cast<int32_t>(doNotDisturbSwitch_));
193 }
194 }
195
ReregisterCurrentUserObserver()196 void VibrationPriorityManager::ReregisterCurrentUserObserver()
197 {
198 UnregisterUserObserver();
199 UpdateCurrentUserId();
200 RegisterUserObserver();
201 }
202
UpdateCurrentUserId()203 void VibrationPriorityManager::UpdateCurrentUserId()
204 {
205 std::lock_guard<std::mutex> lock(g_settingMutex);
206 std::vector<int32_t> activeUserIds;
207 int retId = AccountSA::OsAccountManager::QueryActiveOsAccountIds(activeUserIds);
208 if (retId != 0) {
209 #ifdef HIVIEWDFX_HISYSEVENT_ENABLE
210 HiSysEventWrite(HiSysEvent::Domain::MISCDEVICE, "USER_SWITCHED_EXCEPTION", HiSysEvent::EventType::FAULT,
211 "PKG_NAME", "QueryActiveOsAccountIds", "ERROR_CODE", retId);
212 #endif // HIVIEWDFX_HISYSEVENT_ENABLE
213 MISC_HILOGE("QueryActiveOsAccountIds failed %{public}d", retId);
214 return;
215 }
216 if (activeUserIds.empty()) {
217 #ifdef HIVIEWDFX_HISYSEVENT_ENABLE
218 HiSysEventWrite(HiSysEvent::Domain::MISCDEVICE, "USER_SWITCHED_EXCEPTION", HiSysEvent::EventType::FAULT,
219 "PKG_NAME", "activeUserIdsEmpty", "ERROR_CODE", ERROR);
220 #endif // HIVIEWDFX_HISYSEVENT_ENABLE
221 MISC_HILOGE("activeUserIds empty");
222 return;
223 }
224 g_currentUserId = activeUserIds[0];
225 #ifdef HIVIEWDFX_HISYSEVENT_ENABLE
226 HiSysEventWrite(HiSysEvent::Domain::MISCDEVICE, "USER_SWITCHED_EXCEPTION", HiSysEvent::EventType::FAULT,
227 "PKG_NAME", "UpdateCurrentUserId", "ERROR_CODE", ERR_OK);
228 #endif // HIVIEWDFX_HISYSEVENT_ENABLE
229 MISC_HILOGI("g_currentUserId is %{public}d", g_currentUserId);
230 }
231
RegisterUserObserver()232 int32_t VibrationPriorityManager::RegisterUserObserver()
233 {
234 MISC_HILOGI("RegisterUserObserver start");
235 std::lock_guard<std::mutex> currentUserObserverLock(currentUserObserverMutex_);
236 MiscDeviceObserver::UpdateFunc updateFunc = [&]() { InitDoNotDisturbData(); };
237 currentUserObserver_ = CreateObserver(updateFunc);
238 if (currentUserObserver_ == nullptr) {
239 MISC_HILOGE("currentUserObserver_ is null");
240 return MISC_NO_INIT_ERR;
241 }
242 std::string callingIdentity = IPCSkeleton::ResetCallingIdentity();
243 auto doNotDisturbHelper =
244 CreateDataShareHelper(ReplaceUserIdForUri(USER_SETTING_SECURE_URI_PROXY, g_currentUserId));
245 if (doNotDisturbHelper == nullptr) {
246 IPCSkeleton::SetCallingIdentity(callingIdentity);
247 #ifdef HIVIEWDFX_HISYSEVENT_ENABLE
248 HiSysEventWrite(HiSysEvent::Domain::MISCDEVICE, "DATASHARE_EXCEPTION", HiSysEvent::EventType::FAULT,
249 "PKG_NAME", "RegisterUserObserver", "ERROR_CODE", MISC_NO_INIT_ERR);
250 #endif // HIVIEWDFX_HISYSEVENT_ENABLE
251 MISC_HILOGE("doNotDisturbHelper is nullptr");
252 return MISC_NO_INIT_ERR;
253 }
254 auto doNotDisturbSwitch = DoNotDisturbAssembleUri(DO_NOT_DISTURB_SWITCH);
255 doNotDisturbHelper->RegisterObserver(doNotDisturbSwitch, currentUserObserver_);
256 doNotDisturbHelper->NotifyChange(doNotDisturbSwitch);
257 auto doNotDisturbWhiteList = DoNotDisturbAssembleUri(DO_NOT_DISTURB_WHITE_LIST);
258 doNotDisturbHelper->RegisterObserver(doNotDisturbWhiteList, currentUserObserver_);
259 doNotDisturbHelper->NotifyChange(doNotDisturbWhiteList);
260 std::thread execCb(VibrationPriorityManager::ExecRegisterCb, currentUserObserver_);
261 execCb.detach();
262 ReleaseDataShareHelper(doNotDisturbHelper);
263 IPCSkeleton::SetCallingIdentity(callingIdentity);
264 MISC_HILOGI("Succeed to RegisterUserObserver of uri");
265 return ERR_OK;
266 }
267
UnregisterUserObserver()268 int32_t VibrationPriorityManager::UnregisterUserObserver()
269 {
270 MISC_HILOGI("UnregisterUserObserver start");
271 if (currentUserObserver_ == nullptr) {
272 MISC_HILOGE("currentUserObserver_ is nullptr");
273 return MISC_NO_INIT_ERR;
274 }
275 std::lock_guard<std::mutex> currentUserObserverLock(currentUserObserverMutex_);
276 std::string callingIdentity = IPCSkeleton::ResetCallingIdentity();
277 auto doNotDisturbHelper =
278 CreateDataShareHelper(ReplaceUserIdForUri(USER_SETTING_SECURE_URI_PROXY, g_currentUserId));
279 if (doNotDisturbHelper == nullptr) {
280 #ifdef HIVIEWDFX_HISYSEVENT_ENABLE
281 HiSysEventWrite(HiSysEvent::Domain::MISCDEVICE, "DATASHARE_EXCEPTION", HiSysEvent::EventType::FAULT,
282 "PKG_NAME", "UnregisterUserObserver", "ERROR_CODE", MISC_NO_INIT_ERR);
283 #endif // HIVIEWDFX_HISYSEVENT_ENABLE
284 IPCSkeleton::SetCallingIdentity(callingIdentity);
285 currentUserObserver_ = nullptr;
286 MISC_HILOGE("doNotDisturbHelper is nullptr");
287 return MISC_NO_INIT_ERR;
288 }
289 auto doNotDisturbSwitch = DoNotDisturbAssembleUri(DO_NOT_DISTURB_SWITCH);
290 doNotDisturbHelper->UnregisterObserver(doNotDisturbSwitch, currentUserObserver_);
291 auto doNotDisturbWhiteList = DoNotDisturbAssembleUri(DO_NOT_DISTURB_WHITE_LIST);
292 doNotDisturbHelper->UnregisterObserver(doNotDisturbWhiteList, currentUserObserver_);
293 ReleaseDataShareHelper(doNotDisturbHelper);
294 IPCSkeleton::SetCallingIdentity(callingIdentity);
295 currentUserObserver_ = nullptr;
296 MISC_HILOGI("Succeed to UnregisterUserObserver observer");
297 return ERR_OK;
298 }
299
ReplaceUserIdForUri(std::string uri,int32_t userId)300 std::string VibrationPriorityManager::ReplaceUserIdForUri(std::string uri, int32_t userId)
301 {
302 std::string tempUri = uri;
303 std::regex pattern(USERID_REPLACE);
304 return std::regex_replace(tempUri, pattern, std::to_string(userId));
305 }
306
DoNotDisturbAssembleUri(const std::string & key)307 Uri VibrationPriorityManager::DoNotDisturbAssembleUri(const std::string &key)
308 {
309 Uri uri(ReplaceUserIdForUri(USER_SETTING_SECURE_URI_PROXY, g_currentUserId) + "&key=" + key);
310 return uri;
311 }
312
GetDoNotDisturbStringValue(const std::string & key,std::string & value)313 int32_t VibrationPriorityManager::GetDoNotDisturbStringValue(const std::string &key, std::string &value)
314 {
315 std::string callingIdentity = IPCSkeleton::ResetCallingIdentity();
316 auto helper = CreateDataShareHelper(ReplaceUserIdForUri(USER_SETTING_SECURE_URI_PROXY, g_currentUserId));
317 if (helper == nullptr) {
318 IPCSkeleton::SetCallingIdentity(callingIdentity);
319 MISC_HILOGE("helper is nullptr");
320 return MISC_NO_INIT_ERR;
321 }
322 std::vector<std::string> columns = { SETTING_COLUMN_VALUE };
323 DataShare::DataSharePredicates predicates;
324 predicates.EqualTo(SETTING_COLUMN_KEYWORD, key);
325 Uri uri(DoNotDisturbAssembleUri(key));
326 auto resultSet = helper->Query(uri, predicates, columns);
327 ReleaseDataShareHelper(helper);
328 if (resultSet == nullptr) {
329 MISC_HILOGE("resultSet is nullptr");
330 IPCSkeleton::SetCallingIdentity(callingIdentity);
331 return MISC_INVALID_OPERATION_ERR;
332 }
333 int32_t count;
334 resultSet->GetRowCount(count);
335 if (count == 0) {
336 MISC_HILOGW("Not found value, key:%{public}s, count:%{public}d", key.c_str(), count);
337 IPCSkeleton::SetCallingIdentity(callingIdentity);
338 return MISC_NAME_NOT_FOUND_ERR;
339 }
340 const int32_t index = 0;
341 resultSet->GoToRow(index);
342 int32_t ret = resultSet->GetString(index, value);
343 if (ret != ERR_OK) {
344 MISC_HILOGW("GetString failed, ret:%{public}d", ret);
345 IPCSkeleton::SetCallingIdentity(callingIdentity);
346 return ERROR;
347 }
348 resultSet->Close();
349 IPCSkeleton::SetCallingIdentity(callingIdentity);
350 return ERR_OK;
351 }
352
GetDoNotDisturbIntValue(const std::string & key,int32_t & value)353 int32_t VibrationPriorityManager::GetDoNotDisturbIntValue(const std::string &key, int32_t &value)
354 {
355 int64_t valueLong;
356 int32_t ret = GetDoNotDisturbLongValue(key, valueLong);
357 if (ret != ERR_OK) {
358 MISC_HILOGE("GetDoNotDisturbLongValue failed, ret:%{public}d", ret);
359 return ret;
360 }
361 value = static_cast<int32_t>(valueLong);
362 return ERR_OK;
363 }
364
GetDoNotDisturbLongValue(const std::string & key,int64_t & value)365 int32_t VibrationPriorityManager::GetDoNotDisturbLongValue(const std::string &key, int64_t &value)
366 {
367 std::string valueStr;
368 int32_t ret = GetDoNotDisturbStringValue(key, valueStr);
369 if (ret != ERR_OK) {
370 #ifdef HIVIEWDFX_HISYSEVENT_ENABLE
371 HiSysEventWrite(HiSysEvent::Domain::MISCDEVICE, "DATASHARE_EXCEPTION", HiSysEvent::EventType::FAULT,
372 "PKG_NAME", "GetDoNotDisturbStringValue", "ERROR_CODE", ret);
373 #endif // HIVIEWDFX_HISYSEVENT_ENABLE
374 MISC_HILOGE("GetDoNotDisturbStringValue failed, ret:%{public}d", ret);
375 return ret;
376 }
377 value = static_cast<int64_t>(strtoll(valueStr.c_str(), nullptr, DECEM_BASE));
378 return ERR_OK;
379 }
380
GetWhiteListValue(const std::string & key,std::vector<WhiteListAppInfo> & value)381 int32_t VibrationPriorityManager::GetWhiteListValue(const std::string &key, std::vector<WhiteListAppInfo> &value)
382 {
383 std::string valueStr;
384 int32_t ret = GetDoNotDisturbStringValue(key, valueStr);
385 if (ret != ERR_OK) {
386 MISC_HILOGE("GetDoNotDisturbStringValue failed, ret:%{public}d", ret);
387 return ret;
388 }
389 if (valueStr.empty()) {
390 MISC_HILOGE("String value empty");
391 return ERROR;
392 }
393 cJSON *jsonArray = nullptr;
394 jsonArray = cJSON_Parse(valueStr.c_str());
395 if (!cJSON_IsArray(jsonArray)) {
396 MISC_HILOGE("The string value is not array");
397 DeleteCJSONValue(jsonArray);
398 return ERROR;
399 }
400 int32_t size = cJSON_GetArraySize(jsonArray);
401 for (int32_t i = 0; i < size; ++i) {
402 cJSON *valJson = cJSON_GetArrayItem(jsonArray, i);
403 if (!cJSON_IsObject(valJson)) {
404 MISC_HILOGE("The json is not object");
405 DeleteCJSONValue(jsonArray);
406 return ERROR;
407 }
408 if (!cJSON_HasObjectItem(valJson, WHITE_LIST_KEY_BUNDLE.c_str()) ||
409 !cJSON_HasObjectItem(valJson, WHITE_LIST_KEY_UID.c_str())) {
410 MISC_HILOGE("The json is not bundle or uid");
411 DeleteCJSONValue(jsonArray);
412 return ERROR;
413 }
414 WhiteListAppInfo whiteListAppInfo;
415 cJSON *valBundle = cJSON_GetObjectItem(valJson, WHITE_LIST_KEY_BUNDLE.c_str());
416 cJSON *valUid = cJSON_GetObjectItem(valJson, WHITE_LIST_KEY_UID.c_str());
417 if ((!cJSON_IsString(valBundle)) || !cJSON_IsNumber(valUid)) {
418 MISC_HILOGE("The value of index %{public}d is not match", i);
419 DeleteCJSONValue(jsonArray);
420 return ERROR;
421 }
422 whiteListAppInfo.bundle = valBundle->valuestring;
423 whiteListAppInfo.uid = static_cast<int64_t>(valUid->valueint);
424 value.push_back(whiteListAppInfo);
425 }
426 DeleteCJSONValue(jsonArray);
427 return ERR_OK;
428 }
429
DeleteCJSONValue(cJSON * jsonValue)430 void VibrationPriorityManager::DeleteCJSONValue(cJSON *jsonValue)
431 {
432 if (jsonValue != nullptr) {
433 cJSON_Delete(jsonValue);
434 }
435 }
436
IgnoreAppVibrations(const VibrateInfo & vibrateInfo)437 bool VibrationPriorityManager::IgnoreAppVibrations(const VibrateInfo &vibrateInfo)
438 {
439 if (vibrateInfo.usage != USAGE_NOTIFICATION && vibrateInfo.usage != USAGE_RING) {
440 MISC_HILOGD("Vibration is not ignored , usage:%{public}d", vibrateInfo.usage);
441 return false;
442 }
443 if (doNotDisturbSwitch_ != DONOTDISTURB_SWITCH_ON) {
444 MISC_HILOGD("DoNotDisturbSwitch is off");
445 return false;
446 }
447 std::lock_guard<std::mutex> whiteListLock(whiteListMutex_);
448 for (const WhiteListAppInfo &whiteListAppInfo : doNotDisturbWhiteList_) {
449 if (vibrateInfo.packageName == whiteListAppInfo.bundle) {
450 MISC_HILOGD("Not ignore app vibration, the app is on the whitelist, bundleName::%{public}s",
451 vibrateInfo.packageName.c_str());
452 return false;
453 }
454 }
455 MISC_HILOGI("Ignore app vibration, bundleName::%{public}s", vibrateInfo.packageName.c_str());
456 return true;
457 }
458 #endif // OHOS_BUILD_ENABLE_DO_NOT_DISTURB
459
460 #ifdef OHOS_BUILD_ENABLE_VIBRATOR_CROWN
MiscCrownIntensityFeedbackInit(void)461 void VibrationPriorityManager::MiscCrownIntensityFeedbackInit(void)
462 {
463 int32_t crownfeedback = miscCrownFeedback_;
464 if (GetIntValue(SETTING_CROWN_FEEDBACK_KEY, crownfeedback) != ERR_OK) {
465 MISC_HILOGE("Get crownfeedback failed");
466 }
467 miscCrownFeedback_ = crownfeedback;
468
469 int32_t intensity = miscIntensity_;
470 if (GetIntValue(SETTING_VIBRATE_INTENSITY_KEY, intensity) != ERR_OK) {
471 intensity = FEEDBACK_INTENSITY_STRONGE;
472 MISC_HILOGE("Get intensity failed");
473 }
474 miscIntensity_ = intensity;
475 }
476
ShouldIgnoreByIntensity(const VibrateInfo & vibrateInfo)477 bool VibrationPriorityManager::ShouldIgnoreByIntensity(const VibrateInfo &vibrateInfo)
478 {
479 std::string effect = vibrateInfo.effect;
480 if (effect.find("crown") != std::string::npos) {
481 if (miscCrownFeedback_ == FEEDBACK_MODE_OFF) {
482 return true;
483 }
484 } else {
485 if (miscIntensity_ == FEEDBACK_INTENSITY_NONE) {
486 if ((effect.find("short") != std::string::npos) || (effect.find("feedback") != std::string::npos)) {
487 return false;
488 }
489 return true;
490 }
491 }
492 return false;
493 }
494 #endif
495
GetIntValue(const std::string & key,int32_t & value)496 int32_t VibrationPriorityManager::GetIntValue(const std::string &key, int32_t &value)
497 {
498 int64_t valueLong;
499 int32_t ret = GetLongValue(key, valueLong);
500 if (ret != ERR_OK) {
501 return ret;
502 }
503 value = static_cast<int32_t>(valueLong);
504 return ERR_OK;
505 }
506
GetLongValue(const std::string & key,int64_t & value)507 int32_t VibrationPriorityManager::GetLongValue(const std::string &key, int64_t &value)
508 {
509 std::string valueStr;
510 int32_t ret = GetStringValue(key, valueStr);
511 if (ret != ERR_OK) {
512 #ifdef HIVIEWDFX_HISYSEVENT_ENABLE
513 HiSysEventWrite(HiSysEvent::Domain::MISCDEVICE, "DATASHARE_EXCEPTION", HiSysEvent::EventType::FAULT,
514 "PKG_NAME", "GetStringValue", "ERROR_CODE", ret);
515 #endif // HIVIEWDFX_HISYSEVENT_ENABLE
516 MISC_HILOGE("GetStringValue failed, ret:%{public}d", ret);
517 return ret;
518 }
519 value = static_cast<int64_t>(strtoll(valueStr.c_str(), nullptr, DECEM_BASE));
520 return ERR_OK;
521 }
522
GetStringValue(const std::string & key,std::string & value)523 int32_t VibrationPriorityManager::GetStringValue(const std::string &key, std::string &value)
524 {
525 std::string callingIdentity = IPCSkeleton::ResetCallingIdentity();
526 auto helper = CreateDataShareHelper(SETTING_URI_PROXY);
527 if (helper == nullptr) {
528 IPCSkeleton::SetCallingIdentity(callingIdentity);
529 return MISC_NO_INIT_ERR;
530 }
531 std::vector<std::string> columns = {SETTING_COLUMN_VALUE};
532 DataShare::DataSharePredicates predicates;
533 predicates.EqualTo(SETTING_COLUMN_KEYWORD, key);
534 Uri uri(AssembleUri(key));
535 auto resultSet = helper->Query(uri, predicates, columns);
536 ReleaseDataShareHelper(helper);
537 if (resultSet == nullptr) {
538 MISC_HILOGE("resultSet is nullptr");
539 IPCSkeleton::SetCallingIdentity(callingIdentity);
540 return MISC_INVALID_OPERATION_ERR;
541 }
542 int32_t count;
543 resultSet->GetRowCount(count);
544 if (count == 0) {
545 MISC_HILOGW("Not found value, key:%{public}s, count:%{public}d", key.c_str(), count);
546 IPCSkeleton::SetCallingIdentity(callingIdentity);
547 return MISC_NAME_NOT_FOUND_ERR;
548 }
549 const int32_t index = 0;
550 resultSet->GoToRow(index);
551 int32_t ret = resultSet->GetString(index, value);
552 if (ret != ERR_OK) {
553 MISC_HILOGW("GetString failed, ret:%{public}d", ret);
554 IPCSkeleton::SetCallingIdentity(callingIdentity);
555 return ERROR;
556 }
557 resultSet->Close();
558 IPCSkeleton::SetCallingIdentity(callingIdentity);
559 return ERR_OK;
560 }
561
UpdateStatus()562 void VibrationPriorityManager::UpdateStatus()
563 {
564 if (miscFeedback_ == FEEDBACK_MODE_INVALID) {
565 int32_t feedback = FEEDBACK_MODE_INVALID;
566 if (GetIntValue(SETTING_FEEDBACK_KEY, feedback) != ERR_OK) {
567 feedback = FEEDBACK_MODE_ON;
568 MISC_HILOGE("Get feedback failed");
569 }
570 miscFeedback_ = feedback;
571 }
572 if (miscAudioRingerMode_ == RINGER_MODE_INVALID) {
573 int32_t ringerMode = RINGER_MODE_INVALID;
574 if (GetIntValue(SETTING_RINGER_MODE_KEY, ringerMode) != ERR_OK) {
575 ringerMode = RINGER_MODE_NORMAL;
576 MISC_HILOGE("Get ringerMode failed");
577 }
578 miscAudioRingerMode_ = ringerMode;
579 }
580 #ifdef OHOS_BUILD_ENABLE_DO_NOT_DISTURB
581 if (doNotDisturbSwitch_ == DONOTDISTURB_SWITCH_INVALID) {
582 InitDoNotDisturbData();
583 }
584 #endif // OHOS_BUILD_ENABLE_DO_NOT_DISTURB
585 #ifdef OHOS_BUILD_ENABLE_VIBRATOR_CROWN
586 if (miscCrownFeedback_ == FEEDBACK_MODE_INVALID) {
587 int32_t corwnfeedback = FEEDBACK_MODE_INVALID;
588 if (GetIntValue(SETTING_CROWN_FEEDBACK_KEY, corwnfeedback) != ERR_OK) {
589 corwnfeedback = FEEDBACK_MODE_ON;
590 MISC_HILOGE("Get corwnfeedback failed");
591 }
592 miscCrownFeedback_ = corwnfeedback;
593 }
594 if (miscIntensity_ == FEEDBACK_INTENSITY_INVALID) {
595 int32_t intensity = FEEDBACK_INTENSITY_INVALID;
596 if (GetIntValue(SETTING_VIBRATE_INTENSITY_KEY, intensity) != ERR_OK) {
597 intensity = FEEDBACK_INTENSITY_STRONGE;
598 MISC_HILOGE("Get intensity failed");
599 }
600 miscIntensity_ = intensity;
601 }
602 #endif
603 }
604
IsSystemServiceCalling()605 bool VibrationPriorityManager::IsSystemServiceCalling()
606 {
607 const auto tokenId = IPCSkeleton::GetCallingTokenID();
608 const auto flag = Security::AccessToken::AccessTokenKit::GetTokenTypeFlag(tokenId);
609 if (flag == Security::AccessToken::ATokenTypeEnum::TOKEN_NATIVE) {
610 MISC_HILOGD("System service calling, flag: %{public}u", flag);
611 return true;
612 }
613 return false;
614 }
615
IsSystemCalling()616 bool VibrationPriorityManager::IsSystemCalling()
617 {
618 if (IsSystemServiceCalling()) {
619 return true;
620 }
621 return Security::AccessToken::TokenIdKit::IsSystemAppByFullTokenID(IPCSkeleton::GetCallingFullTokenID());
622 }
623
624 #ifdef OHOS_BUILD_ENABLE_VIBRATOR_INPUT_METHOD
ShouldIgnoreInputMethod(const VibrateInfo & vibrateInfo)625 bool VibrationPriorityManager::ShouldIgnoreInputMethod(const VibrateInfo &vibrateInfo)
626 {
627 if (vibrateInfo.packageName == SCENEBOARD_BUNDLENAME) {
628 MISC_HILOGD("Can not ignore for %{public}s", vibrateInfo.packageName.c_str());
629 return false;
630 }
631 int32_t pid = vibrateInfo.pid;
632 AppExecFwk::RunningProcessInfo processinfo{};
633 appMgrClientPtr_ = DelayedSingleton<AppExecFwk::AppMgrClient>::GetInstance();
634 if (appMgrClientPtr_ == nullptr) {
635 MISC_HILOGE("appMgrClientPtr is nullptr");
636 return false;
637 }
638 int32_t ret = appMgrClientPtr_->AppExecFwk::AppMgrClient::GetRunningProcessInfoByPid(pid, processinfo);
639 if (ret != ERR_OK) {
640 MISC_HILOGE("Getrunningprocessinfobypid failed");
641 return false;
642 }
643 if (processinfo.extensionType_ == AppExecFwk::ExtensionAbilityType::INPUTMETHOD) {
644 return true;
645 }
646 std::vector<int32_t> activeUserIds;
647 int retId = AccountSA::OsAccountManager::QueryActiveOsAccountIds(activeUserIds);
648 if (retId != 0) {
649 MISC_HILOGE("QueryActiveOsAccountIds failed %{public}d", retId);
650 return false;
651 }
652 if (activeUserIds.empty()) {
653 MISC_HILOGE("activeUserId empty");
654 return false;
655 }
656 for (const auto &bundleName : processinfo.bundleNames) {
657 MISC_HILOGD("bundleName = %{public}s", bundleName.c_str());
658 AppExecFwk::BundleMgrClient bundleMgrClient;
659 AppExecFwk::BundleInfo bundleInfo;
660 auto res = bundleMgrClient.AppExecFwk::BundleMgrClient::GetBundleInfo(bundleName,
661 AppExecFwk::BundleFlag::GET_BUNDLE_WITH_EXTENSION_INFO, bundleInfo, activeUserIds[0]);
662 if (!res) {
663 MISC_HILOGE("Getbundleinfo fail");
664 return false;
665 }
666 for (const auto &extensionInfo : bundleInfo.extensionInfos) {
667 if (extensionInfo.type == AppExecFwk::ExtensionAbilityType::INPUTMETHOD) {
668 MISC_HILOGD("extensioninfo type is %{public}d", extensionInfo.type);
669 return true;
670 }
671 }
672 }
673 return false;
674 }
675 #endif // OHOS_BUILD_ENABLE_VIBRATOR_INPUT_METHOD
676
ShouldIgnoreVibrate(const VibrateInfo & vibrateInfo,const std::shared_ptr<VibratorThread> & vibratorThread,const VibratorIdentifierIPC & identifier)677 VibrateStatus VibrationPriorityManager::ShouldIgnoreVibrate(const VibrateInfo &vibrateInfo,
678 const std::shared_ptr<VibratorThread> &vibratorThread, const VibratorIdentifierIPC& identifier)
679 {
680 UpdateStatus();
681 if (!IsSystemCalling() || vibrateInfo.systemUsage == false) {
682 #ifdef OHOS_BUILD_ENABLE_DO_NOT_DISTURB
683 if (IgnoreAppVibrations(vibrateInfo)) {
684 MISC_HILOGD("Vibration is ignored for doNotDisturb, usage:%{public}d", vibrateInfo.usage);
685 return IGNORE_GLOBAL_SETTINGS;
686 }
687 #endif // OHOS_BUILD_ENABLE_DO_NOT_DISTURB
688 if ((vibrateInfo.usage == USAGE_ALARM || vibrateInfo.usage == USAGE_RING
689 || vibrateInfo.usage == USAGE_NOTIFICATION || vibrateInfo.usage == USAGE_COMMUNICATION)
690 && (miscAudioRingerMode_ == RINGER_MODE_SILENT)) {
691 MISC_HILOGD("Vibration is ignored for ringer mode:%{public}d", static_cast<int32_t>(miscAudioRingerMode_));
692 return IGNORE_RINGER_MODE;
693 }
694 if (((vibrateInfo.usage == USAGE_TOUCH || vibrateInfo.usage == USAGE_MEDIA || vibrateInfo.usage == USAGE_UNKNOWN
695 || vibrateInfo.usage == USAGE_PHYSICAL_FEEDBACK || vibrateInfo.usage == USAGE_SIMULATE_REALITY)
696 && (miscFeedback_ == FEEDBACK_MODE_OFF))
697 #ifdef OHOS_BUILD_ENABLE_VIBRATOR_INPUT_METHOD
698 && !ShouldIgnoreInputMethod(vibrateInfo)) {
699 #else // OHOS_BUILD_ENABLE_VIBRATOR_INPUT_METHOD
700 ) {
701 #endif // OHOS_BUILD_ENABLE_VIBRATOR_INPUT_METHOD
702 MISC_HILOGD("Vibration is ignored for feedback:%{public}d", static_cast<int32_t>(miscFeedback_));
703 return IGNORE_FEEDBACK;
704 }
705 }
706 #ifdef OHOS_BUILD_ENABLE_VIBRATOR_CROWN
707 if (ShouldIgnoreByIntensity(vibrateInfo)) {
708 MISC_HILOGI("ShouldIgnoreByIntensity: vibrateInfo.effect:%{public}s", vibrateInfo.effect.c_str());
709 return IGNORE_FEEDBACK;
710 }
711 #endif
712 if (vibratorThread == nullptr) {
713 MISC_HILOGD("There is no vibration, it can vibrate");
714 return VIBRATION;
715 }
716 if (!IsCurrentVibrate(vibratorThread, identifier)) {
717 MISC_HILOGD("There is no vibration at the moment, it can vibrate");
718 return VIBRATION;
719 }
720 if (IsLoopVibrate(vibrateInfo)) {
721 MISC_HILOGD("Can vibrate, loop priority is high");
722 return VIBRATION;
723 }
724 return ShouldIgnoreVibrate(vibrateInfo, vibratorThread->GetCurrentVibrateInfo());
725 }
726
727 bool VibrationPriorityManager::IsCurrentVibrate(const std::shared_ptr<VibratorThread> &vibratorThread,
728 const VibratorIdentifierIPC& identifier) const
729 {
730 #if defined(OHOS_BUILD_ENABLE_VIBRATOR_CUSTOM) && defined(HDF_DRIVERS_INTERFACE_VIBRATOR)
731 return ((vibratorThread != nullptr) && (vibratorThread->IsRunning() ||
732 VibratorDevice.IsVibratorRunning(identifier)));
733 #else
734 return ((vibratorThread != nullptr) && (vibratorThread->IsRunning()));
735 #endif // OHOS_BUILD_ENABLE_VIBRATOR_CUSTOM && HDF_DRIVERS_INTERFACE_VIBRATOR
736 }
737
738 bool VibrationPriorityManager::IsLoopVibrate(const VibrateInfo &vibrateInfo) const
739 {
740 return ((vibrateInfo.mode == "preset") && (vibrateInfo.count > 1));
741 }
742
743 VibrateStatus VibrationPriorityManager::ShouldIgnoreVibrate(const VibrateInfo &vibrateInfo,
744 VibrateInfo currentVibrateInfo) const
745 {
746 if (currentVibrateInfo.usage == USAGE_ALARM) {
747 MISC_HILOGD("Vibration is ignored for alarm");
748 return IGNORE_ALARM;
749 }
750 if (IsLoopVibrate(currentVibrateInfo)) {
751 MISC_HILOGD("Vibration is ignored for repeat");
752 return IGNORE_REPEAT;
753 }
754 if ((currentVibrateInfo.usage != vibrateInfo.usage) && (vibrateInfo.usage == USAGE_UNKNOWN)) {
755 MISC_HILOGD("Vibration is ignored, unknown has a low priority");
756 return IGNORE_UNKNOWN;
757 }
758 return VIBRATION;
759 }
760
761 sptr<MiscDeviceObserver> VibrationPriorityManager::CreateObserver(const MiscDeviceObserver::UpdateFunc &func)
762 {
763 sptr<MiscDeviceObserver> observer = new MiscDeviceObserver();
764 if (observer == nullptr) {
765 MISC_HILOGE("observer is null");
766 return observer;
767 }
768 observer->SetUpdateFunc(func);
769 return observer;
770 }
771
772 Uri VibrationPriorityManager::AssembleUri(const std::string &key)
773 {
774 Uri uri(SETTING_URI_PROXY + "&key=" + key);
775 return uri;
776 }
777
778 std::shared_ptr<DataShare::DataShareHelper> VibrationPriorityManager::CreateDataShareHelper(const std::string &tableUrl)
779 {
780 if (remoteObj_ == nullptr) {
781 MISC_HILOGE("remoteObj_ is nullptr");
782 return nullptr;
783 }
784 auto [ret, helper] = DataShare::DataShareHelper::Create(remoteObj_, tableUrl, SETTINGS_DATA_EXT_URI);
785 if (ret == DATA_SHARE_READY) {
786 return helper;
787 } else if (ret == DATA_SHARE_NOT_READY) {
788 MISC_HILOGE("Create data_share helper failed, uri proxy:%{public}s", tableUrl.c_str());
789 return nullptr;
790 }
791 MISC_HILOGI("Data_share create unknown");
792 return nullptr;
793 }
794
795 bool VibrationPriorityManager::ReleaseDataShareHelper(std::shared_ptr<DataShare::DataShareHelper> &helper)
796 {
797 if (!helper->Release()) {
798 MISC_HILOGW("Release helper fail");
799 return false;
800 }
801 return true;
802 }
803
804 void VibrationPriorityManager::ExecRegisterCb(const sptr<MiscDeviceObserver> &observer)
805 {
806 if (observer == nullptr) {
807 MISC_HILOGE("observer is nullptr");
808 return;
809 }
810 observer->OnChange();
811 }
812
813 int32_t VibrationPriorityManager::RegisterObserver(const sptr<MiscDeviceObserver> &observer)
814 {
815 if (observer == nullptr) {
816 MISC_HILOGE("observer is nullptr");
817 return MISC_NO_INIT_ERR;
818 }
819 std::string callingIdentity = IPCSkeleton::ResetCallingIdentity();
820 auto helper = CreateDataShareHelper(SETTING_URI_PROXY);
821 if (helper == nullptr) {
822 #ifdef HIVIEWDFX_HISYSEVENT_ENABLE
823 HiSysEventWrite(HiSysEvent::Domain::MISCDEVICE, "DATASHARE_EXCEPTION", HiSysEvent::EventType::FAULT,
824 "PKG_NAME", "RegisterObserver", "ERROR_CODE", MISC_NO_INIT_ERR);
825 #endif // HIVIEWDFX_HISYSEVENT_ENABLE
826 IPCSkeleton::SetCallingIdentity(callingIdentity);
827 return MISC_NO_INIT_ERR;
828 }
829 auto uriFeedback = AssembleUri(SETTING_FEEDBACK_KEY);
830 helper->RegisterObserver(uriFeedback, observer);
831 helper->NotifyChange(uriFeedback);
832 #ifdef OHOS_BUILD_ENABLE_VIBRATOR_CROWN
833 auto uriCrownFeedback = AssembleUri(SETTING_CROWN_FEEDBACK_KEY);
834 helper->RegisterObserver(uriCrownFeedback, observer);
835 helper->NotifyChange(uriCrownFeedback);
836 auto uriIntensityContrl = AssembleUri(SETTING_CROWN_FEEDBACK_KEY);
837 helper->RegisterObserver(uriIntensityContrl, observer);
838 helper->NotifyChange(uriIntensityContrl);
839 #endif
840 auto uriRingerMode = AssembleUri(SETTING_RINGER_MODE_KEY);
841 helper->RegisterObserver(uriRingerMode, observer);
842 helper->NotifyChange(uriRingerMode);
843 std::thread execCb(VibrationPriorityManager::ExecRegisterCb, observer);
844 execCb.detach();
845 ReleaseDataShareHelper(helper);
846 IPCSkeleton::SetCallingIdentity(callingIdentity);
847 MISC_HILOGI("Succeed to register observer of uri");
848 return ERR_OK;
849 }
850
851 int32_t VibrationPriorityManager::UnregisterObserver(const sptr<MiscDeviceObserver> &observer)
852 {
853 if (observer == nullptr) {
854 MISC_HILOGE("observer is nullptr");
855 return MISC_NO_INIT_ERR;
856 }
857 std::string callingIdentity = IPCSkeleton::ResetCallingIdentity();
858 auto helper = CreateDataShareHelper(SETTING_URI_PROXY);
859 if (helper == nullptr) {
860 #ifdef HIVIEWDFX_HISYSEVENT_ENABLE
861 HiSysEventWrite(HiSysEvent::Domain::MISCDEVICE, "DATASHARE_EXCEPTION", HiSysEvent::EventType::FAULT,
862 "PKG_NAME", "UnregisterObserver", "ERROR_CODE", MISC_NO_INIT_ERR);
863 #endif // HIVIEWDFX_HISYSEVENT_ENABLE
864 IPCSkeleton::SetCallingIdentity(callingIdentity);
865 return MISC_NO_INIT_ERR;
866 }
867 auto uriFeedback = AssembleUri(SETTING_FEEDBACK_KEY);
868 helper->UnregisterObserver(uriFeedback, observer);
869 #ifdef OHOS_BUILD_ENABLE_VIBRATOR_CROWN
870 auto uriCrownnFeedback = AssembleUri(SETTING_CROWN_FEEDBACK_KEY);
871 helper->UnregisterObserver(uriCrownnFeedback, observer);
872 auto uriIntensityContrl = AssembleUri(SETTING_CROWN_FEEDBACK_KEY);
873 helper->UnregisterObserver(uriIntensityContrl, observer);
874 #endif
875 auto uriRingerMode = AssembleUri(SETTING_RINGER_MODE_KEY);
876 helper->UnregisterObserver(uriRingerMode, observer);
877 ReleaseDataShareHelper(helper);
878 IPCSkeleton::SetCallingIdentity(callingIdentity);
879 MISC_HILOGI("Succeed to unregister observer");
880 return ERR_OK;
881 }
882 } // namespace Sensors
883 } // namespace OHOS