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