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
20 #include "accesstoken_kit.h"
21 #ifdef HIVIEWDFX_HISYSEVENT_ENABLE
22 #include "hisysevent.h"
23 #endif // HIVIEWDFX_HISYSEVENT_ENABLE
24 #include "ipc_skeleton.h"
25 #include "iservice_registry.h"
26 #include "system_ability_definition.h"
27
28 #ifdef OHOS_BUILD_ENABLE_VIBRATOR_INPUT_METHOD
29 #include "bundle_mgr_client.h"
30 #include "os_account_manager.h"
31 #endif // OHOS_BUILD_ENABLE_VIBRATOR_INPUT_METHOD
32
33 #include "sensors_errors.h"
34
35 #undef LOG_TAG
36 #define LOG_TAG "VibrationPriorityManager"
37
38 namespace OHOS {
39 namespace Sensors {
40 using namespace OHOS::HiviewDFX;
41 namespace {
42 const std::string SETTING_COLUMN_KEYWORD = "KEYWORD";
43 const std::string SETTING_COLUMN_VALUE = "VALUE";
44 const std::string SETTING_FEEDBACK_KEY = "physic_navi_haptic_feedback_enabled";
45 const std::string SETTING_RINGER_MODE_KEY = "ringer_mode";
46 const std::string SETTING_URI_PROXY = "datashare:///com.ohos.settingsdata/entry/settingsdata/SETTINGSDATA?Proxy=true";
47 const std::string SCENEBOARD_BUNDLENAME = "com.ohos.sceneboard";
48 constexpr const char *SETTINGS_DATA_EXT_URI = "datashare:///com.ohos.settingsdata.DataAbility";
49 #ifdef OHOS_BUILD_ENABLE_VIBRATOR_CROWN
50 const std::string SETTING_CROWN_FEEDBACK_KEY = "watch_crown_feedback_enabled";
51 const std::string SETTING_VIBRATE_INTENSITY_KEY = "vibration_intensity_index";
52 #endif
53 constexpr int32_t DECEM_BASE = 10;
54 constexpr int32_t DATA_SHARE_READY = 0;
55 constexpr int32_t DATA_SHARE_NOT_READY = 1055;
56 } // namespace
57
VibrationPriorityManager()58 VibrationPriorityManager::VibrationPriorityManager() {}
59
~VibrationPriorityManager()60 VibrationPriorityManager::~VibrationPriorityManager()
61 {
62 remoteObj_ = nullptr;
63 if (UnregisterObserver(observer_) != ERR_OK) {
64 MISC_HILOGE("UnregisterObserver failed");
65 }
66 }
67
Init()68 bool VibrationPriorityManager::Init()
69 {
70 auto sm = SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager();
71 if (sm == nullptr) {
72 MISC_HILOGE("sm cannot be nullptr");
73 return false;
74 }
75 remoteObj_ = sm->GetSystemAbility(MISCDEVICE_SERVICE_ABILITY_ID);
76 if (remoteObj_ == nullptr) {
77 MISC_HILOGE("GetSystemAbility return nullptr");
78 return false;
79 }
80 MiscDeviceObserver::UpdateFunc updateFunc = [&]() {
81 int32_t feedback = miscFeedback_;
82 if (GetIntValue(SETTING_FEEDBACK_KEY, feedback) != ERR_OK) {
83 MISC_HILOGE("Get feedback failed");
84 }
85 miscFeedback_ = feedback;
86 MISC_HILOGI("feedback:%{public}d", feedback);
87 #ifdef HIVIEWDFX_HISYSEVENT_ENABLE
88 HiSysEventWrite(HiSysEvent::Domain::MISCDEVICE, "SWITCHES_TOGGLE",
89 HiSysEvent::EventType::BEHAVIOR, "SWITCH_TYPE", "feedback", "STATUS", feedback);
90 #endif // HIVIEWDFX_HISYSEVENT_ENABLE
91 int32_t ringerMode = miscAudioRingerMode_;
92 if (GetIntValue(SETTING_RINGER_MODE_KEY, ringerMode) != ERR_OK) {
93 MISC_HILOGE("Get ringerMode failed");
94 }
95 miscAudioRingerMode_ = ringerMode;
96 #ifdef HIVIEWDFX_HISYSEVENT_ENABLE
97 HiSysEventWrite(HiSysEvent::Domain::MISCDEVICE, "SWITCHES_TOGGLE",
98 HiSysEvent::EventType::BEHAVIOR, "SWITCH_TYPE", "ringerMode", "STATUS", ringerMode);
99 #endif // HIVIEWDFX_HISYSEVENT_ENABLE
100 MISC_HILOGI("ringerMode:%{public}d", ringerMode);
101 #ifdef OHOS_BUILD_ENABLE_VIBRATOR_CROWN
102 MiscCrownIntensityFeedbackInit();
103 #endif
104 };
105 auto observer_ = CreateObserver(updateFunc);
106 if (observer_ == nullptr) {
107 MISC_HILOGE("observer is null");
108 return false;
109 }
110 if (RegisterObserver(observer_) != ERR_OK) {
111 MISC_HILOGE("RegisterObserver failed");
112 return false;
113 }
114 return true;
115 }
116
117 #ifdef OHOS_BUILD_ENABLE_VIBRATOR_CROWN
MiscCrownIntensityFeedbackInit(void)118 void VibrationPriorityManager::MiscCrownIntensityFeedbackInit(void)
119 {
120 int32_t crownfeedback = miscCrownFeedback_;
121 if (GetIntValue(SETTING_CROWN_FEEDBACK_KEY, crownfeedback) != ERR_OK) {
122 MISC_HILOGE("Get crownfeedback failed");
123 }
124 miscCrownFeedback_ = crownfeedback;
125
126 int32_t intensity = miscIntensity_;
127 if (GetIntValue(SETTING_VIBRATE_INTENSITY_KEY, intensity) != ERR_OK) {
128 MISC_HILOGE("Get intensity failed");
129 }
130 miscIntensity_ = intensity;
131 return;
132 }
133
ShouldIgnoreByIntensity(const VibrateInfo & vibrateInfo)134 bool VibrationPriorityManager::ShouldIgnoreByIntensity(const VibrateInfo &vibrateInfo)
135 {
136 std::string effect = vibrateInfo.effect;
137 if (effect.find("crown") != std::string::npos) {
138 if (miscCrownFeedback_ == FEEDBACK_MODE_OFF) {
139 return true;
140 }
141 } else {
142 if (miscIntensity_ == FEEDBACK_INTENSITY_NONE) {
143 if ((effect.find("short") != std::string::npos) || (effect.find("feedback") != std::string::npos)) {
144 return false;
145 }
146 return true;
147 }
148 }
149 return false;
150 }
151 #endif
152
GetIntValue(const std::string & key,int32_t & value)153 int32_t VibrationPriorityManager::GetIntValue(const std::string &key, int32_t &value)
154 {
155 int64_t valueLong;
156 int32_t ret = GetLongValue(key, valueLong);
157 if (ret != ERR_OK) {
158 return ret;
159 }
160 value = static_cast<int32_t>(valueLong);
161 return ERR_OK;
162 }
163
GetLongValue(const std::string & key,int64_t & value)164 int32_t VibrationPriorityManager::GetLongValue(const std::string &key, int64_t &value)
165 {
166 std::string valueStr;
167 int32_t ret = GetStringValue(key, valueStr);
168 if (ret != ERR_OK) {
169 return ret;
170 }
171 value = static_cast<int64_t>(strtoll(valueStr.c_str(), nullptr, DECEM_BASE));
172 return ERR_OK;
173 }
174
GetStringValue(const std::string & key,std::string & value)175 int32_t VibrationPriorityManager::GetStringValue(const std::string &key, std::string &value)
176 {
177 std::string callingIdentity = IPCSkeleton::ResetCallingIdentity();
178 auto helper = CreateDataShareHelper();
179 if (helper == nullptr) {
180 IPCSkeleton::SetCallingIdentity(callingIdentity);
181 return MISC_NO_INIT_ERR;
182 }
183 std::vector<std::string> columns = {SETTING_COLUMN_VALUE};
184 DataShare::DataSharePredicates predicates;
185 predicates.EqualTo(SETTING_COLUMN_KEYWORD, key);
186 Uri uri(AssembleUri(key));
187 auto resultSet = helper->Query(uri, predicates, columns);
188 ReleaseDataShareHelper(helper);
189 if (resultSet == nullptr) {
190 MISC_HILOGE("resultSet is nullptr");
191 IPCSkeleton::SetCallingIdentity(callingIdentity);
192 return MISC_INVALID_OPERATION_ERR;
193 }
194 int32_t count;
195 resultSet->GetRowCount(count);
196 if (count == 0) {
197 MISC_HILOGW("Not found value, key:%{public}s, count:%{public}d", key.c_str(), count);
198 IPCSkeleton::SetCallingIdentity(callingIdentity);
199 return MISC_NAME_NOT_FOUND_ERR;
200 }
201 const int32_t index = 0;
202 resultSet->GoToRow(index);
203 int32_t ret = resultSet->GetString(index, value);
204 if (ret != ERR_OK) {
205 MISC_HILOGW("GetString failed, ret:%{public}d", ret);
206 IPCSkeleton::SetCallingIdentity(callingIdentity);
207 return ERROR;
208 }
209 resultSet->Close();
210 IPCSkeleton::SetCallingIdentity(callingIdentity);
211 return ERR_OK;
212 }
213
UpdateStatus()214 void VibrationPriorityManager::UpdateStatus()
215 {
216 if (miscFeedback_ == FEEDBACK_MODE_INVALID) {
217 int32_t feedback = FEEDBACK_MODE_INVALID;
218 if (GetIntValue(SETTING_FEEDBACK_KEY, feedback) != ERR_OK) {
219 feedback = FEEDBACK_MODE_ON;
220 MISC_HILOGE("Get feedback failed");
221 }
222 miscFeedback_ = feedback;
223 }
224 if (miscAudioRingerMode_ == RINGER_MODE_INVALID) {
225 int32_t ringerMode = RINGER_MODE_INVALID;
226 if (GetIntValue(SETTING_RINGER_MODE_KEY, ringerMode) != ERR_OK) {
227 ringerMode = RINGER_MODE_NORMAL;
228 MISC_HILOGE("Get ringerMode failed");
229 }
230 miscAudioRingerMode_ = ringerMode;
231 }
232 #ifdef OHOS_BUILD_ENABLE_VIBRATOR_CROWN
233 if (miscCrownFeedback_ == FEEDBACK_MODE_INVALID) {
234 int32_t corwnfeedback = FEEDBACK_MODE_INVALID;
235 if (GetIntValue(SETTING_CROWN_FEEDBACK_KEY, corwnfeedback) != ERR_OK) {
236 corwnfeedback = FEEDBACK_MODE_ON;
237 MISC_HILOGE("Get corwnfeedback failed");
238 }
239 miscCrownFeedback_ = corwnfeedback;
240 }
241 if (miscIntensity_ == FEEDBACK_INTENSITY_INVALID) {
242 int32_t intensity = FEEDBACK_INTENSITY_INVALID;
243 if (GetIntValue(SETTING_VIBRATE_INTENSITY_KEY, intensity) != ERR_OK) {
244 intensity = FEEDBACK_INTENSITY_NONE;
245 MISC_HILOGE("Get intensity failed");
246 }
247 miscIntensity_ = intensity;
248 }
249 #endif
250 return;
251 }
252
IsSystemServiceCalling()253 bool VibrationPriorityManager::IsSystemServiceCalling()
254 {
255 const auto tokenId = IPCSkeleton::GetCallingTokenID();
256 const auto flag = Security::AccessToken::AccessTokenKit::GetTokenTypeFlag(tokenId);
257 if (flag == Security::AccessToken::ATokenTypeEnum::TOKEN_NATIVE) {
258 MISC_HILOGD("System service calling, flag: %{public}u", flag);
259 return true;
260 }
261 return false;
262 }
263
IsSystemCalling()264 bool VibrationPriorityManager::IsSystemCalling()
265 {
266 if (IsSystemServiceCalling()) {
267 return true;
268 }
269 return Security::AccessToken::TokenIdKit::IsSystemAppByFullTokenID(IPCSkeleton::GetCallingFullTokenID());
270 }
271
272 #ifdef OHOS_BUILD_ENABLE_VIBRATOR_INPUT_METHOD
ShouldIgnoreInputMethod(const VibrateInfo & vibrateInfo)273 bool VibrationPriorityManager::ShouldIgnoreInputMethod(const VibrateInfo &vibrateInfo)
274 {
275 if (vibrateInfo.packageName == SCENEBOARD_BUNDLENAME) {
276 MISC_HILOGD("Can not ignore for %{public}s", vibrateInfo.packageName.c_str());
277 return false;
278 }
279 int32_t pid = vibrateInfo.pid;
280 AppExecFwk::RunningProcessInfo processinfo{};
281 appMgrClientPtr_ = DelayedSingleton<AppExecFwk::AppMgrClient>::GetInstance();
282 if (appMgrClientPtr_ == nullptr) {
283 MISC_HILOGE("appMgrClientPtr is nullptr");
284 return false;
285 }
286 int32_t ret = appMgrClientPtr_->AppExecFwk::AppMgrClient::GetRunningProcessInfoByPid(pid, processinfo);
287 if (ret != ERR_OK) {
288 MISC_HILOGE("Getrunningprocessinfobypid failed");
289 return false;
290 }
291 if (processinfo.extensionType_ == AppExecFwk::ExtensionAbilityType::INPUTMETHOD) {
292 return true;
293 }
294 std::vector<int32_t> activeUserIds;
295 int retId = AccountSA::OsAccountManager::QueryActiveOsAccountIds(activeUserIds);
296 if (retId != 0) {
297 MISC_HILOGE("QueryActiveOsAccountIds failed %{public}d", retId);
298 return false;
299 }
300 if (activeUserIds.empty()) {
301 MISC_HILOGE("activeUserId empty");
302 return false;
303 }
304 for (const auto &bundleName : processinfo.bundleNames) {
305 MISC_HILOGD("bundleName = %{public}s", bundleName.c_str());
306 AppExecFwk::BundleMgrClient bundleMgrClient;
307 AppExecFwk::BundleInfo bundleInfo;
308 auto res = bundleMgrClient.AppExecFwk::BundleMgrClient::GetBundleInfo(bundleName,
309 AppExecFwk::BundleFlag::GET_BUNDLE_WITH_EXTENSION_INFO, bundleInfo, activeUserIds[0]);
310 if (!res) {
311 MISC_HILOGE("Getbundleinfo fail");
312 return false;
313 }
314 for (const auto &extensionInfo : bundleInfo.extensionInfos) {
315 if (extensionInfo.type == AppExecFwk::ExtensionAbilityType::INPUTMETHOD) {
316 MISC_HILOGD("extensioninfo type is %{public}d", extensionInfo.type);
317 return true;
318 }
319 }
320 }
321 return false;
322 }
323 #endif // OHOS_BUILD_ENABLE_VIBRATOR_INPUT_METHOD
324
ShouldIgnoreVibrate(const VibrateInfo & vibrateInfo,std::shared_ptr<VibratorThread> vibratorThread)325 VibrateStatus VibrationPriorityManager::ShouldIgnoreVibrate(const VibrateInfo &vibrateInfo,
326 std::shared_ptr<VibratorThread> vibratorThread)
327 {
328 UpdateStatus();
329 if (!IsSystemCalling() || vibrateInfo.systemUsage == false) {
330 if ((vibrateInfo.usage == USAGE_ALARM || vibrateInfo.usage == USAGE_RING
331 || vibrateInfo.usage == USAGE_NOTIFICATION || vibrateInfo.usage == USAGE_COMMUNICATION)
332 && (miscAudioRingerMode_ == RINGER_MODE_SILENT)) {
333 MISC_HILOGD("Vibration is ignored for ringer mode:%{public}d", static_cast<int32_t>(miscAudioRingerMode_));
334 return IGNORE_RINGER_MODE;
335 }
336 if (((vibrateInfo.usage == USAGE_TOUCH || vibrateInfo.usage == USAGE_MEDIA || vibrateInfo.usage == USAGE_UNKNOWN
337 || vibrateInfo.usage == USAGE_PHYSICAL_FEEDBACK || vibrateInfo.usage == USAGE_SIMULATE_REALITY)
338 && (miscFeedback_ == FEEDBACK_MODE_OFF))
339 #ifdef OHOS_BUILD_ENABLE_VIBRATOR_INPUT_METHOD
340 && !ShouldIgnoreInputMethod(vibrateInfo)) {
341 #else // OHOS_BUILD_ENABLE_VIBRATOR_INPUT_METHOD
342 ) {
343 #endif // OHOS_BUILD_ENABLE_VIBRATOR_INPUT_METHOD
344 MISC_HILOGD("Vibration is ignored for feedback:%{public}d", static_cast<int32_t>(miscFeedback_));
345 return IGNORE_FEEDBACK;
346 }
347 }
348 #ifdef OHOS_BUILD_ENABLE_VIBRATOR_CROWN
349 if (ShouldIgnoreByIntensity(vibrateInfo)) {
350 MISC_HILOGI("ShouldIgnoreByIntensity: vibrateInfo.effect:%{public}s", vibrateInfo.effect.c_str());
351 return IGNORE_FEEDBACK;
352 }
353 #endif
354 if (vibratorThread == nullptr) {
355 MISC_HILOGD("There is no vibration, it can vibrate");
356 return VIBRATION;
357 }
358 if (!IsCurrentVibrate(vibratorThread)) {
359 MISC_HILOGD("There is no vibration at the moment, it can vibrate");
360 return VIBRATION;
361 }
362 if (IsLoopVibrate(vibrateInfo)) {
363 MISC_HILOGD("Can vibrate, loop priority is high");
364 return VIBRATION;
365 }
366 return ShouldIgnoreVibrate(vibrateInfo, vibratorThread->GetCurrentVibrateInfo());
367 }
368
369 bool VibrationPriorityManager::IsCurrentVibrate(std::shared_ptr<VibratorThread> vibratorThread) const
370 {
371 #if defined(OHOS_BUILD_ENABLE_VIBRATOR_CUSTOM) && defined(HDF_DRIVERS_INTERFACE_VIBRATOR)
372 return ((vibratorThread != nullptr) && (vibratorThread->IsRunning() || VibratorDevice.IsVibratorRunning()));
373 #else
374 return ((vibratorThread != nullptr) && (vibratorThread->IsRunning()));
375 #endif // OHOS_BUILD_ENABLE_VIBRATOR_CUSTOM && HDF_DRIVERS_INTERFACE_VIBRATOR
376 }
377
378 bool VibrationPriorityManager::IsLoopVibrate(const VibrateInfo &vibrateInfo) const
379 {
380 return ((vibrateInfo.mode == "preset") && (vibrateInfo.count > 1));
381 }
382
383 VibrateStatus VibrationPriorityManager::ShouldIgnoreVibrate(const VibrateInfo &vibrateInfo,
384 VibrateInfo currentVibrateInfo) const
385 {
386 if (currentVibrateInfo.usage == USAGE_ALARM) {
387 MISC_HILOGD("Vibration is ignored for alarm");
388 return IGNORE_ALARM;
389 }
390 if (IsLoopVibrate(currentVibrateInfo)) {
391 MISC_HILOGD("Vibration is ignored for repeat");
392 return IGNORE_REPEAT;
393 }
394 if ((currentVibrateInfo.usage != vibrateInfo.usage) && (vibrateInfo.usage == USAGE_UNKNOWN)) {
395 MISC_HILOGD("Vibration is ignored, unknown has a low priority");
396 return IGNORE_UNKNOWN;
397 }
398 return VIBRATION;
399 }
400
401 sptr<MiscDeviceObserver> VibrationPriorityManager::CreateObserver(const MiscDeviceObserver::UpdateFunc &func)
402 {
403 sptr<MiscDeviceObserver> observer = new MiscDeviceObserver();
404 if (observer == nullptr) {
405 MISC_HILOGE("observer is null");
406 return observer;
407 }
408 observer->SetUpdateFunc(func);
409 return observer;
410 }
411
412 Uri VibrationPriorityManager::AssembleUri(const std::string &key)
413 {
414 Uri uri(SETTING_URI_PROXY + "&key=" + key);
415 return uri;
416 }
417
418 std::shared_ptr<DataShare::DataShareHelper> VibrationPriorityManager::CreateDataShareHelper()
419 {
420 if (remoteObj_ == nullptr) {
421 MISC_HILOGE("remoteObj_ is nullptr");
422 return nullptr;
423 }
424 auto [ret, helper] = DataShare::DataShareHelper::Create(remoteObj_, SETTING_URI_PROXY, SETTINGS_DATA_EXT_URI);
425 if (ret == DATA_SHARE_READY) {
426 return helper;
427 } else if (ret == DATA_SHARE_NOT_READY) {
428 MISC_HILOGE("Create data_share helper failed, uri proxy:%{public}s", SETTING_URI_PROXY.c_str());
429 return nullptr;
430 }
431 MISC_HILOGI("Data_share create unknown");
432 return nullptr;
433 }
434
435 bool VibrationPriorityManager::ReleaseDataShareHelper(std::shared_ptr<DataShare::DataShareHelper> &helper)
436 {
437 if (!helper->Release()) {
438 MISC_HILOGW("Release helper fail");
439 return false;
440 }
441 return true;
442 }
443
444 void VibrationPriorityManager::ExecRegisterCb(const sptr<MiscDeviceObserver> &observer)
445 {
446 if (observer == nullptr) {
447 MISC_HILOGE("observer is nullptr");
448 return;
449 }
450 observer->OnChange();
451 }
452
453 int32_t VibrationPriorityManager::RegisterObserver(const sptr<MiscDeviceObserver> &observer)
454 {
455 if (observer == nullptr) {
456 MISC_HILOGE("observer is nullptr");
457 return MISC_NO_INIT_ERR;
458 }
459 std::string callingIdentity = IPCSkeleton::ResetCallingIdentity();
460 auto helper = CreateDataShareHelper();
461 if (helper == nullptr) {
462 IPCSkeleton::SetCallingIdentity(callingIdentity);
463 return MISC_NO_INIT_ERR;
464 }
465 auto uriFeedback = AssembleUri(SETTING_FEEDBACK_KEY);
466 helper->RegisterObserver(uriFeedback, observer);
467 helper->NotifyChange(uriFeedback);
468 #ifdef OHOS_BUILD_ENABLE_VIBRATOR_CROWN
469 auto uriCrownFeedback = AssembleUri(SETTING_CROWN_FEEDBACK_KEY);
470 helper->RegisterObserver(uriCrownFeedback, observer);
471 helper->NotifyChange(uriCrownFeedback);
472 auto uriIntensityContrl = AssembleUri(SETTING_CROWN_FEEDBACK_KEY);
473 helper->RegisterObserver(uriIntensityContrl, observer);
474 helper->NotifyChange(uriIntensityContrl);
475 #endif
476 auto uriRingerMode = AssembleUri(SETTING_RINGER_MODE_KEY);
477 helper->RegisterObserver(uriRingerMode, observer);
478 helper->NotifyChange(uriRingerMode);
479 std::thread execCb(VibrationPriorityManager::ExecRegisterCb, observer);
480 execCb.detach();
481 ReleaseDataShareHelper(helper);
482 IPCSkeleton::SetCallingIdentity(callingIdentity);
483 MISC_HILOGI("Succeed to register observer of uri");
484 return ERR_OK;
485 }
486
487 int32_t VibrationPriorityManager::UnregisterObserver(const sptr<MiscDeviceObserver> &observer)
488 {
489 if (observer == nullptr) {
490 MISC_HILOGE("observer is nullptr");
491 return MISC_NO_INIT_ERR;
492 }
493 std::string callingIdentity = IPCSkeleton::ResetCallingIdentity();
494 auto helper = CreateDataShareHelper();
495 if (helper == nullptr) {
496 IPCSkeleton::SetCallingIdentity(callingIdentity);
497 return MISC_NO_INIT_ERR;
498 }
499 auto uriFeedback = AssembleUri(SETTING_FEEDBACK_KEY);
500 helper->UnregisterObserver(uriFeedback, observer);
501 #ifdef OHOS_BUILD_ENABLE_VIBRATOR_CROWN
502 auto uriCrownnFeedback = AssembleUri(SETTING_CROWN_FEEDBACK_KEY);
503 helper->UnregisterObserver(uriCrownnFeedback, observer);
504 auto uriIntensityContrl = AssembleUri(SETTING_CROWN_FEEDBACK_KEY);
505 helper->UnregisterObserver(uriIntensityContrl, observer);
506 #endif
507 auto uriRingerMode = AssembleUri(SETTING_RINGER_MODE_KEY);
508 helper->UnregisterObserver(uriRingerMode, observer);
509 ReleaseDataShareHelper(helper);
510 IPCSkeleton::SetCallingIdentity(callingIdentity);
511 MISC_HILOGI("Succeed to unregister observer");
512 return ERR_OK;
513 }
514 } // namespace Sensors
515 } // namespace OHOS