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