• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2024 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 #ifndef LOG_TAG
16 #define LOG_TAG "AudioSafeVolumeNotificationImpl"
17 #endif
18 
19 #include "audio_safe_volume_notification_impl.h"
20 
21 #include <map>
22 
23 #include "want_agent_helper.h"
24 #include "want_agent_info.h"
25 #include "notification_helper.h"
26 #include "notification_request.h"
27 #include "notification_constant.h"
28 #include "notification_bundle_option.h"
29 #include "rstate.h"
30 #include "ipc_skeleton.h"
31 #include "audio_policy_log.h"
32 #include "os_account_manager.h"
33 #include "locale_config.h"
34 #include "resource_manager_adapter.h"
35 
36 namespace OHOS {
37 namespace AudioStandard {
GetSystemStringByName(std::string name)38 std::string AudioSafeVolumeNotificationImpl::GetSystemStringByName(std::string name)
39 {
40     std::string identity = IPCSkeleton::ResetCallingIdentity();
41     std::string result = ResourceManagerAdapter::GetInstance()->GetSystemStringByName(name);
42     IPCSkeleton::SetCallingIdentity(identity);
43     return result;
44 }
45 
SetTitleAndText(int32_t notificationId,std::shared_ptr<Notification::NotificationNormalContent> content)46 bool AudioSafeVolumeNotificationImpl::SetTitleAndText(int32_t notificationId,
47     std::shared_ptr<Notification::NotificationNormalContent> content)
48 {
49     if (content == nullptr) {
50         AUDIO_ERR_LOG("notification normal content nullptr");
51         return false;
52     }
53 
54     switch (notificationId) {
55         case RESTORE_VOLUME_NOTIFICATION_ID:
56             content->SetTitle(GetSystemStringByName(SAFE_VOLUME_MUSIC_TIMER_TITTLE_ID));
57             content->SetText(GetSystemStringByName(SAFE_VOLUME_MUSIC_TIMER_TEXT_ID));
58             break;
59         case INCREASE_VOLUME_NOTIFICATION_ID:
60             content->SetTitle(GetSystemStringByName(SAFE_VOLUME_INCREASE_VOLUME_TITTLE_ID));
61             content->SetText(GetSystemStringByName(SAFE_VOLUME_INCREASE_VOLUME_TEXT_ID));
62             break;
63         default:
64             AUDIO_ERR_LOG("error notificationId");
65             return false;
66     }
67     return true;
68 }
69 
GetButtonName(uint32_t notificationId)70 std::string AudioSafeVolumeNotificationImpl::GetButtonName(uint32_t notificationId)
71 {
72     std::string buttonName;
73 
74     switch (notificationId) {
75         case RESTORE_VOLUME_NOTIFICATION_ID:
76             AUDIO_INFO_LOG("GetButtonName RESTORE_VOLUME_NOTIFICATION_ID.");
77             buttonName = GetSystemStringByName(SAFE_VOLUME_RESTORE_VOL_BUTTON_ID);
78             break;
79         case INCREASE_VOLUME_NOTIFICATION_ID:
80             AUDIO_INFO_LOG("GetButtonName INCREASE_VOLUME_NOTIFICATION_ID.");
81             buttonName = GetSystemStringByName(SAFE_VOLUME_INCREASE_VOL_BUTTON_ID);
82             break;
83         default:
84             AUDIO_ERR_LOG("resource name is error.");
85             return buttonName;
86     }
87     return buttonName;
88 }
89 
SetActionButton(int32_t notificationId,const std::string & buttonName,Notification::NotificationRequest & request)90 static void SetActionButton(int32_t notificationId, const std::string& buttonName,
91     Notification::NotificationRequest& request)
92 {
93     auto want = std::make_shared<AAFwk::Want>();
94     if (notificationId == RESTORE_VOLUME_NOTIFICATION_ID) {
95         AUDIO_INFO_LOG("SetActionButton AUDIO_RESTORE_VOLUME_EVENT.");
96         want->SetAction(AUDIO_RESTORE_VOLUME_EVENT);
97     } else {
98         AUDIO_INFO_LOG("SetActionButton AUDIO_INCREASE_VOLUME_EVENT.");
99         want->SetAction(AUDIO_INCREASE_VOLUME_EVENT);
100     }
101     std::vector<std::shared_ptr<AAFwk::Want>> wants;
102     wants.push_back(want);
103     std::vector<AbilityRuntime::WantAgent::WantAgentConstant::Flags> flags;
104     flags.push_back(AbilityRuntime::WantAgent::WantAgentConstant::Flags::CONSTANT_FLAG);
105     AbilityRuntime::WantAgent::WantAgentInfo wantAgentInfo(
106         0, AbilityRuntime::WantAgent::WantAgentConstant::OperationType::SEND_COMMON_EVENT,
107         flags, wants, nullptr
108     );
109     auto wantAgentDeal = AbilityRuntime::WantAgent::WantAgentHelper::GetWantAgent(wantAgentInfo);
110     std::shared_ptr<Notification::NotificationActionButton> actionButtonDeal =
111         Notification::NotificationActionButton::Create(nullptr, buttonName, wantAgentDeal);
112     if (actionButtonDeal == nullptr) {
113         AUDIO_ERR_LOG("get notification actionButton nullptr");
114         return;
115     }
116     AUDIO_INFO_LOG("SetActionButton AddActionButton.");
117     request.AddActionButton(actionButtonDeal);
118 }
119 
SetExtraParam(int32_t notificationId,Notification::NotificationRequest & request)120 static void SetExtraParam(int32_t notificationId, Notification::NotificationRequest& request)
121 {
122     std::shared_ptr<AAFwk::WantParams> wantParams = std::make_shared<AAFwk::WantParams>();
123     if (notificationId == RESTORE_VOLUME_NOTIFICATION_ID) {
124         AUDIO_INFO_LOG("SetExtraParam AUDIO_RESTORE_VOLUME_EVENT.");
125         wantParams->SetParam(SAVE_VOLUME_SYS_ABILITY_NAME, AAFwk::String::Box(AUDIO_RESTORE_VOLUME_EVENT));
126     } else {
127         AUDIO_INFO_LOG("SetExtraParam AUDIO_INCREASE_VOLUME_EVENT.");
128         wantParams->SetParam(SAVE_VOLUME_SYS_ABILITY_NAME, AAFwk::String::Box(AUDIO_INCREASE_VOLUME_EVENT));
129     }
130 
131     request.SetAdditionalData(wantParams);
132 }
133 
GetPixelMap()134 bool AudioSafeVolumeNotificationImpl::GetPixelMap()
135 {
136     if (iconPixelMap_ != nullptr) {
137         AUDIO_ERR_LOG("icon pixel map already exists.");
138         return false;
139     }
140 
141     std::unique_ptr<uint8_t[]> resourceData;
142     size_t resourceDataLength = 0;
143     auto ret = GetMediaDataByName(SAFE_VOLUME_ICON_ID, resourceDataLength, resourceData);
144     if (ret != Global::Resource::RState::SUCCESS) {
145         AUDIO_ERR_LOG("get (%{public}s) failed, errorCode:%{public}d", SAFE_VOLUME_ICON_ID.c_str(),
146             static_cast<int32_t>(ret));
147         return false;
148     }
149 
150     Media::SourceOptions opts;
151     uint32_t errorCode = 0;
152     std::unique_ptr<Media::ImageSource> imageSource =
153         Media::ImageSource::CreateImageSource(resourceData.get(), resourceDataLength, opts, errorCode);
154     Media::DecodeOptions decodeOpts;
155     decodeOpts.desiredSize = {ICON_WIDTH, ICON_HEIGHT};
156     decodeOpts.desiredPixelFormat = Media::PixelFormat::BGRA_8888;
157     if (imageSource) {
158         AUDIO_INFO_LOG("GetPixelMap SUCCESS.");
159         auto pixelMapPtr = imageSource->CreatePixelMap(decodeOpts, errorCode);
160         iconPixelMap_ = std::shared_ptr<Media::PixelMap>(pixelMapPtr.release());
161     }
162     if (errorCode != 0 || (iconPixelMap_ == nullptr)) {
163         AUDIO_ERR_LOG("get badge failed, errorCode:%{public}u", errorCode);
164         return false;
165     }
166     return true;
167 }
168 
SetBasicOption(int32_t notificationId,Notification::NotificationRequest & request)169 static void SetBasicOption(int32_t notificationId, Notification::NotificationRequest &request)
170 {
171     request.SetCreatorUid(SAVE_VOLUME_SYS_ABILITY_ID);
172     Notification::NotificationBundleOption bundle(SAVE_VOLUME_SYS_ABILITY_NAME, SAVE_VOLUME_SYS_ABILITY_ID);
173     Notification::NotificationHelper::SetNotificationSlotFlagsAsBundle(bundle, NOTIFICATION_BANNER_FLAG);
174     int32_t userId;
175     AccountSA::OsAccountManager::GetOsAccountLocalIdFromUid(SAVE_VOLUME_SYS_ABILITY_ID, userId);
176     request.SetCreatorUserId(userId);
177     request.SetCreatorPid(getpid());
178     request.SetAutoDeletedTime(OHOS::Notification::NotificationConstant::INVALID_AUTO_DELETE_TIME);
179     request.SetTapDismissed(false);
180     request.SetSlotType(OHOS::Notification::NotificationConstant::SlotType::SOCIAL_COMMUNICATION);
181     if (notificationId == RESTORE_VOLUME_NOTIFICATION_ID) {
182         request.SetNotificationControlFlags(NOTIFICATION_BANNER_FLAG);
183     } else {
184         request.SetNotificationControlFlags(NOTIFICATION_BANNER_FLAG | NOTIFICATION_CLOSE_SOUND_FLAG);
185     }
186 }
187 
PublishSafeVolumeNotification(int32_t notificationId)188 void AudioSafeVolumeNotificationImpl::PublishSafeVolumeNotification(int32_t notificationId)
189 {
190     std::shared_ptr<Notification::NotificationNormalContent> normalContent =
191         std::make_shared<Notification::NotificationNormalContent>();
192     if (normalContent == nullptr) {
193         AUDIO_ERR_LOG("get notification normal content nullptr");
194         return;
195     }
196 
197     if (!SetTitleAndText(notificationId, normalContent)) {
198         AUDIO_ERR_LOG("error setting title and text");
199         return;
200     }
201 
202     std::shared_ptr<Notification::NotificationContent> content =
203         std::make_shared<Notification::NotificationContent>(normalContent);
204 
205     if (content == nullptr) {
206         AUDIO_ERR_LOG("get notification content nullptr");
207         return;
208     }
209 
210     Notification::NotificationRequest request;
211     SetBasicOption(notificationId, request);
212     request.SetContent(content);
213     request.SetNotificationId(notificationId);
214     GetPixelMap();
215     if (iconPixelMap_ != nullptr) {
216         request.SetLittleIcon(iconPixelMap_);
217         request.SetBadgeIconStyle(Notification::NotificationRequest::BadgeStyle::LITTLE);
218     }
219 
220     std::string buttonName = GetButtonName(notificationId);
221     if (!buttonName.empty()) {
222         SetActionButton(notificationId, buttonName, request);
223     }
224 
225     SetExtraParam(notificationId, request);
226 
227     auto ret = Notification::NotificationHelper::PublishNotification(request);
228     AUDIO_INFO_LOG("safe volume service publish notification result = %{public}d", ret);
229 }
230 
CancelSafeVolumeNotification(int32_t notificationId)231 void AudioSafeVolumeNotificationImpl::CancelSafeVolumeNotification(int32_t notificationId)
232 {
233     auto ret = Notification::NotificationHelper::CancelNotification(notificationId);
234     AUDIO_INFO_LOG("safe volume service cancel notification result = %{public}d", ret);
235 
236     std::string identity = IPCSkeleton::ResetCallingIdentity();
237     ResourceManagerAdapter::GetInstance()->ReleaseSystemResourceManager();
238     IPCSkeleton::SetCallingIdentity(identity);
239 }
240 
GetMediaDataByName(const std::string & name,size_t & len,std::unique_ptr<uint8_t[]> & outValue,uint32_t density)241 Global::Resource::RState AudioSafeVolumeNotificationImpl::GetMediaDataByName(const std::string& name, size_t& len,
242     std::unique_ptr<uint8_t[]>& outValue, uint32_t density)
243 {
244     std::string identity = IPCSkeleton::ResetCallingIdentity();
245     Global::Resource::RState rstate =
246         ResourceManagerAdapter::GetInstance()->GetMediaDataByName(name, len, outValue, density);
247     IPCSkeleton::SetCallingIdentity(identity);
248     return rstate;
249 }
250 }  // namespace AudioStandard
251 }  // namespace OHOS
252