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