• 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     int32_t beautyStatus = GetBeautyStatus();
64     int32_t beautyTimes = GetBeautyTimes();
65     std::shared_ptr<Notification::NotificationContent> content =
66         std::make_shared<Notification::NotificationContent>(CreateNotificationNormalContent(beautyStatus));
67 
68     if (content == nullptr) {
69         MEDIA_ERR_LOG("Create notification content failed");
70         return;
71     }
72 
73     Notification::NotificationRequest request;
74     request.SetCreatorUid(CAMERA_UID);
75     request.SetCreatorPid(getpid());
76 
77     int32_t userId;
78     AccountSA::OsAccountManager::GetOsAccountLocalIdFromUid(CAMERA_UID, userId);
79 
80     request.SetCreatorUserId(userId);
81     request.SetDeliveryTime(GetTimestamp());
82     request.SetAutoDeletedTime(OHOS::Notification::NotificationConstant::INVALID_AUTO_DELETE_TIME);
83     request.SetTapDismissed(false);
84     request.SetSlotType(OHOS::Notification::NotificationConstant::SlotType::SOCIAL_COMMUNICATION);
85     request.SetNotificationId(BEAUTY_NOTIFICATION_ID);
86     request.SetGroupName(BEAUTY_NOTIFICATION_GROUP_NAME);
87     uint32_t baseFlag = 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     if (ret == CAMERA_OK && isBanner && beautyTimes <= CONTROL_FLAG_LIMIT && isRecordTimes) {
109         beautyTimes_.operator++();
110         SetBeautyTimesFromDataShareHelper(GetBeautyTimes());
111     }
112 }
113 
CancelNotification()114 void CameraBeautyNotification::CancelNotification()
115 {
116     std::lock_guard<std::mutex> lock(notificationMutex_);
117     int ret = Notification::NotificationHelper::CancelNotification(BEAUTY_NOTIFICATION_ID);
118     MEDIA_INFO_LOG("CameraBeautyNotification::CancelNotification result = %{public}d", ret);
119 }
120 
SetBeautyStatus(int32_t beautyStatus)121 void CameraBeautyNotification::SetBeautyStatus(int32_t beautyStatus)
122 {
123     beautyStatus_.store(beautyStatus);
124 }
125 
GetBeautyStatus()126 int32_t CameraBeautyNotification::GetBeautyStatus()
127 {
128     return beautyStatus_.load();
129 }
130 
SetBeautyTimes(int32_t beautyTimes)131 void CameraBeautyNotification::SetBeautyTimes(int32_t beautyTimes)
132 {
133     beautyTimes_.store(beautyTimes);
134 }
135 
GetBeautyTimes()136 int32_t CameraBeautyNotification::GetBeautyTimes()
137 {
138     return beautyTimes_.load();
139 }
140 
GetBeautyStatusFromDataShareHelper(int32_t & beautyStatus)141 int32_t CameraBeautyNotification::GetBeautyStatusFromDataShareHelper(int32_t &beautyStatus)
142 {
143     if (cameraDataShareHelper_ == nullptr) {
144         cameraDataShareHelper_ = std::make_shared<CameraDataShareHelper>();
145     }
146     std::string value = "";
147     auto ret = cameraDataShareHelper_->QueryOnce(PREDICATES_CAMERA_BEAUTY_STATUS, value);
148     if (ret != CAMERA_OK) {
149         beautyStatus = BEAUTY_STATUS_OFF;
150     } else {
151         beautyStatus = std::stoi(value);
152     }
153     return CAMERA_OK;
154 }
155 
SetBeautyStatusFromDataShareHelper(int32_t beautyStatus)156 int32_t CameraBeautyNotification::SetBeautyStatusFromDataShareHelper(int32_t beautyStatus)
157 {
158     if (cameraDataShareHelper_ == nullptr) {
159         cameraDataShareHelper_ = std::make_shared<CameraDataShareHelper>();
160     }
161     auto ret = cameraDataShareHelper_->UpdateOnce(PREDICATES_CAMERA_BEAUTY_STATUS, std::to_string(beautyStatus));
162     CHECK_ERROR_RETURN_RET_LOG(ret != CAMERA_OK, CAMERA_ALLOC_ERROR,
163         "SetBeautyStatusFromDataShareHelper UpdateOnce fail.");
164     return CAMERA_OK;
165 }
166 
GetBeautyTimesFromDataShareHelper(int32_t & times)167 int32_t CameraBeautyNotification::GetBeautyTimesFromDataShareHelper(int32_t &times)
168 {
169     if (cameraDataShareHelper_ == nullptr) {
170         cameraDataShareHelper_ = std::make_shared<CameraDataShareHelper>();
171     }
172     std::string value = "";
173     auto ret = cameraDataShareHelper_->QueryOnce(PREDICATES_CAMERA_BEAUTY_TIMES, value);
174     if (ret != CAMERA_OK) {
175         times = 0;
176     } else {
177         times = std::stoi(value);
178     }
179     return CAMERA_OK;
180 }
181 
SetBeautyTimesFromDataShareHelper(int32_t times)182 int32_t CameraBeautyNotification::SetBeautyTimesFromDataShareHelper(int32_t times)
183 {
184     if (cameraDataShareHelper_ == nullptr) {
185         cameraDataShareHelper_ = std::make_shared<CameraDataShareHelper>();
186     }
187     auto ret = cameraDataShareHelper_->UpdateOnce(PREDICATES_CAMERA_BEAUTY_TIMES, std::to_string(times));
188     CHECK_ERROR_RETURN_RET_LOG(ret != CAMERA_OK, CAMERA_ALLOC_ERROR,
189         "SetBeautyTimesFromDataShareHelper UpdateOnce fail.");
190     return CAMERA_OK;
191 }
192 
InitBeautyStatus()193 void CameraBeautyNotification::InitBeautyStatus()
194 {
195     int32_t beautyStatus = BEAUTY_STATUS_OFF;
196     int32_t times = 0;
197     GetBeautyStatusFromDataShareHelper(beautyStatus);
198     GetBeautyTimesFromDataShareHelper(times);
199     MEDIA_INFO_LOG("InitBeautyStatus beautyStatus = %{public}d, times = %{public}d", beautyStatus, times);
200     SetBeautyStatus(beautyStatus);
201     SetBeautyTimes(times);
202 }
203 
CreateNotificationNormalContent(int32_t beautyStatus)204 std::shared_ptr<Notification::NotificationNormalContent> CameraBeautyNotification::CreateNotificationNormalContent(
205     int32_t beautyStatus)
206 {
207     std::shared_ptr<Notification::NotificationNormalContent> normalContent =
208         std::make_shared<Notification::NotificationNormalContent>();
209     CHECK_ERROR_RETURN_RET_LOG(normalContent == nullptr, nullptr, "Create normalContent failed");
210     normalContent->SetTitle(GetSystemStringByName(BEAUTY_NOTIFICATION_TITLE));
211     normalContent->SetText(beautyStatus == BEAUTY_STATUS_OFF ? GetSystemStringByName(BEAUTY_NOTIFICATION_CONTENT_ON) :
212         GetSystemStringByName(BEAUTY_NOTIFICATION_CONTENT_OFF));
213     return normalContent;
214 }
215 
SetActionButton(const std::string & buttonName,Notification::NotificationRequest & request,int32_t beautyStatus)216 void CameraBeautyNotification::SetActionButton(const std::string& buttonName,
217     Notification::NotificationRequest& request, int32_t beautyStatus)
218 {
219     auto want = std::make_shared<AAFwk::Want>();
220     want->SetAction(EVENT_CAMERA_BEAUTY_NOTIFICATION);
221 
222     std::shared_ptr<OHOS::AAFwk::WantParams> wantParams = std::make_shared<OHOS::AAFwk::WantParams>();
223     sptr<OHOS::AAFwk::IInterface> intIt = OHOS::AAFwk::Integer::Box(beautyStatus);
224     wantParams->SetParam(BEAUTY_NOTIFICATION_ACTION_PARAM, intIt);
225 
226     want->SetParams(*wantParams);
227     std::vector<std::shared_ptr<AAFwk::Want>> wants;
228     wants.push_back(want);
229 
230     std::vector<AbilityRuntime::WantAgent::WantAgentConstant::Flags> flags;
231     flags.push_back(AbilityRuntime::WantAgent::WantAgentConstant::Flags::CONSTANT_FLAG);
232 
233     AbilityRuntime::WantAgent::WantAgentInfo wantAgentInfo(
234         0, AbilityRuntime::WantAgent::WantAgentConstant::OperationType::SEND_COMMON_EVENT,
235         flags, wants, wantParams
236     );
237     auto wantAgentDeal = AbilityRuntime::WantAgent::WantAgentHelper::GetWantAgent(wantAgentInfo);
238     std::shared_ptr<Notification::NotificationActionButton> actionButtonDeal =
239         Notification::NotificationActionButton::Create(nullptr, buttonName, wantAgentDeal);
240     if (actionButtonDeal == nullptr) {
241         MEDIA_INFO_LOG("Create actionButtonDeal failed");
242         return;
243     }
244     request.AddActionButton(actionButtonDeal);
245 }
246 
GetSystemStringByName(std::string name)247 std::string CameraBeautyNotification::GetSystemStringByName(std::string name)
248 {
249     InitResourceManager();
250     std::string result;
251     std::string identity = IPCSkeleton::ResetCallingIdentity();
252     resourceManager_->GetStringByName(name.c_str(), result);
253     IPCSkeleton::SetCallingIdentity(identity);
254     MEDIA_DEBUG_LOG("name: %{public}s, result: %{public}s", name.c_str(), result.c_str());
255     return result;
256 }
257 
GetPixelMap()258 void CameraBeautyNotification::GetPixelMap()
259 {
260     if (iconPixelMap_ != nullptr) {
261         MEDIA_ERR_LOG("Pixel map already exists.");
262         return;
263     }
264 
265     size_t len = 0;
266     std::unique_ptr<uint8_t[]> data;
267     Global::Resource::RState rstate = GetMediaDataByName(BEAUTY_NOTIFICATION_ICON_NAME.c_str(), len, data);
268     if (rstate != Global::Resource::RState::SUCCESS) {
269         MEDIA_ERR_LOG("GetMediaDataByName failed");
270         return;
271     }
272 
273     OHOS::Media::SourceOptions opts;
274     uint32_t errorCode = 0;
275     std::unique_ptr<OHOS::Media::ImageSource> imageSource =
276         OHOS::Media::ImageSource::CreateImageSource(data.get(), len, opts, errorCode);
277     MEDIA_INFO_LOG("CreateImageSource errorCode: %{public}d", static_cast<int32_t>(errorCode));
278     if (imageSource == nullptr) {
279         MEDIA_ERR_LOG("imageSource is nullptr");
280         return;
281     }
282     OHOS::Media::DecodeOptions decodeOpts;
283     decodeOpts.desiredSize = {ICON_WIDTH, ICON_HEIGHT};
284     decodeOpts.desiredPixelFormat = OHOS::Media::PixelFormat::BGRA_8888;
285     std::unique_ptr<OHOS::Media::PixelMap> pixelMap = imageSource->CreatePixelMap(decodeOpts, errorCode);
286     MEDIA_INFO_LOG("CreatePixelMap errorCode: %{public}d", static_cast<int32_t>(errorCode));
287     if (pixelMap == nullptr) {
288         MEDIA_ERR_LOG("pixelMap is nullptr");
289         return;
290     }
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     resConfig_->SetLocaleInfo(locale.getLanguage(), locale.getScript(), locale.getCountry());
335     if (!resourceManager_) {
336         MEDIA_INFO_LOG("resourceManager_ is nullptr");
337         return;
338     }
339     resourceManager_->UpdateResConfig(*resConfig_);
340     MEDIA_INFO_LOG("Refresh success");
341 }
342 } // namespace CameraStandard
343 } // namespace OHOS
344