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