1 /*
2  * Copyright (C) 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 "devattest_notification_publish.h"
17 
18 #include <securec.h>
19 #include "notification_helper.h"
20 #include "notification_content.h"
21 #include "notification_request.h"
22 #include "iservice_registry.h"
23 #include "os_account_manager.h"
24 #include "locale_config.h"
25 #include "devattest_log.h"
26 #include "devattest_errno.h"
27 #include "attest_entry.h"
28 
29 namespace OHOS {
30 namespace DevAttest {
31 using namespace OHOS;
32 using namespace OHOS::EventFwk;
33 using namespace std;
34 using namespace AppExecFwk;
35 
36 constexpr std::int32_t BUNDLE_MGR_SERVICE_SA_ID = 401;
37 constexpr std::int32_t INVALID_UID = -1;
38 constexpr std::int32_t LOCALE_ITEM_SIZE = 5;
39 constexpr std::int32_t PARAM_THREE = 3;
40 constexpr std::int32_t DEVATTEST_PUBLISH_NOTIFICATION_ID = 0;
41 const char* DEVATTEST_PUBLISH_BUNDLE = "com.ohos.settingsdata";
42 const char* DEVATTEST_SETTINGS_BUNDLE = "com.ohos.settings";
43 const char* DEVATTEST_CONTENT_TITLE = "OpenHarmony_Compatibility_Assessment";
44 const char* DEVATTEST_CONTENT_TEXT = "assessmentPassFailedText";
45 
DevAttestNotificationPublish()46 DevAttestNotificationPublish::DevAttestNotificationPublish()
47 {
48 }
49 
~DevAttestNotificationPublish()50 DevAttestNotificationPublish::~DevAttestNotificationPublish()
51 {
52 }
53 
PublishNotification(void)54 void DevAttestNotificationPublish::PublishNotification(void)
55 {
56     int32_t publishable = DEVATTEST_INIT;
57     int32_t ret = QueryAttestPublishable(&publishable);
58     if (ret != DEVATTEST_SUCCESS) {
59         HILOGE("[PublishNotification] QueryAttestPublishable fail");
60         return;
61     }
62     if (publishable != DEVATTEST_SUCCESS) {
63         HILOGE("[PublishNotification] No need to publish notifications");
64         return;
65     }
66 
67     ret = PublishNotificationImpl();
68     if (ret != DEVATTEST_SUCCESS) {
69         HILOGE("[PublishNotification] public notification fail");
70         return;
71     }
72     AttestPublishComplete();
73     HILOGI("[PublishNotification] publish notification success");
74     return;
75 }
76 
PublishNotificationImpl(void)77 int32_t DevAttestNotificationPublish::PublishNotificationImpl(void)
78 {
79     int32_t uid = 0;
80     std::string settingsHapPath;
81     std::string contentTitle;
82     std::string contentText;
83     if (GetDevattestBundleUid(&uid) != DEVATTEST_SUCCESS) {
84         HILOGE("[PublishNotificationImpl] failed to get uid");
85         return DEVATTEST_FAIL;
86     }
87 
88     if (GetDevattestHapPath(settingsHapPath) != DEVATTEST_SUCCESS) {
89         HILOGE("[PublishNotificationImpl] failed to get hap path");
90         return DEVATTEST_FAIL;
91     }
92 
93     if (GetDevattestContent(contentTitle, contentText, settingsHapPath) != DEVATTEST_SUCCESS) {
94         HILOGE("[PublishNotificationImpl] failed to get Content");
95         return DEVATTEST_FAIL;
96     }
97 
98     shared_ptr<Notification::NotificationNormalContent> normalContent =
99         std::make_shared<Notification::NotificationNormalContent>();
100     if (normalContent == nullptr) {
101         HILOGE("[PublishNotificationImpl] normalContent is null");
102         return DEVATTEST_FAIL;
103     }
104     normalContent->SetTitle(contentTitle);
105     normalContent->SetText(contentText);
106     shared_ptr<Notification::NotificationContent> content =
107         std::make_shared<Notification::NotificationContent>(normalContent);
108     if (content == nullptr) {
109         HILOGE("[PublishNotificationImpl] content is null");
110         return DEVATTEST_FAIL;
111     }
112     Notification::NotificationRequest request;
113     request.SetNotificationId(DEVATTEST_PUBLISH_NOTIFICATION_ID);
114     request.SetCreatorUid(uid);
115     request.SetContent(content);
116     request.SetSlotType(Notification::NotificationConstant::OTHER);
117     int32_t result = Notification::NotificationHelper::PublishNotification(request);
118     if (result != DEVATTEST_SUCCESS) {
119         HILOGE("[PublishNotificationImpl] publish result:%{public}d", result);
120         return result;
121     }
122     return DEVATTEST_SUCCESS;
123 }
124 
GetBundleMgr(void)125 sptr<IBundleMgr> DevAttestNotificationPublish::GetBundleMgr(void)
126 {
127     sptr<ISystemAbilityManager> systemAbilityManager =
128         SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager();
129     if (systemAbilityManager == nullptr) {
130         HILOGE("[GetBundleMgr] get systemAbilityManager failed");
131         return nullptr;
132     }
133     sptr<IRemoteObject> remoteObject = systemAbilityManager->GetSystemAbility(BUNDLE_MGR_SERVICE_SA_ID);
134     if (remoteObject == nullptr) {
135         HILOGE("[GetBundleMgr] get remoteObject failed");
136         return nullptr;
137     }
138     sptr<IBundleMgr> bundleMgr = iface_cast<IBundleMgr>(remoteObject);
139     if (bundleMgr == nullptr) {
140         HILOGE("[GetBundleMgr] get bundleMgr failed");
141         return nullptr;
142     }
143     return bundleMgr;
144 }
145 
GetDevattestBundleUid(int32_t* uid)146 int32_t DevAttestNotificationPublish::GetDevattestBundleUid(int32_t* uid)
147 {
148     int32_t userId = -1;
149     int32_t ret = OHOS::AccountSA::OsAccountManager::GetOsAccountLocalIdFromProcess(userId);
150     if (ret != DEVATTEST_SUCCESS) {
151         HILOGE("[GetDevattestBundleUid] GetOsAccountLocalIdFromProcess failed, ret:%{public}d", ret);
152         return DEVATTEST_FAIL;
153     }
154     sptr<IBundleMgr> bundleMgr = GetBundleMgr();
155     if (bundleMgr == nullptr) {
156         HILOGE("[GetDevattestBundleUid] GetBundleMgr failed");
157         return DEVATTEST_FAIL;
158     }
159     *uid = bundleMgr->GetUidByBundleName(std::string(DEVATTEST_PUBLISH_BUNDLE), userId);
160     if (*uid == INVALID_UID) {
161         HILOGE("[GetDevattestBundleUid] GetUidByBundleName failed");
162         return DEVATTEST_FAIL;
163     }
164     return DEVATTEST_SUCCESS;
165 }
166 
GetDevattestHapPath(std::string &settingsHapPath)167 int32_t DevAttestNotificationPublish::GetDevattestHapPath(std::string &settingsHapPath)
168 {
169     sptr<IBundleMgr> bundleMgr = GetBundleMgr();
170     if (bundleMgr == nullptr) {
171         HILOGE("[GetDevattestHapPath] GetBundleMgr failed");
172         return DEVATTEST_FAIL;
173     }
174     std::vector<int32_t> ids;
175     int32_t ret = OHOS::AccountSA::OsAccountManager::QueryActiveOsAccountIds(ids);
176     if (ret != DEVATTEST_SUCCESS) {
177         HILOGE("[GetDevattestHapPath] QueryActiveOsAccountIds failed, ret:%{public}d", ret);
178         return DEVATTEST_FAIL;
179     }
180     BundleInfo bundleInfo;
181     ret = DEVATTEST_FAIL;
182     for (int32_t id : ids) {
183         if (bundleMgr->GetBundleInfo(DEVATTEST_SETTINGS_BUNDLE, GET_BUNDLE_WITH_EXTENSION_INFO, bundleInfo, id)) {
184             ret = DEVATTEST_SUCCESS;
185             break;
186         }
187     }
188     if (ret != DEVATTEST_SUCCESS) {
189         HILOGE("[GetDevattestHapPath] GetBundleInfo failed");
190         return DEVATTEST_FAIL;
191     }
192     for (HapModuleInfo hapModuleInfo : bundleInfo.hapModuleInfos) {
193         std::string moduleResPath = hapModuleInfo.hapPath.empty() ? hapModuleInfo.resourcePath : hapModuleInfo.hapPath;
194         if (!moduleResPath.empty()) {
195             settingsHapPath = moduleResPath;
196         }
197     }
198     if (settingsHapPath.empty()) {
199         HILOGE("[GetDevattestHapPath] get setiingsHapPath failed");
200         return DEVATTEST_FAIL;
201     }
202     return DEVATTEST_SUCCESS;
203 }
204 
GetDevattestResConfig(void)205 std::shared_ptr<Global::Resource::ResConfig> DevAttestNotificationPublish::GetDevattestResConfig(void)
206 {
207     std::shared_ptr<Global::Resource::ResConfig> pResConfig(Global::Resource::CreateResConfig());
208 
209     string localeStr = Global::I18n::LocaleConfig::GetSystemLocale();
210     if (localeStr.empty()) {
211         HILOGE("[GetDevattestResConfig] failed to GetSystemLocale");
212         return nullptr;
213     }
214 
215     char language[LOCALE_ITEM_SIZE] = {0};
216     char script[LOCALE_ITEM_SIZE] = {0};
217     char region[LOCALE_ITEM_SIZE] = {0};
218     // zh-Hans-CN
219     int32_t ret = sscanf_s(localeStr.c_str(), "%[a-zA-Z]-%[a-zA-Z]-%[a-zA-Z]",
220         language, LOCALE_ITEM_SIZE,
221         script, LOCALE_ITEM_SIZE,
222         region, LOCALE_ITEM_SIZE);
223     if (ret != PARAM_THREE) {
224         HILOGE("[GetDevattestResConfig] failed to split locale locale:%{public}s", localeStr.c_str());
225         return nullptr;
226     }
227 
228     Global::Resource::RState state = pResConfig->SetLocaleInfo(language, script, region);
229     if (state != Global::Resource::RState::SUCCESS) {
230         HILOGE("[GetDevattestResConfig] failed to SetLocaleInfo state:%{public}d", state);
231         return nullptr;
232     }
233     return pResConfig;
234 }
235 
GetDevattestContent(std::string &title, std::string &text, std::string &settingsHapPath)236 int32_t DevAttestNotificationPublish::GetDevattestContent(std::string &title,
237     std::string &text, std::string &settingsHapPath)
238 {
239     std::shared_ptr<Global::Resource::ResourceManager> pResMgr(Global::Resource::CreateResourceManager());
240     if (pResMgr == nullptr) {
241         HILOGE("[GetDevattestContent] get resourceManager failed");
242         return DEVATTEST_FAIL;
243     }
244 
245     if (!pResMgr->AddResource(settingsHapPath.c_str())) {
246         HILOGE("[GetDevattestContent] failed to AddResource");
247         return DEVATTEST_FAIL;
248     }
249 
250     std::shared_ptr<Global::Resource::ResConfig> pResConfig = GetDevattestResConfig();
251     Global::Resource::RState state = pResMgr->UpdateResConfig(*pResConfig);
252     if (state != Global::Resource::RState::SUCCESS) {
253         HILOGE("[GetDevattestContent] failed to UpdateResConfig state:%{public}d", state);
254         return DEVATTEST_FAIL;
255     }
256 
257     state = pResMgr->GetStringByName(DEVATTEST_CONTENT_TITLE, title);
258     if (state != Global::Resource::RState::SUCCESS) {
259         HILOGE("[GetDevattestContent] failed to get title form resource state:%{public}d", state);
260         return DEVATTEST_FAIL;
261     }
262 
263     state = pResMgr->GetStringByName(DEVATTEST_CONTENT_TEXT, text);
264     if (state != Global::Resource::RState::SUCCESS) {
265         HILOGE("[GetDevattestContent] failed to get text form resource state:%{public}d", state);
266         return DEVATTEST_FAIL;
267     }
268     return DEVATTEST_SUCCESS;
269 }
270 } // DevAttest
271 } // OHOS
272 
273