1 /*
2 * Copyright (C) 2022 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 #include "wallpaper_service.h"
16
17 #include <cerrno>
18 #include <cstdio>
19 #include <cstdlib>
20 #include <cstring>
21 #include <fcntl.h>
22 #include <iostream>
23 #include <sys/prctl.h>
24 #include <sys/sendfile.h>
25 #include <sys/stat.h>
26 #include <sys/types.h>
27 #include <thread>
28 #include <unistd.h>
29 #include <window_manager.h>
30
31 #include "ability_manager_client.h"
32 #include "bundle_mgr_interface.h"
33 #include "bundle_mgr_proxy.h"
34 #include "color_picker.h"
35 #include "command.h"
36 #include "directory_ex.h"
37 #include "dump_helper.h"
38 #include "effect_errors.h"
39 #include "export/color.h"
40 #include "file_deal.h"
41 #include "file_ex.h"
42 #include "hilog_wrapper.h"
43 #include "hitrace_meter.h"
44 #include "image_packer.h"
45 #include "image_source.h"
46 #include "image_type.h"
47 #include "image_utils.h"
48 #include "iservice_registry.h"
49 #include "memory_guard.h"
50 #include "nlohmann/json.hpp"
51 #include "parameter.h"
52 #include "pixel_map.h"
53 #include "scene_board_judgement.h"
54 #include "surface.h"
55 #include "system_ability_definition.h"
56 #include "tokenid_kit.h"
57 #include "uri.h"
58 #include "uri_permission_manager_client.h"
59 #include "wallpaper_common.h"
60 #include "wallpaper_common_event_manager.h"
61 #include "wallpaper_extension_ability_connection.h"
62 #include "wallpaper_extension_ability_death_recipient.h"
63 #include "wallpaper_service_cb_proxy.h"
64 #include "want.h"
65 #include "window.h"
66
67 namespace OHOS {
68 namespace WallpaperMgrService {
69 REGISTER_SYSTEM_ABILITY_BY_ID(WallpaperService, WALLPAPER_MANAGER_SERVICE_ID, true);
70
71 using namespace OHOS::Media;
72 using namespace OHOS::MiscServices;
73 using namespace OHOS::Security::AccessToken;
74 using namespace OHOS::AccountSA;
75
76 constexpr const char *WALLPAPER_SYSTEM_ORIG = "wallpaper_system_orig";
77 constexpr const char *WALLPAPER_LOCK_ORIG = "wallpaper_lock_orig";
78 constexpr const char *LIVE_WALLPAPER_SYSTEM_ORIG = "live_wallpaper_system_orig";
79 constexpr const char *LIVE_WALLPAPER_LOCK_ORIG = "live_wallpaper_lock_orig";
80 constexpr const char *CUSTOM_WALLPAPER_LOCK = "custom_wallpaper_lock";
81 constexpr const char *CUSTOM_WALLPAPER_SYSTEM = "custom_wallpaper_system";
82 constexpr const char *OHOS_WALLPAPER_BUNDLE_NAME = "com.ohos.launcher";
83 constexpr const char *SHOW_SYSTEM_SCREEN = "SHOW_SYSTEMSCREEN";
84 constexpr const char *SHOW_LOCK_SCREEN = "SHOW_LOCKSCREEN";
85 constexpr const char *SYSTEM_RES_TYPE = "SystemResType";
86 constexpr const char *LOCKSCREEN_RES_TYPE = "LockScreenResType";
87 constexpr const char *WALLPAPER_CHANGE = "wallpaperChange";
88 constexpr const char *COLOR_CHANGE = "colorChange";
89 constexpr const char *BUNDLE_NAME_KEY = "persist.wallpaper_mgr.bundleName";
90 constexpr const char *SCENEBOARD_BUNDLE_NAME = "com.ohos.sceneboard";
91
92 constexpr const char *WALLPAPER_USERID_PATH = "/data/service/el1/public/wallpaper/";
93 constexpr const char *WALLPAPER_SYSTEM_DIRNAME = "system";
94 constexpr const char *WALLPAPER_TMP_DIRNAME = "fwsettmp";
95 constexpr const char *WALLPAPER_LOCKSCREEN_DIRNAME = "lockscreen";
96 constexpr const char *WALLPAPER_DEFAULT_FILEFULLPATH = "/system/etc/wallpaperdefault.jpeg";
97 constexpr const char *WALLPAPER_DEFAULT_LOCK_FILEFULLPATH = "/system/etc/wallpaperlockdefault.jpeg";
98 constexpr const char *WALLPAPER_PREFABRICATE_FILEFULLPATH = "/sys_prod/media/themes/wallpaperdefault.jpeg";
99 constexpr const char *WALLPAPER_PREFABRICATE_LOCK_FILEFULLPATH = "/sys_prod/media/themes/wallpaperlockdefault.jpeg";
100 constexpr const char *WALLPAPER_CROP_PICTURE = "crop_file";
101
102 constexpr int64_t INIT_INTERVAL = 10000L;
103 constexpr int64_t DELAY_TIME = 1000L;
104 constexpr int64_t QUERY_USER_ID_INTERVAL = 300L;
105 constexpr int32_t CONNECT_EXTENSION_INTERVAL = 100;
106 constexpr int32_t CONNECT_EXTENSION_MAX_RETRY_TIMES = 50;
107 constexpr int32_t FOO_MAX_LEN = 52428800;
108 constexpr int32_t MAX_RETRY_TIMES = 20;
109 constexpr int32_t QUERY_USER_MAX_RETRY_TIMES = 100;
110 constexpr int32_t DEFAULT_WALLPAPER_ID = -1;
111 constexpr int32_t DEFAULT_USER_ID = 0;
112 constexpr int32_t DEFAULT_VALUE = -1;
113 constexpr int32_t MAX_VIDEO_SIZE = 104857600;
114 const int CONFIG_LEN = 30;
115
116 std::mutex WallpaperService::instanceLock_;
117
118 sptr<WallpaperService> WallpaperService::instance_;
119
120 std::shared_ptr<AppExecFwk::EventHandler> WallpaperService::serviceHandler_;
121
WallpaperService(int32_t systemAbilityId,bool runOnCreate)122 WallpaperService::WallpaperService(int32_t systemAbilityId, bool runOnCreate)
123 : SystemAbility(systemAbilityId, runOnCreate), state_(ServiceRunningState::STATE_NOT_START)
124 {
125 }
126
WallpaperService()127 WallpaperService::WallpaperService() : state_(ServiceRunningState::STATE_NOT_START)
128 {
129 }
130
~WallpaperService()131 WallpaperService::~WallpaperService()
132 {
133 }
134
Init()135 int32_t WallpaperService::Init()
136 {
137 InitQueryUserId(QUERY_USER_MAX_RETRY_TIMES);
138 bool ret = Publish(this);
139 if (!ret) {
140 HILOG_ERROR("Publish failed.");
141 ReporterFault(FaultType::SERVICE_FAULT, FaultCode::SF_SERVICE_UNAVAILABLE);
142 return -1;
143 }
144 HILOG_INFO("Publish success.");
145 state_ = ServiceRunningState::STATE_RUNNING;
146 StartExtensionAbility(CONNECT_EXTENSION_MAX_RETRY_TIMES);
147 return E_OK;
148 }
149
OnStart()150 void WallpaperService::OnStart()
151 {
152 HILOG_INFO("Enter OnStart.");
153 MemoryGuard cacheGuard;
154 if (state_ == ServiceRunningState::STATE_RUNNING) {
155 HILOG_ERROR("WallpaperService is already running.");
156 return;
157 }
158 InitData();
159 InitServiceHandler();
160 AddSystemAbilityListener(COMMON_EVENT_SERVICE_ID);
161 auto cmd = std::make_shared<Command>(std::vector<std::string>({ "-all" }), "Show all",
162 [this](const std::vector<std::string> &input, std::string &output) -> bool {
163 output.append(
164 "WallpaperExtensionAbility\t: ExtensionInfo{" + std::string(OHOS_WALLPAPER_BUNDLE_NAME) + "}\n");
165 return true;
166 });
167 DumpHelper::GetInstance().RegisterCommand(cmd);
168 if (Init() != E_OK) {
169 auto callback = [=]() { Init(); };
170 serviceHandler_->PostTask(callback, INIT_INTERVAL);
171 HILOG_ERROR("Init failed. Try again 10s later");
172 }
173 return;
174 }
175
OnAddSystemAbility(int32_t systemAbilityId,const std::string & deviceId)176 void WallpaperService::OnAddSystemAbility(int32_t systemAbilityId, const std::string &deviceId)
177 {
178 HILOG_INFO("OnAddSystemAbility systemAbilityId:%{public}d added!", systemAbilityId);
179 if (systemAbilityId == COMMON_EVENT_SERVICE_ID) {
180 int32_t times = 0;
181 RegisterSubscriber(times);
182 }
183 }
184
RegisterSubscriber(int32_t times)185 void WallpaperService::RegisterSubscriber(int32_t times)
186 {
187 MemoryGuard cacheGuard;
188 times++;
189 subscriber_ = std::make_shared<WallpaperCommonEventSubscriber>(*this);
190 bool subRes = OHOS::EventFwk::CommonEventManager::SubscribeCommonEvent(subscriber_);
191 if (!subRes && times <= MAX_RETRY_TIMES) {
192 HILOG_INFO("RegisterSubscriber failed");
193 auto callback = [this, times]() { RegisterSubscriber(times); };
194 serviceHandler_->PostTask(callback, DELAY_TIME);
195 }
196 }
197
InitServiceHandler()198 void WallpaperService::InitServiceHandler()
199 {
200 HILOG_INFO("InitServiceHandler started.");
201 if (serviceHandler_ != nullptr) {
202 HILOG_ERROR("InitServiceHandler already init.");
203 return;
204 }
205 std::shared_ptr<AppExecFwk::EventRunner> runner = AppExecFwk::EventRunner::Create("WallpaperService");
206 serviceHandler_ = std::make_shared<AppExecFwk::EventHandler>(runner);
207
208 HILOG_INFO("InitServiceHandler succeeded.");
209 }
210
OnStop()211 void WallpaperService::OnStop()
212 {
213 HILOG_INFO("OnStop started.");
214 if (state_ != ServiceRunningState::STATE_RUNNING) {
215 return;
216 }
217 serviceHandler_ = nullptr;
218 connection_ = nullptr;
219 recipient_ = nullptr;
220 extensionRemoteObject_ = nullptr;
221 if (subscriber_ != nullptr) {
222 bool unSubscribeResult = OHOS::EventFwk::CommonEventManager::UnSubscribeCommonEvent(subscriber_);
223 subscriber_ = nullptr;
224 HILOG_INFO("UnregisterSubscriber end, unSubscribeResult = %{public}d", unSubscribeResult);
225 }
226 state_ = ServiceRunningState::STATE_NOT_START;
227 HILOG_INFO("OnStop end.");
228 }
229
InitData()230 void WallpaperService::InitData()
231 {
232 HILOG_INFO("WallpaperService::initData --> start ");
233 wallpaperId_ = DEFAULT_WALLPAPER_ID;
234 int32_t userId = DEFAULT_USER_ID;
235 systemWallpaperMap_.Clear();
236 lockWallpaperMap_.Clear();
237 wallpaperTmpFullPath_ = std::string(WALLPAPER_USERID_PATH) + std::string(WALLPAPER_TMP_DIRNAME);
238 wallpaperCropPath_ = std::string(WALLPAPER_USERID_PATH) + std::string(WALLPAPER_CROP_PICTURE);
239 systemWallpaperColor_ = 0;
240 lockWallpaperColor_ = 0;
241 wallpaperEventMap_.clear();
242 appBundleName_ = SCENEBOARD_BUNDLE_NAME;
243 InitBundleNameParameter();
244 InitUserDir(userId);
245 LoadSettingsLocked(userId, true);
246 InitResources(userId, WALLPAPER_SYSTEM);
247 InitResources(userId, WALLPAPER_LOCKSCREEN);
248 LoadWallpaperState();
249 HILOG_INFO("WallpaperService::initData --> end ");
250 }
251
InitBundleNameParameter()252 void WallpaperService::InitBundleNameParameter()
253 {
254 char value[CONFIG_LEN] = "";
255 if (GetParameter(BUNDLE_NAME_KEY, "", value, CONFIG_LEN) < 0 || strlen(value) == 0) {
256 HILOG_ERROR("No found bundle name from system parameter.");
257 return;
258 }
259 appBundleName_ = value;
260 HILOG_INFO("get appBundleName_ :%{public}s", appBundleName_.c_str());
261 }
262
AddWallpaperExtensionDeathRecipient(const sptr<IRemoteObject> & remoteObject)263 void WallpaperService::AddWallpaperExtensionDeathRecipient(const sptr<IRemoteObject> &remoteObject)
264 {
265 if (remoteObject != nullptr) {
266 std::lock_guard<std::mutex> lock(remoteObjectMutex_);
267 IPCObjectProxy *proxy = reinterpret_cast<IPCObjectProxy *>(remoteObject.GetRefPtr());
268 if (recipient_ == nullptr) {
269 recipient_ = sptr<IRemoteObject::DeathRecipient>(new WallpaperExtensionAbilityDeathRecipient(*this));
270 }
271 if (proxy != nullptr && !proxy->IsObjectDead()) {
272 HILOG_INFO("get remoteObject succeed");
273 proxy->AddDeathRecipient(recipient_);
274 extensionRemoteObject_ = remoteObject;
275 }
276 }
277 }
278
RemoveExtensionDeathRecipient()279 void WallpaperService::RemoveExtensionDeathRecipient()
280 {
281 if (extensionRemoteObject_ != nullptr && recipient_ != nullptr) {
282 HILOG_INFO("Remove Extension DeathRecipient");
283 std::lock_guard<std::mutex> lock(remoteObjectMutex_);
284 extensionRemoteObject_->RemoveDeathRecipient(recipient_);
285 recipient_ = nullptr;
286 extensionRemoteObject_ = nullptr;
287 }
288 }
289
InitQueryUserId(int32_t times)290 void WallpaperService::InitQueryUserId(int32_t times)
291 {
292 times--;
293 bool ret = InitUsersOnBoot();
294 if (!ret && times > 0) {
295 HILOG_INFO("InitQueryUserId failed");
296 auto callback = [this, times]() { InitQueryUserId(times); };
297 serviceHandler_->PostTask(callback, QUERY_USER_ID_INTERVAL);
298 }
299 }
300
StartExtensionAbility(int32_t times)301 void WallpaperService::StartExtensionAbility(int32_t times)
302 {
303 times--;
304 bool ret = ConnectExtensionAbility();
305 if (!ret && times > 0 && serviceHandler_ != nullptr) {
306 HILOG_ERROR("StartExtensionAbilty failed, remainder of the times: %{public}d", times);
307 auto callback = [this, times]() { StartExtensionAbility(times); };
308 serviceHandler_->PostTask(callback, CONNECT_EXTENSION_INTERVAL);
309 }
310 }
311
InitUsersOnBoot()312 bool WallpaperService::InitUsersOnBoot()
313 {
314 std::vector<int32_t> userIds;
315 if (AccountSA::OsAccountManager::QueryActiveOsAccountIds(userIds) != ERR_OK || userIds.empty()) {
316 HILOG_INFO("WallpaperService: failed to get current userIds");
317 return false;
318 }
319 HILOG_INFO("WallpaperService::get current userIds success, Current userId: %{public}d", userIds[0]);
320 for (auto userId : userIds) {
321 InitUserDir(userId);
322 LoadSettingsLocked(userId, true);
323 InitResources(userId, WALLPAPER_SYSTEM);
324 InitResources(userId, WALLPAPER_LOCKSCREEN);
325 }
326 return true;
327 }
328
OnInitUser(int32_t userId)329 void WallpaperService::OnInitUser(int32_t userId)
330 {
331 if (userId < 0) {
332 HILOG_ERROR("userId error, userId = %{public}d", userId);
333 return;
334 }
335 std::string userDir = WALLPAPER_USERID_PATH + std::to_string(userId);
336 if (FileDeal::IsFileExist(userDir)) {
337 std::lock_guard<std::mutex> lock(mtx_);
338 if (!OHOS::ForceRemoveDirectory(userDir)) {
339 HILOG_ERROR("Force remove user directory path failed, errno %{public}d, userId:%{public}d", errno, userId);
340 return;
341 }
342 }
343 if (!InitUserDir(userId)) {
344 return;
345 }
346 LoadSettingsLocked(userId, true);
347 InitResources(userId, WALLPAPER_SYSTEM);
348 InitResources(userId, WALLPAPER_LOCKSCREEN);
349 HILOG_INFO("OnInitUser success, userId = %{public}d", userId);
350 }
351
InitResources(int32_t userId,WallpaperType wallpaperType)352 void WallpaperService::InitResources(int32_t userId, WallpaperType wallpaperType)
353 {
354 std::string pathName;
355 if (!GetFileNameFromMap(userId, wallpaperType, pathName)) {
356 HILOG_ERROR("Get user file name from map failed, userId = %{public}d", userId);
357 return;
358 }
359 if (!FileDeal::IsFileExist(pathName)) {
360 WallpaperData wallpaperData;
361 if (!GetWallpaperSafeLocked(userId, wallpaperType, wallpaperData)) {
362 HILOG_ERROR("Get wallpaper data failed, userId = %{public}d", userId);
363 return;
364 }
365 if (!RestoreUserResources(wallpaperData, wallpaperType)) {
366 HILOG_ERROR("RestoreUserResources error");
367 return;
368 }
369 }
370 }
371
InitUserDir(int32_t userId)372 bool WallpaperService::InitUserDir(int32_t userId)
373 {
374 std::string userDir = WALLPAPER_USERID_PATH + std::to_string(userId);
375 if (!FileDeal::Mkdir(userDir)) {
376 HILOG_ERROR("Failed to create destination path, userId:%{public}d ", userId);
377 return false;
378 }
379 std::string wallpaperSystemFilePath = userDir + "/" + WALLPAPER_SYSTEM_DIRNAME;
380 if (!FileDeal::Mkdir(wallpaperSystemFilePath)) {
381 HILOG_ERROR("Failed to create destination wallpaper system path, userId:%{public}d, type:%{public}s", userId,
382 WALLPAPER_SYSTEM_DIRNAME);
383 return false;
384 }
385 std::string wallpaperLockScreenFilePath = userDir + "/" + WALLPAPER_LOCKSCREEN_DIRNAME;
386 if (!FileDeal::Mkdir(wallpaperLockScreenFilePath)) {
387 HILOG_ERROR("Failed to create destination wallpaper lockscreen path, userId:%{public}d, type:%{public}s",
388 userId, WALLPAPER_LOCKSCREEN_DIRNAME);
389 return false;
390 }
391 return true;
392 }
393
RestoreUserResources(const WallpaperData & wallpaperData,WallpaperType wallpaperType)394 bool WallpaperService::RestoreUserResources(const WallpaperData &wallpaperData, WallpaperType wallpaperType)
395 {
396 std::string wallpaperDefaultPath = wallpaperType == WallpaperType::WALLPAPER_SYSTEM
397 ? WALLPAPER_DEFAULT_FILEFULLPATH
398 : WALLPAPER_DEFAULT_LOCK_FILEFULLPATH;
399 if (wallpaperType == WallpaperType::WALLPAPER_SYSTEM) {
400 if (FileDeal::IsFileExist(WALLPAPER_PREFABRICATE_FILEFULLPATH)) {
401 wallpaperDefaultPath = WALLPAPER_PREFABRICATE_FILEFULLPATH;
402 }
403 } else {
404 if (FileDeal::IsFileExist(WALLPAPER_PREFABRICATE_LOCK_FILEFULLPATH)) {
405 wallpaperDefaultPath = WALLPAPER_PREFABRICATE_LOCK_FILEFULLPATH;
406 }
407 }
408 if (!FileDeal::IsFileExist(wallpaperDefaultPath) ||
409 !FileDeal::IsFileExist(GetWallpaperDir(wallpaperData.userId, wallpaperType))) {
410 HILOG_INFO("Copy file path is not exist");
411 return false;
412 }
413 std::lock_guard<std::mutex> lock(mtx_);
414 if (!FileDeal::CopyFile(wallpaperDefaultPath, wallpaperData.wallpaperFile)) {
415 HILOG_INFO("CopyFile WALLPAPER_DEFAULT_FILEFULLPATH failed");
416 return false;
417 }
418 HILOG_INFO("Restore user resources end ");
419 return true;
420 }
421
OnRemovedUser(int32_t userId)422 void WallpaperService::OnRemovedUser(int32_t userId)
423 {
424 if (userId < 0) {
425 HILOG_ERROR("userId error, userId = %{public}d", userId);
426 return;
427 }
428 ClearWallpaperLocked(userId, WALLPAPER_SYSTEM);
429 ClearWallpaperLocked(userId, WALLPAPER_LOCKSCREEN);
430 std::string userDir = WALLPAPER_USERID_PATH + std::to_string(userId);
431 std::lock_guard<std::mutex> lock(mtx_);
432 if (!OHOS::ForceRemoveDirectory(userDir)) {
433 HILOG_ERROR("Force remove user directory path failed, errno %{public}d.", errno);
434 }
435 HILOG_INFO("OnRemovedUser end, userId = %{public}d", userId);
436 }
437
OnSwitchedUser(int32_t userId)438 void WallpaperService::OnSwitchedUser(int32_t userId)
439 {
440 if (userId < 0) {
441 HILOG_ERROR("userId error, userId = %{public}d", userId);
442 return;
443 }
444 RemoveExtensionDeathRecipient();
445 ConnectExtensionAbility();
446 std::string userDir = WALLPAPER_USERID_PATH + std::to_string(userId);
447 LoadSettingsLocked(userId, true);
448 if (!FileDeal::IsFileExist(userDir)) {
449 HILOG_INFO("User file is not exist, userId = %{public}d", userId);
450 InitUserDir(userId);
451 InitResources(userId, WALLPAPER_SYSTEM);
452 InitResources(userId, WALLPAPER_LOCKSCREEN);
453 }
454 LoadWallpaperState();
455 GrantUriPermissionByUserId(userId);
456 SendWallpaperChangeEvent(userId, WALLPAPER_SYSTEM);
457 SendWallpaperChangeEvent(userId, WALLPAPER_LOCKSCREEN);
458 SaveColor(userId, WALLPAPER_SYSTEM);
459 SaveColor(userId, WALLPAPER_LOCKSCREEN);
460 HILOG_INFO("OnSwitchedUser end, newUserId = %{public}d", userId);
461 }
462
GrantUriPermissionByUserId(int32_t userId)463 void WallpaperService::GrantUriPermissionByUserId(int32_t userId)
464 {
465 WallpaperData systemData;
466 WallpaperData lockScreenData;
467 if (!GetWallpaperSafeLocked(userId, WALLPAPER_SYSTEM, systemData) ||
468 !GetWallpaperSafeLocked(userId, WALLPAPER_LOCKSCREEN, lockScreenData)) {
469 return;
470 }
471 if (systemData.resourceType == PACKAGE) {
472 GrantUriPermission(systemData.customPackageUri, appBundleName_);
473 }
474 if (lockScreenData.resourceType == PACKAGE) {
475 GrantUriPermission(lockScreenData.customPackageUri, appBundleName_);
476 }
477 }
478
OnBootPhase()479 void WallpaperService::OnBootPhase()
480 {
481 HILOG_INFO("WallpaperService OnBootPhase");
482 }
483
GetWallpaperDir(int32_t userId,WallpaperType wallpaperType)484 std::string WallpaperService::GetWallpaperDir(int32_t userId, WallpaperType wallpaperType)
485 {
486 std::string userIdPath = WALLPAPER_USERID_PATH + std::to_string(userId);
487 std::string wallpaperFilePath;
488 if (wallpaperType == WALLPAPER_SYSTEM) {
489 wallpaperFilePath = userIdPath + "/" + WALLPAPER_SYSTEM_DIRNAME;
490 } else if (wallpaperType == WALLPAPER_LOCKSCREEN) {
491 wallpaperFilePath = userIdPath + "/" + WALLPAPER_LOCKSCREEN_DIRNAME;
492 }
493 return wallpaperFilePath;
494 }
495
GetFileNameFromMap(int32_t userId,WallpaperType wallpaperType,std::string & filePathName)496 bool WallpaperService::GetFileNameFromMap(int32_t userId, WallpaperType wallpaperType, std::string &filePathName)
497 {
498 auto iterator = wallpaperType == WALLPAPER_SYSTEM ? systemWallpaperMap_.Find(userId)
499 : lockWallpaperMap_.Find(userId);
500 if (!iterator.first) {
501 HILOG_ERROR("system wallpaper already cleared");
502 return false;
503 }
504 HILOG_INFO("GetFileNameFromMap resourceType : %{public}d", static_cast<int32_t>(iterator.second.resourceType));
505 switch (iterator.second.resourceType) {
506 case PICTURE:
507 filePathName = iterator.second.wallpaperFile;
508 break;
509 case VIDEO:
510 filePathName = iterator.second.liveWallpaperFile;
511 break;
512 case DEFAULT:
513 filePathName = iterator.second.wallpaperFile;
514 break;
515 case PACKAGE:
516 filePathName = iterator.second.customPackageUri;
517 break;
518 default:
519 filePathName = "";
520 break;
521 }
522 return filePathName != "";
523 }
524
GetPictureFileName(int32_t userId,WallpaperType wallpaperType,std::string & filePathName)525 bool WallpaperService::GetPictureFileName(int32_t userId, WallpaperType wallpaperType, std::string &filePathName)
526 {
527 auto iterator = wallpaperType == WALLPAPER_SYSTEM ? systemWallpaperMap_.Find(userId)
528 : lockWallpaperMap_.Find(userId);
529 if (!iterator.first) {
530 HILOG_ERROR("system wallpaper already cleared");
531 return false;
532 }
533 filePathName = iterator.second.wallpaperFile;
534 HILOG_INFO("GetPictureFileName filePathName : %{public}s", filePathName.c_str());
535 return filePathName != "";
536 }
537
MakeWallpaperIdLocked()538 int32_t WallpaperService::MakeWallpaperIdLocked()
539 {
540 HILOG_INFO("MakeWallpaperIdLocked start");
541 if (wallpaperId_ == INT32_MAX) {
542 wallpaperId_ = DEFAULT_WALLPAPER_ID;
543 }
544 return ++wallpaperId_;
545 }
546
LoadSettingsLocked(int32_t userId,bool keepDimensionHints)547 void WallpaperService::LoadSettingsLocked(int32_t userId, bool keepDimensionHints)
548 {
549 HILOG_INFO("load Setting locked start.");
550 if (!systemWallpaperMap_.Contains(userId)) {
551 HILOG_INFO("systemWallpaperMap_ does not contains userId");
552 std::string wallpaperSystemFilePath = GetWallpaperDir(userId, WALLPAPER_SYSTEM);
553 WallpaperData wallpaperSystem(userId, wallpaperSystemFilePath + "/" + WALLPAPER_SYSTEM_ORIG);
554 wallpaperSystem.liveWallpaperFile = wallpaperSystemFilePath + "/" + LIVE_WALLPAPER_SYSTEM_ORIG;
555 wallpaperSystem.customPackageUri = wallpaperSystemFilePath + "/" + CUSTOM_WALLPAPER_SYSTEM;
556 wallpaperSystem.allowBackup = true;
557 wallpaperSystem.resourceType = PICTURE;
558 wallpaperSystem.wallpaperId = DEFAULT_WALLPAPER_ID;
559 systemWallpaperMap_.InsertOrAssign(userId, wallpaperSystem);
560 }
561 if (!lockWallpaperMap_.Contains(userId)) {
562 HILOG_INFO("lockWallpaperMap_ does not Contains userId");
563 std::string wallpaperLockScreenFilePath = GetWallpaperDir(userId, WALLPAPER_LOCKSCREEN);
564 WallpaperData wallpaperLock(userId, wallpaperLockScreenFilePath + "/" + WALLPAPER_LOCK_ORIG);
565 wallpaperLock.liveWallpaperFile = wallpaperLockScreenFilePath + "/" + LIVE_WALLPAPER_LOCK_ORIG;
566 wallpaperLock.customPackageUri = wallpaperLockScreenFilePath + "/" + CUSTOM_WALLPAPER_LOCK;
567 wallpaperLock.allowBackup = true;
568 wallpaperLock.resourceType = PICTURE;
569 wallpaperLock.wallpaperId = DEFAULT_WALLPAPER_ID;
570 lockWallpaperMap_.InsertOrAssign(userId, wallpaperLock);
571 }
572 HILOG_INFO("load Setting locked end.");
573 }
574
GetColors(int32_t wallpaperType,std::vector<uint64_t> & colors)575 ErrorCode WallpaperService::GetColors(int32_t wallpaperType, std::vector<uint64_t> &colors)
576 {
577 if (wallpaperType == WALLPAPER_SYSTEM) {
578 colors.emplace_back(systemWallpaperColor_);
579 } else if (wallpaperType == WALLPAPER_LOCKSCREEN) {
580 colors.emplace_back(lockWallpaperColor_);
581 }
582 HILOG_INFO(" Service End!");
583 return E_OK;
584 }
585
GetColorsV9(int32_t wallpaperType,std::vector<uint64_t> & colors)586 ErrorCode WallpaperService::GetColorsV9(int32_t wallpaperType, std::vector<uint64_t> &colors)
587 {
588 if (!IsSystemApp()) {
589 HILOG_INFO("CallingApp is not SystemApp");
590 return E_NOT_SYSTEM_APP;
591 }
592 return GetColors(wallpaperType, colors);
593 }
594
GetFile(int32_t wallpaperType,int32_t & wallpaperFd)595 ErrorCode WallpaperService::GetFile(int32_t wallpaperType, int32_t &wallpaperFd)
596 {
597 if (!CheckCallingPermission(WALLPAPER_PERMISSION_NAME_GET_WALLPAPER)) {
598 HILOG_ERROR("GetPixelMap no get permission!");
599 return E_NO_PERMISSION;
600 }
601 if (wallpaperType != static_cast<int32_t>(WALLPAPER_LOCKSCREEN) &&
602 wallpaperType != static_cast<int32_t>(WALLPAPER_SYSTEM)) {
603 return E_PARAMETERS_INVALID;
604 }
605 auto type = static_cast<WallpaperType>(wallpaperType);
606 int32_t userId = QueryActiveUserId();
607 if (GetResType(userId, type) == WallpaperResourceType::PACKAGE) {
608 HILOG_ERROR("Current user's wallpaper is custom package");
609 wallpaperFd = -1; // -1: invalid file description
610 return E_OK;
611 }
612 HILOG_INFO("QueryCurrentOsAccount userId: %{public}d", userId);
613 ErrorCode ret = GetImageFd(userId, type, wallpaperFd);
614 HILOG_INFO("GetImageFd fd:%{public}d, ret:%{public}d", wallpaperFd, ret);
615 return ret;
616 }
617
CompareColor(const uint64_t & localColor,const ColorManager::Color & color)618 bool WallpaperService::CompareColor(const uint64_t &localColor, const ColorManager::Color &color)
619 {
620 return localColor == color.PackValue();
621 }
622
SaveColor(int32_t userId,WallpaperType wallpaperType)623 bool WallpaperService::SaveColor(int32_t userId, WallpaperType wallpaperType)
624 {
625 uint32_t errorCode = 0;
626 OHOS::Media::SourceOptions opts;
627 opts.formatHint = "image/jpeg";
628 std::string pathName;
629 if (!GetPictureFileName(userId, wallpaperType, pathName)) {
630 return false;
631 }
632 std::unique_ptr<OHOS::Media::ImageSource> imageSource =
633 OHOS::Media::ImageSource::CreateImageSource(pathName, opts, errorCode);
634 if (errorCode != 0) {
635 HILOG_ERROR("CreateImageSource failed");
636 return false;
637 }
638 OHOS::Media::DecodeOptions decodeOpts;
639 std::unique_ptr<PixelMap> wallpaperPixelMap = imageSource->CreatePixelMap(decodeOpts, errorCode);
640 if (errorCode != 0) {
641 HILOG_ERROR("CreatePixelMap failed");
642 return false;
643 }
644
645 pictureHeight_ = wallpaperPixelMap->GetHeight();
646 pictureWidth_ = wallpaperPixelMap->GetWidth();
647
648 auto colorPicker = Rosen::ColorPicker::CreateColorPicker(std::move(wallpaperPixelMap), errorCode);
649 if (errorCode != 0) {
650 HILOG_ERROR("CreateColorPicker failed");
651 return false;
652 }
653 auto color = ColorManager::Color();
654 uint32_t ret = colorPicker->GetMainColor(color);
655 if (ret != Rosen::SUCCESS) {
656 HILOG_ERROR("GetMainColor failed ret is : %{public}d", ret);
657 return false;
658 }
659 OnColorsChange(wallpaperType, color);
660 return true;
661 }
662
SetWallpaper(int32_t fd,int32_t wallpaperType,int32_t length)663 ErrorCode WallpaperService::SetWallpaper(int32_t fd, int32_t wallpaperType, int32_t length)
664 {
665 StartAsyncTrace(HITRACE_TAG_MISC, "SetWallpaper", static_cast<int32_t>(TraceTaskId::SET_WALLPAPER));
666 ErrorCode wallpaperErrorCode = SetWallpaper(fd, wallpaperType, length, PICTURE);
667 FinishAsyncTrace(HITRACE_TAG_MISC, "SetWallpaper", static_cast<int32_t>(TraceTaskId::SET_WALLPAPER));
668 return wallpaperErrorCode;
669 }
670
SetWallpaperV9(int32_t fd,int32_t wallpaperType,int32_t length)671 ErrorCode WallpaperService::SetWallpaperV9(int32_t fd, int32_t wallpaperType, int32_t length)
672 {
673 if (!IsSystemApp()) {
674 HILOG_INFO("CallingApp is not SystemApp");
675 return E_NOT_SYSTEM_APP;
676 }
677 return SetWallpaper(fd, wallpaperType, length);
678 }
679
SetWallpaperBackupData(int32_t userId,WallpaperResourceType resourceType,const std::string & uriOrPixelMap,WallpaperType wallpaperType)680 ErrorCode WallpaperService::SetWallpaperBackupData(int32_t userId, WallpaperResourceType resourceType,
681 const std::string &uriOrPixelMap, WallpaperType wallpaperType)
682 {
683 HILOG_INFO("set wallpaper and backup data Start.");
684 if (!OHOS::FileExists(uriOrPixelMap)) {
685 return E_DEAL_FAILED;
686 }
687 WallpaperData wallpaperData;
688 bool ret = GetWallpaperSafeLocked(userId, wallpaperType, wallpaperData);
689 if (!ret) {
690 HILOG_ERROR("GetWallpaperSafeLocked failed !");
691 return E_DEAL_FAILED;
692 }
693 wallpaperData.resourceType = resourceType;
694 wallpaperData.wallpaperId = MakeWallpaperIdLocked();
695 std::string wallpaperFile = resourceType == VIDEO ? wallpaperData.liveWallpaperFile : wallpaperData.wallpaperFile;
696 if (!FileDeal::CopyFile(uriOrPixelMap, wallpaperFile)) {
697 HILOG_ERROR("CopyFile failed !");
698 return E_DEAL_FAILED;
699 }
700 if (!FileDeal::DeleteFile(uriOrPixelMap)) {
701 return E_DEAL_FAILED;
702 }
703 if (!SaveWallpaperState(userId, wallpaperType)) {
704 HILOG_ERROR("Save wallpaper state failed!");
705 }
706 if (wallpaperType == WALLPAPER_SYSTEM) {
707 systemWallpaperMap_.InsertOrAssign(userId, wallpaperData);
708 } else if (wallpaperType == WALLPAPER_LOCKSCREEN) {
709 lockWallpaperMap_.InsertOrAssign(userId, wallpaperData);
710 }
711 if (!SendWallpaperChangeEvent(userId, wallpaperType)) {
712 HILOG_ERROR("Send wallpaper state failed!");
713 return E_DEAL_FAILED;
714 }
715 return E_OK;
716 }
717
GetResType(int32_t userId,WallpaperType wallpaperType)718 WallpaperResourceType WallpaperService::GetResType(int32_t userId, WallpaperType wallpaperType)
719 {
720 if (wallpaperType == WALLPAPER_LOCKSCREEN) {
721 auto iterator = lockWallpaperMap_.Find(userId);
722 if (iterator.first) {
723 return iterator.second.resourceType;
724 }
725 } else if (wallpaperType == WALLPAPER_SYSTEM) {
726 auto iterator = systemWallpaperMap_.Find(userId);
727 if (iterator.first) {
728 return iterator.second.resourceType;
729 }
730 }
731 return WallpaperResourceType::DEFAULT;
732 }
733
SendEvent(const std::string & eventType)734 ErrorCode WallpaperService::SendEvent(const std::string &eventType)
735 {
736 HILOG_DEBUG("Send event start.");
737 if (!CheckCallingPermission(WALLPAPER_PERMISSION_NAME_SET_WALLPAPER)) {
738 HILOG_ERROR("Send event not set permission!");
739 return E_NO_PERMISSION;
740 }
741
742 int32_t userId = QueryActiveUserId();
743 WallpaperType wallpaperType;
744 WallpaperData data;
745 if (eventType == SHOW_SYSTEM_SCREEN) {
746 wallpaperType = WALLPAPER_SYSTEM;
747 } else if (eventType == SHOW_LOCK_SCREEN) {
748 wallpaperType = WALLPAPER_LOCKSCREEN;
749 } else {
750 HILOG_ERROR("Event type error!");
751 return E_PARAMETERS_INVALID;
752 }
753
754 if (!GetWallpaperSafeLocked(userId, wallpaperType, data)) {
755 HILOG_ERROR("Get wallpaper safe locked failed!");
756 return E_PARAMETERS_INVALID;
757 }
758 std::string uri;
759 GetFileNameFromMap(userId, WALLPAPER_SYSTEM, uri);
760 WallpaperChanged(wallpaperType, data.resourceType, uri);
761 return E_OK;
762 }
763
SendWallpaperChangeEvent(int32_t userId,WallpaperType wallpaperType)764 bool WallpaperService::SendWallpaperChangeEvent(int32_t userId, WallpaperType wallpaperType)
765 {
766 WallpaperData wallpaperData;
767 if (!GetWallpaperSafeLocked(userId, wallpaperType, wallpaperData)) {
768 HILOG_ERROR("GetWallpaperSafeLocked failed !");
769 return false;
770 }
771 shared_ptr<WallpaperCommonEventManager> wallpaperCommonEventManager = make_shared<WallpaperCommonEventManager>();
772 if (wallpaperType == WALLPAPER_SYSTEM) {
773 HILOG_INFO("Send wallpaper system setting message");
774 wallpaperCommonEventManager->SendWallpaperSystemSettingMessage(wallpaperData.resourceType);
775 } else if (wallpaperType == WALLPAPER_LOCKSCREEN) {
776 HILOG_INFO("Send wallpaper lock setting message");
777 wallpaperCommonEventManager->SendWallpaperLockSettingMessage(wallpaperData.resourceType);
778 }
779 HILOG_INFO("SetWallpaperBackupData callbackProxy_->OnCall start");
780 if (callbackProxy_ != nullptr && (wallpaperData.resourceType == PICTURE || wallpaperData.resourceType == DEFAULT)) {
781 callbackProxy_->OnCall(wallpaperType);
782 }
783 std::string uri;
784 WallpaperChanged(wallpaperType, wallpaperData.resourceType, uri);
785 return true;
786 }
787
SetVideo(int32_t fd,int32_t wallpaperType,int32_t length)788 ErrorCode WallpaperService::SetVideo(int32_t fd, int32_t wallpaperType, int32_t length)
789 {
790 if (!IsSystemApp()) {
791 HILOG_ERROR("current app is not SystemApp");
792 return E_NOT_SYSTEM_APP;
793 }
794 StartAsyncTrace(HITRACE_TAG_MISC, "SetVideo", static_cast<int32_t>(TraceTaskId::SET_VIDEO));
795 ErrorCode wallpaperErrorCode = SetWallpaper(fd, wallpaperType, length, VIDEO);
796 FinishAsyncTrace(HITRACE_TAG_MISC, "SetVideo", static_cast<int32_t>(TraceTaskId::SET_VIDEO));
797 return wallpaperErrorCode;
798 }
799
SetCustomWallpaper(const std::string & uri,int32_t type)800 ErrorCode WallpaperService::SetCustomWallpaper(const std::string &uri, int32_t type)
801 {
802 if (!IsSystemApp()) {
803 HILOG_ERROR("current app is not SystemApp");
804 return E_NOT_SYSTEM_APP;
805 }
806 if (!CheckCallingPermission(WALLPAPER_PERMISSION_NAME_SET_WALLPAPER)) {
807 HILOG_INFO("SetWallpaper no set permission!");
808 return E_NO_PERMISSION;
809 }
810 if (type != static_cast<int32_t>(WALLPAPER_LOCKSCREEN) && type != static_cast<int32_t>(WALLPAPER_SYSTEM)) {
811 return E_PARAMETERS_INVALID;
812 }
813 StartAsyncTrace(HITRACE_TAG_MISC, "SetCustomWallpaper", static_cast<int32_t>(TraceTaskId::SET_CUSTOM_WALLPAPER));
814 int32_t userId = QueryActiveUserId();
815 WallpaperType wallpaperType = static_cast<WallpaperType>(type);
816 WallpaperData wallpaperData;
817 if (!GetWallpaperSafeLocked(userId, wallpaperType, wallpaperData)) {
818 HILOG_ERROR("GetWallpaper data failed!");
819 return E_DEAL_FAILED;
820 }
821 if (!Rosen::SceneBoardJudgement::IsSceneBoardEnabled()) {
822 HILOG_ERROR("SceneBoard is not Enabled");
823 return E_NO_PERMISSION;
824 }
825 wallpaperData.resourceType = PACKAGE;
826 wallpaperData.wallpaperId = MakeWallpaperIdLocked();
827 if (wallpaperType == WALLPAPER_SYSTEM) {
828 systemWallpaperMap_.InsertOrAssign(userId, wallpaperData);
829 } else if (wallpaperType == WALLPAPER_LOCKSCREEN) {
830 lockWallpaperMap_.InsertOrAssign(userId, wallpaperData);
831 }
832 if (!SaveWallpaperState(userId, wallpaperType)) {
833 HILOG_ERROR("Save wallpaper state failed!");
834 }
835 if (!SendWallpaperChangeEvent(userId, wallpaperType)) {
836 HILOG_ERROR("Send wallpaper state failed!");
837 return E_DEAL_FAILED;
838 }
839 FinishAsyncTrace(HITRACE_TAG_MISC, "SetCustomWallpaper", static_cast<int32_t>(TraceTaskId::SET_CUSTOM_WALLPAPER));
840 return E_OK;
841 }
842
GetPixelMap(int32_t wallpaperType,IWallpaperService::FdInfo & fdInfo)843 ErrorCode WallpaperService::GetPixelMap(int32_t wallpaperType, IWallpaperService::FdInfo &fdInfo)
844 {
845 HILOG_INFO("WallpaperService::getPixelMap start ");
846 if (!CheckCallingPermission(WALLPAPER_PERMISSION_NAME_GET_WALLPAPER)) {
847 HILOG_INFO("GetPixelMap no get permission!");
848 return E_NO_PERMISSION;
849 }
850 if (!IsSystemApp()) {
851 HILOG_INFO("CallingApp is not SystemApp");
852 return E_NOT_SYSTEM_APP;
853 }
854 if (wallpaperType != static_cast<int32_t>(WALLPAPER_LOCKSCREEN) &&
855 wallpaperType != static_cast<int32_t>(WALLPAPER_SYSTEM)) {
856 return E_PARAMETERS_INVALID;
857 }
858 auto type = static_cast<WallpaperType>(wallpaperType);
859 int32_t userId = QueryActiveUserId();
860 HILOG_INFO("QueryCurrentOsAccount userId: %{public}d", userId);
861 // current user's wallpaper is live video, not image
862 WallpaperResourceType resType = GetResType(userId, type);
863 if (resType != PICTURE && resType != DEFAULT) {
864 HILOG_ERROR("Current user's wallpaper is live video, not image");
865 fdInfo.size = 0; // 0: empty file size
866 fdInfo.fd = -1; // -1: invalid file description
867 return E_OK;
868 }
869 ErrorCode ret = GetImageSize(userId, type, fdInfo.size);
870 if (ret != E_OK) {
871 HILOG_ERROR("GetImageSize failed");
872 return ret;
873 }
874 ret = GetImageFd(userId, type, fdInfo.fd);
875 if (ret != E_OK) {
876 HILOG_ERROR("GetImageFd failed");
877 return ret;
878 }
879 return E_OK;
880 }
881
GetPixelMapV9(int32_t wallpaperType,IWallpaperService::FdInfo & fdInfo)882 ErrorCode WallpaperService::GetPixelMapV9(int32_t wallpaperType, IWallpaperService::FdInfo &fdInfo)
883 {
884 return GetPixelMap(wallpaperType, fdInfo);
885 }
886
GetWallpaperId(int32_t wallpaperType)887 int32_t WallpaperService::GetWallpaperId(int32_t wallpaperType)
888 {
889 HILOG_INFO("WallpaperService::GetWallpaperId --> start ");
890 int32_t iWallpaperId = -1;
891 int32_t userId = QueryActiveUserId();
892 HILOG_INFO("QueryCurrentOsAccount userId: %{public}d", userId);
893 if (wallpaperType == WALLPAPER_LOCKSCREEN) {
894 auto iterator = lockWallpaperMap_.Find(userId);
895 if (iterator.first) {
896 iWallpaperId = iterator.second.wallpaperId;
897 }
898 } else if (wallpaperType == WALLPAPER_SYSTEM) {
899 auto iterator = systemWallpaperMap_.Find(userId);
900 if (iterator.first) {
901 iWallpaperId = iterator.second.wallpaperId;
902 }
903 }
904 HILOG_INFO("WallpaperService::GetWallpaperId --> end ID[%{public}d]", iWallpaperId);
905 return iWallpaperId;
906 }
907
IsChangePermitted()908 bool WallpaperService::IsChangePermitted()
909 {
910 HILOG_INFO("IsChangePermitted wallpaper Start!");
911 bool bFlag = CheckCallingPermission(WALLPAPER_PERMISSION_NAME_SET_WALLPAPER);
912 return bFlag;
913 }
914
IsOperationAllowed()915 bool WallpaperService::IsOperationAllowed()
916 {
917 HILOG_INFO("IsOperationAllowed wallpaper Start!");
918 bool bFlag = CheckCallingPermission(WALLPAPER_PERMISSION_NAME_SET_WALLPAPER);
919 return bFlag;
920 }
921
ResetWallpaper(int32_t wallpaperType)922 ErrorCode WallpaperService::ResetWallpaper(int32_t wallpaperType)
923 {
924 HILOG_INFO("reset wallpaper Start!");
925 bool permissionSet = CheckCallingPermission(WALLPAPER_PERMISSION_NAME_SET_WALLPAPER);
926 if (!permissionSet) {
927 HILOG_INFO("reset wallpaper no set permission!");
928 return E_NO_PERMISSION;
929 }
930
931 if (wallpaperType != static_cast<int32_t>(WALLPAPER_LOCKSCREEN) &&
932 wallpaperType != static_cast<int32_t>(WALLPAPER_SYSTEM)) {
933 HILOG_INFO("wallpaperType = %{public}d type not support ", wallpaperType);
934 return E_PARAMETERS_INVALID;
935 }
936 WallpaperType type = static_cast<WallpaperType>(wallpaperType);
937 int32_t userId = QueryActiveUserId();
938 HILOG_INFO("QueryCurrentOsAccount userId: %{public}d", userId);
939 if (!CheckUserPermissionById(userId)) {
940 return E_USER_IDENTITY_ERROR;
941 }
942 ErrorCode wallpaperErrorCode = SetDefaultDataForWallpaper(userId, type);
943 HILOG_INFO(" Set default data result[%{public}d]", wallpaperErrorCode);
944 return wallpaperErrorCode;
945 }
946
ResetWallpaperV9(int32_t wallpaperType)947 ErrorCode WallpaperService::ResetWallpaperV9(int32_t wallpaperType)
948 {
949 if (!IsSystemApp()) {
950 HILOG_INFO("CallingApp is not SystemApp");
951 return E_NOT_SYSTEM_APP;
952 }
953 return ResetWallpaper(wallpaperType);
954 }
955
SetDefaultDataForWallpaper(int32_t userId,WallpaperType wallpaperType)956 ErrorCode WallpaperService::SetDefaultDataForWallpaper(int32_t userId, WallpaperType wallpaperType)
957 {
958 WallpaperData wallpaperData;
959 if (!GetWallpaperSafeLocked(userId, wallpaperType, wallpaperData)) {
960 return E_DEAL_FAILED;
961 }
962 if (!RestoreUserResources(wallpaperData, wallpaperType)) {
963 HILOG_ERROR("RestoreUserResources error");
964 return E_DEAL_FAILED;
965 }
966 wallpaperData.wallpaperId = DEFAULT_WALLPAPER_ID;
967 wallpaperData.allowBackup = true;
968 if (wallpaperType == WALLPAPER_LOCKSCREEN) {
969 lockWallpaperMap_.InsertOrAssign(userId, wallpaperData);
970 } else if (wallpaperType == WALLPAPER_SYSTEM) {
971 systemWallpaperMap_.InsertOrAssign(userId, wallpaperData);
972 }
973 if (!SendWallpaperChangeEvent(userId, wallpaperType)) {
974 HILOG_ERROR("Send wallpaper state failed!");
975 return E_DEAL_FAILED;
976 }
977 SaveColor(userId, wallpaperType);
978 return E_OK;
979 }
980
On(const std::string & type,sptr<IWallpaperEventListener> listener)981 ErrorCode WallpaperService::On(const std::string &type, sptr<IWallpaperEventListener> listener)
982 {
983 HILOG_DEBUG("WallpaperService::On in");
984 if (listener == nullptr) {
985 HILOG_ERROR("WallpaperService::On listener is null");
986 return E_DEAL_FAILED;
987 }
988 if (type == WALLPAPER_CHANGE && !IsSystemApp()) {
989 HILOG_ERROR("current app is not SystemApp");
990 return E_NOT_SYSTEM_APP;
991 }
992 std::lock_guard<std::mutex> autoLock(listenerMapMutex_);
993 wallpaperEventMap_[type].insert_or_assign(IPCSkeleton::GetCallingTokenID(), listener);
994 HILOG_DEBUG("WallpaperService::On out");
995 return E_OK;
996 }
997
Off(const std::string & type,sptr<IWallpaperEventListener> listener)998 ErrorCode WallpaperService::Off(const std::string &type, sptr<IWallpaperEventListener> listener)
999 {
1000 HILOG_DEBUG("WallpaperService::Off in");
1001 (void)listener;
1002 if (type == WALLPAPER_CHANGE && !IsSystemApp()) {
1003 HILOG_ERROR("current app is not SystemApp");
1004 return E_NOT_SYSTEM_APP;
1005 }
1006 std::lock_guard<std::mutex> autoLock(listenerMapMutex_);
1007 auto iter = wallpaperEventMap_.find(type);
1008 if (iter != wallpaperEventMap_.end()) {
1009 auto it = iter->second.find(IPCSkeleton::GetCallingTokenID());
1010 if (it != iter->second.end()) {
1011 it->second = nullptr;
1012 iter->second.erase(it);
1013 }
1014 }
1015 HILOG_DEBUG("WallpaperService::Off out");
1016 return E_OK;
1017 }
1018
RegisterWallpaperCallback(const sptr<IWallpaperCallback> callback)1019 bool WallpaperService::RegisterWallpaperCallback(const sptr<IWallpaperCallback> callback)
1020 {
1021 HILOG_INFO(" WallpaperService::RegisterWallpaperCallback");
1022 callbackProxy_ = callback;
1023 return true;
1024 }
1025
GetWallpaperSafeLocked(int32_t userId,WallpaperType wallpaperType,WallpaperData & wallpaperData)1026 bool WallpaperService::GetWallpaperSafeLocked(int32_t userId, WallpaperType wallpaperType, WallpaperData &wallpaperData)
1027 {
1028 HILOG_INFO("function start.");
1029 auto iterator = wallpaperType == WALLPAPER_SYSTEM ? systemWallpaperMap_.Find(userId)
1030 : lockWallpaperMap_.Find(userId);
1031 if (!iterator.first) {
1032 HILOG_INFO(" No Lock wallpaper? Not tracking for lock-only ");
1033 LoadSettingsLocked(userId, true);
1034 iterator = wallpaperType == WALLPAPER_SYSTEM ? systemWallpaperMap_.Find(userId)
1035 : lockWallpaperMap_.Find(userId);
1036 if (!iterator.first) {
1037 HILOG_ERROR("Fail to get wallpaper data");
1038 return false;
1039 }
1040 }
1041 wallpaperData = iterator.second;
1042 return true;
1043 }
1044
ClearWallpaperLocked(int32_t userId,WallpaperType wallpaperType)1045 void WallpaperService::ClearWallpaperLocked(int32_t userId, WallpaperType wallpaperType)
1046 {
1047 HILOG_INFO("Clear wallpaper Start!");
1048 auto iterator = wallpaperType == WALLPAPER_SYSTEM ? systemWallpaperMap_.Find(userId)
1049 : lockWallpaperMap_.Find(userId);
1050 if (!iterator.first) {
1051 HILOG_INFO("Lock wallpaper already cleared");
1052 return;
1053 }
1054 if (!iterator.second.wallpaperFile.empty() || !iterator.second.liveWallpaperFile.empty()) {
1055 if (wallpaperType == WALLPAPER_LOCKSCREEN) {
1056 lockWallpaperMap_.Erase(userId);
1057 } else if (wallpaperType == WALLPAPER_SYSTEM) {
1058 systemWallpaperMap_.Erase(userId);
1059 }
1060 }
1061 HILOG_INFO("Clear wallpaper End!");
1062 }
1063
CheckCallingPermission(const std::string & permissionName)1064 bool WallpaperService::CheckCallingPermission(const std::string &permissionName)
1065 {
1066 bool bflag = false;
1067 int32_t result;
1068 AccessTokenID callerToken = IPCSkeleton::GetCallingTokenID();
1069 auto tokenType = AccessTokenKit::GetTokenTypeFlag(callerToken);
1070 if (tokenType == TOKEN_NATIVE || tokenType == TOKEN_SHELL || tokenType == TOKEN_HAP) {
1071 result = AccessTokenKit::VerifyAccessToken(callerToken, permissionName);
1072 } else {
1073 HILOG_INFO("Check permission tokenId illegal");
1074 return false;
1075 }
1076 if (result == TypePermissionState::PERMISSION_GRANTED) {
1077 bflag = true;
1078 } else {
1079 bflag = false;
1080 }
1081 HILOG_INFO("Check permission result %{public}d", result);
1082 return bflag;
1083 }
1084
GetBundleNameByUid(std::int32_t uid,std::string & bname)1085 bool WallpaperService::GetBundleNameByUid(std::int32_t uid, std::string &bname)
1086 {
1087 sptr<ISystemAbilityManager> systemMgr = SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager();
1088 if (systemMgr == nullptr) {
1089 HILOG_ERROR("Fail to get system ability mgr");
1090 return false;
1091 }
1092
1093 sptr<IRemoteObject> remoteObject = systemMgr->GetSystemAbility(BUNDLE_MGR_SERVICE_SYS_ABILITY_ID);
1094 if (remoteObject == nullptr) {
1095 HILOG_ERROR("Fail to get bundle manager proxy");
1096 return false;
1097 }
1098
1099 sptr<OHOS::AppExecFwk::IBundleMgr> bundleMgrProxy = iface_cast<OHOS::AppExecFwk::IBundleMgr>(remoteObject);
1100 if (bundleMgrProxy == nullptr) {
1101 HILOG_ERROR("Bundle mgr proxy is nullptr");
1102 return false;
1103 }
1104
1105 ErrCode errCode = bundleMgrProxy->GetNameForUid(uid, bname);
1106 if (errCode != ERR_OK) {
1107 HILOG_ERROR("Get bundle name failed errcode:%{public}d", errCode);
1108 return false;
1109 }
1110 HILOG_INFO("Get bundle name is %{public}s", bname.c_str());
1111 return true;
1112 }
1113
ReporterFault(FaultType faultType,FaultCode faultCode)1114 void WallpaperService::ReporterFault(FaultType faultType, FaultCode faultCode)
1115 {
1116 FaultMsg msg;
1117 msg.faultType = faultType;
1118 msg.errorCode = faultCode;
1119 ReportStatus nRet;
1120 if (faultType == FaultType::SERVICE_FAULT) {
1121 msg.moduleName = "WallpaperService";
1122 nRet = FaultReporter::ReportServiceFault(msg);
1123 } else {
1124 nRet = FaultReporter::ReportRuntimeFault(msg);
1125 }
1126
1127 if (nRet == ReportStatus::SUCCESS) {
1128 HILOG_INFO("ReporterFault success");
1129 } else {
1130 HILOG_ERROR("ReporterFault failed");
1131 }
1132 }
1133
Dump(int32_t fd,const std::vector<std::u16string> & args)1134 int32_t WallpaperService::Dump(int32_t fd, const std::vector<std::u16string> &args)
1135 {
1136 int32_t uid = static_cast<int32_t>(IPCSkeleton::GetCallingUid());
1137 const int32_t maxUid = 10000;
1138 if (uid > maxUid) {
1139 AccessTokenID callerToken = IPCSkeleton::GetCallingTokenID();
1140 auto tokenType = AccessTokenKit::GetTokenTypeFlag(callerToken);
1141 if (tokenType != TOKEN_NATIVE && tokenType != TOKEN_SHELL) {
1142 return 1;
1143 }
1144 }
1145
1146 std::vector<std::string> argsStr;
1147 for (auto item : args) {
1148 argsStr.emplace_back(Str16ToStr8(item));
1149 }
1150
1151 if (DumpHelper::GetInstance().Dispatch(fd, argsStr)) {
1152 HILOG_ERROR("DumpHelper Dispatch failed");
1153 return 0;
1154 }
1155 return 1;
1156 }
1157
ConnectExtensionAbility()1158 bool WallpaperService::ConnectExtensionAbility()
1159 {
1160 HILOG_DEBUG("ConnectAdapter");
1161 MemoryGuard cacheGuard;
1162 AAFwk::Want want;
1163 want.SetElementName(OHOS_WALLPAPER_BUNDLE_NAME, "WallpaperExtAbility");
1164 ErrCode errCode = AAFwk::AbilityManagerClient::GetInstance()->Connect();
1165 if (errCode != ERR_OK) {
1166 HILOG_ERROR("connect ability server failed errCode=%{public}d", errCode);
1167 return false;
1168 }
1169 if (connection_ == nullptr) {
1170 connection_ = new WallpaperExtensionAbilityConnection(*this);
1171 }
1172 auto ret = AAFwk::AbilityManagerClient::GetInstance()->ConnectExtensionAbility(want, connection_, DEFAULT_VALUE);
1173 HILOG_INFO("ConnectExtensionAbility errCode=%{public}d", ret);
1174 return ret;
1175 }
1176
IsSystemApp()1177 bool WallpaperService::IsSystemApp()
1178 {
1179 HILOG_INFO("IsSystemApp start");
1180 uint64_t tokenId = IPCSkeleton::GetCallingFullTokenID();
1181 return TokenIdKit::IsSystemAppByFullTokenID(tokenId);
1182 }
1183
GetImageFd(int32_t userId,WallpaperType wallpaperType,int32_t & fd)1184 ErrorCode WallpaperService::GetImageFd(int32_t userId, WallpaperType wallpaperType, int32_t &fd)
1185 {
1186 HILOG_INFO("WallpaperService::GetImageFd start ");
1187 std::string filePathName;
1188 if (!GetFileNameFromMap(userId, wallpaperType, filePathName)) {
1189 return E_DEAL_FAILED;
1190 }
1191 if (GetResType(userId, wallpaperType) == WallpaperResourceType::PACKAGE) {
1192 HILOG_INFO("The current wallpaper is a custom wallpaper");
1193 return E_OK;
1194 }
1195 {
1196 std::lock_guard<std::mutex> lock(mtx_);
1197 fd = open(filePathName.c_str(), O_RDONLY, S_IREAD);
1198 }
1199 if (fd < 0) {
1200 HILOG_ERROR("Open file failed, errno %{public}d", errno);
1201 ReporterFault(FaultType::LOAD_WALLPAPER_FAULT, FaultCode::RF_FD_INPUT_FAILED);
1202 return E_DEAL_FAILED;
1203 }
1204 HILOG_INFO("fd = %{public}d", fd);
1205 return E_OK;
1206 }
1207
GetImageSize(int32_t userId,WallpaperType wallpaperType,int32_t & size)1208 ErrorCode WallpaperService::GetImageSize(int32_t userId, WallpaperType wallpaperType, int32_t &size)
1209 {
1210 HILOG_INFO("WallpaperService::GetImageSize start ");
1211 std::string filePathName;
1212 HILOG_INFO("userId = %{public}d", userId);
1213 if (!GetPictureFileName(userId, wallpaperType, filePathName)) {
1214 return E_DEAL_FAILED;
1215 }
1216
1217 if (!OHOS::FileExists(filePathName)) {
1218 HILOG_ERROR("file is not exist!");
1219 return E_NOT_FOUND;
1220 }
1221 std::lock_guard<std::mutex> lock(mtx_);
1222 FILE *fd = fopen(filePathName.c_str(), "rb");
1223 if (fd == nullptr) {
1224 HILOG_ERROR("fopen file failed, errno %{public}d", errno);
1225 return E_FILE_ERROR;
1226 }
1227 int32_t fend = fseek(fd, 0, SEEK_END);
1228 size = ftell(fd);
1229 int32_t fset = fseek(fd, 0, SEEK_SET);
1230 if (size <= 0 || fend != 0 || fset != 0) {
1231 HILOG_ERROR("ftell file failed or fseek file failed, errno %{public}d", errno);
1232 fclose(fd);
1233 return E_FILE_ERROR;
1234 }
1235 fclose(fd);
1236 return E_OK;
1237 }
1238
BlockRetry(int64_t interval,uint32_t maxRetryTimes,std::function<bool ()> function)1239 bool WallpaperService::BlockRetry(int64_t interval, uint32_t maxRetryTimes, std::function<bool()> function)
1240 {
1241 uint32_t times = 0;
1242 bool ret = false;
1243 do {
1244 times++;
1245 ret = function();
1246 if (ret) {
1247 break;
1248 }
1249 std::this_thread::sleep_for(std::chrono::milliseconds(interval));
1250 HILOG_INFO("function() is: %d", ret);
1251 } while (times < maxRetryTimes);
1252 HILOG_INFO("retry times: %d", times);
1253 return ret;
1254 }
1255
QueryActiveUserId()1256 int32_t WallpaperService::QueryActiveUserId()
1257 {
1258 std::vector<int32_t> ids;
1259 ErrCode errCode = AccountSA::OsAccountManager::QueryActiveOsAccountIds(ids);
1260 if (errCode != ERR_OK || ids.empty()) {
1261 HILOG_ERROR("Query active userid failed, errCode: %{public}d, ", errCode);
1262 return DEFAULT_USER_ID;
1263 }
1264 return ids[0];
1265 }
1266
CheckUserPermissionById(int32_t userId)1267 bool WallpaperService::CheckUserPermissionById(int32_t userId)
1268 {
1269 OsAccountInfo osAccountInfo;
1270 ErrCode errCode = OsAccountManager::QueryOsAccountById(userId, osAccountInfo);
1271 if (errCode != ERR_OK) {
1272 HILOG_ERROR("Query os account info failed, errCode: %{public}d, ", errCode);
1273 return false;
1274 }
1275 HILOG_INFO("osAccountInfo GetType: %{public}d", static_cast<int32_t>(osAccountInfo.GetType()));
1276 if (osAccountInfo.GetType() == OsAccountType::GUEST) {
1277 HILOG_ERROR("The guest does not have permissions");
1278 return false;
1279 }
1280 return true;
1281 }
1282
SetWallpaper(int32_t fd,int32_t wallpaperType,int32_t length,WallpaperResourceType resourceType)1283 ErrorCode WallpaperService::SetWallpaper(int32_t fd, int32_t wallpaperType, int32_t length,
1284 WallpaperResourceType resourceType)
1285 {
1286 ErrorCode errCode = CheckValid(wallpaperType, length, resourceType);
1287 if (errCode != E_OK) {
1288 return errCode;
1289 }
1290 std::string uri = wallpaperTmpFullPath_;
1291 char *paperBuf = new (std::nothrow) char[length]();
1292 if (paperBuf == nullptr) {
1293 return E_NO_MEMORY;
1294 }
1295 std::lock_guard<std::mutex> lock(mtx_);
1296 if (read(fd, paperBuf, length) <= 0) {
1297 HILOG_ERROR("read fd failed");
1298 delete[] paperBuf;
1299 return E_DEAL_FAILED;
1300 }
1301 mode_t mode = S_IRUSR | S_IWUSR;
1302 int32_t fdw = open(uri.c_str(), O_WRONLY | O_CREAT, mode);
1303 if (fdw < 0) {
1304 HILOG_ERROR("Open wallpaper tmpFullPath failed, errno %{public}d", errno);
1305 delete[] paperBuf;
1306 return E_DEAL_FAILED;
1307 }
1308 if (write(fdw, paperBuf, length) <= 0) {
1309 HILOG_ERROR("Write to fdw failed, errno %{public}d", errno);
1310 ReporterFault(FaultType::SET_WALLPAPER_FAULT, FaultCode::RF_DROP_FAILED);
1311 delete[] paperBuf;
1312 close(fdw);
1313 return E_DEAL_FAILED;
1314 }
1315 delete[] paperBuf;
1316 close(fdw);
1317 WallpaperType type = static_cast<WallpaperType>(wallpaperType);
1318 int32_t userId = QueryActiveUserId();
1319 HILOG_INFO("QueryCurrentOsAccount userId: %{public}d", userId);
1320 if (!CheckUserPermissionById(userId)) {
1321 return E_USER_IDENTITY_ERROR;
1322 }
1323 ErrorCode wallpaperErrorCode = SetWallpaperBackupData(userId, resourceType, uri, type);
1324 if (resourceType == PICTURE) {
1325 SaveColor(userId, type);
1326 }
1327 return wallpaperErrorCode;
1328 }
1329
OnColorsChange(WallpaperType wallpaperType,const ColorManager::Color & color)1330 void WallpaperService::OnColorsChange(WallpaperType wallpaperType, const ColorManager::Color &color)
1331 {
1332 std::vector<uint64_t> colors;
1333 if (wallpaperType == WALLPAPER_SYSTEM && !CompareColor(systemWallpaperColor_, color)) {
1334 systemWallpaperColor_ = color.PackValue();
1335 colors.emplace_back(systemWallpaperColor_);
1336 NotifyColorChange(colors, WALLPAPER_SYSTEM);
1337 } else if (wallpaperType == WALLPAPER_LOCKSCREEN && !CompareColor(lockWallpaperColor_, color)) {
1338 lockWallpaperColor_ = color.PackValue();
1339 colors.emplace_back(lockWallpaperColor_);
1340 NotifyColorChange(colors, WALLPAPER_LOCKSCREEN);
1341 }
1342 }
1343
CheckValid(int32_t wallpaperType,int32_t length,WallpaperResourceType resourceType)1344 ErrorCode WallpaperService::CheckValid(int32_t wallpaperType, int32_t length, WallpaperResourceType resourceType)
1345 {
1346 if (!CheckCallingPermission(WALLPAPER_PERMISSION_NAME_SET_WALLPAPER)) {
1347 HILOG_INFO("SetWallpaper no set permission!");
1348 return E_NO_PERMISSION;
1349 }
1350 if (wallpaperType != static_cast<int32_t>(WALLPAPER_LOCKSCREEN) &&
1351 wallpaperType != static_cast<int32_t>(WALLPAPER_SYSTEM)) {
1352 return E_PARAMETERS_INVALID;
1353 }
1354
1355 int maxLength = resourceType == VIDEO ? MAX_VIDEO_SIZE : FOO_MAX_LEN;
1356 if (length <= 0 || length > maxLength) {
1357 return E_PARAMETERS_INVALID;
1358 }
1359 return E_OK;
1360 }
1361
WallpaperChanged(WallpaperType wallpaperType,WallpaperResourceType resType,const std::string & uri)1362 bool WallpaperService::WallpaperChanged(WallpaperType wallpaperType, WallpaperResourceType resType,
1363 const std::string &uri)
1364 {
1365 std::lock_guard<std::mutex> autoLock(listenerMapMutex_);
1366 auto it = wallpaperEventMap_.find(WALLPAPER_CHANGE);
1367 if (it != wallpaperEventMap_.end()) {
1368 for (auto iter = it->second.begin(); iter != it->second.end(); iter++) {
1369 if (iter->second == nullptr) {
1370 continue;
1371 }
1372 iter->second->OnWallpaperChange(wallpaperType, resType, uri);
1373 }
1374 return true;
1375 }
1376 return false;
1377 }
1378
NotifyColorChange(const std::vector<uint64_t> & colors,const WallpaperType & wallpaperType)1379 void WallpaperService::NotifyColorChange(const std::vector<uint64_t> &colors, const WallpaperType &wallpaperType)
1380 {
1381 std::lock_guard<std::mutex> autoLock(listenerMapMutex_);
1382 auto it = wallpaperEventMap_.find(COLOR_CHANGE);
1383 if (it != wallpaperEventMap_.end()) {
1384 for (auto iter = it->second.begin(); iter != it->second.end(); iter++) {
1385 if (iter->second == nullptr) {
1386 continue;
1387 }
1388 iter->second->OnColorsChange(colors, wallpaperType);
1389 }
1390 }
1391 }
1392
SaveWallpaperState(int32_t userId,WallpaperType wallpaperType)1393 bool WallpaperService::SaveWallpaperState(int32_t userId, WallpaperType wallpaperType)
1394 {
1395 WallpaperData systemData;
1396 WallpaperData lockScreenData;
1397 if (!GetWallpaperSafeLocked(userId, WALLPAPER_SYSTEM, systemData) ||
1398 !GetWallpaperSafeLocked(userId, WALLPAPER_LOCKSCREEN, lockScreenData)) {
1399 return false;
1400 }
1401 nlohmann::json root;
1402 root[SYSTEM_RES_TYPE] = static_cast<int32_t>(systemData.resourceType);
1403 root[LOCKSCREEN_RES_TYPE] = static_cast<int32_t>(lockScreenData.resourceType);
1404 std::string json = root.dump();
1405 if (json.empty()) {
1406 HILOG_ERROR("write user config file failed. because json content is empty.");
1407 return false;
1408 }
1409
1410 std::string userPath = WALLPAPER_USERID_PATH + std::to_string(userId) + "/wallpapercfg";
1411 mode_t mode = S_IRUSR | S_IWUSR;
1412 int fd = open(userPath.c_str(), O_CREAT | O_WRONLY | O_SYNC, mode);
1413 if (fd <= 0) {
1414 HILOG_ERROR("open user config file failed.");
1415 return false;
1416 }
1417 ssize_t size = write(fd, json.c_str(), json.size());
1418 if (size <= 0) {
1419 HILOG_ERROR("write user config file failed.");
1420 close(fd);
1421 return false;
1422 }
1423 close(fd);
1424 return true;
1425 }
1426
LoadWallpaperState()1427 void WallpaperService::LoadWallpaperState()
1428 {
1429 int32_t userId = QueryActiveUserId();
1430 std::string userPath = WALLPAPER_USERID_PATH + std::to_string(userId) + "/wallpapercfg";
1431 int fd = open(userPath.c_str(), O_RDONLY, S_IREAD);
1432 if (fd <= 0) {
1433 HILOG_ERROR("open user config file failed.");
1434 return;
1435 }
1436 const size_t len = 255;
1437 char buf[len] = { 0 };
1438 ssize_t size = read(fd, buf, len);
1439 if (size <= 0) {
1440 HILOG_ERROR("read user config file failed.");
1441 close(fd);
1442 return;
1443 }
1444 close(fd);
1445
1446 if (buf[0] == '\0') {
1447 return;
1448 }
1449 WallpaperData systemData;
1450 WallpaperData lockScreenData;
1451 if (!GetWallpaperSafeLocked(userId, WALLPAPER_SYSTEM, systemData) ||
1452 !GetWallpaperSafeLocked(userId, WALLPAPER_LOCKSCREEN, lockScreenData)) {
1453 return;
1454 }
1455 auto root = nlohmann::json::parse(buf);
1456 if (root.contains(SYSTEM_RES_TYPE)) {
1457 systemData.resourceType = static_cast<WallpaperResourceType>(root[SYSTEM_RES_TYPE].get<int>());
1458 }
1459 if (root.contains(LOCKSCREEN_RES_TYPE)) {
1460 lockScreenData.resourceType = static_cast<WallpaperResourceType>(root[LOCKSCREEN_RES_TYPE].get<int>());
1461 }
1462 }
1463
GrantUriPermission(const std::string & path,const std::string & bundleName)1464 int32_t WallpaperService::GrantUriPermission(const std::string &path, const std::string &bundleName)
1465 {
1466 Uri uri(path);
1467 return AAFwk::UriPermissionManagerClient::GetInstance().GrantUriPermission(uri,
1468 AAFwk::Want::FLAG_AUTH_READ_URI_PERMISSION, bundleName, 0);
1469 }
1470 } // namespace WallpaperMgrService
1471 } // namespace OHOS