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 || want == nullptr) {
194 USB_HILOGE(MODULE_USB_SERVICE, "notification content nullptr or want nulllptr");
195 want.reset();
196 content.reset();
197 return;
198 }
199 GetFilemanagerBundleName();
200 want->SetElementName(filemanagerBundleName, filemanagerAbilityName);
201 std::vector<std::shared_ptr<OHOS::AAFwk::Want>> wants;
202 wants.push_back(want);
203 std::vector<OHOS::AbilityRuntime::WantAgent::WantAgentConstant::Flags> flags;
204 flags.push_back(OHOS::AbilityRuntime::WantAgent::WantAgentConstant::Flags::UPDATE_PRESENT_FLAG);
205 OHOS::AbilityRuntime::WantAgent::WantAgentInfo wantAgentInfo(
206 REQUEST_CODE,
207 AbilityRuntime::WantAgent::WantAgentConstant::OperationType::START_ABILITY,
208 flags, wants, nullptr
209 );
210 auto wantAgent = OHOS::AbilityRuntime::WantAgent::WantAgentHelper::GetWantAgent(wantAgentInfo);
211 std::string buttonTitle = notificationMap[MASS_STORAGE_NOTIFICATION_BUTTON_KEY];
212 std::shared_ptr<OHOS::Notification::NotificationActionButton> actionButton =
213 OHOS::Notification::NotificationActionButton::Create(nullptr, buttonTitle, wantAgent);
214 if (actionButton == nullptr) {
215 USB_HILOGE(MODULE_USB_SERVICE, "notification actionButton nullptr");
216 return;
217 }
218 OHOS::Notification::NotificationRequest request;
219 request.SetNotificationId(MASS_STORAGE_NOTIFICATION_ID);
220 request.SetContent(content);
221 request.AddActionButton(actionButton);
222 request.SetCreatorUid(USB_SYSTEM_ABILITY_ID);
223 request.SetCreatorBundleName(filemanagerBundleName);
224 request.SetCreatorUserId(osAccountId);
225 request.SetLabel(notificationMap[MASS_STORAGE_NOTIFICATION_LABEL_KEY]);
226 request.SetSlotType(OHOS::Notification::NotificationConstant::SlotType::SOCIAL_COMMUNICATION);
227 int32_t result = OHOS::Notification::NotificationHelper::PublishNotification(request);
228 USB_HILOGI(MODULE_USB_SERVICE, "publish mass storage notification result : %{public}d", result);
229 }
230
CancelNotification(const std::map<std::string,UsbDevice * > & devices,const UsbDevice & dev,const std::string & name)231 void UsbMassStorageNotification::CancelNotification(const std::map<std::string, UsbDevice *> &devices,
232 const UsbDevice &dev, const std::string &name)
233 {
234 if (!IsMassStorage(dev)) {
235 USB_HILOGD(MODULE_USB_SERVICE, "Cancel Notification, not Mass Storage, return!");
236 return;
237 }
238 for (auto it : devices) {
239 UsbDevice *device = it.second;
240 if (device == nullptr) {
241 continue;
242 }
243 if ((it.first != name) && IsMassStorage(*device)) {
244 USB_HILOGD(MODULE_USB_SERVICE, "Cancel Notification, still has other Mass Storage, return!");
245 return;
246 }
247 }
248 int32_t result = OHOS::Notification::NotificationHelper::CancelNotification(MASS_STORAGE_NOTIFICATION_ID);
249 USB_HILOGI(MODULE_USB_SERVICE, "Cancel mass storage notification result : %{public}d", result);
250 }
251 } // namespace USB
252 } // namespace OHOS
253