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