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 "usb_mass_storage_notification.h"
17 #include <parameters.h>
18 #include "hilog_wrapper.h"
19 #include "want_agent_info.h"
20 #include "want_agent_helper.h"
21 #include "notification_normal_content.h"
22 #include "notification_helper.h"
23 #include "notification_content.h"
24 #include "notification_request.h"
25 #include "resource_manager.h"
26 #include "locale_config.h"
27 #include "locale_info.h"
28 #include "string_wrapper.h"
29 #include "iservice_registry.h"
30 #include "bundle_mgr_interface.h"
31 #include "system_ability_definition.h"
32 #include "os_account_manager.h"
33 #include "usb_errors.h"
34
35 using namespace OHOS::AAFwk;
36
37 namespace OHOS {
38 namespace USB {
39 namespace {
40 constexpr int16_t USB_DEVICE_CLASS_MASS_STORAGE = 8;
41 constexpr int16_t MASS_STORAGE_NOTIFICATION_ID = 100;
42 constexpr int32_t REQUEST_CODE = 10;
43 constexpr int32_t GET_APP_INFO_FLAG = 0;
44 const std::string FILEMANAGER_BUNDLE_NAME_KEY = "hmos.filemanager";
45 const std::string FILES_BUNDLE_NAME_KEY = "hmos.files";
46 const std::string FILES_ABILITY_NAME = "EntryAbility";
47 const std::string HAP_PATH = "/system/app/usb_right_dialog/usb_right_dialog.hap";
48 } // namespace
49
50 std::shared_ptr<UsbMassStorageNotification> UsbMassStorageNotification::instance_ = nullptr;
51
GetInstance()52 std::shared_ptr<UsbMassStorageNotification> UsbMassStorageNotification::GetInstance()
53 {
54 if (instance_ == nullptr) {
55 USB_HILOGI(MODULE_USB_SERVICE, "reset to new instance");
56 instance_.reset(new UsbMassStorageNotification());
57 }
58 return instance_;
59 }
60
UsbMassStorageNotification()61 UsbMassStorageNotification::UsbMassStorageNotification()
62 {
63 GetHapString();
64 }
65
~UsbMassStorageNotification()66 UsbMassStorageNotification::~UsbMassStorageNotification() {}
67
GetHapString()68 void UsbMassStorageNotification::GetHapString()
69 {
70 std::shared_ptr<Global::Resource::ResourceManager> resourceManager(Global::Resource::CreateResourceManager());
71 if (resourceManager == nullptr) {
72 USB_HILOGE(MODULE_USB_SERVICE, "resourceManager is null");
73 return;
74 }
75 std::unique_ptr<Global::Resource::ResConfig> resConfig(Global::Resource::CreateResConfig());
76 if (resConfig == nullptr) {
77 USB_HILOGE(MODULE_USB_SERVICE, "resConfig is null");
78 return;
79 }
80 std::map<std::string, std::string> configs;
81 OHOS::Global::I18n::LocaleInfo locale(Global::I18n::LocaleConfig::GetSystemLocale(), configs);
82 resConfig->SetLocaleInfo(locale.GetLanguage().c_str(), locale.GetScript().c_str(), locale.GetRegion().c_str());
83 resourceManager->UpdateResConfig(*resConfig);
84 if (!resourceManager->AddResource(HAP_PATH.c_str())) {
85 USB_HILOGE(MODULE_USB_SERVICE, "AddResource failed");
86 return;
87 }
88 for (auto it : notificationMap) {
89 std::string outValue;
90 resourceManager->GetStringByName(it.first.c_str(), outValue);
91 notificationMap[it.first] = outValue;
92 }
93 return;
94 }
95
GetFilemanagerBundleName()96 void UsbMassStorageNotification::GetFilemanagerBundleName()
97 {
98 auto sam = SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager();
99 if (sam == nullptr) {
100 USB_HILOGW(MODULE_USB_SERVICE, "GetSystemAbilityManager return nullptr");
101 return;
102 }
103 auto bundleMgrSa = sam->GetSystemAbility(BUNDLE_MGR_SERVICE_SYS_ABILITY_ID);
104 if (bundleMgrSa == nullptr) {
105 USB_HILOGW(MODULE_USB_SERVICE, "GetSystemAbility return nullptr");
106 return;
107 }
108 auto bundleMgr = iface_cast<OHOS::AppExecFwk::IBundleMgr>(bundleMgrSa);
109 if (bundleMgr == nullptr) {
110 USB_HILOGW(MODULE_USB_SERVICE, "iface_cast return nullptr");
111 return;
112 }
113
114 std::vector<int> activatedOsAccountIds;
115 int32_t res = OHOS::AccountSA::OsAccountManager::QueryActiveOsAccountIds(activatedOsAccountIds);
116 if ((res != UEC_OK) || (activatedOsAccountIds.size() <= 0)) {
117 USB_HILOGW(MODULE_USB_SERVICE, "QueryActiveOsAccountIds fail. : %{public}d", res);
118 } else {
119 osAccountId = activatedOsAccountIds[0];
120 }
121
122 std::vector<OHOS::AppExecFwk::ApplicationInfo> appInfos {};
123 if (!bundleMgr->GetApplicationInfos(OHOS::AppExecFwk::ApplicationFlag::GET_BASIC_APPLICATION_INFO,
124 osAccountId, appInfos)) {
125 USB_HILOGW(MODULE_USB_SERVICE, "BundleMgr GetApplicationInfos failed");
126 return;
127 }
128 OHOS::AppExecFwk::ApplicationInfo appInfoTemp;
129 for (auto const &appInfo : appInfos) {
130 size_t start_pos = appInfo.bundleName.find(FILEMANAGER_BUNDLE_NAME_KEY);
131 if (start_pos != std::string::npos) {
132 filemanagerBundleName = appInfo.bundleName;
133 std::string bundleNameTemp = appInfo.bundleName;
134 int32_t resultCode = bundleMgr->GetApplicationInfoV9(bundleNameTemp.replace(
135 start_pos, FILEMANAGER_BUNDLE_NAME_KEY.length(), FILES_BUNDLE_NAME_KEY),
136 GET_APP_INFO_FLAG, osAccountId, appInfoTemp);
137 USB_HILOGD(MODULE_USB_SERVICE, "GetApplicationInfoV9 resultCode %{public}d", resultCode);
138 if (resultCode == ERR_OK) {
139 filemanagerBundleName = appInfoTemp.bundleName;
140 filemanagerAbilityName = FILES_ABILITY_NAME;
141 }
142 return;
143 }
144 }
145 return;
146 }
147
IsMassStorage(const UsbDevice &dev)148 bool UsbMassStorageNotification::IsMassStorage(const UsbDevice &dev)
149 {
150 for (int32_t i = 0; i < dev.GetConfigCount(); ++i) {
151 USBConfig config;
152 dev.GetConfig(i, config);
153 for (uint32_t j = 0; j < config.GetInterfaceCount(); ++j) {
154 UsbInterface interface;
155 config.GetInterface(j, interface);
156 if (interface.GetClass() == USB_DEVICE_CLASS_MASS_STORAGE) {
157 return true;
158 }
159 }
160 }
161 return false;
162 }
163
SendNotification(const UsbDevice &dev)164 void UsbMassStorageNotification::SendNotification(const UsbDevice &dev)
165 {
166 USB_HILOGD(MODULE_USB_SERVICE, "enter SendNotification");
167 if (!IsMassStorage(dev)) {
168 USB_HILOGD(MODULE_USB_SERVICE, "Send Notification, not Mass Storage, return!");
169 return;
170 }
171 if (notificationMap[MASS_STORAGE_NOTIFICATION_TITLE_KEY].empty() ||
172 notificationMap[MASS_STORAGE_NOTIFICATION_TEXT_KEY].empty() ||
173 notificationMap[MASS_STORAGE_NOTIFICATION_BUTTON_KEY].empty()) {
174 USB_HILOGE(MODULE_USB_SERVICE, "notificationMap is empty, return!");
175 return;
176 }
177 PublishUsbNotification();
178 }
179
PublishUsbNotification()180 void UsbMassStorageNotification::PublishUsbNotification()
181 {
182 std::shared_ptr<OHOS::Notification::NotificationNormalContent> normalContent =
183 std::make_shared<OHOS::Notification::NotificationNormalContent>();
184 if (normalContent == nullptr) {
185 USB_HILOGE(MODULE_USB_SERVICE, "notification normal content nullptr");
186 return;
187 }
188 normalContent->SetTitle(notificationMap[MASS_STORAGE_NOTIFICATION_TITLE_KEY]);
189 normalContent->SetText(notificationMap[MASS_STORAGE_NOTIFICATION_TEXT_KEY]);
190 std::shared_ptr<OHOS::Notification::NotificationContent> content =
191 std::make_shared<OHOS::Notification::NotificationContent>(normalContent);
192 auto want = std::make_shared<OHOS::AAFwk::Want>();
193 if (content == nullptr) {
194 USB_HILOGE(MODULE_USB_SERVICE, "notification content is nullptr");
195 return;
196 }
197 GetFilemanagerBundleName();
198 want->SetElementName(filemanagerBundleName, filemanagerAbilityName);
199 std::vector<std::shared_ptr<OHOS::AAFwk::Want>> wants;
200 wants.push_back(want);
201 std::vector<OHOS::AbilityRuntime::WantAgent::WantAgentConstant::Flags> flags;
202 flags.push_back(OHOS::AbilityRuntime::WantAgent::WantAgentConstant::Flags::UPDATE_PRESENT_FLAG);
203 OHOS::AbilityRuntime::WantAgent::WantAgentInfo wantAgentInfo(
204 REQUEST_CODE,
205 AbilityRuntime::WantAgent::WantAgentConstant::OperationType::START_ABILITY,
206 flags, wants, nullptr
207 );
208 auto wantAgent = OHOS::AbilityRuntime::WantAgent::WantAgentHelper::GetWantAgent(wantAgentInfo);
209 std::string buttonTitle = notificationMap[MASS_STORAGE_NOTIFICATION_BUTTON_KEY];
210 std::shared_ptr<OHOS::Notification::NotificationActionButton> actionButton =
211 OHOS::Notification::NotificationActionButton::Create(nullptr, buttonTitle, wantAgent);
212 if (actionButton == nullptr) {
213 USB_HILOGE(MODULE_USB_SERVICE, "notification actionButton nullptr");
214 return;
215 }
216 OHOS::Notification::NotificationRequest request;
217 request.SetNotificationId(MASS_STORAGE_NOTIFICATION_ID);
218 request.SetContent(content);
219 request.AddActionButton(actionButton);
220 request.SetCreatorUid(USB_SYSTEM_ABILITY_ID);
221 request.SetCreatorBundleName(filemanagerBundleName);
222 request.SetCreatorUserId(osAccountId);
223 request.SetLabel(notificationMap[MASS_STORAGE_NOTIFICATION_LABEL_KEY]);
224 request.SetSlotType(OHOS::Notification::NotificationConstant::SlotType::SOCIAL_COMMUNICATION);
225 int32_t result = OHOS::Notification::NotificationHelper::PublishNotification(request);
226 USB_HILOGI(MODULE_USB_SERVICE, "publish mass storage notification result : %{public}d", result);
227 }
228
CancelNotification(const std::map<std::string, UsbDevice *> &devices, const UsbDevice &dev, const std::string &name)229 void UsbMassStorageNotification::CancelNotification(const std::map<std::string, UsbDevice *> &devices,
230 const UsbDevice &dev, const std::string &name)
231 {
232 if (!IsMassStorage(dev)) {
233 USB_HILOGD(MODULE_USB_SERVICE, "Cancel Notification, not Mass Storage, return!");
234 return;
235 }
236 for (auto it : devices) {
237 UsbDevice *device = it.second;
238 if (device == nullptr) {
239 continue;
240 }
241 if ((it.first != name) && IsMassStorage(*device)) {
242 USB_HILOGD(MODULE_USB_SERVICE, "Cancel Notification, still has other Mass Storage, return!");
243 return;
244 }
245 }
246 int32_t result = OHOS::Notification::NotificationHelper::CancelNotification(MASS_STORAGE_NOTIFICATION_ID);
247 USB_HILOGI(MODULE_USB_SERVICE, "Cancel mass storage notification result : %{public}d", result);
248 }
249 } // namespace USB
250 } // namespace OHOS
251