1 /*
2  * Copyright (c) 2021 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 #include <dlfcn.h>
16 #include <string>
17 
18 #include "advanced_notification_service.h"
19 #include "notification_extension_wrapper.h"
20 #include "notification_preferences.h"
21 #include "advanced_datashare_observer.h"
22 #include "common_event_manager.h"
23 #include "common_event_support.h"
24 
25 #include "common_event_subscriber.h"
26 #include "system_event_observer.h"
27 
28 namespace OHOS::Notification {
29 const std::string EXTENTION_WRAPPER_PATH = "libans_ext.z.so";
30 const int32_t ACTIVE_DELETE = 0;
31 const int32_t PASSITIVE_DELETE = 1;
32 static constexpr const char *SETTINGS_DATA_UNIFIED_GROUP_ENABLE_URI =
33     "datashare:///com.ohos.settingsdata/entry/settingsdata/"
34     "USER_SETTINGSDATA_SECURE_100?Proxy=true&key=unified_group_enable";
35 ExtensionWrapper::ExtensionWrapper() = default;
36 ExtensionWrapper::~ExtensionWrapper() = default;
37 
38 
39 #ifdef __cplusplus
40 extern "C" {
41 #endif
42 
UpdateUnifiedGroupInfo(const std::string &key, std::shared_ptr<NotificationUnifiedGroupInfo> &groupInfo)43 void UpdateUnifiedGroupInfo(const std::string &key, std::shared_ptr<NotificationUnifiedGroupInfo> &groupInfo)
44 {
45     AdvancedNotificationService::GetInstance()->UpdateUnifiedGroupInfo(key, groupInfo);
46 }
47 
48 #ifdef __cplusplus
49 }
50 #endif
51 
InitExtentionWrapper()52 void ExtensionWrapper::InitExtentionWrapper()
53 {
54     extensionWrapperHandle_ = dlopen(EXTENTION_WRAPPER_PATH.c_str(), RTLD_NOW);
55     if (extensionWrapperHandle_ == nullptr) {
56         ANS_LOGE("extension wrapper symbol failed, error: %{public}s", dlerror());
57         return;
58     }
59 
60     syncAdditionConfig_ = (SYNC_ADDITION_CONFIG)dlsym(extensionWrapperHandle_, "SyncAdditionConfig");
61     localControl_ = (LOCAL_CONTROL)dlsym(extensionWrapperHandle_, "LocalControl");
62     reminderControl_ = (REMINDER_CONTROL)dlsym(extensionWrapperHandle_, "ReminderControl");
63     bannerControl_ = (BANNER_CONTROL)dlsym(extensionWrapperHandle_, "BannerControl");
64     if (syncAdditionConfig_ == nullptr || bannerControl_ == nullptr
65         || localControl_ == nullptr
66         || reminderControl_ == nullptr) {
67         ANS_LOGE("extension wrapper symbol failed, error: %{public}s", dlerror());
68         return;
69     }
70 
71     std::string ctrlConfig = NotificationPreferences::GetInstance()->GetAdditionalConfig("NOTIFICATION_CTL_LIST_PKG");
72     if (!ctrlConfig.empty()) {
73         syncAdditionConfig_("NOTIFICATION_CTL_LIST_PKG", ctrlConfig);
74     }
75 
76     std::string aggregateConfig = NotificationPreferences::GetInstance()->GetAdditionalConfig("AGGREGATE_CONFIG");
77     if (!aggregateConfig.empty()) {
78         syncAdditionConfig_("AGGREGATE_CONFIG", aggregateConfig);
79     }
80     if (initSummary_ != nullptr) {
81         initSummary_(UpdateUnifiedGroupInfo);
82     }
83     ANS_LOGD("extension wrapper init success");
84 }
85 
CheckIfSetlocalSwitch()86 void ExtensionWrapper::CheckIfSetlocalSwitch()
87 {
88     ANS_LOGD("CheckIfSetlocalSwitch enter");
89     if (extensionWrapperHandle_ == nullptr) {
90         return;
91     }
92     if (!isRegisterDataSettingObserver) {
93         RegisterDataSettingObserver();
94         isRegisterDataSettingObserver = true;
95     }
96     std::string enable = "";
97     AdvancedNotificationService::GetInstance()->GetUnifiedGroupInfoFromDb(enable);
98     SetlocalSwitch(enable);
99 }
100 
SetlocalSwitch(std::string &enable)101 void ExtensionWrapper::SetlocalSwitch(std::string &enable)
102 {
103     if (setLocalSwitch_ == nullptr) {
104         return;
105     }
106     bool status = (enable == "false" ? false : true);
107     setLocalSwitch_(status);
108 }
109 
RegisterDataSettingObserver()110 void ExtensionWrapper::RegisterDataSettingObserver()
111 {
112     ANS_LOGD("ExtensionWrapper::RegisterDataSettingObserver enter");
113     sptr<AdvancedAggregationDataRoamingObserver> aggregationRoamingObserver;
114     if (aggregationRoamingObserver == nullptr) {
115         aggregationRoamingObserver = new (std::nothrow) AdvancedAggregationDataRoamingObserver();
116     }
117 
118     if (aggregationRoamingObserver == nullptr) {
119         return;
120     }
121 
122     Uri dataEnableUri(SETTINGS_DATA_UNIFIED_GROUP_ENABLE_URI);
123     AdvancedDatashareObserver::GetInstance().RegisterSettingsObserver(dataEnableUri, aggregationRoamingObserver);
124 }
125 
SyncAdditionConfig(const std::string& key, const std::string& value)126 ErrCode ExtensionWrapper::SyncAdditionConfig(const std::string& key, const std::string& value)
127 {
128     if (syncAdditionConfig_ == nullptr) {
129         ANS_LOGE("syncAdditionConfig wrapper symbol failed");
130         return 0;
131     }
132     return syncAdditionConfig_(key, value);
133 }
134 
UpdateByCancel(const std::vector<sptr<Notification>>& notifications, int deleteReason)135 void ExtensionWrapper::UpdateByCancel(const std::vector<sptr<Notification>>& notifications, int deleteReason)
136 {
137     if (updateByCancel_ == nullptr) {
138         return;
139     }
140     int32_t deleteType = convertToDelType(deleteReason);
141     updateByCancel_(notifications, deleteType);
142 }
143 
GetUnifiedGroupInfo(const sptr<NotificationRequest> &request)144 ErrCode ExtensionWrapper::GetUnifiedGroupInfo(const sptr<NotificationRequest> &request)
145 {
146     if (getUnifiedGroupInfo_ == nullptr) {
147         return 0;
148     }
149     return getUnifiedGroupInfo_(request);
150 }
151 
ReminderControl(const std::string &bundleName)152 int32_t ExtensionWrapper::ReminderControl(const std::string &bundleName)
153 {
154     if (reminderControl_ == nullptr) {
155         ANS_LOGE("ReminderControl wrapper symbol failed");
156         return 0;
157     }
158     return reminderControl_(bundleName);
159 }
160 
BannerControl(const std::string &bundleName)161 int32_t ExtensionWrapper::BannerControl(const std::string &bundleName)
162 {
163     if (bannerControl_ == nullptr) {
164         ANS_LOGE("ReminderControl wrapper symbol failed");
165         return -1;
166     }
167     return bannerControl_(bundleName);
168 }
169 
LocalControl(const sptr<NotificationRequest> &request)170 __attribute__((no_sanitize("cfi"))) int32_t ExtensionWrapper::LocalControl(const sptr<NotificationRequest> &request)
171 {
172     if (localControl_ == nullptr) {
173         ANS_LOGE("LocalControl wrapper symbol failed");
174         return 0;
175     }
176     return localControl_(request);
177 }
178 
UpdateByBundle(const std::string bundleName, int deleteReason)179 void ExtensionWrapper::UpdateByBundle(const std::string bundleName, int deleteReason)
180 {
181     if (updateByBundle_ == nullptr) {
182         return;
183     }
184     int32_t deleteType = convertToDelType(deleteReason);
185     updateByBundle_(bundleName, deleteType);
186 }
187 
convertToDelType(int32_t deleteReason)188 int32_t ExtensionWrapper::convertToDelType(int32_t deleteReason)
189 {
190     int32_t delType = ACTIVE_DELETE;
191     switch (deleteReason) {
192         case NotificationConstant::PACKAGE_CHANGED_REASON_DELETE:
193         case NotificationConstant::USER_REMOVED_REASON_DELETE:
194         case NotificationConstant::DISABLE_SLOT_REASON_DELETE:
195         case NotificationConstant::DISABLE_NOTIFICATION_REASON_DELETE:
196             delType = PASSITIVE_DELETE;
197             break;
198         default:
199             delType = ACTIVE_DELETE;
200     }
201 
202     ANS_LOGD("convertToDelType from delete reason %d to delete type %d", deleteReason, delType);
203     return delType;
204 }
205 } // namespace OHOS::Notification
206