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