• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2022 Huawei Device Co., Ltd.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  *     http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 #include <fcntl.h>
16 #include <sys/stat.h>
17 #include <sys/types.h>
18 #include <unistd.h>
19 
20 #include <cerrno>
21 #include <cstdint>
22 #include <cstdio>
23 #include <cstdlib>
24 #include <cstring>
25 #include <fstream>
26 #include <iostream>
27 #include <mutex>
28 #include <sstream>
29 
30 #include "dfx_types.h"
31 #include "display_manager.h"
32 #include "file_deal.h"
33 #include "file_ex.h"
34 #include "hilog_wrapper.h"
35 #include "hitrace_meter.h"
36 #include "if_system_ability_manager.h"
37 #include "image_packer.h"
38 #include "image_source.h"
39 #include "image_type.h"
40 #include "iservice_registry.h"
41 #include "iwallpaper_service.h"
42 #include "system_ability_definition.h"
43 #include "wallpaper_manager.h"
44 #include "wallpaper_picture_info_by_parcel.h"
45 #include "wallpaper_rawdata.h"
46 #include "wallpaper_service_cb_stub.h"
47 #include "wallpaper_service_proxy.h"
48 namespace OHOS {
49 using namespace MiscServices;
50 namespace WallpaperMgrService {
51 constexpr int32_t MIN_TIME = 0;
52 constexpr int32_t MAX_TIME = 5000;
53 constexpr int32_t MAX_VIDEO_SIZE = 104857600;
54 constexpr int32_t MAX_RETRY_TIMES = 10;
55 constexpr int32_t TIME_INTERVAL = 500000;
56 constexpr int32_t BASE_NUMBER = 10;
57 constexpr mode_t MODE = 0660;
58 
59 using namespace OHOS::Media;
60 
WallpaperManager()61 WallpaperManager::WallpaperManager()
62 {
63 }
~WallpaperManager()64 WallpaperManager::~WallpaperManager()
65 {
66     std::map<int32_t, int32_t>::iterator iter = wallpaperFdMap_.begin();
67     while (iter != wallpaperFdMap_.end()) {
68         close(iter->second);
69         ++iter;
70     }
71 }
GetInstance()72 WallpaperManager &WallpaperManager::GetInstance()
73 {
74     static WallpaperManager wallpaperManager;
75     return wallpaperManager;
76 }
77 
DeathRecipient()78 WallpaperManager::DeathRecipient::DeathRecipient()
79 {
80 }
~DeathRecipient()81 WallpaperManager::DeathRecipient::~DeathRecipient()
82 {
83 }
ResetService(const wptr<IRemoteObject> & remote)84 void WallpaperManager::ResetService(const wptr<IRemoteObject> &remote)
85 {
86     HILOG_INFO("Remote is dead, reset service instance.");
87     std::lock_guard<std::mutex> lock(wallpaperProxyLock_);
88     if (wallpaperProxy_ != nullptr) {
89         sptr<IRemoteObject> object = wallpaperProxy_->AsObject();
90         if ((object != nullptr) && (remote == object)) {
91             object->RemoveDeathRecipient(deathRecipient_);
92             wallpaperProxy_ = nullptr;
93         }
94     }
95 }
96 
GetService()97 sptr<IWallpaperService> WallpaperManager::GetService()
98 {
99     std::lock_guard<std::mutex> lock(wallpaperProxyLock_);
100     if (wallpaperProxy_ != nullptr) {
101         return wallpaperProxy_;
102     }
103 
104     sptr<ISystemAbilityManager> samgr = SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager();
105     if (samgr == nullptr) {
106         HILOG_ERROR("Get samgr failed!");
107         return nullptr;
108     }
109     sptr<IRemoteObject> object = samgr->GetSystemAbility(WALLPAPER_MANAGER_SERVICE_ID);
110     if (object == nullptr) {
111         HILOG_ERROR("Get wallpaper object from samgr failed!");
112         return nullptr;
113     }
114 
115     if (deathRecipient_ == nullptr) {
116         deathRecipient_ = new DeathRecipient();
117     }
118 
119     if ((object->IsProxyObject()) && (!object->AddDeathRecipient(deathRecipient_))) {
120         HILOG_ERROR("Failed to add death recipient!");
121     }
122 
123     wallpaperProxy_ = iface_cast<WallpaperServiceProxy>(object);
124     if (wallpaperProxy_ == nullptr) {
125         HILOG_ERROR("iface_cast failed!");
126     }
127     return wallpaperProxy_;
128 }
129 
OnRemoteDied(const wptr<IRemoteObject> & remote)130 void WallpaperManager::DeathRecipient::OnRemoteDied(const wptr<IRemoteObject> &remote)
131 {
132     WallpaperManager::GetInstance().ResetService(remote);
133     int32_t times = 0;
134     bool result = false;
135     do {
136         times++;
137         result = WallpaperManager::GetInstance().RegisterWallpaperListener();
138         if (result != true) {
139             usleep(TIME_INTERVAL);
140         }
141     } while (result != true && times < MAX_RETRY_TIMES);
142     HILOG_INFO("Register WallpaperListener result:%{public}d.", result);
143 }
144 
CallService(F func,Args &&...args)145 template<typename F, typename... Args> ErrCode WallpaperManager::CallService(F func, Args &&...args)
146 {
147     auto service = GetService();
148     if (service == nullptr) {
149         HILOG_ERROR("get service failed!");
150         return ERR_DEAD_OBJECT;
151     }
152 
153     ErrCode result = (service->*func)(std::forward<Args>(args)...);
154     if (SUCCEEDED(result)) {
155         return ERR_OK;
156     }
157 
158     // Reset service instance if 'ERR_DEAD_OBJECT' happened.
159     if (result == ERR_DEAD_OBJECT) {
160         ResetService(service);
161     }
162 
163     HILOG_ERROR("Callservice failed with: %{public}d.", result);
164     return result;
165 }
166 
GetColors(int32_t wallpaperType,const ApiInfo & apiInfo,std::vector<uint64_t> & colors)167 ErrorCode WallpaperManager::GetColors(int32_t wallpaperType, const ApiInfo &apiInfo, std::vector<uint64_t> &colors)
168 {
169     auto wallpaperServerProxy = GetService();
170     if (wallpaperServerProxy == nullptr) {
171         HILOG_ERROR("Get proxy failed!");
172         return E_DEAL_FAILED;
173     }
174     if (apiInfo.isSystemApi) {
175         return ConvertIntToErrorCode(wallpaperServerProxy->GetColorsV9(wallpaperType, colors));
176     }
177     return ConvertIntToErrorCode(wallpaperServerProxy->GetColors(wallpaperType, colors));
178 }
179 
GetFile(int32_t wallpaperType,int32_t & wallpaperFd)180 ErrorCode WallpaperManager::GetFile(int32_t wallpaperType, int32_t &wallpaperFd)
181 {
182     auto wallpaperServerProxy = GetService();
183     if (wallpaperServerProxy == nullptr) {
184         HILOG_ERROR("Get proxy failed!");
185         return E_DEAL_FAILED;
186     }
187     std::lock_guard<std::mutex> lock(wallpaperFdLock_);
188     std::map<int32_t, int32_t>::iterator iter = wallpaperFdMap_.find(wallpaperType);
189     if (iter != wallpaperFdMap_.end() && fcntl(iter->second, F_GETFL) != -1) {
190         close(iter->second);
191         wallpaperFdMap_.erase(iter);
192     }
193     ErrorCode wallpaperErrorCode = ConvertIntToErrorCode(wallpaperServerProxy->GetFile(wallpaperType, wallpaperFd));
194     if (wallpaperErrorCode == E_OK && wallpaperFd != -1) {
195         wallpaperFdMap_.insert(std::pair<int32_t, int32_t>(wallpaperType, wallpaperFd));
196     }
197     return wallpaperErrorCode;
198 }
199 
SetWallpaper(std::string uri,int32_t wallpaperType,const ApiInfo & apiInfo)200 ErrorCode WallpaperManager::SetWallpaper(std::string uri, int32_t wallpaperType, const ApiInfo &apiInfo)
201 {
202     auto wallpaperServerProxy = GetService();
203     if (wallpaperServerProxy == nullptr) {
204         HILOG_ERROR("Get proxy failed!");
205         return E_DEAL_FAILED;
206     }
207     std::string fileRealPath;
208     if (!FileDeal::GetRealPath(uri, fileRealPath)) {
209         HILOG_ERROR("get real path file failed, len = %{public}zu.", uri.size());
210         return E_PARAMETERS_INVALID;
211     }
212 
213     long length = 0;
214     ErrorCode wallpaperErrorCode = CheckWallpaperFormat(fileRealPath, false, length);
215     if (wallpaperErrorCode != E_OK) {
216         HILOG_ERROR("Check wallpaper format failed!");
217         return wallpaperErrorCode;
218     }
219 
220     int32_t fd = open(fileRealPath.c_str(), O_RDONLY, MODE);
221     if (fd < 0) {
222         HILOG_ERROR("open file failed, errno %{public}d!", errno);
223         ReporterFault(FaultType::SET_WALLPAPER_FAULT, FaultCode::RF_FD_INPUT_FAILED);
224         return E_FILE_ERROR;
225     }
226     fdsan_exchange_owner_tag(fd, 0, WP_DOMAIN);
227     StartAsyncTrace(HITRACE_TAG_MISC, "SetWallpaper", static_cast<int32_t>(TraceTaskId::SET_WALLPAPER));
228     if (apiInfo.isSystemApi) {
229         wallpaperErrorCode = ConvertIntToErrorCode(wallpaperServerProxy->SetWallpaperV9(fd, wallpaperType, length));
230     } else {
231         wallpaperErrorCode = ConvertIntToErrorCode(wallpaperServerProxy->SetWallpaper(fd, wallpaperType, length));
232     }
233     fdsan_close_with_tag(fd, WP_DOMAIN);
234     if (wallpaperErrorCode == E_OK) {
235         CloseWallpaperFd(wallpaperType);
236     }
237     FinishAsyncTrace(HITRACE_TAG_MISC, "SetWallpaper", static_cast<int32_t>(TraceTaskId::SET_WALLPAPER));
238     return wallpaperErrorCode;
239 }
240 
SetWallpaper(std::shared_ptr<OHOS::Media::PixelMap> pixelMap,int32_t wallpaperType,const ApiInfo & apiInfo)241 ErrorCode WallpaperManager::SetWallpaper(
242     std::shared_ptr<OHOS::Media::PixelMap> pixelMap, int32_t wallpaperType, const ApiInfo &apiInfo)
243 {
244     auto wallpaperServerProxy = GetService();
245     if (wallpaperServerProxy == nullptr) {
246         HILOG_ERROR("Get proxy failed!");
247         return E_DEAL_FAILED;
248     }
249 
250     ErrorCode wallpaperErrorCode = E_UNKNOWN;
251     if (pixelMap == nullptr) {
252         HILOG_ERROR("pixelMap is nullptr!");
253         return E_DEAL_FAILED;
254     }
255     std::vector<std::uint8_t> value;
256     if (!pixelMap->EncodeTlv(value)) {
257         HILOG_ERROR("pixelMap encode failed!");
258         return E_DEAL_FAILED;
259     }
260     WallpaperRawData wallpaperRawData;
261     wallpaperRawData.size = value.size();
262     wallpaperRawData.data = value.data();
263     if (apiInfo.isSystemApi) {
264         wallpaperErrorCode =
265             ConvertIntToErrorCode(wallpaperServerProxy->SetWallpaperV9ByPixelMap(wallpaperRawData, wallpaperType));
266     } else {
267         wallpaperErrorCode =
268             ConvertIntToErrorCode(wallpaperServerProxy->SetWallpaperByPixelMap(wallpaperRawData, wallpaperType));
269     }
270     if (wallpaperErrorCode == static_cast<int32_t>(E_OK)) {
271         CloseWallpaperFd(wallpaperType);
272     }
273     return wallpaperErrorCode;
274 }
275 
SetVideo(const std::string & uri,const int32_t wallpaperType)276 ErrorCode WallpaperManager::SetVideo(const std::string &uri, const int32_t wallpaperType)
277 {
278     auto wallpaperServerProxy = GetService();
279     if (wallpaperServerProxy == nullptr) {
280         HILOG_ERROR("Get proxy failed!");
281         return E_DEAL_FAILED;
282     }
283     std::string fileRealPath;
284     if (!FileDeal::GetRealPath(uri, fileRealPath)) {
285         HILOG_ERROR("Get real path failed, uri: %{public}s!", uri.c_str());
286         return E_PARAMETERS_INVALID;
287     }
288 
289     long length = 0;
290     ErrorCode wallpaperErrorCode = CheckWallpaperFormat(fileRealPath, true, length);
291     if (wallpaperErrorCode != E_OK) {
292         HILOG_ERROR("Check wallpaper format failed!");
293         return wallpaperErrorCode;
294     }
295     int32_t fd = open(fileRealPath.c_str(), O_RDONLY, MODE);
296     if (fd < 0) {
297         HILOG_ERROR("Open file failed, errno %{public}d!", errno);
298         ReporterFault(FaultType::SET_WALLPAPER_FAULT, FaultCode::RF_FD_INPUT_FAILED);
299         return E_FILE_ERROR;
300     }
301     fdsan_exchange_owner_tag(fd, 0, WP_DOMAIN);
302     StartAsyncTrace(HITRACE_TAG_MISC, "SetVideo", static_cast<int32_t>(TraceTaskId::SET_VIDEO));
303     wallpaperErrorCode = ConvertIntToErrorCode(wallpaperServerProxy->SetVideo(fd, wallpaperType, length));
304     fdsan_close_with_tag(fd, WP_DOMAIN);
305     FinishAsyncTrace(HITRACE_TAG_MISC, "SetVideo", static_cast<int32_t>(TraceTaskId::SET_VIDEO));
306     return wallpaperErrorCode;
307 }
308 
SetCustomWallpaper(const std::string & uri,const int32_t wallpaperType)309 ErrorCode WallpaperManager::SetCustomWallpaper(const std::string &uri, const int32_t wallpaperType)
310 {
311     auto wallpaperServerProxy = GetService();
312     if (wallpaperServerProxy == nullptr) {
313         HILOG_ERROR("Get proxy failed!");
314         return E_DEAL_FAILED;
315     }
316     std::string fileRealPath;
317     if (!FileDeal::GetRealPath(uri, fileRealPath)) {
318         HILOG_ERROR("Get real path failed, uri: %{public}s!", uri.c_str());
319         return E_PARAMETERS_INVALID;
320     }
321     if (!FileDeal::IsZipFile(uri)) {
322         return E_FILE_ERROR;
323     }
324     long length = 0;
325     ErrorCode wallpaperErrorCode = CheckWallpaperFormat(fileRealPath, false, length);
326     if (wallpaperErrorCode != E_OK) {
327         HILOG_ERROR("Check wallpaper format failed!");
328         return wallpaperErrorCode;
329     }
330     int32_t fd = open(fileRealPath.c_str(), O_RDONLY, MODE);
331     if (fd < 0) {
332         HILOG_ERROR("Open file failed, errno %{public}d!", errno);
333         ReporterFault(FaultType::SET_WALLPAPER_FAULT, FaultCode::RF_FD_INPUT_FAILED);
334         return E_FILE_ERROR;
335     }
336     fdsan_exchange_owner_tag(fd, 0, WP_DOMAIN);
337     StartAsyncTrace(HITRACE_TAG_MISC, "SetCustomWallpaper", static_cast<int32_t>(TraceTaskId::SET_CUSTOM_WALLPAPER));
338     wallpaperErrorCode = ConvertIntToErrorCode(wallpaperServerProxy->SetCustomWallpaper(fd, wallpaperType, length));
339     fdsan_close_with_tag(fd, WP_DOMAIN);
340     FinishAsyncTrace(HITRACE_TAG_MISC, "SetCustomWallpaper", static_cast<int32_t>(TraceTaskId::SET_CUSTOM_WALLPAPER));
341     return wallpaperErrorCode;
342 }
343 
GetPixelMap(int32_t wallpaperType,const ApiInfo & apiInfo,std::shared_ptr<OHOS::Media::PixelMap> & pixelMap)344 ErrorCode WallpaperManager::GetPixelMap(
345     int32_t wallpaperType, const ApiInfo &apiInfo, std::shared_ptr<OHOS::Media::PixelMap> &pixelMap)
346 {
347     HILOG_INFO("FrameWork GetPixelMap Start by FD.");
348     auto wallpaperServerProxy = GetService();
349     if (wallpaperServerProxy == nullptr) {
350         HILOG_ERROR("Get proxy failed!");
351         return E_SA_DIED;
352     }
353     ErrorCode wallpaperErrorCode = E_UNKNOWN;
354     int32_t size = 0;
355     int32_t fd = -1;
356     if (apiInfo.isSystemApi) {
357         wallpaperErrorCode = ConvertIntToErrorCode(wallpaperServerProxy->GetPixelMapV9(wallpaperType, size, fd));
358     } else {
359         wallpaperErrorCode = ConvertIntToErrorCode(wallpaperServerProxy->GetPixelMap(wallpaperType, size, fd));
360     }
361     if (wallpaperErrorCode != E_OK) {
362         return wallpaperErrorCode;
363     }
364     // current wallpaper is live video, not image
365     if (size == 0 && fd == -1) { // 0: empty file size; -1: invalid file description
366         pixelMap = nullptr;
367         return E_OK;
368     }
369     wallpaperErrorCode = CreatePixelMapByFd(fd, size, pixelMap);
370     if (wallpaperErrorCode != E_OK) {
371         pixelMap = nullptr;
372         return wallpaperErrorCode;
373     }
374     return wallpaperErrorCode;
375 }
376 
CreatePixelMapByFd(int32_t fd,int32_t size,std::shared_ptr<OHOS::Media::PixelMap> & pixelMap)377 ErrorCode WallpaperManager::CreatePixelMapByFd(
378     int32_t fd, int32_t size, std::shared_ptr<OHOS::Media::PixelMap> &pixelMap)
379 {
380     if (size <= 0 || fd < 0) {
381         HILOG_ERROR("Size or fd error!");
382         return E_IMAGE_ERRCODE;
383     }
384     uint8_t *buffer = new uint8_t[size];
385     ssize_t bytesRead = read(fd, buffer, size);
386     if (bytesRead < 0) {
387         HILOG_ERROR("Read fd to buffer fail!");
388         delete[] buffer;
389         close(fd);
390         return E_IMAGE_ERRCODE;
391     }
392     uint32_t errorCode = 0;
393     OHOS::Media::SourceOptions opts;
394     opts.formatHint = "image/jpeg";
395     std::unique_ptr<OHOS::Media::ImageSource> imageSource =
396         OHOS::Media::ImageSource::CreateImageSource(buffer, size, opts, errorCode);
397     if (errorCode != 0 || imageSource == nullptr) {
398         HILOG_ERROR("ImageSource::CreateImageSource failed, errcode= %{public}d!", errorCode);
399         delete[] buffer;
400         close(fd);
401         return E_IMAGE_ERRCODE;
402     }
403     OHOS::Media::DecodeOptions decodeOpts;
404     pixelMap = imageSource->CreatePixelMap(decodeOpts, errorCode);
405     if (errorCode != 0) {
406         HILOG_ERROR("ImageSource::CreatePixelMap failed, errcode= %{public}d!", errorCode);
407         delete[] buffer;
408         close(fd);
409         return E_IMAGE_ERRCODE;
410     }
411     delete[] buffer;
412     close(fd);
413     return E_OK;
414 }
415 
GetWallpaperId(int32_t wallpaperType)416 int32_t WallpaperManager::GetWallpaperId(int32_t wallpaperType)
417 {
418     auto wallpaperServerProxy = GetService();
419     if (wallpaperServerProxy == nullptr) {
420         HILOG_ERROR("Get proxy failed!");
421         return -1;
422     }
423     return wallpaperServerProxy->GetWallpaperId(wallpaperType);
424 }
425 
GetWallpaperMinHeight(const ApiInfo & apiInfo,int32_t & minHeight)426 ErrorCode WallpaperManager::GetWallpaperMinHeight(const ApiInfo &apiInfo, int32_t &minHeight)
427 {
428     auto display = Rosen::DisplayManager::GetInstance().GetDefaultDisplay();
429     if (display == nullptr) {
430         HILOG_ERROR("GetDefaultDisplay is nullptr.");
431         return E_DEAL_FAILED;
432     }
433     minHeight = display->GetHeight();
434     return E_OK;
435 }
436 
GetWallpaperMinWidth(const ApiInfo & apiInfo,int32_t & minWidth)437 ErrorCode WallpaperManager::GetWallpaperMinWidth(const ApiInfo &apiInfo, int32_t &minWidth)
438 {
439     auto display = Rosen::DisplayManager::GetInstance().GetDefaultDisplay();
440     if (display == nullptr) {
441         HILOG_ERROR("GetDefaultDisplay is nullptr.");
442         return E_DEAL_FAILED;
443     }
444     minWidth = display->GetWidth();
445     return E_OK;
446 }
447 
IsChangePermitted()448 bool WallpaperManager::IsChangePermitted()
449 {
450     auto wallpaperServerProxy = GetService();
451     if (wallpaperServerProxy == nullptr) {
452         HILOG_ERROR("Get proxy failed!");
453         return false;
454     }
455     bool isChangePermitted = false;
456     wallpaperServerProxy->IsChangePermitted(isChangePermitted);
457     return isChangePermitted;
458 }
459 
IsOperationAllowed()460 bool WallpaperManager::IsOperationAllowed()
461 {
462     auto wallpaperServerProxy = GetService();
463     if (wallpaperServerProxy == nullptr) {
464         HILOG_ERROR("Get proxy failed!");
465         return false;
466     }
467     bool isOperationAllowed = false;
468     wallpaperServerProxy->IsOperationAllowed(isOperationAllowed);
469     return isOperationAllowed;
470 }
ResetWallpaper(std::int32_t wallpaperType,const ApiInfo & apiInfo)471 ErrorCode WallpaperManager::ResetWallpaper(std::int32_t wallpaperType, const ApiInfo &apiInfo)
472 {
473     auto wallpaperServerProxy = GetService();
474     if (wallpaperServerProxy == nullptr) {
475         HILOG_ERROR("Get proxy failed!");
476         return E_SA_DIED;
477     }
478     ErrorCode wallpaperErrorCode = E_UNKNOWN;
479     if (apiInfo.isSystemApi) {
480         wallpaperErrorCode = ConvertIntToErrorCode(wallpaperServerProxy->ResetWallpaperV9(wallpaperType));
481     } else {
482         wallpaperErrorCode = ConvertIntToErrorCode(wallpaperServerProxy->ResetWallpaper(wallpaperType));
483     }
484     if (wallpaperErrorCode == E_OK) {
485         CloseWallpaperFd(wallpaperType);
486     }
487     return wallpaperErrorCode;
488 }
489 
On(const std::string & type,std::shared_ptr<WallpaperEventListener> listener)490 ErrorCode WallpaperManager::On(const std::string &type, std::shared_ptr<WallpaperEventListener> listener)
491 {
492     HILOG_DEBUG("WallpaperManager::On in.");
493     auto wallpaperServerProxy = GetService();
494     if (wallpaperServerProxy == nullptr) {
495         HILOG_ERROR("Get proxy failed!");
496         return E_SA_DIED;
497     }
498     if (listener == nullptr) {
499         HILOG_ERROR("listener is nullptr.");
500         return E_DEAL_FAILED;
501     }
502     sptr<WallpaperEventListenerClient> ipcListener = new (std::nothrow) WallpaperEventListenerClient(listener);
503     if (ipcListener == nullptr) {
504         HILOG_ERROR("new WallpaperEventListenerClient failed!");
505         return E_NO_MEMORY;
506     }
507     {
508         std::lock_guard<std::mutex> lock(listenerMapLock_);
509         listenerMap_.insert_or_assign(type, ipcListener);
510     }
511     return ConvertIntToErrorCode(wallpaperServerProxy->On(type, ipcListener));
512 }
513 
Off(const std::string & type,std::shared_ptr<WallpaperEventListener> listener)514 ErrorCode WallpaperManager::Off(const std::string &type, std::shared_ptr<WallpaperEventListener> listener)
515 {
516     HILOG_DEBUG("WallpaperManager::Off in.");
517     auto wallpaperServerProxy = GetService();
518     if (wallpaperServerProxy == nullptr) {
519         HILOG_ERROR("Get proxy failed!");
520         return E_SA_DIED;
521     }
522     sptr<WallpaperEventListenerClient> ipcListener = nullptr;
523     ipcListener = new (std::nothrow) WallpaperEventListenerClient(listener);
524     if (ipcListener == nullptr) {
525         HILOG_ERROR("new WallpaperEventListenerClient failed!");
526         return E_NO_MEMORY;
527     }
528     return ConvertIntToErrorCode(wallpaperServerProxy->Off(type, ipcListener));
529 }
530 
GetCallback()531 JScallback WallpaperManager::GetCallback()
532 {
533     return callback;
534 }
535 
SetCallback(JScallback cb)536 void WallpaperManager::SetCallback(JScallback cb)
537 {
538     callback = cb;
539 }
540 
RegisterWallpaperCallback(JScallback callback)541 bool WallpaperManager::RegisterWallpaperCallback(JScallback callback)
542 {
543     HILOG_INFO("  WallpaperManager::RegisterWallpaperCallback statrt.");
544     SetCallback(callback);
545     auto wallpaperServerProxy = GetService();
546     if (wallpaperServerProxy == nullptr) {
547         HILOG_ERROR("Get proxy failed");
548         return false;
549     }
550 
551     if (callback == nullptr) {
552         HILOG_ERROR("callback is NULL.");
553         return false;
554     }
555     bool registerWallpaperCallback = false;
556     wallpaperServerProxy->RegisterWallpaperCallback(new WallpaperServiceCbStub(), registerWallpaperCallback);
557     if (!registerWallpaperCallback) {
558         HILOG_ERROR("off failed code=%d.", ERR_NONE);
559         return false;
560     }
561     return registerWallpaperCallback;
562 }
563 
ReporterFault(FaultType faultType,FaultCode faultCode)564 void WallpaperManager::ReporterFault(FaultType faultType, FaultCode faultCode)
565 {
566     MiscServices::FaultMsg msg;
567     msg.faultType = faultType;
568     msg.errorCode = faultCode;
569     FaultReporter::ReportRuntimeFault(msg);
570 }
571 
CloseWallpaperFd(int32_t wallpaperType)572 void WallpaperManager::CloseWallpaperFd(int32_t wallpaperType)
573 {
574     std::lock_guard<std::mutex> lock(wallpaperFdLock_);
575     std::map<int32_t, int32_t>::iterator iter = wallpaperFdMap_.find(wallpaperType);
576     if (iter != wallpaperFdMap_.end() && fcntl(iter->second, F_GETFL) != -1) {
577         close(iter->second);
578         wallpaperFdMap_.erase(iter);
579     }
580 }
581 
RegisterWallpaperListener()582 bool WallpaperManager::RegisterWallpaperListener()
583 {
584     auto service = GetService();
585     if (service == nullptr) {
586         HILOG_ERROR("Get proxy failed!");
587         return false;
588     }
589 
590     std::lock_guard<std::mutex> lock(listenerMapLock_);
591     for (const auto &iter : listenerMap_) {
592         auto ret = ConvertIntToErrorCode(service->On(iter.first, iter.second));
593         if (ret != E_OK) {
594             HILOG_ERROR(
595                 "Register WallpaperListener failed type:%{public}s, errcode:%{public}d", iter.first.c_str(), ret);
596             return false;
597         }
598     }
599     return true;
600 }
SendEvent(const std::string & eventType)601 ErrorCode WallpaperManager::SendEvent(const std::string &eventType)
602 {
603     auto wallpaperServerProxy = GetService();
604     if (wallpaperServerProxy == nullptr) {
605         HILOG_ERROR("Get proxy failed!");
606         return E_DEAL_FAILED;
607     }
608     return ConvertIntToErrorCode(wallpaperServerProxy->SendEvent(eventType));
609 }
610 
CheckVideoFormat(const std::string & fileName)611 bool WallpaperManager::CheckVideoFormat(const std::string &fileName)
612 {
613     int32_t fd = -1;
614     int64_t length = 0;
615     FILE *wallpaperFile = OpenFile(fileName, fd, length);
616     if (wallpaperFile == nullptr) {
617         HILOG_ERROR("Open file: %{public}s failed!", fileName.c_str());
618         return false;
619     }
620     std::shared_ptr<Media::AVMetadataHelper> helper = Media::AVMetadataHelperFactory::CreateAVMetadataHelper();
621     if (helper == nullptr) {
622         HILOG_ERROR("Create metadata helper failed!");
623         fclose(wallpaperFile);
624         return false;
625     }
626     int32_t offset = 0;
627     int32_t errorCode = helper->SetSource(fd, offset, length);
628     if (errorCode != 0) {
629         HILOG_ERROR("Set helper source failed!");
630         fclose(wallpaperFile);
631         return false;
632     }
633     auto metaData = helper->ResolveMetadata();
634     if (metaData.find(Media::AV_KEY_MIME_TYPE) != metaData.end()) {
635         if (metaData[Media::AV_KEY_MIME_TYPE] != "video/mp4") {
636             HILOG_ERROR("Video mime type is not video/mp4!");
637             fclose(wallpaperFile);
638             return false;
639         }
640     } else {
641         HILOG_ERROR("Cannot get video mime type!");
642         fclose(wallpaperFile);
643         return false;
644     }
645 
646     if (metaData.find(Media::AV_KEY_DURATION) != metaData.end()) {
647         int32_t videoDuration = ConverString2Int(metaData[Media::AV_KEY_DURATION]);
648         if (videoDuration < MIN_TIME || videoDuration > MAX_TIME) {
649             HILOG_ERROR("The durations of this vodeo is not between 0s ~ 5s!");
650             fclose(wallpaperFile);
651             return false;
652         }
653     } else {
654         HILOG_ERROR("Cannot get the duration of this video!");
655         fclose(wallpaperFile);
656         return false;
657     }
658     fclose(wallpaperFile);
659     return true;
660 }
661 
OpenFile(const std::string & fileName,int & fd,int64_t & fileSize)662 FILE *WallpaperManager::OpenFile(const std::string &fileName, int &fd, int64_t &fileSize)
663 {
664     if (!OHOS::FileExists(fileName)) {
665         HILOG_ERROR("File is not exist, file: %{public}s.", fileName.c_str());
666         return nullptr;
667     }
668 
669     FILE *file = fopen(fileName.c_str(), "r");
670     if (file == nullptr) {
671         HILOG_ERROR("Get video file failed!");
672         return nullptr;
673     }
674     fd = fileno(file);
675     if (fd < 0) {
676         HILOG_ERROR("Get video videoFd failed!");
677         fclose(file);
678         return nullptr;
679     }
680     struct stat64 st;
681     if (fstat64(fd, &st) != 0) {
682         HILOG_ERROR("Failed to fstat64!");
683         fclose(file);
684         return nullptr;
685     }
686     fileSize = static_cast<int64_t>(st.st_size);
687     return file;
688 }
689 
CheckWallpaperFormat(const std::string & realPath,bool isLive,long & length)690 ErrorCode WallpaperManager::CheckWallpaperFormat(const std::string &realPath, bool isLive, long &length)
691 {
692     if (isLive && (FileDeal::GetExtension(realPath) != ".mp4" || !CheckVideoFormat(realPath))) {
693         HILOG_ERROR("Check live wallpaper file failed!");
694         return E_PARAMETERS_INVALID;
695     }
696 
697     FILE *file = std::fopen(realPath.c_str(), "rb");
698     if (file == nullptr) {
699         HILOG_ERROR("Fopen failed, %{public}s, %{public}s!", realPath.c_str(), strerror(errno));
700         return E_FILE_ERROR;
701     }
702 
703     int32_t fend = fseek(file, 0, SEEK_END);
704     length = ftell(file);
705     int32_t fset = fseek(file, 0, SEEK_SET);
706     if (length <= 0 || (isLive && length > MAX_VIDEO_SIZE) || fend != 0 || fset != 0) {
707         HILOG_ERROR("ftell file failed or fseek file failed, errno %{public}d!", errno);
708         fclose(file);
709         return E_FILE_ERROR;
710     }
711     fclose(file);
712     return E_OK;
713 }
714 
SetAllWallpapers(std::vector<WallpaperInfo> allWallpaperInfos,int32_t wallpaperType)715 ErrorCode WallpaperManager::SetAllWallpapers(std::vector<WallpaperInfo> allWallpaperInfos, int32_t wallpaperType)
716 {
717     auto wallpaperServerProxy = GetService();
718     if (wallpaperServerProxy == nullptr) {
719         HILOG_ERROR("Get proxy failed!");
720         return E_DEAL_FAILED;
721     }
722     WallpaperPictureInfoByParcel wallpaperPictureInfoByParcel;
723     WallpaperPictureInfo wallpaperPictureInfo;
724     std::vector<int32_t> fdVector;
725     ErrorCode wallpaperCode;
726     for (const auto &wallpaperInfo : allWallpaperInfos) {
727         std::string fileRealPath;
728         if (!FileDeal::GetRealPath(wallpaperInfo.source, fileRealPath)) {
729             HILOG_ERROR("get real path file failed, len = %{public}zu.", wallpaperInfo.source.size());
730             return E_PARAMETERS_INVALID;
731         }
732         wallpaperCode = GetFdByPath(wallpaperInfo, wallpaperPictureInfo, fileRealPath);
733         if (wallpaperCode != E_OK) {
734             CloseWallpaperInfoFd(wallpaperPictureInfoByParcel.wallpaperPictureInfo_);
735             HILOG_ERROR("PathConvertFd failed");
736             return wallpaperCode;
737         }
738         wallpaperPictureInfoByParcel.wallpaperPictureInfo_.push_back(wallpaperPictureInfo);
739         fdVector.push_back(wallpaperPictureInfo.fd);
740     }
741 
742     StartAsyncTrace(HITRACE_TAG_MISC, "SetAllWallpapers", static_cast<int32_t>(TraceTaskId::SET_ALL_WALLPAPERS));
743     ErrorCode wallpaperErrorCode = ConvertIntToErrorCode(
744         wallpaperServerProxy->SetAllWallpapers(wallpaperPictureInfoByParcel, wallpaperType, fdVector));
745     if (wallpaperErrorCode == E_OK) {
746         CloseWallpaperFd(wallpaperType);
747     }
748     CloseWallpaperInfoFd(wallpaperPictureInfoByParcel.wallpaperPictureInfo_);
749     FinishAsyncTrace(HITRACE_TAG_MISC, "SetAllWallpapers", static_cast<int32_t>(TraceTaskId::SET_ALL_WALLPAPERS));
750     return wallpaperErrorCode;
751 }
752 
GetFdByPath(const WallpaperInfo & wallpaperInfo,WallpaperPictureInfo & wallpaperPictureInfo,std::string fileRealPath)753 ErrorCode WallpaperManager::GetFdByPath(
754     const WallpaperInfo &wallpaperInfo, WallpaperPictureInfo &wallpaperPictureInfo, std::string fileRealPath)
755 {
756     wallpaperPictureInfo.foldState = wallpaperInfo.foldState;
757     wallpaperPictureInfo.rotateState = wallpaperInfo.rotateState;
758     wallpaperPictureInfo.fd = open(fileRealPath.c_str(), O_RDONLY, MODE);
759     if (wallpaperPictureInfo.fd < 0) {
760         HILOG_ERROR("open file failed, errno %{public}d!", errno);
761         ReporterFault(FaultType::SET_WALLPAPER_FAULT, FaultCode::RF_FD_INPUT_FAILED);
762         return E_FILE_ERROR;
763     }
764     fdsan_exchange_owner_tag(wallpaperPictureInfo.fd, 0, WP_DOMAIN);
765     ErrorCode wallpaperErrorCode = CheckWallpaperFormat(fileRealPath, false, wallpaperPictureInfo.length);
766     if (wallpaperErrorCode != E_OK) {
767         HILOG_ERROR("Check wallpaper format failed!");
768         return wallpaperErrorCode;
769     }
770     uint32_t errorCode = 0;
771     OHOS::Media::SourceOptions opts;
772     std::unique_ptr<OHOS::Media::ImageSource> imageSource =
773         OHOS::Media::ImageSource::CreateImageSource(fileRealPath, opts, errorCode);
774     if (errorCode != 0 || imageSource == nullptr) {
775         HILOG_ERROR("CreateImageSource failed!");
776         return E_PARAMETERS_INVALID;
777     }
778     ImageInfo imageInfo;
779     if (imageSource->GetImageInfo(imageInfo) != 0) {
780         HILOG_ERROR("GetImageInfo failed!");
781         return E_PARAMETERS_INVALID;
782     }
783     return wallpaperErrorCode;
784 }
785 
GetCorrespondWallpaper(int32_t wallpaperType,int32_t foldState,int32_t rotateState,std::shared_ptr<OHOS::Media::PixelMap> & pixelMap)786 ErrorCode WallpaperManager::GetCorrespondWallpaper(
787     int32_t wallpaperType, int32_t foldState, int32_t rotateState, std::shared_ptr<OHOS::Media::PixelMap> &pixelMap)
788 {
789     HILOG_INFO("GetCorrespondWallpaper start.");
790     auto wallpaperServerProxy = GetService();
791     if (wallpaperServerProxy == nullptr) {
792         HILOG_ERROR("Get proxy failed!");
793         return E_SA_DIED;
794     }
795     ErrorCode wallpaperErrorCode = E_UNKNOWN;
796     int32_t size = 0;
797     int32_t fd = -1;
798     wallpaperErrorCode = ConvertIntToErrorCode(
799         wallpaperServerProxy->GetCorrespondWallpaper(wallpaperType, foldState, rotateState, size, fd));
800     if (wallpaperErrorCode != E_OK) {
801         return wallpaperErrorCode;
802     }
803     // current wallpaper is live video, not image
804     if (size == 0 && fd == -1) { // 0: empty file size; -1: invalid file description
805         pixelMap = nullptr;
806         return E_OK;
807     }
808     wallpaperErrorCode = CreatePixelMapByFd(fd, size, pixelMap);
809     if (wallpaperErrorCode != E_OK) {
810         pixelMap = nullptr;
811         return wallpaperErrorCode;
812     }
813     return wallpaperErrorCode;
814 }
815 
CloseWallpaperInfoFd(std::vector<WallpaperPictureInfo> wallpaperPictureInfos)816 void WallpaperManager::CloseWallpaperInfoFd(std::vector<WallpaperPictureInfo> wallpaperPictureInfos)
817 {
818     for (auto &wallpaperInfo : wallpaperPictureInfos) {
819         if (wallpaperInfo.fd >= 0) {
820             fdsan_close_with_tag(wallpaperInfo.fd, WP_DOMAIN);
821         }
822     }
823 }
824 
IsDefaultWallpaperResource(int32_t userId,int32_t wallpaperType)825 bool WallpaperManager::IsDefaultWallpaperResource(int32_t userId, int32_t wallpaperType)
826 {
827     auto wallpaperServerProxy = GetService();
828     if (wallpaperServerProxy == nullptr) {
829         HILOG_ERROR("Get proxy failed!");
830         return false;
831     }
832     bool isDefaultWallpaperResource = false;
833     wallpaperServerProxy->IsDefaultWallpaperResource(userId, wallpaperType, isDefaultWallpaperResource);
834     return isDefaultWallpaperResource;
835 }
836 
ConverString2Int(const std::string & value)837 int32_t WallpaperManager::ConverString2Int(const std::string &value)
838 {
839     int32_t result = -1;
840     if (!value.empty() && std::all_of(value.begin(), value.end(), ::isdigit)) {
841         char *endPtr = nullptr;
842         result = strtol(value.c_str(), &endPtr, BASE_NUMBER);
843         if (*endPtr != '\0') {
844             return -1;
845         }
846     }
847     return result;
848 }
849 
850 std::unordered_map<int32_t, ErrorCode> errorCodeMap = {
851     { static_cast<int32_t>(NO_ERROR), E_OK },
852     { static_cast<int32_t>(E_OK), E_OK },
853     { static_cast<int32_t>(E_SA_DIED), E_SA_DIED },
854     { static_cast<int32_t>(E_READ_PARCEL_ERROR), E_READ_PARCEL_ERROR },
855     { static_cast<int32_t>(E_WRITE_PARCEL_ERROR), E_WRITE_PARCEL_ERROR },
856     { static_cast<int32_t>(E_PUBLISH_FAIL), E_PUBLISH_FAIL },
857     { static_cast<int32_t>(E_TRANSACT_ERROR), E_TRANSACT_ERROR },
858     { static_cast<int32_t>(E_DEAL_FAILED), E_DEAL_FAILED },
859     { static_cast<int32_t>(E_PARAMETERS_INVALID), E_PARAMETERS_INVALID },
860     { static_cast<int32_t>(E_SET_RTC_FAILED), E_SET_RTC_FAILED },
861     { static_cast<int32_t>(E_NOT_FOUND), E_NOT_FOUND },
862     { static_cast<int32_t>(E_NO_PERMISSION), E_NO_PERMISSION },
863     { static_cast<int32_t>(E_FILE_ERROR), E_FILE_ERROR },
864     { static_cast<int32_t>(E_IMAGE_ERRCODE), E_IMAGE_ERRCODE },
865     { static_cast<int32_t>(E_NO_MEMORY), E_NO_MEMORY },
866     { static_cast<int32_t>(E_NOT_SYSTEM_APP), E_NOT_SYSTEM_APP },
867     { static_cast<int32_t>(E_USER_IDENTITY_ERROR), E_USER_IDENTITY_ERROR },
868     { static_cast<int32_t>(E_CHECK_DESCRIPTOR_ERROR), E_CHECK_DESCRIPTOR_ERROR },
869 };
870 
ConvertIntToErrorCode(int32_t errorCode)871 ErrorCode WallpaperManager::ConvertIntToErrorCode(int32_t errorCode)
872 {
873     auto it = errorCodeMap.find(errorCode);
874     if (it == errorCodeMap.end()) {
875         return E_UNKNOWN;
876     }
877     return it->second;
878 }
879 
880 } // namespace WallpaperMgrService
881 } // namespace OHOS