• 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 *MANIFEST = "manifest.json";
108 constexpr const char *RES = "resources/";
109 constexpr const char *HOME = "home/";
110 constexpr const char *LOCK = "lock/";
111 constexpr const char *BASE = "base/";
112 constexpr const char *LAND_PATH = "land/";
113 constexpr const char *HOME_UNFOLDED = "home/unfolded/";
114 constexpr const char *HOME_UNFOLDED2 = "home/unfolded2/";
115 constexpr const char *LOCK_UNFOLDED = "lock/unfolded/";
116 constexpr const char *LOCK_UNFOLDED2 = "lock/unfolded2/";
117 constexpr const char *IMAGE = "image";
118 constexpr const char *SRC = "src";
119 constexpr const char *NORMAL_LAND_WALLPAPER_HOME = "normal_land_wallpaper_home";
120 constexpr const char *UNFOLD1_PORT_WALLPAPER_HOME = "unfold1_port_wallpaper_home";
121 constexpr const char *UNFOLD1_LAND_WALLPAPER_HOME = "unfold1_land_wallpaper_home";
122 constexpr const char *UNFOLD2_PORT_WALLPAPER_HOME = "unfold2_port_wallpaper_home";
123 constexpr const char *UNFOLD2_LAND_WALLPAPER_HOME = "unfold2_land_wallpaper_home";
124 constexpr const char *NORMAL_LAND_WALLPAPER_LOCK = "normal_land_wallpaper_lock";
125 constexpr const char *UNFOLD1_PORT_WALLPAPER_LOCK = "unfold1_port_wallpaper_lock";
126 constexpr const char *UNFOLD1_LAND_WALLPAPER_LOCK = "unfold1_land_wallpaper_lock";
127 constexpr const char *UNFOLD2_PORT_WALLPAPER_LOCK = "unfold2_port_wallpaper_lock";
128 constexpr const char *UNFOLD2_LAND_WALLPAPER_LOCK = "unfold2_land_wallpaper_lock";
129 constexpr int64_t INIT_INTERVAL = 10000L;
130 constexpr int64_t DELAY_TIME = 1000L;
131 constexpr int64_t QUERY_USER_ID_INTERVAL = 300L;
132 constexpr int32_t FOO_MAX_LEN = 52428800;
133 constexpr int32_t MAX_RETRY_TIMES = 20;
134 constexpr int32_t QUERY_USER_MAX_RETRY_TIMES = 100;
135 constexpr int32_t DEFAULT_WALLPAPER_ID = -1;
136 constexpr int32_t DEFAULT_USER_ID = 0;
137 constexpr int32_t MAX_VIDEO_SIZE = 104857600;
138 constexpr int32_t OPTION_QUALITY = 100;
139 
140 #ifndef THEME_SERVICE
141 constexpr int32_t CONNECT_EXTENSION_INTERVAL = 100;
142 constexpr int32_t DEFAULT_VALUE = -1;
143 constexpr int32_t CONNECT_EXTENSION_MAX_RETRY_TIMES = 50;
144 #endif
145 
146 std::shared_ptr<AppExecFwk::EventHandler> WallpaperService::serviceHandler_;
147 
WallpaperService(int32_t systemAbilityId,bool runOnCreate)148 WallpaperService::WallpaperService(int32_t systemAbilityId, bool runOnCreate)
149     : SystemAbility(systemAbilityId, runOnCreate), WallpaperServiceStub(true),
150       state_(ServiceRunningState::STATE_NOT_START)
151 {
152 }
153 
WallpaperService()154 WallpaperService::WallpaperService() : WallpaperServiceStub(true), state_(ServiceRunningState::STATE_NOT_START)
155 {
156 }
157 
~WallpaperService()158 WallpaperService::~WallpaperService()
159 {
160 }
161 
Init()162 int32_t WallpaperService::Init()
163 {
164     InitQueryUserId(QUERY_USER_MAX_RETRY_TIMES);
165     bool ret = Publish(this);
166     if (!ret) {
167         HILOG_ERROR("Publish failed!");
168         ReporterFault(FaultType::SERVICE_FAULT, FaultCode::SF_SERVICE_UNAVAILABLE);
169         return -1;
170     }
171     HILOG_INFO("Publish success.");
172     state_ = ServiceRunningState::STATE_RUNNING;
173 #ifndef THEME_SERVICE
174     StartExtensionAbility(CONNECT_EXTENSION_MAX_RETRY_TIMES);
175 #endif
176     return E_OK;
177 }
178 
OnStart()179 void WallpaperService::OnStart()
180 {
181     HILOG_INFO("Enter OnStart.");
182     MemoryGuard cacheGuard;
183     if (state_ == ServiceRunningState::STATE_RUNNING) {
184         HILOG_ERROR("WallpaperService is already running.");
185         return;
186     }
187     InitData();
188     InitServiceHandler();
189     AddSystemAbilityListener(COMMON_EVENT_SERVICE_ID);
190     AddSystemAbilityListener(MEMORY_MANAGER_SA_ID);
191     auto cmd = std::make_shared<Command>(std::vector<std::string>({ "-all" }), "Show all",
192         [this](const std::vector<std::string> &input, std::string &output) -> bool {
193             output.append(
194                 "WallpaperExtensionAbility\t: ExtensionInfo{" + std::string(OHOS_WALLPAPER_BUNDLE_NAME) + "}\n");
195             return true;
196         });
197     DumpHelper::GetInstance().RegisterCommand(cmd);
198     if (Init() != E_OK) {
199         auto callback = [=]() { Init(); };
200         serviceHandler_->PostTask(callback, INIT_INTERVAL);
201         HILOG_ERROR("Init failed. Try again 10s later.");
202     }
203     return;
204 }
205 
OnAddSystemAbility(int32_t systemAbilityId,const std::string & deviceId)206 void WallpaperService::OnAddSystemAbility(int32_t systemAbilityId, const std::string &deviceId)
207 {
208     HILOG_INFO("OnAddSystemAbility systemAbilityId:%{public}d added!", systemAbilityId);
209     if (systemAbilityId == COMMON_EVENT_SERVICE_ID) {
210         int32_t times = 0;
211         RegisterSubscriber(times);
212     } else if (systemAbilityId == MEMORY_MANAGER_SA_ID) {
213         int32_t pid = getpid();
214         Memory::MemMgrClient::GetInstance().NotifyProcessStatus(pid, 1, 1, WALLPAPER_MANAGER_SERVICE_ID);
215     }
216 }
217 
RegisterSubscriber(int32_t times)218 void WallpaperService::RegisterSubscriber(int32_t times)
219 {
220     MemoryGuard cacheGuard;
221     times++;
222     subscriber_ = std::make_shared<WallpaperCommonEventSubscriber>(*this);
223     bool subRes = OHOS::EventFwk::CommonEventManager::SubscribeCommonEvent(subscriber_);
224     if (!subRes && times <= MAX_RETRY_TIMES) {
225         HILOG_INFO("RegisterSubscriber failed!");
226         auto callback = [this, times]() { RegisterSubscriber(times); };
227         serviceHandler_->PostTask(callback, DELAY_TIME);
228     }
229 }
230 
InitServiceHandler()231 void WallpaperService::InitServiceHandler()
232 {
233     HILOG_INFO("InitServiceHandler started.");
234     if (serviceHandler_ != nullptr) {
235         HILOG_ERROR("InitServiceHandler already init.");
236         return;
237     }
238     std::shared_ptr<AppExecFwk::EventRunner> runner =
239         AppExecFwk::EventRunner::Create("WallpaperService", AppExecFwk::ThreadMode::FFRT);
240     serviceHandler_ = std::make_shared<AppExecFwk::EventHandler>(runner);
241 }
242 
OnStop()243 void WallpaperService::OnStop()
244 {
245     HILOG_INFO("OnStop started.");
246     if (state_ != ServiceRunningState::STATE_RUNNING) {
247         return;
248     }
249     serviceHandler_ = nullptr;
250 #ifndef THEME_SERVICE
251     connection_ = nullptr;
252 #endif
253     recipient_ = nullptr;
254     extensionRemoteObject_ = nullptr;
255     if (subscriber_ != nullptr) {
256         bool unSubscribeResult = OHOS::EventFwk::CommonEventManager::UnSubscribeCommonEvent(subscriber_);
257         subscriber_ = nullptr;
258         HILOG_INFO("UnregisterSubscriber end, unSubscribeResult = %{public}d", unSubscribeResult);
259     }
260     state_ = ServiceRunningState::STATE_NOT_START;
261     int32_t pid = getpid();
262     Memory::MemMgrClient::GetInstance().NotifyProcessStatus(pid, 1, 0, WALLPAPER_MANAGER_SERVICE_ID);
263 }
264 
InitData()265 void WallpaperService::InitData()
266 {
267     HILOG_INFO("WallpaperService::initData --> start.");
268     wallpaperId_ = DEFAULT_WALLPAPER_ID;
269     int32_t userId = DEFAULT_USER_ID;
270     systemWallpaperMap_.Clear();
271     lockWallpaperMap_.Clear();
272     wallpaperTmpFullPath_ = std::string(WALLPAPER_USERID_PATH) + std::string(WALLPAPER_TMP_DIRNAME);
273     wallpaperCropPath_ = std::string(WALLPAPER_USERID_PATH) + std::string(WALLPAPER_CROP_PICTURE);
274     {
275         std::lock_guard<std::mutex> lock(wallpaperColorMtx_);
276         systemWallpaperColor_ = 0;
277         lockWallpaperColor_ = 0;
278     }
279     currentUserId_ = userId;
280     wallpaperEventMap_.clear();
281     appBundleName_ = SCENEBOARD_BUNDLE_NAME;
282     InitUserDir(userId);
283     UpdataWallpaperMap(userId, WALLPAPER_SYSTEM);
284     UpdataWallpaperMap(userId, WALLPAPER_LOCKSCREEN);
285     LoadWallpaperState();
286     ClearRedundantFile(userId, WALLPAPER_SYSTEM, WALLPAPER_SYSTEM_ORIG);
287     ClearRedundantFile(userId, WALLPAPER_LOCKSCREEN, WALLPAPER_LOCK_ORIG);
288 }
289 
290 #ifndef THEME_SERVICE
AddWallpaperExtensionDeathRecipient(const sptr<IRemoteObject> & remoteObject)291 void WallpaperService::AddWallpaperExtensionDeathRecipient(const sptr<IRemoteObject> &remoteObject)
292 {
293     if (remoteObject != nullptr) {
294         std::lock_guard<std::mutex> lock(remoteObjectMutex_);
295         IPCObjectProxy *proxy = reinterpret_cast<IPCObjectProxy *>(remoteObject.GetRefPtr());
296         if (recipient_ == nullptr) {
297             recipient_ = sptr<IRemoteObject::DeathRecipient>(new WallpaperExtensionAbilityDeathRecipient(*this));
298         }
299         if (proxy != nullptr && !proxy->IsObjectDead()) {
300             HILOG_INFO("get remoteObject succeed.");
301             proxy->AddDeathRecipient(recipient_);
302             extensionRemoteObject_ = remoteObject;
303         }
304     }
305 }
306 #endif
307 
RemoveExtensionDeathRecipient()308 void WallpaperService::RemoveExtensionDeathRecipient()
309 {
310     if (extensionRemoteObject_ != nullptr && recipient_ != nullptr) {
311         HILOG_INFO("Remove Extension DeathRecipient.");
312         std::lock_guard<std::mutex> lock(remoteObjectMutex_);
313         if (extensionRemoteObject_ != nullptr) {
314             extensionRemoteObject_->RemoveDeathRecipient(recipient_);
315             recipient_ = nullptr;
316             extensionRemoteObject_ = nullptr;
317         }
318     }
319 }
320 
InitQueryUserId(int32_t times)321 void WallpaperService::InitQueryUserId(int32_t times)
322 {
323     times--;
324     bool ret = InitUsersOnBoot();
325     if (!ret && times > 0) {
326         HILOG_DEBUG("InitQueryUserId failed!");
327         auto callback = [this, times]() { InitQueryUserId(times); };
328         serviceHandler_->PostTask(callback, QUERY_USER_ID_INTERVAL);
329     }
330 }
331 
332 #ifndef THEME_SERVICE
StartExtensionAbility(int32_t times)333 void WallpaperService::StartExtensionAbility(int32_t times)
334 {
335     times--;
336     bool ret = ConnectExtensionAbility();
337     if (!ret && times > 0 && serviceHandler_ != nullptr) {
338         HILOG_ERROR("StartExtensionAbilty failed, remainder of the times: %{public}d", times);
339         auto callback = [this, times]() { StartExtensionAbility(times); };
340         serviceHandler_->PostTask(callback, CONNECT_EXTENSION_INTERVAL);
341     }
342 }
343 #endif
344 
InitUsersOnBoot()345 bool WallpaperService::InitUsersOnBoot()
346 {
347     std::vector<AccountSA::OsAccountInfo> osAccountInfos;
348     ErrCode errCode = AccountSA::OsAccountManager::QueryAllCreatedOsAccounts(osAccountInfos);
349     if (errCode != ERR_OK || osAccountInfos.empty()) {
350         HILOG_ERROR("Query all created userIds failed, errCode:%{public}d", errCode);
351         return false;
352     }
353     for (const auto &osAccountInfo : osAccountInfos) {
354         int32_t userId = osAccountInfo.GetLocalId();
355         HILOG_INFO("InitUsersOnBoot Current userId: %{public}d", userId);
356         InitUserDir(userId);
357         UpdataWallpaperMap(userId, WALLPAPER_SYSTEM);
358         UpdataWallpaperMap(userId, WALLPAPER_LOCKSCREEN);
359         ClearRedundantFile(userId, WALLPAPER_SYSTEM, WALLPAPER_SYSTEM_ORIG);
360         ClearRedundantFile(userId, WALLPAPER_LOCKSCREEN, WALLPAPER_LOCK_ORIG);
361     }
362     return true;
363 }
364 
ClearRedundantFile(int32_t userId,WallpaperType wallpaperType,std::string fileName)365 void WallpaperService::ClearRedundantFile(int32_t userId, WallpaperType wallpaperType, std::string fileName)
366 {
367     HILOG_DEBUG("ClearRedundantFile Current userId: %{public}d", userId);
368     std::string wallpaperFilePath = GetWallpaperDir(userId, wallpaperType) + "/" + fileName;
369     FileDeal::DeleteFile(wallpaperFilePath);
370 }
371 
OnInitUser(int32_t userId)372 void WallpaperService::OnInitUser(int32_t userId)
373 {
374     if (userId < 0) {
375         HILOG_ERROR("userId error, userId = %{public}d", userId);
376         return;
377     }
378     std::string userDir = WALLPAPER_USERID_PATH + std::to_string(userId);
379     if (FileDeal::IsFileExist(userDir)) {
380         std::lock_guard<std::mutex> lock(mtx_);
381         if (!FileDeal::DeleteDir(userDir, true)) {
382             HILOG_ERROR("Force remove user directory path failed, errno %{public}d", errno);
383             return;
384         }
385     }
386     if (!InitUserDir(userId)) {
387         return;
388     }
389     UpdataWallpaperMap(userId, WALLPAPER_SYSTEM);
390     UpdataWallpaperMap(userId, WALLPAPER_LOCKSCREEN);
391     HILOG_INFO("OnInitUser success, userId = %{public}d", userId);
392 }
393 
InitUserDir(int32_t userId)394 bool WallpaperService::InitUserDir(int32_t userId)
395 {
396     std::string userDir = WALLPAPER_USERID_PATH + std::to_string(userId);
397     if (!FileDeal::Mkdir(userDir)) {
398         HILOG_ERROR("Failed to create destination path, userId:%{public}d", userId);
399         return false;
400     }
401     std::string wallpaperSystemFilePath = userDir + "/" + WALLPAPER_SYSTEM_DIRNAME;
402     if (!FileDeal::Mkdir(wallpaperSystemFilePath)) {
403         HILOG_ERROR("Failed to create destination wallpaper system path, userId:%{public}d, type:%{public}s.", userId,
404             WALLPAPER_SYSTEM_DIRNAME);
405         return false;
406     }
407     std::string wallpaperLockScreenFilePath = userDir + "/" + WALLPAPER_LOCKSCREEN_DIRNAME;
408     if (!FileDeal::Mkdir(wallpaperLockScreenFilePath)) {
409         HILOG_ERROR("Failed to create destination wallpaper lockscreen path, userId:%{public}d, type:%{public}s.",
410             userId, WALLPAPER_LOCKSCREEN_DIRNAME);
411         return false;
412     }
413     return true;
414 }
415 
RestoreUserResources(int32_t userId,WallpaperData & wallpaperData,WallpaperType wallpaperType)416 bool WallpaperService::RestoreUserResources(int32_t userId, WallpaperData &wallpaperData, WallpaperType wallpaperType)
417 {
418     if (!FileDeal::DeleteDir(GetWallpaperDir(userId, wallpaperType), false)) {
419         HILOG_ERROR("delete resources failed, userId:%{public}d, wallpaperType:%{public}d.", userId, wallpaperType);
420         return false;
421     }
422     std::string wallpaperPath = GetWallpaperDir(userId, wallpaperType);
423     wallpaperData = GetWallpaperDefaultPath(wallpaperType);
424     wallpaperData.userId = userId;
425     wallpaperData.allowBackup = true;
426     wallpaperData.resourceType = PICTURE;
427     wallpaperData.wallpaperId = DEFAULT_WALLPAPER_ID;
428     wallpaperData.liveWallpaperFile =
429         wallpaperPath + "/"
430         + (wallpaperType == WALLPAPER_SYSTEM ? LIVE_WALLPAPER_SYSTEM_ORIG : LIVE_WALLPAPER_LOCK_ORIG);
431     wallpaperData.customPackageUri =
432         wallpaperPath + "/" + (wallpaperType == WALLPAPER_SYSTEM ? CUSTOM_WALLPAPER_SYSTEM : CUSTOM_WALLPAPER_LOCK);
433     if (wallpaperData.wallpaperFile.empty()) {
434         HILOG_ERROR("get default path failed, userId:%{public}d, wallpaperType:%{public}d.", userId, wallpaperType);
435         return false;
436     }
437     HILOG_INFO("Restore user resources end.");
438     return true;
439 }
440 
GetWallpaperDefaultPath(WallpaperType wallpaperType)441 WallpaperData WallpaperService::GetWallpaperDefaultPath(WallpaperType wallpaperType)
442 {
443     WallpaperData wallpaperData;
444     std::string manifest = MANIFEST;
445     std::string res = RES;
446     std::string base = BASE;
447     std::string land = LAND_PATH;
448     if (wallpaperType == WallpaperType::WALLPAPER_SYSTEM) {
449         wallpaperData.wallpaperFile = GetWallpaperPathInJson(HOME + manifest, HOME + base + res);
450         wallpaperData.normalLandFile = GetWallpaperPathInJson(HOME + base + land + manifest, HOME + base + land + res);
451         wallpaperData.unfoldedOnePortFile = GetWallpaperPathInJson(HOME_UNFOLDED + manifest, HOME_UNFOLDED + res);
452         wallpaperData.unfoldedOneLandFile =
453             GetWallpaperPathInJson(HOME_UNFOLDED + land + manifest, HOME_UNFOLDED + land + res);
454         wallpaperData.unfoldedTwoPortFile = GetWallpaperPathInJson(HOME_UNFOLDED2 + manifest, HOME_UNFOLDED2 + res);
455         wallpaperData.unfoldedTwoLandFile =
456             GetWallpaperPathInJson(HOME_UNFOLDED2 + land + manifest, HOME_UNFOLDED2 + land + res);
457     } else {
458         wallpaperData.wallpaperFile = GetWallpaperPathInJson(LOCK + manifest, LOCK + base + res);
459         wallpaperData.normalLandFile = GetWallpaperPathInJson(LOCK + base + land + manifest, LOCK + base + land + res);
460         wallpaperData.unfoldedOnePortFile = GetWallpaperPathInJson(LOCK_UNFOLDED + manifest, LOCK_UNFOLDED + res);
461         wallpaperData.unfoldedOneLandFile =
462             GetWallpaperPathInJson(LOCK_UNFOLDED + land + manifest, LOCK_UNFOLDED + land + res);
463         wallpaperData.unfoldedTwoPortFile = GetWallpaperPathInJson(LOCK_UNFOLDED2 + manifest, LOCK_UNFOLDED2 + res);
464         wallpaperData.unfoldedTwoLandFile =
465             GetWallpaperPathInJson(LOCK_UNFOLDED2 + land + manifest, LOCK_UNFOLDED2 + land + res);
466     }
467     if (wallpaperData.wallpaperFile.empty()) {
468         wallpaperData.wallpaperFile = (wallpaperType == WallpaperType::WALLPAPER_SYSTEM)
469                                           ? WALLPAPER_DEFAULT_FILEFULLPATH
470                                           : WALLPAPER_DEFAULT_LOCK_FILEFULLPATH;
471     }
472     return wallpaperData;
473 }
OnRemovedUser(int32_t userId)474 void WallpaperService::OnRemovedUser(int32_t userId)
475 {
476     if (userId < 0) {
477         HILOG_ERROR("userId error, userId = %{public}d", userId);
478         return;
479     }
480     ClearWallpaperLocked(userId, WALLPAPER_SYSTEM);
481     ClearWallpaperLocked(userId, WALLPAPER_LOCKSCREEN);
482     std::string userDir = WALLPAPER_USERID_PATH + std::to_string(userId);
483     std::lock_guard<std::mutex> lock(mtx_);
484     if (!FileDeal::DeleteDir(userDir, true)) {
485         HILOG_ERROR("Force remove user directory path failed, errno %{public}d", errno);
486     }
487     HILOG_INFO("OnRemovedUser end, userId = %{public}d", userId);
488 }
489 
OnSwitchedUser(int32_t userId)490 void WallpaperService::OnSwitchedUser(int32_t userId)
491 {
492     if (userId < 0) {
493         HILOG_ERROR("userId error, userId = %{public}d", userId);
494         return;
495     }
496     if (userId == currentUserId_) {
497         HILOG_ERROR("userId not switch, userId = %{public}d", userId);
498         return;
499     }
500     currentUserId_ = userId;
501     RemoveExtensionDeathRecipient();
502 #ifndef THEME_SERVICE
503     ConnectExtensionAbility();
504 #endif
505     std::string userDir = WALLPAPER_USERID_PATH + std::to_string(userId);
506     if (!FileDeal::IsFileExist(userDir)) {
507         HILOG_INFO("User file is not exist, userId = %{public}d", userId);
508         InitUserDir(userId);
509         UpdataWallpaperMap(userId, WALLPAPER_SYSTEM);
510         UpdataWallpaperMap(userId, WALLPAPER_LOCKSCREEN);
511     }
512     LoadWallpaperState();
513     SendWallpaperChangeEvent(userId, WALLPAPER_SYSTEM);
514     SendWallpaperChangeEvent(userId, WALLPAPER_LOCKSCREEN);
515     SaveColor(userId, WALLPAPER_SYSTEM);
516     SaveColor(userId, WALLPAPER_LOCKSCREEN);
517     HILOG_INFO("OnSwitchedUser end, newUserId = %{public}d", userId);
518 }
519 
GetWallpaperDir(int32_t userId,WallpaperType wallpaperType)520 std::string WallpaperService::GetWallpaperDir(int32_t userId, WallpaperType wallpaperType)
521 {
522     std::string userIdPath = WALLPAPER_USERID_PATH + std::to_string(userId);
523     std::string wallpaperFilePath;
524     if (wallpaperType == WALLPAPER_SYSTEM) {
525         wallpaperFilePath = userIdPath + "/" + WALLPAPER_SYSTEM_DIRNAME;
526     } else if (wallpaperType == WALLPAPER_LOCKSCREEN) {
527         wallpaperFilePath = userIdPath + "/" + WALLPAPER_LOCKSCREEN_DIRNAME;
528     }
529     return wallpaperFilePath;
530 }
531 
GetFileNameFromMap(int32_t userId,WallpaperType wallpaperType,std::string & filePathName)532 bool WallpaperService::GetFileNameFromMap(int32_t userId, WallpaperType wallpaperType, std::string &filePathName)
533 {
534     auto iterator = wallpaperType == WALLPAPER_SYSTEM ? systemWallpaperMap_.Find(userId)
535                                                       : lockWallpaperMap_.Find(userId);
536     if (!iterator.first) {
537         HILOG_ERROR("system wallpaper already cleared.");
538         return false;
539     }
540     HILOG_DEBUG("GetFileNameFromMap resourceType : %{public}d", static_cast<int32_t>(iterator.second.resourceType));
541     switch (iterator.second.resourceType) {
542         case PICTURE:
543             filePathName = iterator.second.wallpaperFile;
544             break;
545         case VIDEO:
546             filePathName = iterator.second.liveWallpaperFile;
547             break;
548         case DEFAULT:
549             filePathName = iterator.second.wallpaperFile;
550             break;
551         case PACKAGE:
552             filePathName = iterator.second.customPackageUri;
553             break;
554         default:
555             filePathName = "";
556             break;
557     }
558     return filePathName != "";
559 }
560 
GetPictureFileName(int32_t userId,WallpaperType wallpaperType,std::string & filePathName)561 bool WallpaperService::GetPictureFileName(int32_t userId, WallpaperType wallpaperType, std::string &filePathName)
562 {
563     auto iterator = wallpaperType == WALLPAPER_SYSTEM ? systemWallpaperMap_.Find(userId)
564                                                       : lockWallpaperMap_.Find(userId);
565     if (!iterator.first) {
566         HILOG_INFO("WallpaperType:%{public}d, WallpaperMap not found userId: %{public}d", wallpaperType, userId);
567         OnInitUser(userId);
568         iterator = wallpaperType == WALLPAPER_SYSTEM ? systemWallpaperMap_.Find(userId)
569                                                      : lockWallpaperMap_.Find(userId);
570     }
571     filePathName = iterator.second.wallpaperFile;
572     HILOG_INFO("GetPictureFileName filePathName : %{public}s", filePathName.c_str());
573     return filePathName != "";
574 }
575 
MakeWallpaperIdLocked()576 int32_t WallpaperService::MakeWallpaperIdLocked()
577 {
578     HILOG_INFO("MakeWallpaperIdLocked start.");
579     if (wallpaperId_ == INT32_MAX) {
580         wallpaperId_ = DEFAULT_WALLPAPER_ID;
581     }
582     return ++wallpaperId_;
583 }
584 
UpdataWallpaperMap(int32_t userId,WallpaperType wallpaperType)585 void WallpaperService::UpdataWallpaperMap(int32_t userId, WallpaperType wallpaperType)
586 {
587     HILOG_INFO("updata wallpaperMap.");
588     std::string wallpaperPath = GetWallpaperDir(userId, wallpaperType);
589     std::string wallpaperFilePath =
590         wallpaperPath + "/" + (wallpaperType == WALLPAPER_SYSTEM ? WALLPAPER_HOME : WALLPAPER_LOCK);
591     ConcurrentMap<int32_t, WallpaperData> &wallpaperMap = [&]() -> ConcurrentMap<int32_t, WallpaperData>& {
592         if (wallpaperType == WALLPAPER_SYSTEM) {
593             return systemWallpaperMap_;
594         } else {
595             return lockWallpaperMap_;
596         }
597     }();
598     auto wallpaperData = GetWallpaperDefaultPath(wallpaperType);
599     wallpaperData.userId = userId;
600     wallpaperData.allowBackup = true;
601     wallpaperData.resourceType = PICTURE;
602     wallpaperData.wallpaperId = DEFAULT_WALLPAPER_ID;
603     wallpaperData.liveWallpaperFile =
604         wallpaperPath + "/"
605         + (wallpaperType == WALLPAPER_SYSTEM ? LIVE_WALLPAPER_SYSTEM_ORIG : LIVE_WALLPAPER_LOCK_ORIG);
606     wallpaperData.customPackageUri =
607         wallpaperPath + "/" + (wallpaperType == WALLPAPER_SYSTEM ? CUSTOM_WALLPAPER_SYSTEM : CUSTOM_WALLPAPER_LOCK);
608     if (FileDeal::IsFileExist(wallpaperFilePath)) {
609         wallpaperData.wallpaperFile = GetExistFilePath(
610             wallpaperPath + "/" + (wallpaperType == WALLPAPER_SYSTEM ? WALLPAPER_HOME : WALLPAPER_LOCK));
611         wallpaperData.normalLandFile = GetExistFilePath(
612             wallpaperPath + "/"
613             + (wallpaperType == WALLPAPER_SYSTEM ? NORMAL_LAND_WALLPAPER_HOME : NORMAL_LAND_WALLPAPER_LOCK));
614         wallpaperData.unfoldedOnePortFile = GetExistFilePath(
615             wallpaperPath + "/"
616             + (wallpaperType == WALLPAPER_SYSTEM ? UNFOLD1_PORT_WALLPAPER_HOME : UNFOLD1_PORT_WALLPAPER_LOCK));
617         wallpaperData.unfoldedOneLandFile = GetExistFilePath(
618             wallpaperPath + "/"
619             + (wallpaperType == WALLPAPER_SYSTEM ? UNFOLD1_LAND_WALLPAPER_HOME : UNFOLD1_LAND_WALLPAPER_LOCK));
620         wallpaperData.unfoldedTwoPortFile = GetExistFilePath(
621             wallpaperPath + "/"
622             + (wallpaperType == WALLPAPER_SYSTEM ? UNFOLD2_PORT_WALLPAPER_HOME : UNFOLD2_PORT_WALLPAPER_LOCK));
623         wallpaperData.unfoldedTwoLandFile = GetExistFilePath(
624             wallpaperPath + "/"
625             + (wallpaperType == WALLPAPER_SYSTEM ? UNFOLD2_LAND_WALLPAPER_HOME : UNFOLD2_LAND_WALLPAPER_LOCK));
626     }
627     wallpaperMap.InsertOrAssign(userId, wallpaperData);
628 }
629 
GetColors(int32_t wallpaperType,std::vector<uint64_t> & colors)630 ErrorCode WallpaperService::GetColors(int32_t wallpaperType, std::vector<uint64_t> &colors)
631 {
632     if (wallpaperType == WALLPAPER_SYSTEM) {
633         std::lock_guard<std::mutex> lock(wallpaperColorMtx_);
634         colors.emplace_back(systemWallpaperColor_);
635     } else if (wallpaperType == WALLPAPER_LOCKSCREEN) {
636         std::lock_guard<std::mutex> lock(wallpaperColorMtx_);
637         colors.emplace_back(lockWallpaperColor_);
638     }
639     HILOG_INFO("GetColors Service End.");
640     return E_OK;
641 }
642 
GetColorsV9(int32_t wallpaperType,std::vector<uint64_t> & colors)643 ErrorCode WallpaperService::GetColorsV9(int32_t wallpaperType, std::vector<uint64_t> &colors)
644 {
645     if (!IsSystemApp()) {
646         HILOG_ERROR("CallingApp is not SystemApp.");
647         return E_NOT_SYSTEM_APP;
648     }
649     return GetColors(wallpaperType, colors);
650 }
651 
GetFile(int32_t wallpaperType,int32_t & wallpaperFd)652 ErrorCode WallpaperService::GetFile(int32_t wallpaperType, int32_t &wallpaperFd)
653 {
654     if (!CheckCallingPermission(WALLPAPER_PERMISSION_NAME_GET_WALLPAPER)) {
655         HILOG_ERROR("GetPixelMap no get permission!");
656         return E_NO_PERMISSION;
657     }
658     if (wallpaperType != static_cast<int32_t>(WALLPAPER_LOCKSCREEN)
659         && wallpaperType != static_cast<int32_t>(WALLPAPER_SYSTEM)) {
660         return E_PARAMETERS_INVALID;
661     }
662     auto type = static_cast<WallpaperType>(wallpaperType);
663     int32_t userId = QueryActiveUserId();
664     HILOG_INFO("QueryCurrentOsAccount userId: %{public}d", userId);
665     ErrorCode ret = GetImageFd(userId, type, wallpaperFd);
666     HILOG_INFO("GetImageFd fd:%{public}d, ret:%{public}d", wallpaperFd, ret);
667     return ret;
668 }
669 
CompareColor(const uint64_t & localColor,const ColorManager::Color & color)670 bool WallpaperService::CompareColor(const uint64_t &localColor, const ColorManager::Color &color)
671 {
672     return localColor == color.PackValue();
673 }
674 
SaveColor(int32_t userId,WallpaperType wallpaperType)675 bool WallpaperService::SaveColor(int32_t userId, WallpaperType wallpaperType)
676 {
677     uint32_t errorCode = 0;
678     OHOS::Media::SourceOptions opts;
679     opts.formatHint = "image/jpeg";
680     std::string pathName;
681     if (!GetPictureFileName(userId, wallpaperType, pathName)) {
682         return false;
683     }
684     std::unique_ptr<OHOS::Media::ImageSource> imageSource =
685         OHOS::Media::ImageSource::CreateImageSource(pathName, opts, errorCode);
686     if (errorCode != 0 || imageSource == nullptr) {
687         HILOG_ERROR("CreateImageSource failed!");
688         return false;
689     }
690     OHOS::Media::DecodeOptions decodeOpts;
691     std::unique_ptr<PixelMap> wallpaperPixelMap = imageSource->CreatePixelMap(decodeOpts, errorCode);
692     if (errorCode != 0) {
693         HILOG_ERROR("CreatePixelMap failed!");
694         return false;
695     }
696     auto colorPicker = Rosen::ColorPicker::CreateColorPicker(std::move(wallpaperPixelMap), errorCode);
697     if (errorCode != 0) {
698         HILOG_ERROR("CreateColorPicker failed!");
699         return false;
700     }
701     auto color = ColorManager::Color();
702     uint32_t ret = colorPicker->GetMainColor(color);
703     if (ret != Rosen::SUCCESS) {
704         HILOG_ERROR("GetMainColor failed ret is : %{public}d", ret);
705         return false;
706     }
707     OnColorsChange(wallpaperType, color);
708     return true;
709 }
710 
SetWallpaper(int32_t fd,int32_t wallpaperType,int32_t length)711 ErrorCode WallpaperService::SetWallpaper(int32_t fd, int32_t wallpaperType, int32_t length)
712 {
713     StartAsyncTrace(HITRACE_TAG_MISC, "SetWallpaper", static_cast<int32_t>(TraceTaskId::SET_WALLPAPER));
714     ErrorCode wallpaperErrorCode = SetWallpaper(fd, wallpaperType, length, PICTURE);
715     FinishAsyncTrace(HITRACE_TAG_MISC, "SetWallpaper", static_cast<int32_t>(TraceTaskId::SET_WALLPAPER));
716     return wallpaperErrorCode;
717 }
718 
SetWallpaperByPixelMap(std::shared_ptr<OHOS::Media::PixelMap> pixelMap,int32_t wallpaperType)719 ErrorCode WallpaperService::SetWallpaperByPixelMap(
720     std::shared_ptr<OHOS::Media::PixelMap> pixelMap, int32_t wallpaperType)
721 {
722     if (pixelMap == nullptr) {
723         HILOG_ERROR("pixelMap is nullptr");
724         return E_FILE_ERROR;
725     }
726     StartAsyncTrace(HITRACE_TAG_MISC, "SetWallpaper", static_cast<int32_t>(TraceTaskId::SET_WALLPAPER));
727     ErrorCode wallpaperErrorCode = SetWallpaperByPixelMap(pixelMap, wallpaperType, PICTURE);
728     FinishAsyncTrace(HITRACE_TAG_MISC, "SetWallpaper", static_cast<int32_t>(TraceTaskId::SET_WALLPAPER));
729     return wallpaperErrorCode;
730 }
731 
SetWallpaperV9(int32_t fd,int32_t wallpaperType,int32_t length)732 ErrorCode WallpaperService::SetWallpaperV9(int32_t fd, int32_t wallpaperType, int32_t length)
733 {
734     if (!IsSystemApp()) {
735         HILOG_ERROR("CallingApp is not SystemApp.");
736         return E_NOT_SYSTEM_APP;
737     }
738     return SetWallpaper(fd, wallpaperType, length);
739 }
740 
SetWallpaperV9ByPixelMap(std::shared_ptr<OHOS::Media::PixelMap> pixelMap,int32_t wallpaperType)741 ErrorCode WallpaperService::SetWallpaperV9ByPixelMap(
742     std::shared_ptr<OHOS::Media::PixelMap> pixelMap, int32_t wallpaperType)
743 {
744     if (!IsSystemApp()) {
745         HILOG_INFO("CallingApp is not SystemApp.");
746         return E_NOT_SYSTEM_APP;
747     }
748     if (pixelMap == nullptr) {
749         HILOG_ERROR("pixelMap is nullptr");
750         return E_FILE_ERROR;
751     }
752     return SetWallpaperByPixelMap(pixelMap, wallpaperType);
753 }
754 
SetWallpaperBackupData(int32_t userId,WallpaperResourceType resourceType,const std::string & uriOrPixelMap,WallpaperType wallpaperType)755 ErrorCode WallpaperService::SetWallpaperBackupData(
756     int32_t userId, WallpaperResourceType resourceType, const std::string &uriOrPixelMap, WallpaperType wallpaperType)
757 {
758     HILOG_INFO("set wallpaper and backup data Start.");
759     if (!OHOS::FileExists(uriOrPixelMap)) {
760         return E_DEAL_FAILED;
761     }
762     if (!FileDeal::DeleteDir(GetWallpaperDir(userId, wallpaperType), false)) {
763         return E_DEAL_FAILED;
764     }
765     WallpaperData wallpaperData;
766     bool ret = GetWallpaperSafeLocked(userId, wallpaperType, wallpaperData);
767     if (!ret) {
768         HILOG_ERROR("GetWallpaperSafeLocked failed!");
769         return E_DEAL_FAILED;
770     }
771     if (resourceType == PICTURE || resourceType == DEFAULT) {
772         wallpaperData.wallpaperFile = GetWallpaperDir(userId, wallpaperType) + "/"
773                                       + (wallpaperType == WALLPAPER_SYSTEM ? WALLPAPER_HOME : WALLPAPER_LOCK);
774     }
775     wallpaperData.resourceType = resourceType;
776     wallpaperData.wallpaperId = MakeWallpaperIdLocked();
777     std::string wallpaperFile;
778     WallpaperService::GetWallpaperFile(resourceType, wallpaperData, wallpaperFile);
779     {
780         std::lock_guard<std::mutex> lock(mtx_);
781         if (!FileDeal::CopyFile(uriOrPixelMap, wallpaperFile)) {
782             HILOG_ERROR("CopyFile failed!");
783             FileDeal::DeleteFile(uriOrPixelMap);
784             return E_DEAL_FAILED;
785         }
786         if (!FileDeal::DeleteFile(uriOrPixelMap)) {
787             return E_DEAL_FAILED;
788         }
789     }
790     if (!SaveWallpaperState(userId, wallpaperType, resourceType)) {
791         HILOG_ERROR("Save wallpaper state failed!");
792         return E_DEAL_FAILED;
793     }
794     if (wallpaperType == WALLPAPER_SYSTEM) {
795         systemWallpaperMap_.InsertOrAssign(userId, wallpaperData);
796     } else if (wallpaperType == WALLPAPER_LOCKSCREEN) {
797         lockWallpaperMap_.InsertOrAssign(userId, wallpaperData);
798     }
799     if (!SendWallpaperChangeEvent(userId, wallpaperType)) {
800         HILOG_ERROR("Send wallpaper state failed!");
801         return E_DEAL_FAILED;
802     }
803     return E_OK;
804 }
805 
GetWallpaperFile(WallpaperResourceType resourceType,const WallpaperData & wallpaperData,std::string & wallpaperFile)806 void WallpaperService::GetWallpaperFile(
807     WallpaperResourceType resourceType, const WallpaperData &wallpaperData, std::string &wallpaperFile)
808 {
809     switch (resourceType) {
810         case PICTURE:
811             wallpaperFile = wallpaperData.wallpaperFile;
812             break;
813         case DEFAULT:
814             wallpaperFile = wallpaperData.wallpaperFile;
815             break;
816         case VIDEO:
817             wallpaperFile = wallpaperData.liveWallpaperFile;
818             break;
819         case PACKAGE:
820             wallpaperFile = wallpaperData.customPackageUri;
821             break;
822         default:
823             HILOG_ERROR("Non-existent error type!");
824             break;
825     }
826 }
827 
GetResType(int32_t userId,WallpaperType wallpaperType)828 WallpaperResourceType WallpaperService::GetResType(int32_t userId, WallpaperType wallpaperType)
829 {
830     if (wallpaperType == WALLPAPER_LOCKSCREEN) {
831         auto iterator = lockWallpaperMap_.Find(userId);
832         if (iterator.first) {
833             return iterator.second.resourceType;
834         }
835     } else if (wallpaperType == WALLPAPER_SYSTEM) {
836         auto iterator = systemWallpaperMap_.Find(userId);
837         if (iterator.first) {
838             return iterator.second.resourceType;
839         }
840     }
841     return WallpaperResourceType::DEFAULT;
842 }
843 
SendEvent(const std::string & eventType)844 ErrorCode WallpaperService::SendEvent(const std::string &eventType)
845 {
846     HILOG_INFO("Send event start.");
847     if (!CheckCallingPermission(WALLPAPER_PERMISSION_NAME_SET_WALLPAPER)) {
848         HILOG_ERROR("Send event not set permission!");
849         return E_NO_PERMISSION;
850     }
851 
852     int32_t userId = QueryActiveUserId();
853     WallpaperType wallpaperType;
854     WallpaperData data;
855     if (eventType == SHOW_SYSTEM_SCREEN) {
856         wallpaperType = WALLPAPER_SYSTEM;
857     } else if (eventType == SHOW_LOCK_SCREEN) {
858         wallpaperType = WALLPAPER_LOCKSCREEN;
859     } else {
860         HILOG_ERROR("Event type error!");
861         return E_PARAMETERS_INVALID;
862     }
863 
864     if (!GetWallpaperSafeLocked(userId, wallpaperType, data)) {
865         HILOG_ERROR("Get wallpaper safe locked failed!");
866         return E_PARAMETERS_INVALID;
867     }
868     std::string uri;
869     GetFileNameFromMap(userId, WALLPAPER_SYSTEM, uri);
870     WallpaperChanged(wallpaperType, data.resourceType, uri);
871     return E_OK;
872 }
873 
SendWallpaperChangeEvent(int32_t userId,WallpaperType wallpaperType)874 bool WallpaperService::SendWallpaperChangeEvent(int32_t userId, WallpaperType wallpaperType)
875 {
876     WallpaperData wallpaperData;
877     if (!GetWallpaperSafeLocked(userId, wallpaperType, wallpaperData)) {
878         HILOG_ERROR("GetWallpaperSafeLocked failed!");
879         return false;
880     }
881     shared_ptr<WallpaperCommonEventManager> wallpaperCommonEventManager = make_shared<WallpaperCommonEventManager>();
882     if (wallpaperType == WALLPAPER_SYSTEM) {
883         HILOG_INFO("Send wallpaper system setting message.");
884         wallpaperCommonEventManager->SendWallpaperSystemSettingMessage(wallpaperData.resourceType);
885     } else if (wallpaperType == WALLPAPER_LOCKSCREEN) {
886         HILOG_INFO("Send wallpaper lock setting message.");
887         wallpaperCommonEventManager->SendWallpaperLockSettingMessage(wallpaperData.resourceType);
888     }
889     HILOG_INFO("SetWallpaperBackupData callbackProxy_->OnCall start.");
890     if (callbackProxy_ != nullptr && (wallpaperData.resourceType == PICTURE || wallpaperData.resourceType == DEFAULT)) {
891         callbackProxy_->OnCall(wallpaperType);
892     }
893     std::string uri;
894     WallpaperChanged(wallpaperType, wallpaperData.resourceType, uri);
895     return true;
896 }
897 
SetVideo(int32_t fd,int32_t wallpaperType,int32_t length)898 ErrorCode WallpaperService::SetVideo(int32_t fd, int32_t wallpaperType, int32_t length)
899 {
900     if (!IsSystemApp()) {
901         HILOG_ERROR("current app is not SystemApp.");
902         return E_NOT_SYSTEM_APP;
903     }
904     StartAsyncTrace(HITRACE_TAG_MISC, "SetVideo", static_cast<int32_t>(TraceTaskId::SET_VIDEO));
905     ErrorCode wallpaperErrorCode = SetWallpaper(fd, wallpaperType, length, VIDEO);
906     FinishAsyncTrace(HITRACE_TAG_MISC, "SetVideo", static_cast<int32_t>(TraceTaskId::SET_VIDEO));
907     return wallpaperErrorCode;
908 }
909 
SetCustomWallpaper(int32_t fd,int32_t type,int32_t length)910 ErrorCode WallpaperService::SetCustomWallpaper(int32_t fd, int32_t type, int32_t length)
911 {
912     if (!IsSystemApp()) {
913         HILOG_ERROR("current app is not SystemApp.");
914         return E_NOT_SYSTEM_APP;
915     }
916     if (!CheckCallingPermission(WALLPAPER_PERMISSION_NAME_SET_WALLPAPER)) {
917         HILOG_ERROR("SetWallpaper no set permission!");
918         return E_NO_PERMISSION;
919     }
920     if (type != static_cast<int32_t>(WALLPAPER_LOCKSCREEN) && type != static_cast<int32_t>(WALLPAPER_SYSTEM)) {
921         return E_PARAMETERS_INVALID;
922     }
923     StartAsyncTrace(HITRACE_TAG_MISC, "SetCustomWallpaper", static_cast<int32_t>(TraceTaskId::SET_CUSTOM_WALLPAPER));
924     int32_t userId = QueryActiveUserId();
925     WallpaperType wallpaperType = static_cast<WallpaperType>(type);
926     WallpaperData wallpaperData;
927     if (!GetWallpaperSafeLocked(userId, wallpaperType, wallpaperData)) {
928         HILOG_ERROR("GetWallpaper data failed!");
929         return E_DEAL_FAILED;
930     }
931     if (!Rosen::SceneBoardJudgement::IsSceneBoardEnabled()) {
932         HILOG_ERROR("SceneBoard is not Enabled.");
933         return E_NO_PERMISSION;
934     }
935     if (!SaveWallpaperState(userId, wallpaperType, PACKAGE)) {
936         HILOG_ERROR("Save wallpaper state failed!");
937         return E_DEAL_FAILED;
938     }
939     ErrorCode wallpaperErrorCode = SetWallpaper(fd, wallpaperType, length, PACKAGE);
940     wallpaperData.resourceType = PACKAGE;
941     wallpaperData.wallpaperId = MakeWallpaperIdLocked();
942     if (wallpaperType == WALLPAPER_SYSTEM) {
943         systemWallpaperMap_.InsertOrAssign(userId, wallpaperData);
944     } else if (wallpaperType == WALLPAPER_LOCKSCREEN) {
945         lockWallpaperMap_.InsertOrAssign(userId, wallpaperData);
946     }
947     if (!SendWallpaperChangeEvent(userId, wallpaperType)) {
948         HILOG_ERROR("Send wallpaper state failed!");
949         return E_DEAL_FAILED;
950     }
951     FinishAsyncTrace(HITRACE_TAG_MISC, "SetCustomWallpaper", static_cast<int32_t>(TraceTaskId::SET_CUSTOM_WALLPAPER));
952     return wallpaperErrorCode;
953 }
954 
GetPixelMap(int32_t wallpaperType,IWallpaperService::FdInfo & fdInfo)955 ErrorCode WallpaperService::GetPixelMap(int32_t wallpaperType, IWallpaperService::FdInfo &fdInfo)
956 {
957     HILOG_INFO("WallpaperService::getPixelMap start.");
958     if (!IsSystemApp()) {
959         HILOG_ERROR("CallingApp is not SystemApp.");
960         return E_NOT_SYSTEM_APP;
961     }
962     if (!CheckCallingPermission(WALLPAPER_PERMISSION_NAME_GET_WALLPAPER)) {
963         HILOG_ERROR("GetPixelMap no get permission!");
964         return E_NO_PERMISSION;
965     }
966     if (wallpaperType != static_cast<int32_t>(WALLPAPER_LOCKSCREEN)
967         && wallpaperType != static_cast<int32_t>(WALLPAPER_SYSTEM)) {
968         return E_PARAMETERS_INVALID;
969     }
970     auto type = static_cast<WallpaperType>(wallpaperType);
971     int32_t userId = QueryActiveUserId();
972     HILOG_INFO("QueryCurrentOsAccount userId: %{public}d", userId);
973     // current user's wallpaper is live video, not image
974     WallpaperResourceType resType = GetResType(userId, type);
975     if (resType != PICTURE && resType != DEFAULT) {
976         HILOG_ERROR("Current user's wallpaper is live video, not image.");
977         fdInfo.size = 0; // 0: empty file size
978         fdInfo.fd = -1;  // -1: invalid file description
979         return E_OK;
980     }
981     ErrorCode ret = GetImageSize(userId, type, fdInfo.size);
982     if (ret != E_OK) {
983         HILOG_ERROR("GetImageSize failed!");
984         return ret;
985     }
986     ret = GetImageFd(userId, type, fdInfo.fd);
987     if (ret != E_OK) {
988         HILOG_ERROR("GetImageFd failed!");
989         return ret;
990     }
991     return E_OK;
992 }
993 
GetPixelMapV9(int32_t wallpaperType,IWallpaperService::FdInfo & fdInfo)994 ErrorCode WallpaperService::GetPixelMapV9(int32_t wallpaperType, IWallpaperService::FdInfo &fdInfo)
995 {
996     return GetPixelMap(wallpaperType, fdInfo);
997 }
998 
GetWallpaperId(int32_t wallpaperType)999 int32_t WallpaperService::GetWallpaperId(int32_t wallpaperType)
1000 {
1001     HILOG_INFO("WallpaperService::GetWallpaperId --> start.");
1002     int32_t iWallpaperId = -1;
1003     int32_t userId = QueryActiveUserId();
1004     HILOG_INFO("QueryCurrentOsAccount userId: %{public}d", userId);
1005     if (wallpaperType == WALLPAPER_LOCKSCREEN) {
1006         auto iterator = lockWallpaperMap_.Find(userId);
1007         if (iterator.first) {
1008             iWallpaperId = iterator.second.wallpaperId;
1009         }
1010     } else if (wallpaperType == WALLPAPER_SYSTEM) {
1011         auto iterator = systemWallpaperMap_.Find(userId);
1012         if (iterator.first) {
1013             iWallpaperId = iterator.second.wallpaperId;
1014         }
1015     }
1016     HILOG_INFO("WallpaperService::GetWallpaperId --> end ID[%{public}d]", iWallpaperId);
1017     return iWallpaperId;
1018 }
1019 
IsChangePermitted()1020 bool WallpaperService::IsChangePermitted()
1021 {
1022     HILOG_INFO("IsChangePermitted wallpaper Start.");
1023     bool bFlag = CheckCallingPermission(WALLPAPER_PERMISSION_NAME_SET_WALLPAPER);
1024     return bFlag;
1025 }
1026 
IsOperationAllowed()1027 bool WallpaperService::IsOperationAllowed()
1028 {
1029     HILOG_INFO("IsOperationAllowed wallpaper Start.");
1030     bool bFlag = CheckCallingPermission(WALLPAPER_PERMISSION_NAME_SET_WALLPAPER);
1031     return bFlag;
1032 }
1033 
ResetWallpaper(int32_t wallpaperType)1034 ErrorCode WallpaperService::ResetWallpaper(int32_t wallpaperType)
1035 {
1036     HILOG_INFO("reset wallpaper Start.");
1037     bool permissionSet = CheckCallingPermission(WALLPAPER_PERMISSION_NAME_SET_WALLPAPER);
1038     if (!permissionSet) {
1039         HILOG_ERROR("reset wallpaper no set permission!");
1040         return E_NO_PERMISSION;
1041     }
1042     if (wallpaperType != static_cast<int32_t>(WALLPAPER_LOCKSCREEN)
1043         && wallpaperType != static_cast<int32_t>(WALLPAPER_SYSTEM)) {
1044         HILOG_ERROR("wallpaperType = %{public}d type not support ", wallpaperType);
1045         return E_PARAMETERS_INVALID;
1046     }
1047     WallpaperType type = static_cast<WallpaperType>(wallpaperType);
1048     int32_t userId = QueryActiveUserId();
1049     HILOG_INFO("QueryCurrentOsAccount userId: %{public}d", userId);
1050     if (!CheckUserPermissionById(userId)) {
1051         return E_USER_IDENTITY_ERROR;
1052     }
1053     ErrorCode wallpaperErrorCode = SetDefaultDataForWallpaper(userId, type);
1054     HILOG_INFO(" Set default data result[%{public}d]", wallpaperErrorCode);
1055     return wallpaperErrorCode;
1056 }
1057 
ResetWallpaperV9(int32_t wallpaperType)1058 ErrorCode WallpaperService::ResetWallpaperV9(int32_t wallpaperType)
1059 {
1060     if (!IsSystemApp()) {
1061         HILOG_ERROR("CallingApp is not SystemApp.");
1062         return E_NOT_SYSTEM_APP;
1063     }
1064     return ResetWallpaper(wallpaperType);
1065 }
1066 
SetDefaultDataForWallpaper(int32_t userId,WallpaperType wallpaperType)1067 ErrorCode WallpaperService::SetDefaultDataForWallpaper(int32_t userId, WallpaperType wallpaperType)
1068 {
1069     WallpaperData wallpaperData;
1070     if (!GetWallpaperSafeLocked(userId, wallpaperType, wallpaperData)) {
1071         return E_DEAL_FAILED;
1072     }
1073     if (!RestoreUserResources(userId, wallpaperData, wallpaperType)) {
1074         HILOG_ERROR("RestoreUserResources error!");
1075         return E_DEAL_FAILED;
1076     }
1077     if (!SaveWallpaperState(userId, wallpaperType, DEFAULT)) {
1078         HILOG_ERROR("Save wallpaper state failed!");
1079         return E_DEAL_FAILED;
1080     }
1081     wallpaperData.wallpaperId = DEFAULT_WALLPAPER_ID;
1082     wallpaperData.resourceType = DEFAULT;
1083     wallpaperData.allowBackup = true;
1084     if (wallpaperType == WALLPAPER_LOCKSCREEN) {
1085         lockWallpaperMap_.InsertOrAssign(userId, wallpaperData);
1086     } else if (wallpaperType == WALLPAPER_SYSTEM) {
1087         systemWallpaperMap_.InsertOrAssign(userId, wallpaperData);
1088     }
1089     if (!SendWallpaperChangeEvent(userId, wallpaperType)) {
1090         HILOG_ERROR("Send wallpaper state failed!");
1091         return E_DEAL_FAILED;
1092     }
1093     SaveColor(userId, wallpaperType);
1094     return E_OK;
1095 }
1096 
On(const std::string & type,sptr<IWallpaperEventListener> listener)1097 ErrorCode WallpaperService::On(const std::string &type, sptr<IWallpaperEventListener> listener)
1098 {
1099     HILOG_DEBUG("WallpaperService::On in.");
1100     if (listener == nullptr) {
1101         HILOG_ERROR("WallpaperService::On listener is null.");
1102         return E_DEAL_FAILED;
1103     }
1104     if (type == WALLPAPER_CHANGE && !IsSystemApp()) {
1105         HILOG_ERROR("current app is not SystemApp.");
1106         return E_NOT_SYSTEM_APP;
1107     }
1108     std::lock_guard<std::mutex> autoLock(listenerMapMutex_);
1109     wallpaperEventMap_[type].insert_or_assign(IPCSkeleton::GetCallingTokenID(), listener);
1110     return E_OK;
1111 }
1112 
Off(const std::string & type,sptr<IWallpaperEventListener> listener)1113 ErrorCode WallpaperService::Off(const std::string &type, sptr<IWallpaperEventListener> listener)
1114 {
1115     HILOG_DEBUG("WallpaperService::Off in.");
1116     (void)listener;
1117     if (type == WALLPAPER_CHANGE && !IsSystemApp()) {
1118         HILOG_ERROR("current app is not SystemApp.");
1119         return E_NOT_SYSTEM_APP;
1120     }
1121     std::lock_guard<std::mutex> autoLock(listenerMapMutex_);
1122     auto iter = wallpaperEventMap_.find(type);
1123     if (iter != wallpaperEventMap_.end()) {
1124         auto it = iter->second.find(IPCSkeleton::GetCallingTokenID());
1125         if (it != iter->second.end()) {
1126             it->second = nullptr;
1127             iter->second.erase(it);
1128         }
1129     }
1130     return E_OK;
1131 }
1132 
RegisterWallpaperCallback(const sptr<IWallpaperCallback> callback)1133 bool WallpaperService::RegisterWallpaperCallback(const sptr<IWallpaperCallback> callback)
1134 {
1135     HILOG_INFO("  WallpaperService::RegisterWallpaperCallback.");
1136     callbackProxy_ = callback;
1137     return true;
1138 }
1139 
GetWallpaperSafeLocked(int32_t userId,WallpaperType wallpaperType,WallpaperData & wallpaperData)1140 bool WallpaperService::GetWallpaperSafeLocked(int32_t userId, WallpaperType wallpaperType, WallpaperData &wallpaperData)
1141 {
1142     HILOG_DEBUG("GetWallpaperSafeLocked start.");
1143     auto iterator = wallpaperType == WALLPAPER_SYSTEM ? systemWallpaperMap_.Find(userId)
1144                                                       : lockWallpaperMap_.Find(userId);
1145     if (!iterator.first) {
1146         HILOG_INFO("No Lock wallpaper?  Not tracking for lock-only");
1147         UpdataWallpaperMap(userId, wallpaperType);
1148         iterator = wallpaperType == WALLPAPER_SYSTEM ? systemWallpaperMap_.Find(userId)
1149                                                      : lockWallpaperMap_.Find(userId);
1150         if (!iterator.first) {
1151             HILOG_ERROR("Fail to get wallpaper data");
1152             return false;
1153         }
1154     }
1155     wallpaperData = iterator.second;
1156     ClearnWallpaperDataFile(wallpaperData);
1157     return true;
1158 }
1159 
ClearWallpaperLocked(int32_t userId,WallpaperType wallpaperType)1160 void WallpaperService::ClearWallpaperLocked(int32_t userId, WallpaperType wallpaperType)
1161 {
1162     HILOG_INFO("Clear wallpaper Start.");
1163     auto iterator = wallpaperType == WALLPAPER_SYSTEM ? systemWallpaperMap_.Find(userId)
1164                                                       : lockWallpaperMap_.Find(userId);
1165     if (!iterator.first) {
1166         HILOG_ERROR("Lock wallpaper already cleared.");
1167         return;
1168     }
1169     if (!iterator.second.wallpaperFile.empty() || !iterator.second.liveWallpaperFile.empty()) {
1170         if (wallpaperType == WALLPAPER_LOCKSCREEN) {
1171             lockWallpaperMap_.Erase(userId);
1172         } else if (wallpaperType == WALLPAPER_SYSTEM) {
1173             systemWallpaperMap_.Erase(userId);
1174         }
1175     }
1176 }
1177 
CheckCallingPermission(const std::string & permissionName)1178 bool WallpaperService::CheckCallingPermission(const std::string &permissionName)
1179 {
1180     AccessTokenID callerToken = IPCSkeleton::GetCallingTokenID();
1181     int32_t result = AccessTokenKit::VerifyAccessToken(callerToken, permissionName);
1182     if (result != TypePermissionState::PERMISSION_GRANTED) {
1183         HILOG_ERROR("Check permission failed!");
1184         return false;
1185     }
1186     return true;
1187 }
1188 
ReporterFault(FaultType faultType,FaultCode faultCode)1189 void WallpaperService::ReporterFault(FaultType faultType, FaultCode faultCode)
1190 {
1191     FaultMsg msg;
1192     msg.faultType = faultType;
1193     msg.errorCode = faultCode;
1194     ReportStatus nRet;
1195     if (faultType == FaultType::SERVICE_FAULT) {
1196         msg.moduleName = "WallpaperService";
1197         nRet = FaultReporter::ReportServiceFault(msg);
1198     } else {
1199         nRet = FaultReporter::ReportRuntimeFault(msg);
1200     }
1201 
1202     if (nRet == ReportStatus::SUCCESS) {
1203         HILOG_INFO("ReporterFault success.");
1204     } else {
1205         HILOG_ERROR("ReporterFault failed!");
1206     }
1207 }
1208 
Dump(int32_t fd,const std::vector<std::u16string> & args)1209 int32_t WallpaperService::Dump(int32_t fd, const std::vector<std::u16string> &args)
1210 {
1211     std::vector<std::string> argsStr;
1212     for (auto item : args) {
1213         argsStr.emplace_back(Str16ToStr8(item));
1214     }
1215 
1216     if (DumpHelper::GetInstance().Dispatch(fd, argsStr)) {
1217         HILOG_ERROR("DumpHelper Dispatch failed!");
1218         return 0;
1219     }
1220     return 1;
1221 }
1222 
1223 #ifndef THEME_SERVICE
ConnectExtensionAbility()1224 bool WallpaperService::ConnectExtensionAbility()
1225 {
1226     HILOG_DEBUG("ConnectAdapter.");
1227     MemoryGuard cacheGuard;
1228     AAFwk::Want want;
1229     want.SetElementName(OHOS_WALLPAPER_BUNDLE_NAME, "WallpaperExtAbility");
1230     ErrCode errCode = AAFwk::AbilityManagerClient::GetInstance()->Connect();
1231     if (errCode != ERR_OK) {
1232         HILOG_ERROR("connect ability server failed errCode=%{public}d", errCode);
1233         return false;
1234     }
1235     if (connection_ == nullptr) {
1236         connection_ = new WallpaperExtensionAbilityConnection(*this);
1237     }
1238     auto ret = AAFwk::AbilityManagerClient::GetInstance()->ConnectExtensionAbility(want, connection_, DEFAULT_VALUE);
1239     HILOG_INFO("ConnectExtensionAbility errCode=%{public}d", ret);
1240     return ret;
1241 }
1242 #endif
1243 
IsSystemApp()1244 bool WallpaperService::IsSystemApp()
1245 {
1246     HILOG_INFO("IsSystemApp start.");
1247     uint64_t tokenId = IPCSkeleton::GetCallingFullTokenID();
1248     return TokenIdKit::IsSystemAppByFullTokenID(tokenId);
1249 }
1250 
IsNativeSa()1251 bool WallpaperService::IsNativeSa()
1252 {
1253     HILOG_INFO("IsNativeSa start.");
1254     AccessTokenID tokenId = IPCSkeleton::GetCallingTokenID();
1255     return AccessTokenKit::GetTokenTypeFlag(tokenId) == TypeATokenTypeEnum::TOKEN_NATIVE;
1256 }
1257 
GetImageFd(int32_t userId,WallpaperType wallpaperType,int32_t & fd)1258 ErrorCode WallpaperService::GetImageFd(int32_t userId, WallpaperType wallpaperType, int32_t &fd)
1259 {
1260     HILOG_INFO("WallpaperService::GetImageFd start.");
1261     std::string filePathName;
1262     if (!GetFileNameFromMap(userId, wallpaperType, filePathName)) {
1263         return E_DEAL_FAILED;
1264     }
1265     if (GetResType(userId, wallpaperType) == WallpaperResourceType::PACKAGE) {
1266         HILOG_INFO("The current wallpaper is a custom wallpaper");
1267         return E_OK;
1268     }
1269     {
1270         std::lock_guard<std::mutex> lock(mtx_);
1271         fd = open(filePathName.c_str(), O_RDONLY, S_IREAD);
1272     }
1273     if (fd < 0) {
1274         HILOG_ERROR("Open file failed, errno %{public}d", errno);
1275         ReporterFault(FaultType::LOAD_WALLPAPER_FAULT, FaultCode::RF_FD_INPUT_FAILED);
1276         return E_DEAL_FAILED;
1277     }
1278     HILOG_INFO("fd = %{public}d", fd);
1279     return E_OK;
1280 }
1281 
GetImageSize(int32_t userId,WallpaperType wallpaperType,int32_t & size)1282 ErrorCode WallpaperService::GetImageSize(int32_t userId, WallpaperType wallpaperType, int32_t &size)
1283 {
1284     HILOG_INFO("WallpaperService::GetImageSize start.");
1285     std::string filePathName;
1286     HILOG_INFO("userId = %{public}d", userId);
1287     if (!GetPictureFileName(userId, wallpaperType, filePathName)) {
1288         return E_DEAL_FAILED;
1289     }
1290 
1291     if (!OHOS::FileExists(filePathName)) {
1292         HILOG_ERROR("file is not exist.");
1293         return E_NOT_FOUND;
1294     }
1295     std::lock_guard<std::mutex> lock(mtx_);
1296     FILE *fd = fopen(filePathName.c_str(), "rb");
1297     if (fd == nullptr) {
1298         HILOG_ERROR("fopen file failed, errno %{public}d", errno);
1299         return E_FILE_ERROR;
1300     }
1301     int32_t fend = fseek(fd, 0, SEEK_END);
1302     size = ftell(fd);
1303     int32_t fset = fseek(fd, 0, SEEK_SET);
1304     if (size <= 0 || fend != 0 || fset != 0) {
1305         HILOG_ERROR("ftell file failed or fseek file failed, errno %{public}d", errno);
1306         fclose(fd);
1307         return E_FILE_ERROR;
1308     }
1309     fclose(fd);
1310     return E_OK;
1311 }
1312 
QueryActiveUserId()1313 int32_t WallpaperService::QueryActiveUserId()
1314 {
1315     std::vector<int32_t> ids;
1316     ErrCode errCode = AccountSA::OsAccountManager::QueryActiveOsAccountIds(ids);
1317     if (errCode != ERR_OK || ids.empty()) {
1318         HILOG_ERROR("Query active userid failed, errCode: %{public}d,", errCode);
1319         return DEFAULT_USER_ID;
1320     }
1321     return ids[0];
1322 }
1323 
CheckUserPermissionById(int32_t userId)1324 bool WallpaperService::CheckUserPermissionById(int32_t userId)
1325 {
1326     OsAccountInfo osAccountInfo;
1327     ErrCode errCode = OsAccountManager::QueryOsAccountById(userId, osAccountInfo);
1328     if (errCode != ERR_OK) {
1329         HILOG_ERROR("Query os account info failed, errCode: %{public}d", errCode);
1330         return false;
1331     }
1332     HILOG_INFO("osAccountInfo GetType: %{public}d", static_cast<int32_t>(osAccountInfo.GetType()));
1333     if (osAccountInfo.GetType() == OsAccountType::GUEST) {
1334         HILOG_ERROR("The guest does not have permissions.");
1335         return false;
1336     }
1337     return true;
1338 }
1339 
SetWallpaper(int32_t fd,int32_t wallpaperType,int32_t length,WallpaperResourceType resourceType)1340 ErrorCode WallpaperService::SetWallpaper(
1341     int32_t fd, int32_t wallpaperType, int32_t length, WallpaperResourceType resourceType)
1342 {
1343     int32_t userId = QueryActiveUserId();
1344     HILOG_INFO("QueryCurrentOsAccount userId: %{public}d", userId);
1345     if (!CheckUserPermissionById(userId)) {
1346         return E_USER_IDENTITY_ERROR;
1347     }
1348     ErrorCode errCode = CheckValid(wallpaperType, length, resourceType);
1349     if (errCode != E_OK) {
1350         return errCode;
1351     }
1352     std::string uri = wallpaperTmpFullPath_;
1353     char *paperBuf = new (std::nothrow) char[length]();
1354     if (paperBuf == nullptr) {
1355         return E_NO_MEMORY;
1356     }
1357     {
1358         std::lock_guard<std::mutex> lock(mtx_);
1359         if (read(fd, paperBuf, length) <= 0) {
1360             HILOG_ERROR("read fd failed!");
1361             delete[] paperBuf;
1362             return E_DEAL_FAILED;
1363         }
1364         mode_t mode = S_IRUSR | S_IWUSR;
1365         int32_t fdw = open(uri.c_str(), O_WRONLY | O_CREAT, mode);
1366         if (fdw < 0) {
1367             HILOG_ERROR("Open wallpaper tmpFullPath failed, errno %{public}d", errno);
1368             delete[] paperBuf;
1369             return E_DEAL_FAILED;
1370         }
1371         if (write(fdw, paperBuf, length) <= 0) {
1372             HILOG_ERROR("Write to fdw failed, errno %{public}d", errno);
1373             ReporterFault(FaultType::SET_WALLPAPER_FAULT, FaultCode::RF_DROP_FAILED);
1374             delete[] paperBuf;
1375             close(fdw);
1376             return E_DEAL_FAILED;
1377         }
1378         delete[] paperBuf;
1379         close(fdw);
1380     }
1381     WallpaperType type = static_cast<WallpaperType>(wallpaperType);
1382     ErrorCode wallpaperErrorCode = SetWallpaperBackupData(userId, resourceType, uri, type);
1383     if (resourceType == PICTURE) {
1384         SaveColor(userId, type);
1385     }
1386     return wallpaperErrorCode;
1387 }
1388 
SetWallpaperByPixelMap(std::shared_ptr<OHOS::Media::PixelMap> pixelMap,int32_t wallpaperType,WallpaperResourceType resourceType)1389 ErrorCode WallpaperService::SetWallpaperByPixelMap(
1390     std::shared_ptr<OHOS::Media::PixelMap> pixelMap, int32_t wallpaperType, WallpaperResourceType resourceType)
1391 {
1392     if (pixelMap == nullptr) {
1393         HILOG_ERROR("pixelMap is nullptr");
1394         return E_FILE_ERROR;
1395     }
1396     int32_t userId = QueryActiveUserId();
1397     HILOG_INFO("QueryCurrentOsAccount userId: %{public}d", userId);
1398     if (!CheckUserPermissionById(userId)) {
1399         return E_USER_IDENTITY_ERROR;
1400     }
1401     std::string uri = wallpaperTmpFullPath_;
1402     ErrorCode errCode = WritePixelMapToFile(pixelMap, uri, wallpaperType, resourceType);
1403     if (errCode != E_OK) {
1404         HILOG_ERROR("WritePixelMapToFile failed!");
1405         return errCode;
1406     }
1407     WallpaperType type = static_cast<WallpaperType>(wallpaperType);
1408     ErrorCode wallpaperErrorCode = SetWallpaperBackupData(userId, resourceType, uri, type);
1409     if (resourceType == PICTURE) {
1410         SaveColor(userId, type);
1411     }
1412     return wallpaperErrorCode;
1413 }
1414 
WritePixelMapToFile(std::shared_ptr<OHOS::Media::PixelMap> pixelMap,std::string wallpaperTmpFullPath,int32_t wallpaperType,WallpaperResourceType resourceType)1415 ErrorCode WallpaperService::WritePixelMapToFile(std::shared_ptr<OHOS::Media::PixelMap> pixelMap,
1416     std::string wallpaperTmpFullPath, int32_t wallpaperType, WallpaperResourceType resourceType)
1417 {
1418     if (pixelMap == nullptr) {
1419         HILOG_ERROR("pixelMap is nullptr");
1420         return E_FILE_ERROR;
1421     }
1422     std::stringbuf stringBuf;
1423     std::ostream ostream(&stringBuf);
1424     int32_t mapSize = WritePixelMapToStream(pixelMap, ostream);
1425     if (mapSize <= 0) {
1426         HILOG_ERROR("WritePixelMapToStream failed!");
1427         return E_WRITE_PARCEL_ERROR;
1428     }
1429     ErrorCode errCode = CheckValid(wallpaperType, mapSize, resourceType);
1430     if (errCode != E_OK) {
1431         HILOG_ERROR("CheckValid failed!");
1432         return errCode;
1433     }
1434     char *buffer = new (std::nothrow) char[mapSize]();
1435     if (buffer == nullptr) {
1436         HILOG_ERROR("buffer failed!");
1437         return E_NO_MEMORY;
1438     }
1439     stringBuf.sgetn(buffer, mapSize);
1440     {
1441         std::lock_guard<std::mutex> lock(mtx_);
1442         mode_t mode = S_IRUSR | S_IWUSR;
1443         int32_t fdw = open(wallpaperTmpFullPath.c_str(), O_WRONLY | O_CREAT, mode);
1444         if (fdw < 0) {
1445             HILOG_ERROR("Open wallpaper tmpFullPath failed, errno %{public}d", errno);
1446             delete[] buffer;
1447             return E_DEAL_FAILED;
1448         }
1449         if (write(fdw, buffer, mapSize) <= 0) {
1450             HILOG_ERROR("Write to fdw failed, errno %{public}d", errno);
1451             ReporterFault(FaultType::SET_WALLPAPER_FAULT, FaultCode::RF_DROP_FAILED);
1452             delete[] buffer;
1453             close(fdw);
1454             return E_DEAL_FAILED;
1455         }
1456         delete[] buffer;
1457         close(fdw);
1458     }
1459     return E_OK;
1460 }
1461 
WritePixelMapToStream(std::shared_ptr<OHOS::Media::PixelMap> pixelMap,std::ostream & outputStream)1462 int64_t WallpaperService::WritePixelMapToStream(
1463     std::shared_ptr<OHOS::Media::PixelMap> pixelMap, std::ostream &outputStream)
1464 {
1465     if (pixelMap == nullptr) {
1466         HILOG_ERROR("pixelMap is nullptr");
1467         return 0;
1468     }
1469     OHOS::Media::ImagePacker imagePacker;
1470     OHOS::Media::PackOption option;
1471     option.format = "image/jpeg";
1472     option.quality = OPTION_QUALITY;
1473     option.numberHint = 1;
1474     std::set<std::string> formats;
1475     uint32_t ret = imagePacker.GetSupportedFormats(formats);
1476     if (ret != 0) {
1477         HILOG_ERROR("image packer get supported format failed, ret=%{public}u.", ret);
1478     }
1479 
1480     imagePacker.StartPacking(outputStream, option);
1481     imagePacker.AddImage(*pixelMap);
1482     int64_t packedSize = 0;
1483     imagePacker.FinalizePacking(packedSize);
1484     HILOG_INFO("FrameWork WritePixelMapToStream End! packedSize=%{public}lld.", static_cast<long long>(packedSize));
1485     return packedSize;
1486 }
1487 
OnColorsChange(WallpaperType wallpaperType,const ColorManager::Color & color)1488 void WallpaperService::OnColorsChange(WallpaperType wallpaperType, const ColorManager::Color &color)
1489 {
1490     std::vector<uint64_t> colors;
1491     if (wallpaperType == WALLPAPER_SYSTEM && !CompareColor(systemWallpaperColor_, color)) {
1492         {
1493             std::lock_guard<std::mutex> lock(wallpaperColorMtx_);
1494             systemWallpaperColor_ = color.PackValue();
1495             colors.emplace_back(systemWallpaperColor_);
1496         }
1497         NotifyColorChange(colors, WALLPAPER_SYSTEM);
1498     } else if (wallpaperType == WALLPAPER_LOCKSCREEN && !CompareColor(lockWallpaperColor_, color)) {
1499         {
1500             std::lock_guard<std::mutex> lock(wallpaperColorMtx_);
1501             lockWallpaperColor_ = color.PackValue();
1502             colors.emplace_back(lockWallpaperColor_);
1503         }
1504         NotifyColorChange(colors, WALLPAPER_LOCKSCREEN);
1505     }
1506 }
1507 
CheckValid(int32_t wallpaperType,int32_t length,WallpaperResourceType resourceType)1508 ErrorCode WallpaperService::CheckValid(int32_t wallpaperType, int32_t length, WallpaperResourceType resourceType)
1509 {
1510     if (!CheckCallingPermission(WALLPAPER_PERMISSION_NAME_SET_WALLPAPER)) {
1511         HILOG_ERROR("SetWallpaper no set permission.");
1512         return E_NO_PERMISSION;
1513     }
1514     if (wallpaperType != static_cast<int32_t>(WALLPAPER_LOCKSCREEN)
1515         && wallpaperType != static_cast<int32_t>(WALLPAPER_SYSTEM)) {
1516         return E_PARAMETERS_INVALID;
1517     }
1518 
1519     int32_t maxLength = resourceType == VIDEO ? MAX_VIDEO_SIZE : FOO_MAX_LEN;
1520     if (length <= 0) {
1521         return E_PARAMETERS_INVALID;
1522     }
1523     if (length > maxLength) {
1524         return E_PICTURE_OVERSIZED;
1525     }
1526     return E_OK;
1527 }
1528 
WallpaperChanged(WallpaperType wallpaperType,WallpaperResourceType resType,const std::string & uri)1529 bool WallpaperService::WallpaperChanged(
1530     WallpaperType wallpaperType, WallpaperResourceType resType, const std::string &uri)
1531 {
1532     std::lock_guard<std::mutex> autoLock(listenerMapMutex_);
1533     auto it = wallpaperEventMap_.find(WALLPAPER_CHANGE);
1534     if (it != wallpaperEventMap_.end()) {
1535         for (auto iter = it->second.begin(); iter != it->second.end(); iter++) {
1536             if (iter->second == nullptr) {
1537                 continue;
1538             }
1539             iter->second->OnWallpaperChange(wallpaperType, resType, uri);
1540         }
1541         return true;
1542     }
1543     return false;
1544 }
1545 
NotifyColorChange(const std::vector<uint64_t> & colors,const WallpaperType & wallpaperType)1546 void WallpaperService::NotifyColorChange(const std::vector<uint64_t> &colors, const WallpaperType &wallpaperType)
1547 {
1548     std::lock_guard<std::mutex> autoLock(listenerMapMutex_);
1549     auto it = wallpaperEventMap_.find(COLOR_CHANGE);
1550     if (it != wallpaperEventMap_.end()) {
1551         for (auto iter = it->second.begin(); iter != it->second.end(); iter++) {
1552             if (iter->second == nullptr) {
1553                 continue;
1554             }
1555             iter->second->OnColorsChange(colors, wallpaperType);
1556         }
1557     }
1558 }
1559 
SaveWallpaperState(int32_t userId,WallpaperType wallpaperType,WallpaperResourceType resourceType)1560 bool WallpaperService::SaveWallpaperState(
1561     int32_t userId, WallpaperType wallpaperType, WallpaperResourceType resourceType)
1562 {
1563     WallpaperData systemData;
1564     WallpaperData lockScreenData;
1565     if (!GetWallpaperSafeLocked(userId, WALLPAPER_SYSTEM, systemData)
1566         || !GetWallpaperSafeLocked(userId, WALLPAPER_LOCKSCREEN, lockScreenData)) {
1567         return false;
1568     }
1569     nlohmann::json root;
1570     if (wallpaperType == WALLPAPER_SYSTEM) {
1571         root[SYSTEM_RES_TYPE] = static_cast<int32_t>(resourceType);
1572         root[LOCKSCREEN_RES_TYPE] = static_cast<int32_t>(lockScreenData.resourceType);
1573     } else {
1574         root[LOCKSCREEN_RES_TYPE] = static_cast<int32_t>(resourceType);
1575         root[SYSTEM_RES_TYPE] = static_cast<int32_t>(systemData.resourceType);
1576     }
1577     std::string json = root.dump();
1578     if (json.empty()) {
1579         HILOG_ERROR("write user config file failed. because json content is empty.");
1580         return false;
1581     }
1582 
1583     std::string userPath = WALLPAPER_USERID_PATH + std::to_string(userId) + "/wallpapercfg";
1584     mode_t mode = S_IRUSR | S_IWUSR;
1585     int fd = open(userPath.c_str(), O_CREAT | O_WRONLY | O_SYNC, mode);
1586     if (fd <= 0) {
1587         HILOG_ERROR("open user config file failed!");
1588         return false;
1589     }
1590     ssize_t size = write(fd, json.c_str(), json.size());
1591     if (size <= 0) {
1592         HILOG_ERROR("write user config file failed!");
1593         close(fd);
1594         return false;
1595     }
1596     close(fd);
1597     return true;
1598 }
1599 
LoadWallpaperState()1600 void WallpaperService::LoadWallpaperState()
1601 {
1602     int32_t userId = QueryActiveUserId();
1603     std::string userPath = WALLPAPER_USERID_PATH + std::to_string(userId) + "/wallpapercfg";
1604     int fd = open(userPath.c_str(), O_RDONLY, S_IREAD);
1605     if (fd <= 0) {
1606         HILOG_ERROR("open user config file failed!");
1607         return;
1608     }
1609     const size_t len = 255;
1610     char buf[len] = { 0 };
1611     ssize_t size = read(fd, buf, len);
1612     if (size <= 0) {
1613         HILOG_ERROR("read user config file failed!");
1614         close(fd);
1615         return;
1616     }
1617     close(fd);
1618 
1619     if (buf[0] == '\0') {
1620         return;
1621     }
1622     WallpaperData systemData;
1623     WallpaperData lockScreenData;
1624     if (!GetWallpaperSafeLocked(userId, WALLPAPER_SYSTEM, systemData)
1625         || !GetWallpaperSafeLocked(userId, WALLPAPER_LOCKSCREEN, lockScreenData)) {
1626         return;
1627     }
1628     if (Json::accept(buf)) {
1629         auto root = nlohmann::json::parse(buf);
1630         if (root.contains(SYSTEM_RES_TYPE) && root[SYSTEM_RES_TYPE].is_number()) {
1631             systemData.resourceType = static_cast<WallpaperResourceType>(root[SYSTEM_RES_TYPE].get<int>());
1632         }
1633         if (root.contains(LOCKSCREEN_RES_TYPE) && root[SYSTEM_RES_TYPE].is_number()) {
1634             lockScreenData.resourceType = static_cast<WallpaperResourceType>(root[LOCKSCREEN_RES_TYPE].get<int>());
1635         }
1636     }
1637 }
1638 
GetDefaultResDir()1639 std::string WallpaperService::GetDefaultResDir()
1640 {
1641     std::string resPath;
1642     CfgFiles *cfgFiles = GetCfgFiles(RESOURCE_PATH);
1643     if (cfgFiles != nullptr) {
1644         for (auto &cfgPath : cfgFiles->paths) {
1645             if (cfgPath != nullptr) {
1646                 HILOG_DEBUG("GetCfgFiles path is :%{public}s", cfgPath);
1647                 resPath = cfgPath + std::string(DEFAULT_PATH);
1648                 break;
1649             }
1650         }
1651         FreeCfgFiles(cfgFiles);
1652     }
1653     return resPath;
1654 }
1655 
GetWallpaperPathInJson(const std::string manifestName,const std::string filePath)1656 std::string WallpaperService::GetWallpaperPathInJson(const std::string manifestName, const std::string filePath)
1657 {
1658     std::string wallpaperPath;
1659     std::string resPath = GetDefaultResDir();
1660     if (resPath.empty() && !FileDeal::IsDirExist(resPath)) {
1661         HILOG_ERROR("wallpaperDefaultDir get failed!");
1662         return "";
1663     }
1664     std::string manifestFile = resPath + manifestName;
1665     std::ifstream file(manifestFile);
1666     if (!file.is_open()) {
1667         HILOG_ERROR("open fail:%{public}s", manifestFile.c_str());
1668         file.close();
1669         return "";
1670     }
1671     std::string content((std::istreambuf_iterator<char>(file)), std::istreambuf_iterator<char>());
1672     file.close();
1673     if (!nlohmann::json::accept(content)) {
1674         HILOG_ERROR("accept failed!");
1675         return "";
1676     }
1677     auto root = nlohmann::json::parse(content.c_str());
1678     if (root.contains(IMAGE) && root[IMAGE].contains(SRC)) {
1679         std::string srcValue = root[IMAGE][SRC];
1680         return GetExistFilePath(resPath + filePath + srcValue);
1681     }
1682     HILOG_ERROR("src not exist.");
1683     return "";
1684 }
1685 
GetExistFilePath(const std::string & filePath)1686 std::string WallpaperService::GetExistFilePath(const std::string &filePath)
1687 {
1688     if (!FileDeal::IsFileExist(filePath)) {
1689         HILOG_ERROR("path file is not exist! %{public}s", filePath.c_str());
1690         return "";
1691     }
1692     return filePath;
1693 }
1694 
SetAllWallpapers(std::vector<WallpaperPictureInfo> allWallpaperInfos,int32_t wallpaperType)1695 ErrorCode WallpaperService::SetAllWallpapers(std::vector<WallpaperPictureInfo> allWallpaperInfos, int32_t wallpaperType)
1696 {
1697     StartAsyncTrace(HITRACE_TAG_MISC, "SetAllWallpapers", static_cast<int32_t>(TraceTaskId::SET_ALL_WALLPAPERS));
1698     ErrorCode wallpaperErrorCode = SetAllWallpapers(allWallpaperInfos, wallpaperType, PICTURE);
1699     FinishAsyncTrace(HITRACE_TAG_MISC, "SetAllWallpapers", static_cast<int32_t>(TraceTaskId::SET_ALL_WALLPAPERS));
1700     return wallpaperErrorCode;
1701 }
1702 
SetAllWallpapers(std::vector<WallpaperPictureInfo> allWallpaperInfos,int32_t wallpaperType,WallpaperResourceType resourceType)1703 ErrorCode WallpaperService::SetAllWallpapers(
1704     std::vector<WallpaperPictureInfo> allWallpaperInfos, int32_t wallpaperType, WallpaperResourceType resourceType)
1705 {
1706     StartAsyncTrace(HITRACE_TAG_MISC, "SetAllWallpapers", static_cast<int32_t>(TraceTaskId::SET_ALL_WALLPAPERS));
1707     if (!IsSystemApp() && !IsNativeSa()) {
1708         HILOG_ERROR("Is not SystemApp or NativeSA.");
1709         return E_NOT_SYSTEM_APP;
1710     }
1711     int32_t userId = QueryActiveUserId();
1712     HILOG_INFO("SetAllWallpapers userId: %{public}d", userId);
1713     if (!CheckUserPermissionById(userId)) {
1714         return E_USER_IDENTITY_ERROR;
1715     }
1716     ErrorCode errCode;
1717     for (auto &wallpaperInfo : allWallpaperInfos) {
1718         wallpaperInfo.tempPath = std::string(WALLPAPER_USERID_PATH) + GetFoldStateName(wallpaperInfo.foldState) + "_"
1719                                  + GetRotateStateName(wallpaperInfo.rotateState);
1720         errCode = CheckValid(wallpaperType, wallpaperInfo.length, resourceType);
1721         if (errCode != E_OK) {
1722             return errCode;
1723         }
1724         errCode = WriteFdToFile(wallpaperInfo, wallpaperInfo.tempPath);
1725         if (errCode != E_OK) {
1726             DeleteTempResource(allWallpaperInfos);
1727             HILOG_ERROR("WriteFdToFile failed!");
1728             return errCode;
1729         }
1730     }
1731     WallpaperType type = static_cast<WallpaperType>(wallpaperType);
1732     std::string wallpaperPath = GetWallpaperDir(userId, type);
1733     FileDeal::DeleteDir(wallpaperPath, false);
1734     errCode = UpdateWallpaperData(allWallpaperInfos, userId, type);
1735     if (errCode != E_OK) {
1736         HILOG_ERROR("UpdateWallpaperData failed!");
1737         return errCode;
1738     }
1739     SaveColor(userId, type);
1740     if (!SendWallpaperChangeEvent(userId, type)) {
1741         HILOG_ERROR("Send wallpaper state failed!");
1742         return E_DEAL_FAILED;
1743     }
1744     FinishAsyncTrace(HITRACE_TAG_MISC, "SetAllWallpapers", static_cast<int32_t>(TraceTaskId::SET_ALL_WALLPAPERS));
1745     return errCode;
1746 }
1747 
UpdateWallpaperData(std::vector<WallpaperPictureInfo> allWallpaperInfos,int32_t userId,WallpaperType wallpaperType)1748 ErrorCode WallpaperService::UpdateWallpaperData(
1749     std::vector<WallpaperPictureInfo> allWallpaperInfos, int32_t userId, WallpaperType wallpaperType)
1750 {
1751     ErrorCode errCode;
1752     WallpaperData wallpaperData;
1753     bool ret = GetWallpaperSafeLocked(userId, wallpaperType, wallpaperData);
1754     if (!ret) {
1755         HILOG_ERROR("GetWallpaperSafeLocked failed!");
1756         return E_DEAL_FAILED;
1757     }
1758     ClearnWallpaperDataFile(wallpaperData);
1759     errCode = SetAllWallpaperBackupData(allWallpaperInfos, userId, wallpaperType, wallpaperData);
1760     if (errCode != E_OK) {
1761         DeleteTempResource(allWallpaperInfos);
1762         HILOG_ERROR("SetAllWallpaperBackupData failed!");
1763         return errCode;
1764     }
1765     wallpaperData.resourceType = PICTURE;
1766     wallpaperData.wallpaperId = MakeWallpaperIdLocked();
1767     if (wallpaperType == WALLPAPER_SYSTEM) {
1768         systemWallpaperMap_.InsertOrAssign(userId, wallpaperData);
1769     } else if (wallpaperType == WALLPAPER_LOCKSCREEN) {
1770         lockWallpaperMap_.InsertOrAssign(userId, wallpaperData);
1771     }
1772     return E_OK;
1773 }
1774 
WriteFdToFile(WallpaperPictureInfo & wallpaperPictureInfo,std::string & path)1775 ErrorCode WallpaperService::WriteFdToFile(WallpaperPictureInfo &wallpaperPictureInfo, std::string &path)
1776 {
1777     std::lock_guard<std::mutex> lock(mtx_);
1778     char *wallpaperBuffer = new (std::nothrow) char[wallpaperPictureInfo.length]();
1779     if (wallpaperBuffer == nullptr) {
1780         HILOG_ERROR("create wallpaperBuffer failed!");
1781         return E_NO_MEMORY;
1782     }
1783     if (read(wallpaperPictureInfo.fd, wallpaperBuffer, wallpaperPictureInfo.length) <= 0) {
1784         HILOG_ERROR("read fd failed!");
1785         delete[] wallpaperBuffer;
1786         return E_DEAL_FAILED;
1787     }
1788     mode_t mode = S_IRUSR | S_IWUSR;
1789     int32_t fdw = open(path.c_str(), O_WRONLY | O_CREAT, mode);
1790     if (fdw < 0) {
1791         HILOG_ERROR("Open wallpaper tmpFullPath failed, errno %{public}d", errno);
1792         delete[] wallpaperBuffer;
1793         return E_DEAL_FAILED;
1794     }
1795     if (write(fdw, wallpaperBuffer, wallpaperPictureInfo.length) <= 0) {
1796         HILOG_ERROR("Write to fdw failed, errno %{public}d", errno);
1797         ReporterFault(FaultType::SET_WALLPAPER_FAULT, FaultCode::RF_DROP_FAILED);
1798         delete[] wallpaperBuffer;
1799         close(fdw);
1800         return E_DEAL_FAILED;
1801     }
1802     delete[] wallpaperBuffer;
1803     close(fdw);
1804     return E_OK;
1805 }
1806 
SetAllWallpaperBackupData(std::vector<WallpaperPictureInfo> allWallpaperInfos,int32_t userId,WallpaperType wallpaperType,WallpaperData & wallpaperData)1807 ErrorCode WallpaperService::SetAllWallpaperBackupData(std::vector<WallpaperPictureInfo> allWallpaperInfos,
1808     int32_t userId, WallpaperType wallpaperType, WallpaperData &wallpaperData)
1809 {
1810     HILOG_INFO("set All wallpaper and backup data Start.");
1811     for (auto &wallpaperInfo : allWallpaperInfos) {
1812         if (!OHOS::FileExists(wallpaperInfo.tempPath)) {
1813             return E_DEAL_FAILED;
1814         }
1815         UpdateWallpaperDataFile(wallpaperInfo, userId, wallpaperType, wallpaperData);
1816         std::string wallpaperFile = GetWallpaperDataFile(wallpaperInfo, userId, wallpaperType);
1817         {
1818             std::lock_guard<std::mutex> lock(mtx_);
1819             if (!FileDeal::CopyFile(wallpaperInfo.tempPath, wallpaperFile)) {
1820                 HILOG_ERROR("CopyFile failed!");
1821                 FileDeal::DeleteFile(wallpaperInfo.tempPath);
1822                 return E_DEAL_FAILED;
1823             }
1824             if (!FileDeal::DeleteFile(wallpaperInfo.tempPath)) {
1825                 return E_DEAL_FAILED;
1826             }
1827         }
1828     }
1829     return E_OK;
1830 }
1831 
UpdateWallpaperDataFile(WallpaperPictureInfo & wallpaperPictureInfo,int32_t userId,WallpaperType wallpaperType,WallpaperData & wallpaperData)1832 void WallpaperService::UpdateWallpaperDataFile(WallpaperPictureInfo &wallpaperPictureInfo, int32_t userId,
1833     WallpaperType wallpaperType, WallpaperData &wallpaperData)
1834 {
1835     switch (static_cast<FoldState>(wallpaperPictureInfo.foldState)) {
1836         case FoldState::NORMAL:
1837             if (static_cast<RotateState>(wallpaperPictureInfo.rotateState) == RotateState::PORT) {
1838                 wallpaperData.wallpaperFile = GetWallpaperDir(userId, wallpaperType) + "/"
1839                                               + (wallpaperType == WALLPAPER_SYSTEM ? WALLPAPER_HOME : WALLPAPER_LOCK);
1840             } else if (static_cast<RotateState>(wallpaperPictureInfo.rotateState) == RotateState::LAND) {
1841                 wallpaperData.normalLandFile = GetWallpaperDataFile(wallpaperPictureInfo, userId, wallpaperType);
1842             }
1843             break;
1844 
1845         case FoldState::UNFOLD_1:
1846             if (static_cast<RotateState>(wallpaperPictureInfo.rotateState) == RotateState::PORT) {
1847                 wallpaperData.unfoldedOnePortFile = GetWallpaperDataFile(wallpaperPictureInfo, userId, wallpaperType);
1848             } else if (static_cast<RotateState>(wallpaperPictureInfo.rotateState) == RotateState::LAND) {
1849                 wallpaperData.unfoldedOneLandFile = GetWallpaperDataFile(wallpaperPictureInfo, userId, wallpaperType);
1850             }
1851             break;
1852 
1853         case FoldState::UNFOLD_2:
1854             if (static_cast<RotateState>(wallpaperPictureInfo.rotateState) == RotateState::PORT) {
1855                 wallpaperData.unfoldedTwoPortFile = GetWallpaperDataFile(wallpaperPictureInfo, userId, wallpaperType);
1856             } else if (static_cast<RotateState>(wallpaperPictureInfo.rotateState) == RotateState::LAND) {
1857                 wallpaperData.unfoldedTwoLandFile = GetWallpaperDataFile(wallpaperPictureInfo, userId, wallpaperType);
1858             }
1859             break;
1860         default:
1861             break;
1862     }
1863 }
1864 
GetWallpaperDataFile(WallpaperPictureInfo & wallpaperPictureInfo,int32_t userId,WallpaperType wallpaperType)1865 std::string WallpaperService::GetWallpaperDataFile(
1866     WallpaperPictureInfo &wallpaperPictureInfo, int32_t userId, WallpaperType wallpaperType)
1867 {
1868     std::string wallpaperTypeName = wallpaperType == WALLPAPER_SYSTEM ? WALLPAPER_HOME : WALLPAPER_LOCK;
1869     std::string foldStateName = GetFoldStateName(wallpaperPictureInfo.foldState);
1870     std::string rotateStateName = GetRotateStateName(wallpaperPictureInfo.rotateState);
1871     if (foldStateName == "normal" && rotateStateName == "port") {
1872         return GetWallpaperDir(userId, wallpaperType) + "/" + wallpaperTypeName;
1873     }
1874     std::string wallpaperFile =
1875         GetWallpaperDir(userId, wallpaperType) + "/" + foldStateName + "_" + rotateStateName + "_" + wallpaperTypeName;
1876     return wallpaperFile;
1877 }
1878 
ClearnWallpaperDataFile(WallpaperData & wallpaperData)1879 void WallpaperService::ClearnWallpaperDataFile(WallpaperData &wallpaperData)
1880 {
1881     wallpaperData.normalLandFile = "";
1882     wallpaperData.unfoldedOnePortFile = "";
1883     wallpaperData.unfoldedOneLandFile = "";
1884     wallpaperData.unfoldedTwoPortFile = "";
1885     wallpaperData.unfoldedTwoLandFile = "";
1886 }
1887 
GetCorrespondWallpaper(int32_t wallpaperType,int32_t foldState,int32_t rotateState,IWallpaperService::FdInfo & fdInfo)1888 ErrorCode WallpaperService::GetCorrespondWallpaper(
1889     int32_t wallpaperType, int32_t foldState, int32_t rotateState, IWallpaperService::FdInfo &fdInfo)
1890 {
1891     StartAsyncTrace(
1892         HITRACE_TAG_MISC, "GetCorrespondWallpaper", static_cast<int32_t>(TraceTaskId::GET_CORRESPOND_WALLPAPER));
1893     HILOG_DEBUG("WallpaperService::GetCorrespondWallpaper start.");
1894     if (!IsSystemApp()) {
1895         HILOG_ERROR("CallingApp is not SystemApp.");
1896         return E_NOT_SYSTEM_APP;
1897     }
1898     if (!CheckCallingPermission(WALLPAPER_PERMISSION_NAME_GET_WALLPAPER)) {
1899         HILOG_ERROR("GetPixelMap no get permission!");
1900         return E_NO_PERMISSION;
1901     }
1902     if (wallpaperType != static_cast<int32_t>(WALLPAPER_LOCKSCREEN)
1903         && wallpaperType != static_cast<int32_t>(WALLPAPER_SYSTEM)) {
1904         return E_PARAMETERS_INVALID;
1905     }
1906     auto type = static_cast<WallpaperType>(wallpaperType);
1907     int32_t userId = QueryActiveUserId();
1908     HILOG_INFO("QueryCurrentOsAccount userId: %{public}d", userId);
1909     // current user's wallpaper is live video, not image
1910     WallpaperResourceType resType = GetResType(userId, type);
1911     if (resType != PICTURE && resType != DEFAULT) {
1912         HILOG_ERROR("Current user's wallpaper is live video, not image.");
1913         fdInfo.size = 0; // 0: empty file size
1914         fdInfo.fd = -1;  // -1: invalid file description
1915         return E_OK;
1916     }
1917     ErrorCode ret = GetImageSize(userId, type, fdInfo.size, foldState, rotateState);
1918     if (ret != E_OK) {
1919         HILOG_ERROR("GetImageSize failed!");
1920         return ret;
1921     }
1922     ret = GetImageFd(userId, type, fdInfo.fd, foldState, rotateState);
1923     if (ret != E_OK) {
1924         HILOG_ERROR("GetImageFd failed!");
1925         return ret;
1926     }
1927     return E_OK;
1928 }
1929 
GetImageSize(int32_t userId,WallpaperType wallpaperType,int32_t & size,int32_t foldState,int32_t rotateState)1930 ErrorCode WallpaperService::GetImageSize(
1931     int32_t userId, WallpaperType wallpaperType, int32_t &size, int32_t foldState, int32_t rotateState)
1932 {
1933     HILOG_DEBUG("WallpaperService::GetImageSize start.");
1934     std::string filePathName;
1935     if (!GetWallpaperDataPath(userId, wallpaperType, filePathName, foldState, rotateState)) {
1936         return E_DEAL_FAILED;
1937     }
1938     HILOG_INFO("GetImageSize file: %{public}s", filePathName.c_str());
1939     if (!OHOS::FileExists(filePathName)) {
1940         HILOG_ERROR("file is not exist.");
1941         return E_NOT_FOUND;
1942     }
1943     std::lock_guard<std::mutex> lock(mtx_);
1944     FILE *fd = fopen(filePathName.c_str(), "rb");
1945     if (fd == nullptr) {
1946         HILOG_ERROR("fopen file failed, errno %{public}d", errno);
1947         return E_FILE_ERROR;
1948     }
1949     int32_t fend = fseek(fd, 0, SEEK_END);
1950     size = ftell(fd);
1951     int32_t fset = fseek(fd, 0, SEEK_SET);
1952     if (size <= 0 || fend != 0 || fset != 0) {
1953         HILOG_ERROR("ftell file failed or fseek file failed, errno %{public}d", errno);
1954         fclose(fd);
1955         return E_FILE_ERROR;
1956     }
1957     fclose(fd);
1958     return E_OK;
1959 }
1960 
GetImageFd(int32_t userId,WallpaperType wallpaperType,int32_t & fd,int32_t foldState,int32_t rotateState)1961 ErrorCode WallpaperService::GetImageFd(
1962     int32_t userId, WallpaperType wallpaperType, int32_t &fd, int32_t foldState, int32_t rotateState)
1963 {
1964     HILOG_DEBUG("WallpaperService::GetImageFd start.");
1965     std::string filePathName;
1966     if (!GetWallpaperDataPath(userId, wallpaperType, filePathName, foldState, rotateState)) {
1967         return E_DEAL_FAILED;
1968     }
1969     if (GetResType(userId, wallpaperType) == WallpaperResourceType::PACKAGE) {
1970         HILOG_INFO("The current wallpaper is a custom wallpaper");
1971         return E_OK;
1972     }
1973     fd = open(filePathName.c_str(), O_RDONLY, S_IREAD);
1974     if (fd < 0) {
1975         HILOG_ERROR("Open file failed, errno %{public}d", errno);
1976         ReporterFault(FaultType::LOAD_WALLPAPER_FAULT, FaultCode::RF_FD_INPUT_FAILED);
1977         return E_DEAL_FAILED;
1978     }
1979     HILOG_INFO("fd = %{public}d", fd);
1980     return E_OK;
1981 }
1982 
GetWallpaperDataPath(int32_t userId,WallpaperType wallpaperType,std::string & filePathName,int32_t foldState,int32_t rotateState)1983 bool WallpaperService::GetWallpaperDataPath(
1984     int32_t userId, WallpaperType wallpaperType, std::string &filePathName, int32_t foldState, int32_t rotateState)
1985 {
1986     auto iterator = wallpaperType == WALLPAPER_SYSTEM ? systemWallpaperMap_.Find(userId)
1987                                                       : lockWallpaperMap_.Find(userId);
1988     if (!iterator.first) {
1989         HILOG_INFO("WallpaperType:%{public}d, WallpaperMap not found userId: %{public}d", wallpaperType, userId);
1990         OnInitUser(userId);
1991         iterator = wallpaperType == WALLPAPER_SYSTEM ? systemWallpaperMap_.Find(userId)
1992                                                      : lockWallpaperMap_.Find(userId);
1993     }
1994     filePathName = GetWallpaperPath(foldState, rotateState, iterator.second);
1995     return filePathName != "";
1996 }
1997 
GetWallpaperPath(int32_t foldState,int32_t rotateState,WallpaperData & wallpaperData)1998 std::string WallpaperService::GetWallpaperPath(int32_t foldState, int32_t rotateState, WallpaperData &wallpaperData)
1999 {
2000     std::string wallpaperFilePath;
2001     if (foldState == static_cast<int32_t>(FoldState::UNFOLD_2)) {
2002         if (rotateState == static_cast<int32_t>(RotateState::LAND)) {
2003             wallpaperFilePath = wallpaperData.unfoldedTwoLandFile;
2004             if (wallpaperFilePath != "") {
2005                 return wallpaperFilePath;
2006             }
2007         }
2008         wallpaperFilePath = wallpaperData.unfoldedTwoPortFile;
2009         if (wallpaperFilePath != "") {
2010             return wallpaperFilePath;
2011         }
2012         wallpaperFilePath = wallpaperData.wallpaperFile;
2013     }
2014     if (foldState == static_cast<int32_t>(FoldState::UNFOLD_1)) {
2015         if (rotateState == static_cast<int32_t>(RotateState::LAND)) {
2016             wallpaperFilePath = wallpaperData.unfoldedOneLandFile;
2017             if (wallpaperFilePath != "") {
2018                 return wallpaperFilePath;
2019             }
2020         }
2021         wallpaperFilePath = wallpaperData.unfoldedOnePortFile;
2022         if (wallpaperFilePath != "") {
2023             return wallpaperFilePath;
2024         }
2025         wallpaperFilePath = wallpaperData.wallpaperFile;
2026     }
2027     if (foldState == static_cast<int32_t>(FoldState::NORMAL)) {
2028         if (rotateState == static_cast<int32_t>(RotateState::LAND)) {
2029             wallpaperFilePath = wallpaperData.normalLandFile;
2030             if (wallpaperFilePath != "") {
2031                 return wallpaperFilePath;
2032             }
2033         }
2034         wallpaperFilePath = wallpaperData.wallpaperFile;
2035     }
2036     return wallpaperFilePath;
2037 }
2038 
DeleteTempResource(std::vector<WallpaperPictureInfo> & tempResourceFiles)2039 void WallpaperService::DeleteTempResource(std::vector<WallpaperPictureInfo> &tempResourceFiles)
2040 {
2041     for (auto &wallpaperFile : tempResourceFiles) {
2042         FileDeal::DeleteFile(wallpaperFile.tempPath);
2043     }
2044 }
2045 
GetFoldStateName(FoldState foldState)2046 std::string WallpaperService::GetFoldStateName(FoldState foldState)
2047 {
2048     std::string foldStateName;
2049     switch (foldState) {
2050         case FoldState::NORMAL:
2051             foldStateName = "normal";
2052             break;
2053         case FoldState::UNFOLD_1:
2054             foldStateName = "unfold1";
2055             break;
2056         case FoldState::UNFOLD_2:
2057             foldStateName = "unfold2";
2058             break;
2059         default:
2060             break;
2061     }
2062     return foldStateName;
2063 }
2064 
GetRotateStateName(RotateState rotateState)2065 std::string WallpaperService::GetRotateStateName(RotateState rotateState)
2066 {
2067     std::string rotateStateName;
2068     switch (rotateState) {
2069         case RotateState::PORT:
2070             rotateStateName = "port";
2071             break;
2072         case RotateState::LAND:
2073             rotateStateName = "land";
2074             break;
2075         default:
2076             break;
2077     }
2078     return rotateStateName;
2079 }
2080 
IsDefaultWallpaperResource(int32_t userId,int32_t wallpaperType)2081 bool WallpaperService::IsDefaultWallpaperResource(int32_t userId, int32_t wallpaperType)
2082 {
2083     HILOG_INFO("IsDefaultWallpaperResource start");
2084     if (wallpaperType == static_cast<int32_t>(WALLPAPER_SYSTEM)) {
2085         std::string wallpaperSystemPath = std::string(WALLPAPER_USERID_PATH) + std::to_string(userId) + "/"
2086                                           + std::string(WALLPAPER_SYSTEM_DIRNAME) + "/";
2087         if (!FileDeal::IsFileExistInDir(wallpaperSystemPath)) {
2088             HILOG_INFO("System is empty");
2089             return true;
2090         }
2091     } else if (wallpaperType == static_cast<int32_t>(WALLPAPER_LOCKSCREEN)) {
2092         std::string wallpaperLockscreenPath = std::string(WALLPAPER_USERID_PATH) + std::to_string(userId) + "/"
2093                                               + std::string(WALLPAPER_LOCKSCREEN_DIRNAME) + "/";
2094         if (!FileDeal::IsFileExistInDir(wallpaperLockscreenPath)) {
2095             HILOG_INFO("Lockscreen is empty");
2096             return true;
2097         }
2098     }
2099     return false;
2100 }
2101 } // namespace WallpaperMgrService
2102 } // namespace OHOS
2103