1 /*
2 * Copyright (c) 2021-2023 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 "advanced_notification_service.h"
17
18 #include <functional>
19 #include <iomanip>
20 #include <sstream>
21 #include <filesystem>
22 #include <file_ex.h>
23
24 #include "accesstoken_kit.h"
25 #include "ans_inner_errors.h"
26 #include "ans_log_wrapper.h"
27 #include "errors.h"
28
29 #include "ipc_skeleton.h"
30 #include "access_token_helper.h"
31 #include "notification_constant.h"
32 #include "notification_request.h"
33 #include "reminder_helper.h"
34 #include "os_account_manager.h"
35 #include "hitrace_meter_adapter.h"
36 #ifdef DISTRIBUTED_NOTIFICATION_SUPPORTED
37 #include "distributed_notification_manager.h"
38 #include "distributed_preferences.h"
39 #include "distributed_screen_status_manager.h"
40 #endif
41
42 #include "advanced_notification_inline.cpp"
43
44 namespace OHOS {
45 namespace Notification {
46 constexpr const char* REMINDER_DB_PATH = "/data/service/el1/public/notification/notification.db";
47 constexpr const char* REMINDER_AGENT_SERVICE_CONFIG_PATH =
48 "/data/service/el1/public/notification/reminder_agent_service_config";
49 constexpr const char* CALENDAR_DATA_NAME = "com.ohos.calendardata";
50
51 #ifdef DISTRIBUTED_NOTIFICATION_SUPPORTED
GetRemindType()52 NotificationConstant::RemindType AdvancedNotificationService::GetRemindType()
53 {
54 bool remind = localScreenOn_;
55 if (distributedReminderPolicy_ == NotificationConstant::DistributedReminderPolicy::DEFAULT) {
56 bool remoteUsing = false;
57 ErrCode result = DistributedScreenStatusManager::GetInstance()->CheckRemoteDevicesIsUsing(remoteUsing);
58 if (result != ERR_OK) {
59 remind = true;
60 }
61 if (!localScreenOn_ && !remoteUsing) {
62 remind = true;
63 }
64 } else if (distributedReminderPolicy_ == NotificationConstant::DistributedReminderPolicy::ALWAYS_REMIND) {
65 remind = true;
66 } else if (distributedReminderPolicy_ == NotificationConstant::DistributedReminderPolicy::DO_NOT_REMIND) {
67 remind = false;
68 }
69
70 if (localScreenOn_) {
71 if (remind) {
72 return NotificationConstant::RemindType::DEVICE_ACTIVE_REMIND;
73 } else {
74 return NotificationConstant::RemindType::DEVICE_ACTIVE_DONOT_REMIND;
75 }
76 } else {
77 if (remind) {
78 return NotificationConstant::RemindType::DEVICE_IDLE_REMIND;
79 } else {
80 return NotificationConstant::RemindType::DEVICE_IDLE_DONOT_REMIND;
81 }
82 }
83 }
84 #endif
85
GetDeviceRemindType(NotificationConstant::RemindType & remindType)86 ErrCode AdvancedNotificationService::GetDeviceRemindType(NotificationConstant::RemindType &remindType)
87 {
88 ANS_LOGD("%{public}s", __FUNCTION__);
89
90 bool isSubsystem = AccessTokenHelper::VerifyNativeToken(IPCSkeleton::GetCallingTokenID());
91 if (!isSubsystem && !AccessTokenHelper::IsSystemApp()) {
92 return ERR_ANS_NON_SYSTEM_APP;
93 }
94
95 if (!AccessTokenHelper::CheckPermission(OHOS_PERMISSION_NOTIFICATION_CONTROLLER)) {
96 return ERR_ANS_PERMISSION_DENIED;
97 }
98
99 #ifdef DISTRIBUTED_NOTIFICATION_SUPPORTED
100 if (notificationSvrQueue_ == nullptr) {
101 ANS_LOGE("Serial queue is invalid.");
102 return ERR_ANS_INVALID_PARAM;
103 }
104 ffrt::task_handle handler = notificationSvrQueue_->submit_h(std::bind([&]() { remindType = GetRemindType(); }));
105 notificationSvrQueue_->wait(handler);
106 return ERR_OK;
107 #else
108 return ERR_INVALID_OPERATION;
109 #endif
110 }
111
SetNotificationRemindType(sptr<Notification> notification,bool isLocal)112 ErrCode AdvancedNotificationService::SetNotificationRemindType(sptr<Notification> notification, bool isLocal)
113 {
114 #ifdef DISTRIBUTED_NOTIFICATION_SUPPORTED
115 notification->SetRemindType(GetRemindType());
116 #else
117 notification->SetRemindType(NotificationConstant::RemindType::NONE);
118 #endif
119 return ERR_OK;
120 }
121
TryStartReminderAgentService()122 void AdvancedNotificationService::TryStartReminderAgentService()
123 {
124 auto checkCalendarFunc = []() {
125 int32_t activeUserId = 0;
126 if (OsAccountManagerHelper::GetInstance().GetCurrentActiveUserId(activeUserId) != ERR_OK) {
127 ANSR_LOGE("Failed to get active user id");
128 return false;
129 }
130 std::shared_ptr<BundleManagerHelper> bundleMgr = BundleManagerHelper::GetInstance();
131 if (bundleMgr == nullptr) {
132 ANSR_LOGE("Failed to get bundle manager");
133 return false;
134 }
135 int32_t uid = bundleMgr->GetDefaultUidByBundleName(CALENDAR_DATA_NAME, activeUserId);
136 return uid != -1;
137 };
138 if (!checkCalendarFunc()) {
139 if (access(REMINDER_DB_PATH, F_OK) != 0) {
140 ANS_LOGW("Reminder db no exist");
141 return;
142 }
143 std::string reminderAgentServiceConfig;
144 OHOS::LoadStringFromFile(REMINDER_AGENT_SERVICE_CONFIG_PATH, reminderAgentServiceConfig);
145 if (reminderAgentServiceConfig != "1") {
146 return;
147 }
148 }
149 ANS_LOGI("Reminder db exist, start reminder service");
150 ReminderHelper::StartReminderAgentService();
151 }
152 } // namespace Notification
153 } // namespace OHOS
154