• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2024-2024 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 "reminder_data_manager.h"
17 
18 #include "ability_manager_client.h"
19 #include "ans_log_wrapper.h"
20 #include "ans_trace_wrapper.h"
21 #include "ans_const_define.h"
22 #include "common_event_support.h"
23 #include "common_event_manager.h"
24 #include "reminder_request_calendar.h"
25 #include "in_process_call_wrapper.h"
26 #include "ipc_skeleton.h"
27 #include "notification_slot.h"
28 #include "os_account_manager.h"
29 #include "reminder_event_manager.h"
30 #include "time_service_client.h"
31 #include "singleton.h"
32 #include "locale_config.h"
33 #include "datashare_predicates_object.h"
34 #include "datashare_value_object.h"
35 #include "datashare_helper.h"
36 #include "data_share_permission.h"
37 #include "datashare_errno.h"
38 #include "datashare_template.h"
39 #include "system_ability_definition.h"
40 #include "app_mgr_constants.h"
41 #include "iservice_registry.h"
42 #include "config_policy_utils.h"
43 #include "hitrace_meter_adapter.h"
44 #include "notification_helper.h"
45 #include "reminder_datashare_helper.h"
46 #ifdef HAS_HISYSEVENT_PART
47 #include <sys/statfs.h>
48 #include "hisysevent.h"
49 #include "reminder_utils.h"
50 #include "directory_ex.h"
51 #endif
52 
53 namespace OHOS {
54 namespace Notification {
55 namespace {
56 constexpr int32_t ALL_SA_READY_FLAG = 2;  // bundle service and ability service ready.
57 // The maximum number of applications that can be displayed at a time
58 constexpr int32_t ONE_HAP_MAX_NUMBER_SHOW_AT_ONCE = 10;
59 // The maximum number of system that can be displayed at a time
60 constexpr int32_t TOTAL_MAX_NUMBER_SHOW_AT_ONCE = 500;
61 // The maximun number of system that can be start extension count
62 constexpr int32_t TOTAL_MAX_NUMBER_START_EXTENSION = 100;
63 constexpr int32_t CONNECT_EXTENSION_INTERVAL = 100;
64 static constexpr const char* USER_SETINGS_DATA_SECURE_URI =
65     "datashare:///com.ohos.settingsdata/entry/settingsdata/USER_SETTINGSDATA_SECURE_";
66 static constexpr const char* FOCUS_MODE_ENABLE_URI = "?Proxy=true&key=focus_mode_enable";
67 static constexpr const char* FOCUS_MODE_ENABLE = "focus_mode_enable";
68 }
69 
GetRemainPartitionSize(const std::string & partitionName)70 static uint64_t GetRemainPartitionSize(const std::string& partitionName)
71 {
72 #ifdef HAS_HISYSEVENT_PART
73     struct statfs stat;
74     if (statfs(partitionName.c_str(), &stat) != 0) {
75         return -1;
76     }
77     uint64_t blockSize = stat.f_bsize;
78     uint64_t freeSize = stat.f_bfree * blockSize;
79     constexpr double units = 1024.0;
80     return freeSize/(units * units);
81 #else
82     return 0;
83 #endif
84 }
85 
GetFileOrFolderSize(const std::vector<std::string> & paths)86 static std::vector<uint64_t> GetFileOrFolderSize(const std::vector<std::string>& paths)
87 {
88     std::vector<uint64_t> folderSize;
89 #ifdef HAS_HISYSEVENT_PART
90     for (auto path : paths) {
91         folderSize.emplace_back(OHOS::GetFolderSize(path));
92     }
93 #endif
94     return folderSize;
95 }
96 
IsSystemReady()97 bool ReminderDataManager::IsSystemReady()
98 {
99     return saReadyFlag_ >= ALL_SA_READY_FLAG;
100 }
101 
IsActionButtonDataShareValid(const sptr<ReminderRequest> & reminder,const uint32_t callerTokenId)102 bool ReminderDataManager::IsActionButtonDataShareValid(const sptr<ReminderRequest>& reminder,
103     const uint32_t callerTokenId)
104 {
105     auto actionButtonMap = reminder->GetActionButtons();
106     for (auto it = actionButtonMap.begin(); it != actionButtonMap.end(); ++it) {
107         ReminderRequest::ActionButtonInfo& buttonInfo = it->second;
108         if (buttonInfo.dataShareUpdate->uri.empty()) {
109             continue;
110         }
111         Uri uri(buttonInfo.dataShareUpdate->uri);
112         auto ret = DataShare::DataSharePermission::VerifyPermission(callerTokenId, uri, false);
113         if (ret != DataShare::E_OK) {
114             ANSR_LOGE("publish failed, DataSharePermission::VerifyPermission return error[%{public}d],",
115                 static_cast<int32_t>(ret));
116             return false;
117         }
118     }
119     return true;
120 }
121 
HandleAutoDeleteReminder(const int32_t notificationId,const int32_t uid,const int64_t autoDeletedTime)122 void ReminderDataManager::HandleAutoDeleteReminder(const int32_t notificationId, const int32_t uid,
123     const int64_t autoDeletedTime)
124 {
125     ANSR_LOGD("called");
126     std::vector<sptr<ReminderRequest>> showedReminder;
127     {
128         std::lock_guard<std::mutex> lock(ReminderDataManager::SHOW_MUTEX);
129         showedReminder = showedReminderVector_;
130     }
131     for (auto reminder : showedReminder) {
132         if (reminder == nullptr) {
133             continue;
134         }
135 
136         if (reminder->GetUid() != uid || notificationId != reminder->GetNotificationId() ||
137             reminder->GetAutoDeletedTime() != autoDeletedTime) {
138             continue;
139         }
140         CloseReminder(reminder, true);
141         UpdateAppDatabase(reminder, ReminderRequest::ActionButtonType::CLOSE);
142         CheckNeedNotifyStatus(reminder, ReminderRequest::ActionButtonType::CLOSE);
143     }
144     StartRecentReminder();
145 }
146 
OnBundleMgrServiceStart()147 void ReminderDataManager::OnBundleMgrServiceStart()
148 {
149     saReadyFlag_.fetch_add(1);
150 }
151 
OnAbilityMgrServiceStart()152 void ReminderDataManager::OnAbilityMgrServiceStart()
153 {
154     saReadyFlag_.fetch_add(1);
155 }
156 
GetCustomRingFileDesc(const sptr<ReminderRequest> & reminder,Global::Resource::ResourceManager::RawFileDescriptor & desc)157 bool ReminderDataManager::GetCustomRingFileDesc(const sptr<ReminderRequest>& reminder,
158     Global::Resource::ResourceManager::RawFileDescriptor& desc)
159 {
160     // obtains the resource manager
161     std::lock_guard<std::mutex> locker(resourceMutex_);
162     soundResource_ = GetResourceMgr(reminder->GetBundleName(), reminder->GetUid());
163     if (soundResource_ == nullptr) {
164         ANSR_LOGE("null soundResource");
165         return false;
166     }
167     auto result = soundResource_->GetRawFileDescriptor(reminder->GetCustomRingUri(), desc);
168     if (result != Global::Resource::SUCCESS) {
169         ANSR_LOGE("GetRawFileDescriptor fail[%{public}d].", static_cast<int32_t>(result));
170         return false;
171     }
172     return true;
173 }
174 
CloseCustomRingFileDesc(const int32_t reminderId,const std::string & customRingUri)175 void ReminderDataManager::CloseCustomRingFileDesc(const int32_t reminderId, const std::string& customRingUri)
176 {
177     std::lock_guard<std::mutex> locker(resourceMutex_);
178     if (soundResource_ == nullptr) {
179         ANSR_LOGE("null soundResource");
180         return;
181     }
182     auto result = soundResource_->CloseRawFileDescriptor(customRingUri);
183     if (result != Global::Resource::SUCCESS) {
184         ANSR_LOGE("CloseRawFileDescriptor fail[%{public}d]", static_cast<int32_t>(result));
185     }
186     ANSR_LOGI("reminderId:[%{public}d]", reminderId);
187     soundResource_ = nullptr;
188 }
189 
ReportSysEvent(const sptr<ReminderRequest> & reminder)190 void ReminderDataManager::ReportSysEvent(const sptr<ReminderRequest>& reminder)
191 {
192 #ifdef HAS_HISYSEVENT_PART
193     std::string event = "ALARM_TRIGGER";
194     std::string bundleName = reminder->GetBundleName();
195     int32_t uid = reminder->GetUid();
196     int32_t type = static_cast<int32_t>(reminder->GetReminderType());
197     int32_t repeat = static_cast<int32_t>(reminder->IsRepeat());
198     uint64_t triggerTime = reminder->GetTriggerTimeInMilli();
199     int32_t ringTime = static_cast<int32_t>(reminder->GetRingDuration());
200     HiSysEventWrite(HiviewDFX::HiSysEvent::Domain::NOTIFICATION, event, HiviewDFX::HiSysEvent::EventType::STATISTIC,
201         "UID", uid, "NAME", bundleName, "TYPE", type, "REPEAT", repeat, "TRIGGER_TIME", triggerTime,
202         "RING_TIME", ringTime);
203 #endif
204 }
205 
CheckShowLimit(std::unordered_map<std::string,int32_t> & limits,int32_t & totalCount,sptr<ReminderRequest> & reminder)206 bool ReminderDataManager::CheckShowLimit(std::unordered_map<std::string, int32_t>& limits, int32_t& totalCount,
207     sptr<ReminderRequest>& reminder)
208 {
209     if (totalCount > TOTAL_MAX_NUMBER_SHOW_AT_ONCE) {
210         ANSR_LOGE("The maximum number of displays that can be displayed at a time has been reached.");
211         return false;
212     }
213     ++totalCount;
214     std::string key = std::to_string(reminder->GetUid()) + "_" + std::to_string(reminder->GetTriggerTimeInMilli());
215     auto iter = limits.find(key);
216     if (iter == limits.end()) {
217         limits[key] = 1;
218         return true;
219     }
220     if (iter->second > ONE_HAP_MAX_NUMBER_SHOW_AT_ONCE) {
221         ANSR_LOGE("The maximum number of displays that can be displayed in a single app[%{public}s] has been reached",
222             reminder->GetBundleName().c_str());
223         return false;
224     }
225     ++iter->second;
226     return true;
227 }
228 
OnDataShareInsertOrDelete()229 void ReminderDataManager::OnDataShareInsertOrDelete()
230 {
231     LoadShareReminders();
232     std::vector<sptr<ReminderRequest>> immediatelyReminders;
233     std::vector<sptr<ReminderRequest>> extensionReminders;
234     CheckReminderTime(immediatelyReminders, extensionReminders);
235     HandleImmediatelyShow(immediatelyReminders, false);
236     StartRecentReminder();
237 }
238 
OnDataShareUpdate(const std::map<std::string,sptr<ReminderRequest>> & reminders)239 void ReminderDataManager::OnDataShareUpdate(const std::map<std::string, sptr<ReminderRequest>>& reminders)
240 {
241     UpdateShareReminders(reminders);
242 }
243 
UpdateShareReminders(const std::map<std::string,sptr<ReminderRequest>> & reminders)244 void ReminderDataManager::UpdateShareReminders(const std::map<std::string, sptr<ReminderRequest>>& reminders)
245 {
246     std::lock_guard<std::mutex> locker(ReminderDataManager::MUTEX);
247     for (auto it = reminderVector_.begin(); it != reminderVector_.end(); ++it) {
248         if (!(*it)->IsShare() || (*it)->GetReminderType() != ReminderRequest::ReminderType::CALENDAR) {
249             continue;
250         }
251         int32_t reminderId = (*it)->GetReminderId();
252         std::string identifier = (*it)->GetIdentifier();
253         auto iter = reminders.find(identifier);
254         if (iter == reminders.end()) {
255             continue;
256         }
257         ReminderRequestCalendar* calendar = static_cast<ReminderRequestCalendar*>((*it).GetRefPtr());
258         calendar->Copy(iter->second);
259         if ((*it)->IsShowing()) {
260             ShowReminder((*it), false, false, false, false, false);
261         }
262     }
263 }
264 
AsyncStartExtensionAbility(const sptr<ReminderRequest> & reminder,int32_t times,const int8_t type,int32_t & count)265 void ReminderDataManager::AsyncStartExtensionAbility(const sptr<ReminderRequest> &reminder, int32_t times,
266     const int8_t type, int32_t& count)
267 {
268     auto manager = ReminderDataManager::GetInstance();
269     if (manager == nullptr) {
270         ANSR_LOGE("null manager");
271         return;
272     }
273     if (!manager->IsSystemReady()) {
274         ANSR_LOGE("bundle service or ability service not ready.");
275         return;
276     }
277     if (!reminder->IsSystemApp()) {
278         ANSR_LOGE("Start extension ability failed, is not system app");
279         return;
280     }
281     if (count > TOTAL_MAX_NUMBER_START_EXTENSION) {
282         ANSR_LOGE("The maximum number of start extension has been reached.");
283         return;
284     }
285     ++count;
286     times--;
287     bool ret = ReminderDataManager::StartExtensionAbility(reminder, type);
288     if (!ret && times > 0 && serviceQueue_ != nullptr) {
289         ANSR_LOGD("StartExtensionAbilty failed, reminder times: %{public}d", times);
290         ffrt::task_attr taskAttr;
291         taskAttr.delay(CONNECT_EXTENSION_INTERVAL);
292         auto callback = [reminder, times, type]() {
293             int32_t count = 0;
294             ReminderDataManager::AsyncStartExtensionAbility(reminder, times, type, count);
295         };
296         serviceQueue_->submit(callback, taskAttr);
297     }
298 }
299 
UpdateReminderFromDb(const std::vector<sptr<ReminderRequest>> & remindersFromDb)300 void ReminderDataManager::UpdateReminderFromDb(const std::vector<sptr<ReminderRequest>>& remindersFromDb)
301 {
302     std::map<int32_t, sptr<ReminderRequest>> reminders;
303     for (const auto& reminder : remindersFromDb) {
304         reminders[reminder->GetReminderId()] = reminder;
305     }
306     // Only alerts that do not exist in memory are processed
307     for (const auto& reminder : reminderVector_) {
308         if (reminder->IsShare()) {
309             continue;
310         }
311         int32_t reminderId = reminder->GetReminderId();
312         auto iter = reminders.find(reminderId);
313         if (iter != reminders.end()) {
314             reminders.erase(iter);
315         }
316     }
317     // new reminder
318     for (auto& each : reminders) {
319         reminderVector_.push_back(each.second);
320     }
321 }
322 
UpdateReminder(const sptr<ReminderRequest> & reminder,const int32_t callingUid)323 ErrCode ReminderDataManager::UpdateReminder(const sptr<ReminderRequest>& reminder, const int32_t callingUid)
324 {
325     NOTIFICATION_HITRACE(HITRACE_TAG_OHOS);
326     sptr<ReminderRequest> reminderOld = FindReminderRequestLocked(reminder->GetReminderId(), false);
327     bool existInMemory = true;
328     if (nullptr != reminderOld) {
329         if (!CheckIsSameApp(reminderOld, callingUid)) {
330             ANSR_LOGW("Not find the reminder due to not match");
331             return ERR_REMINDER_NOT_EXIST;
332         }
333         if (reminderOld->IsShowing()) {
334             ANSR_LOGW("Reminder already showing, update reminder failed.");
335             return ERR_REMINDER_NOT_EXIST;
336         }
337     } else {
338         existInMemory = false;
339         std::lock_guard<std::mutex> lock(ReminderDataManager::MUTEX);
340         if (!store_->IsReminderExist(reminder->GetReminderId(), reminder->GetCreatorUid())) {
341             ANSR_LOGW("Reminder not find, update reminder failed.");
342             return ERR_REMINDER_NOT_EXIST;
343         }
344     }
345     uint32_t callerTokenId = IPCSkeleton::GetCallingTokenID();
346     if (callerTokenId == 0) {
347         ANSR_LOGE("pushlish failed, callerTokenId is 0");
348         return ERR_REMINDER_CALLER_TOKEN_INVALID;
349     }
350     if (!IsActionButtonDataShareValid(reminder, callerTokenId)) {
351         return ERR_REMINDER_DATA_SHARE_PERMISSION_DENIED;
352     }
353 
354     UpdateAndSaveReminderLocked(reminder, existInMemory);
355     queue_->submit([this, reminder]() {
356         StartRecentReminder();
357     });
358     return ERR_OK;
359 }
360 
UpdateAndSaveReminderLocked(const sptr<ReminderRequest> & reminder,const bool isInMemory)361 void ReminderDataManager::UpdateAndSaveReminderLocked(const sptr<ReminderRequest>& reminder, const bool isInMemory)
362 {
363     std::lock_guard<std::mutex> lock(ReminderDataManager::MUTEX);
364     if (reminder->GetTriggerTimeInMilli() == ReminderRequest::INVALID_LONG_LONG_VALUE) {
365         ANSR_LOGW("now publish reminder is expired. reminder is =%{public}s", reminder->Dump().c_str());
366         reminder->SetExpired(true);
367     }
368     if (isInMemory) {
369         for (auto it = reminderVector_.begin(); it != reminderVector_.end(); ++it) {
370             if (reminder->GetReminderId() == (*it)->GetReminderId() && !(*it)->IsShare()) {
371                 *it = reminder;
372                 break;
373             }
374         }
375     } else {
376         reminderVector_.push_back(reminder);
377     }
378     store_->UpdateOrInsert(reminder);
379 }
380 
SetActiveReminder(const sptr<ReminderRequest> & reminder)381 void ReminderDataManager::SetActiveReminder(const sptr<ReminderRequest> &reminder)
382 {
383     if (reminder == nullptr) {
384         // activeReminder_ should not be set with null as it point to actual object.
385         activeReminderId_ = -1;
386         activeTriggerTime_ = 0;
387     } else {
388         activeReminderId_ = reminder->GetReminderId();
389         activeTriggerTime_ = reminder->GetTriggerTimeInMilli();
390         std::lock_guard<std::mutex> locker(ReminderDataManager::ACTIVE_MUTEX);
391         activeReminder_ = reminder;
392     }
393     ANSR_LOGD("Set activeReminderId=%{public}d", activeReminderId_.load());
394 }
395 
SetAlertingReminder(const sptr<ReminderRequest> & reminder)396 void ReminderDataManager::SetAlertingReminder(const sptr<ReminderRequest> &reminder)
397 {
398     if (reminder == nullptr) {
399         // alertingReminder_ should not be set with null as it point to actual object.
400         alertingReminderId_ = -1;
401     } else {
402         alertingReminderId_ = reminder->GetReminderId();
403         alertingReminder_ = reminder;
404     }
405     ANSR_LOGD("Set alertingReminderId=%{public}d", alertingReminderId_.load());
406 }
407 
CancelReminderToDb(const int32_t reminderId,const int32_t callingUid)408 ErrCode ReminderDataManager::CancelReminderToDb(const int32_t reminderId, const int32_t callingUid)
409 {
410     if (store_ == nullptr) {
411         ANSR_LOGE("null store");
412         return ERR_REMINDER_NOT_EXIST;
413     }
414     std::lock_guard<std::mutex> lock(ReminderDataManager::MUTEX);
415     if (!store_->IsReminderExist(reminderId, callingUid)) {
416         ANSR_LOGE("Not find reminder[%{public}d] in db.", reminderId);
417         return ERR_REMINDER_NOT_EXIST;
418     }
419     store_->Delete(reminderId);
420     return ERR_OK;
421 }
422 
IsAllowedNotify(const sptr<ReminderRequest> & reminder) const423 bool ReminderDataManager::IsAllowedNotify(const sptr<ReminderRequest> &reminder) const
424 {
425     if (reminder == nullptr) {
426         return false;
427     }
428     bool isAllowed = false;
429     NotificationBundleOption bundleOption(reminder->GetBundleName(), reminder->GetUid());
430     ErrCode errCode = IN_PROCESS_CALL(NotificationHelper::IsAllowedNotify(bundleOption, isAllowed));
431     if (errCode != ERR_OK) {
432         ANSR_LOGE("Failed to call IsAllowedNotify, errCode=%{public}d", errCode);
433         return false;
434     }
435     return isAllowed;
436 }
437 
ReportTimerEvent(const int64_t targetTime,const bool isSysTimeChanged)438 void ReminderDataManager::ReportTimerEvent(const int64_t targetTime, const bool isSysTimeChanged)
439 {
440 #ifdef HAS_HISYSEVENT_PART
441     if (targetTime == 0) {
442         return;
443     }
444     constexpr int64_t deviation = 1000 * 60;  // 1min
445     int64_t now = GetCurrentTime();
446     if ((now - targetTime) <= deviation) {
447         return;
448     }
449     uint8_t errorCode = isSysTimeChanged ? 0 : 1;
450     HiSysEventWrite(HiviewDFX::HiSysEvent::Domain::NOTIFICATION, "REMINDER_TIMER_ERROR",
451         HiviewDFX::HiSysEvent::EventType::STATISTIC,
452         "TARGET_TIME", targetTime, "TRIGGER_TIME", now, "ERROR_CODE", errorCode);
453 #endif
454 }
455 
ReportUserDataSizeEvent()456 void ReminderDataManager::ReportUserDataSizeEvent()
457 {
458 #ifdef HAS_HISYSEVENT_PART
459     std::vector<std::string> paths = {
460         "/data/service/el1/public/notification/"
461     };
462     uint64_t remainPartitionSize = GetRemainPartitionSize("/data");
463     std::vector<uint64_t> folderSize = GetFileOrFolderSize(paths);
464     HiSysEventWrite(HiviewDFX::HiSysEvent::Domain::FILEMANAGEMENT, "USER_DATA_SIZE",
465         HiviewDFX::HiSysEvent::EventType::STATISTIC,
466         "COMPONENT_NAME", "resource_schedule_service",
467         "PARTITION_NAME", "/data",
468         "REMAIN_PARTITION_SIZE", remainPartitionSize,
469         "FILE_OR_FOLDER_PATH", paths,
470         "FILE_OR_FOLDER_SIZE", folderSize);
471 #endif
472 }
473 
CheckSoundConfig(const sptr<ReminderRequest> reminder)474 bool ReminderDataManager::CheckSoundConfig(const sptr<ReminderRequest> reminder)
475 {
476 #ifdef PLAYER_FRAMEWORK_ENABLE
477     NotificationBundleOption option;
478     option.SetBundleName(reminder->GetBundleName());
479     option.SetUid(reminder->GetUid());
480     uint32_t slotFlags;
481     ErrCode err = NotificationHelper::GetNotificationSlotFlagsAsBundle(option, slotFlags);
482     if (err != ERR_OK) {
483         ANSR_LOGE("GetNotificationSlotFlagsAsBundle failed.");
484         return false;
485     }
486     if (!(slotFlags & 1)) {
487         return false;
488     }
489     std::string uriStr = USER_SETINGS_DATA_SECURE_URI + std::to_string(reminder->GetUserId())
490         + FOCUS_MODE_ENABLE_URI;
491     Uri enableUri(uriStr);
492     std::string enable;
493     bool ret = ReminderDataShareHelper::GetInstance().Query(enableUri, FOCUS_MODE_ENABLE, enable);
494     if (!ret) {
495         ANSR_LOGE("Query focus mode enable failed.");
496         return false;
497     }
498     if (enable.compare("1") == 0) {
499         ANSR_LOGI("Currently not is do not disurb mode.");
500         return false;
501     }
502 #endif
503     return true;
504 }
505 
ConvertRingChannel(ReminderRequest::RingChannel channel)506 int32_t ReminderDataManager::ConvertRingChannel(ReminderRequest::RingChannel channel)
507 {
508     switch (channel) {
509         case ReminderRequest::RingChannel::ALARM:
510             return static_cast<int32_t>(AudioStandard::StreamUsage::STREAM_USAGE_ALARM);
511         case ReminderRequest::RingChannel::MEDIA:
512             return static_cast<int32_t>(AudioStandard::StreamUsage::STREAM_USAGE_MEDIA);
513         case ReminderRequest::RingChannel::NOTIFICATION:
514             return static_cast<int32_t>(AudioStandard::StreamUsage::STREAM_USAGE_NOTIFICATION);
515         default:
516             return static_cast<int32_t>(AudioStandard::StreamUsage::STREAM_USAGE_ALARM);
517     }
518 }
519 }
520 }
521