• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2025-2025 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 "camera_beauty_notification.h"
17 #include "image_source_proxy.h"
18 
19 namespace OHOS {
20 namespace CameraStandard {
21 
22 sptr<CameraBeautyNotification> CameraBeautyNotification::instance_ = nullptr;
23 std::mutex CameraBeautyNotification::instanceMutex_;
24 static constexpr int32_t CAMERA_UID = 1047;
25 const int BEAUTY_NOTIFICATION_ID = 1047001;
26 const std::string BEAUTY_NOTIFICATION_TITLE = "title_adjust_beauty";
27 const std::string BEAUTY_NOTIFICATION_CONTENT_ON = "summary_closed_beauty";
28 const std::string BEAUTY_NOTIFICATION_CONTENT_OFF = "summary_opened_beauty";
29 const std::string BEAUTY_NOTIFICATION_BUTTON_ON = "open_beauty";
30 const std::string BEAUTY_NOTIFICATION_BUTTON_OFF = "close_beauty";
31 const uint32_t BEAUTY_NOTIFICATION_CLOSE_SOUND_FLAG = 1 << 0;
32 const uint32_t BEAUTY_NOTIFICATION_CONTROL_FLAG = 1 << 9;
33 const uint32_t BEAUTY_NOTIFICATION_LOCKSCREEN_FLAG = 1 << 1;
34 const uint32_t BEAUTY_NOTIFICATION_CLOSE_VIBRATION_FLAG = 1 << 4;
35 const std::string BEAUTY_NOTIFICATION_ICON_NAME = "ic_public_camera_beauty";
36 const std::string BEAUTY_NOTIFICATION_GROUP_NAME = "camera_beauty";
37 const int32_t ICON_WIDTH = 220;
38 const int32_t ICON_HEIGHT = 220;
39 const int32_t CONTROL_FLAG_LIMIT = 3;
40 
CameraBeautyNotification()41 CameraBeautyNotification::CameraBeautyNotification()
42 {
43     InitBeautyStatus();
44 }
45 
~CameraBeautyNotification()46 CameraBeautyNotification::~CameraBeautyNotification()
47 {}
48 
GetInstance()49 sptr<CameraBeautyNotification> CameraBeautyNotification::GetInstance()
50 {
51     CHECK_RETURN_RET(instance_ != nullptr, instance_);
52     std::lock_guard<std::mutex> lock(instanceMutex_);
53     CHECK_RETURN_RET(instance_ != nullptr, instance_);
54     instance_ = new (std::nothrow) CameraBeautyNotification();
55     return instance_;
56 }
57 
PublishNotification(bool isRecordTimes)58 void CameraBeautyNotification::PublishNotification(bool isRecordTimes)
59 {
60     std::lock_guard<std::mutex> lock(notificationMutex_);
61     isNotificationSuccess_ = false;
62     int32_t beautyStatus = GetBeautyStatus();
63     int32_t beautyTimes = GetBeautyTimes();
64     std::shared_ptr<Notification::NotificationContent> content =
65         std::make_shared<Notification::NotificationContent>(CreateNotificationNormalContent(beautyStatus));
66 
67     if (content == nullptr) {
68         MEDIA_ERR_LOG("Create notification content failed");
69         return;
70     }
71 
72     Notification::NotificationRequest request;
73     request.SetCreatorUid(CAMERA_UID);
74     request.SetCreatorPid(getpid());
75 
76     int32_t userId;
77     AccountSA::OsAccountManager::GetOsAccountLocalIdFromUid(CAMERA_UID, userId);
78 
79     request.SetCreatorUserId(userId);
80     request.SetDeliveryTime(GetTimestamp());
81     request.SetAutoDeletedTime(OHOS::Notification::NotificationConstant::INVALID_AUTO_DELETE_TIME);
82     request.SetTapDismissed(false);
83     request.SetSlotType(OHOS::Notification::NotificationConstant::SlotType::SOCIAL_COMMUNICATION);
84     request.SetNotificationId(BEAUTY_NOTIFICATION_ID);
85     request.SetGroupName(BEAUTY_NOTIFICATION_GROUP_NAME);
86     uint32_t baseFlag = BEAUTY_NOTIFICATION_CLOSE_SOUND_FLAG |
87         BEAUTY_NOTIFICATION_CLOSE_VIBRATION_FLAG | BEAUTY_NOTIFICATION_LOCKSCREEN_FLAG;
88 
89     bool isBanner = beautyTimes < CONTROL_FLAG_LIMIT;
90     if (isBanner) {
91         request.SetNotificationControlFlags(baseFlag|BEAUTY_NOTIFICATION_CONTROL_FLAG);
92     } else {
93         request.SetNotificationControlFlags(baseFlag);
94     }
95     request.SetContent(content);
96 
97     GetPixelMap();
98     if (iconPixelMap_ != nullptr) {
99         request.SetLittleIcon(iconPixelMap_);
100         request.SetBadgeIconStyle(Notification::NotificationRequest::BadgeStyle::LITTLE);
101     }
102 
103     std::string buttonName = beautyStatus == BEAUTY_STATUS_OFF ? GetSystemStringByName(BEAUTY_NOTIFICATION_BUTTON_ON) :
104         GetSystemStringByName(BEAUTY_NOTIFICATION_BUTTON_OFF);
105     SetActionButton(buttonName, request, beautyStatus);
106     int ret = Notification::NotificationHelper::PublishNotification(request);
107     MEDIA_INFO_LOG("CameraBeautyNotification::PublishNotification result = %{public}d", ret);
108     isNotificationSuccess_ = (ret == CAMERA_OK);
109     if (ret == CAMERA_OK && isBanner && beautyTimes <= CONTROL_FLAG_LIMIT && isRecordTimes) {
110         beautyTimes_.operator++();
111         SetBeautyTimesFromDataShareHelper(GetBeautyTimes());
112     }
113 }
114 
CancelNotification()115 void CameraBeautyNotification::CancelNotification()
116 {
117     std::lock_guard<std::mutex> lock(notificationMutex_);
118     if (!isNotificationSuccess_) {
119         return;
120     }
121     isNotificationSuccess_ = false;
122     int ret = Notification::NotificationHelper::CancelNotification(BEAUTY_NOTIFICATION_ID);
123     MEDIA_INFO_LOG("CameraBeautyNotification::CancelNotification result = %{public}d", ret);
124 }
125 
SetBeautyStatus(int32_t beautyStatus)126 void CameraBeautyNotification::SetBeautyStatus(int32_t beautyStatus)
127 {
128     beautyStatus_.store(beautyStatus);
129 }
130 
GetBeautyStatus()131 int32_t CameraBeautyNotification::GetBeautyStatus()
132 {
133     return beautyStatus_.load();
134 }
135 
SetBeautyTimes(int32_t beautyTimes)136 void CameraBeautyNotification::SetBeautyTimes(int32_t beautyTimes)
137 {
138     beautyTimes_.store(beautyTimes);
139 }
140 
GetBeautyTimes()141 int32_t CameraBeautyNotification::GetBeautyTimes()
142 {
143     return beautyTimes_.load();
144 }
145 
GetBeautyStatusFromDataShareHelper(int32_t & beautyStatus)146 int32_t CameraBeautyNotification::GetBeautyStatusFromDataShareHelper(int32_t &beautyStatus)
147 {
148     if (cameraDataShareHelper_ == nullptr) {
149         cameraDataShareHelper_ = std::make_shared<CameraDataShareHelper>();
150     }
151     std::string value = "";
152     auto ret = cameraDataShareHelper_->QueryOnce(PREDICATES_CAMERA_BEAUTY_STATUS, value);
153     if (ret != CAMERA_OK) {
154         beautyStatus = BEAUTY_STATUS_OFF;
155     } else {
156         beautyStatus = std::stoi(value);
157     }
158     return CAMERA_OK;
159 }
160 
SetBeautyStatusFromDataShareHelper(int32_t beautyStatus)161 int32_t CameraBeautyNotification::SetBeautyStatusFromDataShareHelper(int32_t beautyStatus)
162 {
163     if (cameraDataShareHelper_ == nullptr) {
164         cameraDataShareHelper_ = std::make_shared<CameraDataShareHelper>();
165     }
166     auto ret = cameraDataShareHelper_->UpdateOnce(PREDICATES_CAMERA_BEAUTY_STATUS, std::to_string(beautyStatus));
167     CHECK_RETURN_RET_ELOG(ret != CAMERA_OK, CAMERA_ALLOC_ERROR,
168         "SetBeautyStatusFromDataShareHelper UpdateOnce fail.");
169     return CAMERA_OK;
170 }
171 
GetBeautyTimesFromDataShareHelper(int32_t & times)172 int32_t CameraBeautyNotification::GetBeautyTimesFromDataShareHelper(int32_t &times)
173 {
174     if (cameraDataShareHelper_ == nullptr) {
175         cameraDataShareHelper_ = std::make_shared<CameraDataShareHelper>();
176     }
177     std::string value = "";
178     auto ret = cameraDataShareHelper_->QueryOnce(PREDICATES_CAMERA_BEAUTY_TIMES, value);
179     if (ret != CAMERA_OK) {
180         times = 0;
181     } else {
182         times = std::stoi(value);
183     }
184     return CAMERA_OK;
185 }
186 
SetBeautyTimesFromDataShareHelper(int32_t times)187 int32_t CameraBeautyNotification::SetBeautyTimesFromDataShareHelper(int32_t times)
188 {
189     if (cameraDataShareHelper_ == nullptr) {
190         cameraDataShareHelper_ = std::make_shared<CameraDataShareHelper>();
191     }
192     auto ret = cameraDataShareHelper_->UpdateOnce(PREDICATES_CAMERA_BEAUTY_TIMES, std::to_string(times));
193     CHECK_RETURN_RET_ELOG(ret != CAMERA_OK, CAMERA_ALLOC_ERROR,
194         "SetBeautyTimesFromDataShareHelper UpdateOnce fail.");
195     return CAMERA_OK;
196 }
197 
InitBeautyStatus()198 void CameraBeautyNotification::InitBeautyStatus()
199 {
200     int32_t beautyStatus = BEAUTY_STATUS_OFF;
201     int32_t times = 0;
202     GetBeautyStatusFromDataShareHelper(beautyStatus);
203     GetBeautyTimesFromDataShareHelper(times);
204     MEDIA_INFO_LOG("InitBeautyStatus beautyStatus = %{public}d, times = %{public}d", beautyStatus, times);
205     SetBeautyStatus(beautyStatus);
206     SetBeautyTimes(times);
207 }
208 
CreateNotificationNormalContent(int32_t beautyStatus)209 std::shared_ptr<Notification::NotificationNormalContent> CameraBeautyNotification::CreateNotificationNormalContent(
210     int32_t beautyStatus)
211 {
212     std::shared_ptr<Notification::NotificationNormalContent> normalContent =
213         std::make_shared<Notification::NotificationNormalContent>();
214     CHECK_RETURN_RET_ELOG(normalContent == nullptr, nullptr, "Create normalContent failed");
215     normalContent->SetTitle(GetSystemStringByName(BEAUTY_NOTIFICATION_TITLE));
216     normalContent->SetText(beautyStatus == BEAUTY_STATUS_OFF ? GetSystemStringByName(BEAUTY_NOTIFICATION_CONTENT_ON) :
217         GetSystemStringByName(BEAUTY_NOTIFICATION_CONTENT_OFF));
218     return normalContent;
219 }
220 
SetActionButton(const std::string & buttonName,Notification::NotificationRequest & request,int32_t beautyStatus)221 void CameraBeautyNotification::SetActionButton(const std::string& buttonName,
222     Notification::NotificationRequest& request, int32_t beautyStatus)
223 {
224     auto want = std::make_shared<AAFwk::Want>();
225     want->SetAction(EVENT_CAMERA_BEAUTY_NOTIFICATION);
226 
227     std::shared_ptr<OHOS::AAFwk::WantParams> wantParams = std::make_shared<OHOS::AAFwk::WantParams>();
228     sptr<OHOS::AAFwk::IInterface> intIt = OHOS::AAFwk::Integer::Box(beautyStatus);
229     wantParams->SetParam(BEAUTY_NOTIFICATION_ACTION_PARAM, intIt);
230 
231     want->SetParams(*wantParams);
232     std::vector<std::shared_ptr<AAFwk::Want>> wants;
233     wants.push_back(want);
234 
235     std::vector<AbilityRuntime::WantAgent::WantAgentConstant::Flags> flags;
236     flags.push_back(AbilityRuntime::WantAgent::WantAgentConstant::Flags::CONSTANT_FLAG);
237 
238     AbilityRuntime::WantAgent::WantAgentInfo wantAgentInfo(
239         0, AbilityRuntime::WantAgent::WantAgentConstant::OperationType::SEND_COMMON_EVENT,
240         flags, wants, wantParams
241     );
242     auto wantAgentDeal = AbilityRuntime::WantAgent::WantAgentHelper::GetWantAgent(wantAgentInfo);
243     std::shared_ptr<Notification::NotificationActionButton> actionButtonDeal =
244         Notification::NotificationActionButton::Create(nullptr, buttonName, wantAgentDeal);
245     if (actionButtonDeal == nullptr) {
246         MEDIA_INFO_LOG("Create actionButtonDeal failed");
247         return;
248     }
249     request.AddActionButton(actionButtonDeal);
250 }
251 
GetSystemStringByName(std::string name)252 std::string CameraBeautyNotification::GetSystemStringByName(std::string name)
253 {
254     InitResourceManager();
255     std::string result;
256     std::string identity = IPCSkeleton::ResetCallingIdentity();
257     resourceManager_->GetStringByName(name.c_str(), result);
258     IPCSkeleton::SetCallingIdentity(identity);
259     MEDIA_DEBUG_LOG("name: %{public}s, result: %{public}s", name.c_str(), result.c_str());
260     return result;
261 }
262 
GetPixelMap()263 void CameraBeautyNotification::GetPixelMap()
264 {
265     if (iconPixelMap_ != nullptr) {
266         MEDIA_ERR_LOG("Pixel map already exists.");
267         return;
268     }
269 
270     size_t len = 0;
271     std::unique_ptr<uint8_t[]> data;
272     Global::Resource::RState rstate = GetMediaDataByName(BEAUTY_NOTIFICATION_ICON_NAME.c_str(), len, data);
273     if (rstate != Global::Resource::RState::SUCCESS) {
274         MEDIA_ERR_LOG("GetMediaDataByName failed");
275         return;
276     }
277 
278     OHOS::Media::SourceOptions opts;
279     uint32_t errorCode = 0;
280     std::shared_ptr<ImageSourceProxy> imageSourceProxy = ImageSourceProxy::CreateImageSourceProxy();
281     CHECK_RETURN_ELOG(imageSourceProxy == nullptr, "CreateImageSourceProxy failed");
282     auto ret = imageSourceProxy->CreateImageSource(data.get(), len, opts, errorCode);
283     CHECK_RETURN_ELOG(ret != 0, "CreateImageSource failed");
284     MEDIA_INFO_LOG("CreateImageSource errorCode: %{public}d", static_cast<int32_t>(errorCode));
285     OHOS::Media::DecodeOptions decodeOpts;
286     decodeOpts.desiredSize = {ICON_WIDTH, ICON_HEIGHT};
287     decodeOpts.desiredPixelFormat = OHOS::Media::PixelFormat::BGRA_8888;
288     std::unique_ptr<Media::PixelMap> pixelMap = imageSourceProxy->CreatePixelMap(decodeOpts, errorCode);
289     MEDIA_INFO_LOG("CreateImageSource errorCode: %{public}d", static_cast<int32_t>(errorCode));
290     CHECK_RETURN_ELOG(pixelMap == nullptr, "Create icon pixel map failed,pixelMap is nullptr");
291     iconPixelMap_ = std::move(pixelMap);
292 }
293 
GetMediaDataByName(std::string name,size_t & len,std::unique_ptr<uint8_t[]> & outValue,uint32_t density)294 Global::Resource::RState CameraBeautyNotification::GetMediaDataByName(std::string name, size_t& len,
295     std::unique_ptr<uint8_t[]> &outValue, uint32_t density)
296 {
297     InitResourceManager();
298     std::string identity = IPCSkeleton::ResetCallingIdentity();
299     Global::Resource::RState rstate = resourceManager_->GetMediaDataByName(name.c_str(), len, outValue);
300     IPCSkeleton::SetCallingIdentity(identity);
301     MEDIA_INFO_LOG("rstate: %{public}d", static_cast<int32_t>(rstate));
302     return rstate;
303 }
304 
InitResourceManager()305 void CameraBeautyNotification::InitResourceManager()
306 {
307     if (!resourceManager_) {
308         MEDIA_INFO_LOG("Init");
309         resourceManager_ = Global::Resource::GetSystemResourceManagerNoSandBox();
310     }
311     if (!resConfig_) {
312         resConfig_ = Global::Resource::CreateResConfig();
313     }
314     RefreshResConfig();
315 }
316 
RefreshResConfig()317 void CameraBeautyNotification::RefreshResConfig()
318 {
319     std::string language = Global::I18n::LocaleConfig::GetSystemLanguage();
320     if (language.empty()) {
321         MEDIA_INFO_LOG("Get system language failed, skip RefreshResConfig");
322         return;
323     }
324     UErrorCode status = U_ZERO_ERROR;
325     icu::Locale locale = icu::Locale::forLanguageTag(language, status);
326     if (status != U_ZERO_ERROR || locale == nullptr) {
327         MEDIA_INFO_LOG("forLanguageTag failed, errCode:%{public}d", status);
328         return;
329     }
330     if (!resConfig_) {
331         MEDIA_INFO_LOG("resConfig_ is nullptr");
332         return;
333     }
334     std::string region = Global::I18n::LocaleConfig::GetSystemRegion();
335     resConfig_->SetLocaleInfo(locale.getLanguage(), locale.getScript(), region.c_str());
336     if (!resourceManager_) {
337         MEDIA_INFO_LOG("resourceManager_ is nullptr");
338         return;
339     }
340     resourceManager_->UpdateResConfig(*resConfig_);
341     MEDIA_INFO_LOG("Refresh success");
342 }
343 } // namespace CameraStandard
344 } // namespace OHOS
345