• 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 "ipc_skeleton.h"
19 #include "iservice_registry.h"
20 #include "system_ability_definition.h"
21 #include "uri.h"
22 
23 #include "sensors_errors.h"
24 
25 #undef LOG_TAG
26 #define LOG_TAG "VibrationPriorityManager"
27 
28 namespace OHOS {
29 namespace Sensors {
30 namespace {
31 const std::string SETTING_COLUMN_KEYWORD = "KEYWORD";
32 const std::string SETTING_COLUMN_VALUE = "VALUE";
33 const std::string SETTING_FEEDBACK_KEY = "physic_navi_haptic_feedback_enabled";
34 const std::string SETTING_RINGER_MODE_KEY = "ringer_mode";
35 const std::string SETTING_URI_PROXY = "datashare:///com.ohos.settingsdata/entry/settingsdata/SETTINGSDATA?Proxy=true";
36 constexpr const char *SETTINGS_DATA_EXT_URI = "datashare:///com.ohos.settingsdata.DataAbility";
37 constexpr int32_t DECEM_BASE = 10;
38 }  // namespace
39 
VibrationPriorityManager()40 VibrationPriorityManager::VibrationPriorityManager()
41 {
42     Initialize();
43     MiscDeviceObserver::UpdateFunc updateFunc = [&]() {
44         int32_t feedback = miscFeedback_;
45         if (GetIntValue(SETTING_FEEDBACK_KEY, feedback) != ERR_OK) {
46             MISC_HILOGE("Get feedback failed");
47         }
48         miscFeedback_ = feedback;
49         MISC_HILOGI("feedback:%{public}d", feedback);
50         int32_t ringerMode = miscAudioRingerMode_;
51         if (GetIntValue(SETTING_RINGER_MODE_KEY, ringerMode) != ERR_OK) {
52             MISC_HILOGE("Get ringerMode failed");
53         }
54         miscAudioRingerMode_ = ringerMode;
55         MISC_HILOGI("ringerMode:%{public}d", ringerMode);
56     };
57     auto observer = CreateObserver(updateFunc);
58     if (observer == nullptr) {
59         MISC_HILOGE("observer is null");
60         return;
61     }
62     observer_ = observer;
63     if (RegisterObserver(observer_) != ERR_OK) {
64         MISC_HILOGE("RegisterObserver failed");
65     }
66 }
67 
~VibrationPriorityManager()68 VibrationPriorityManager::~VibrationPriorityManager()
69 {
70     remoteObj_ = nullptr;
71     if (UnregisterObserver(observer_) != ERR_OK) {
72         MISC_HILOGE("UnregisterObserver failed");
73     }
74 }
75 
GetIntValue(const std::string & key,int32_t & value)76 int32_t VibrationPriorityManager::GetIntValue(const std::string &key, int32_t &value)
77 {
78     int64_t valueLong;
79     int32_t ret = GetLongValue(key, valueLong);
80     if (ret != ERR_OK) {
81         return ret;
82     }
83     value = static_cast<int32_t>(valueLong);
84     return ERR_OK;
85 }
86 
GetLongValue(const std::string & key,int64_t & value)87 int32_t VibrationPriorityManager::GetLongValue(const std::string &key, int64_t &value)
88 {
89     std::string valueStr;
90     int32_t ret = GetStringValue(key, valueStr);
91     if (ret != ERR_OK) {
92         return ret;
93     }
94     value = static_cast<int64_t>(strtoll(valueStr.c_str(), nullptr, DECEM_BASE));
95     return ERR_OK;
96 }
97 
GetStringValue(const std::string & key,std::string & value)98 int32_t VibrationPriorityManager::GetStringValue(const std::string &key, std::string &value)
99 {
100     std::string callingIdentity = IPCSkeleton::ResetCallingIdentity();
101     auto helper = CreateDataShareHelper();
102     if (helper == nullptr) {
103         IPCSkeleton::SetCallingIdentity(callingIdentity);
104         return MISC_NO_INIT_ERR;
105     }
106     std::vector<std::string> columns = {SETTING_COLUMN_VALUE};
107     DataShare::DataSharePredicates predicates;
108     predicates.EqualTo(SETTING_COLUMN_KEYWORD, key);
109     Uri uri(AssembleUri(key));
110     auto resultSet = helper->Query(uri, predicates, columns);
111     ReleaseDataShareHelper(helper);
112     if (resultSet == nullptr) {
113         MISC_HILOGE("resultSet is nullptr");
114         IPCSkeleton::SetCallingIdentity(callingIdentity);
115         return MISC_INVALID_OPERATION_ERR;
116     }
117     int32_t count;
118     resultSet->GetRowCount(count);
119     if (count == 0) {
120         MISC_HILOGW("Not found value, key:%{public}s, count:%{public}d", key.c_str(), count);
121         IPCSkeleton::SetCallingIdentity(callingIdentity);
122         return MISC_NAME_NOT_FOUND_ERR;
123     }
124     const int32_t index = 0;
125     resultSet->GoToRow(index);
126     int32_t ret = resultSet->GetString(index, value);
127     if (ret != ERR_OK) {
128         MISC_HILOGW("GetString failed, ret:%{public}d", ret);
129         IPCSkeleton::SetCallingIdentity(callingIdentity);
130         return ERROR;
131     }
132     resultSet->Close();
133     IPCSkeleton::SetCallingIdentity(callingIdentity);
134     return ERR_OK;
135 }
136 
UpdateStatus()137 void VibrationPriorityManager::UpdateStatus()
138 {
139     if (miscFeedback_ == FEEDBACK_MODE_INVALID) {
140         int32_t feedback = FEEDBACK_MODE_INVALID;
141         if (GetIntValue(SETTING_FEEDBACK_KEY, feedback) != ERR_OK) {
142             feedback = FEEDBACK_MODE_ON;
143             MISC_HILOGE("Get feedback failed");
144         }
145         miscFeedback_ = feedback;
146     }
147     if (miscAudioRingerMode_ == RINGER_MODE_INVALID) {
148         int32_t ringerMode = RINGER_MODE_INVALID;
149         if (GetIntValue(SETTING_RINGER_MODE_KEY, ringerMode) != ERR_OK) {
150             ringerMode = RINGER_MODE_NORMAL;
151             MISC_HILOGE("Get ringerMode failed");
152         }
153         miscAudioRingerMode_ = ringerMode;
154     }
155 }
156 
ShouldIgnoreVibrate(const VibrateInfo & vibrateInfo,std::shared_ptr<VibratorThread> vibratorThread)157 VibrateStatus VibrationPriorityManager::ShouldIgnoreVibrate(const VibrateInfo &vibrateInfo,
158     std::shared_ptr<VibratorThread> vibratorThread)
159 {
160     if (vibratorThread == nullptr) {
161         MISC_HILOGD("There is no vibration, it can vibrate");
162         return VIBRATION;
163     }
164     UpdateStatus();
165     if ((vibrateInfo.usage == USAGE_ALARM || vibrateInfo.usage == USAGE_RING || vibrateInfo.usage == USAGE_NOTIFICATION
166         || vibrateInfo.usage == USAGE_COMMUNICATION) && (miscAudioRingerMode_ == RINGER_MODE_SILENT)) {
167         MISC_HILOGD("Vibration is ignored for ringer mode:%{public}d", static_cast<int32_t>(miscAudioRingerMode_));
168         return IGNORE_RINGER_MODE;
169     }
170     if ((vibrateInfo.usage == USAGE_TOUCH || vibrateInfo.usage == USAGE_MEDIA || vibrateInfo.usage == USAGE_UNKNOWN
171         || vibrateInfo.usage == USAGE_PHYSICAL_FEEDBACK || vibrateInfo.usage == USAGE_SIMULATE_REALITY)
172         && (miscFeedback_ == FEEDBACK_MODE_OFF)) {
173         MISC_HILOGD("Vibration is ignored for feedback:%{public}d", static_cast<int32_t>(miscFeedback_));
174         return IGNORE_FEEDBACK;
175     }
176     if (vibratorThread == nullptr) {
177         MISC_HILOGD("There is no vibration, it can vibrate");
178         return VIBRATION;
179     }
180     if (!IsCurrentVibrate(vibratorThread)) {
181         MISC_HILOGD("There is no vibration at the moment, it can vibrate");
182         return VIBRATION;
183     }
184     if (IsLoopVibrate(vibrateInfo)) {
185         MISC_HILOGD("Can vibrate, loop priority is high");
186         return VIBRATION;
187     }
188     return ShouldIgnoreVibrate(vibrateInfo, vibratorThread->GetCurrentVibrateInfo());
189 }
190 
IsCurrentVibrate(std::shared_ptr<VibratorThread> vibratorThread) const191 bool VibrationPriorityManager::IsCurrentVibrate(std::shared_ptr<VibratorThread> vibratorThread) const
192 {
193 #if defined(OHOS_BUILD_ENABLE_VIBRATOR_CUSTOM)
194     return ((vibratorThread != nullptr) && (vibratorThread->IsRunning() || VibratorDevice.IsVibratorRunning()));
195 #else
196     return ((vibratorThread != nullptr) && (vibratorThread->IsRunning()));
197 #endif // OHOS_BUILD_ENABLE_VIBRATOR_CUSTOM
198 }
199 
IsLoopVibrate(const VibrateInfo & vibrateInfo) const200 bool VibrationPriorityManager::IsLoopVibrate(const VibrateInfo &vibrateInfo) const
201 {
202     return ((vibrateInfo.mode == "preset") && (vibrateInfo.count > 1));
203 }
204 
ShouldIgnoreVibrate(const VibrateInfo & vibrateInfo,VibrateInfo currentVibrateInfo) const205 VibrateStatus VibrationPriorityManager::ShouldIgnoreVibrate(const VibrateInfo &vibrateInfo,
206     VibrateInfo currentVibrateInfo) const
207 {
208     if (currentVibrateInfo.usage == USAGE_ALARM) {
209         MISC_HILOGD("Vibration is ignored for alarm");
210         return IGNORE_ALARM;
211     }
212     if (IsLoopVibrate(currentVibrateInfo)) {
213         MISC_HILOGD("Vibration is ignored for repeat");
214         return IGNORE_REPEAT;
215     }
216     if ((currentVibrateInfo.usage != vibrateInfo.usage) && (vibrateInfo.usage == USAGE_UNKNOWN)) {
217         MISC_HILOGD("Vibration is ignored, unknown has a low priority");
218         return IGNORE_UNKNOWN;
219     }
220     return VIBRATION;
221 }
222 
CreateObserver(const MiscDeviceObserver::UpdateFunc & func)223 sptr<MiscDeviceObserver> VibrationPriorityManager::CreateObserver(const MiscDeviceObserver::UpdateFunc &func)
224 {
225     sptr<MiscDeviceObserver> observer = new MiscDeviceObserver();
226     if (observer == nullptr) {
227         MISC_HILOGE("observer is null");
228         return observer;
229     }
230     observer->SetUpdateFunc(func);
231     return observer;
232 }
233 
Initialize()234 void VibrationPriorityManager::Initialize()
235 {
236     auto sm = SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager();
237     if (sm == nullptr) {
238         MISC_HILOGE("sm cannot be nullptr");
239         return;
240     }
241     auto remoteObj = sm->GetSystemAbility(MISCDEVICE_SERVICE_ABILITY_ID);
242     if (remoteObj == nullptr) {
243         MISC_HILOGE("GetSystemAbility return nullptr");
244         return;
245     }
246     remoteObj_ = remoteObj;
247 }
248 
AssembleUri(const std::string & key)249 Uri VibrationPriorityManager::AssembleUri(const std::string &key)
250 {
251     Uri uri(SETTING_URI_PROXY + "&key=" + key);
252     return uri;
253 }
254 
CreateDataShareHelper()255 std::shared_ptr<DataShare::DataShareHelper> VibrationPriorityManager::CreateDataShareHelper()
256 {
257     if (remoteObj_ == nullptr) {
258         MISC_HILOGE("remoteObj_ is nullptr");
259         return nullptr;
260     }
261     auto helper = DataShare::DataShareHelper::Creator(remoteObj_, SETTING_URI_PROXY, SETTINGS_DATA_EXT_URI);
262     if (helper == nullptr) {
263         MISC_HILOGW("helper is nullptr, uri proxy:%{public}s", SETTING_URI_PROXY.c_str());
264         return nullptr;
265     }
266     return helper;
267 }
268 
ReleaseDataShareHelper(std::shared_ptr<DataShare::DataShareHelper> & helper)269 bool VibrationPriorityManager::ReleaseDataShareHelper(std::shared_ptr<DataShare::DataShareHelper> &helper)
270 {
271     if (!helper->Release()) {
272         MISC_HILOGW("release helper fail");
273         return false;
274     }
275     return true;
276 }
277 
ExecRegisterCb(const sptr<MiscDeviceObserver> & observer)278 void VibrationPriorityManager::ExecRegisterCb(const sptr<MiscDeviceObserver> &observer)
279 {
280     if (observer == nullptr) {
281         MISC_HILOGE("observer is nullptr");
282         return;
283     }
284     observer->OnChange();
285 }
286 
RegisterObserver(const sptr<MiscDeviceObserver> & observer)287 int32_t VibrationPriorityManager::RegisterObserver(const sptr<MiscDeviceObserver> &observer)
288 {
289     if (observer == nullptr) {
290         MISC_HILOGE("observer is nullptr");
291         return MISC_NO_INIT_ERR;
292     }
293     std::string callingIdentity = IPCSkeleton::ResetCallingIdentity();
294     auto helper = CreateDataShareHelper();
295     if (helper == nullptr) {
296         IPCSkeleton::SetCallingIdentity(callingIdentity);
297         return MISC_NO_INIT_ERR;
298     }
299     auto uriFeedback = AssembleUri(SETTING_FEEDBACK_KEY);
300     helper->RegisterObserver(uriFeedback, observer);
301     helper->NotifyChange(uriFeedback);
302     auto uriRingerMode = AssembleUri(SETTING_RINGER_MODE_KEY);
303     helper->RegisterObserver(uriRingerMode, observer);
304     helper->NotifyChange(uriRingerMode);
305     std::thread execCb(VibrationPriorityManager::ExecRegisterCb, observer);
306     execCb.detach();
307     ReleaseDataShareHelper(helper);
308     IPCSkeleton::SetCallingIdentity(callingIdentity);
309     MISC_HILOGD("succeed to register observer of uri");
310     return ERR_OK;
311 }
312 
UnregisterObserver(const sptr<MiscDeviceObserver> & observer)313 int32_t VibrationPriorityManager::UnregisterObserver(const sptr<MiscDeviceObserver> &observer)
314 {
315     if (observer == nullptr) {
316         MISC_HILOGE("observer is nullptr");
317         return MISC_NO_INIT_ERR;
318     }
319     std::string callingIdentity = IPCSkeleton::ResetCallingIdentity();
320     auto helper = CreateDataShareHelper();
321     if (helper == nullptr) {
322         IPCSkeleton::SetCallingIdentity(callingIdentity);
323         return MISC_NO_INIT_ERR;
324     }
325     auto uriFeedback = AssembleUri(SETTING_FEEDBACK_KEY);
326     helper->UnregisterObserver(uriFeedback, observer);
327     auto uriRingerMode = AssembleUri(SETTING_RINGER_MODE_KEY);
328     helper->UnregisterObserver(uriRingerMode, observer);
329     ReleaseDataShareHelper(helper);
330     IPCSkeleton::SetCallingIdentity(callingIdentity);
331     MISC_HILOGD("succeed to unregister observer");
332     return ERR_OK;
333 }
334 }  // namespace Sensors
335 }  // namespace OHOS