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