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 "i_wallpaper_service.h"
37 #include "if_system_ability_manager.h"
38 #include "image_packer.h"
39 #include "image_source.h"
40 #include "image_type.h"
41 #include "iservice_registry.h"
42 #include "system_ability_definition.h"
43 #include "wallpaper_manager.h"
44 #include "wallpaper_service_cb_stub.h"
45 #include "wallpaper_service_proxy.h"
46 
47 namespace OHOS {
48 using namespace MiscServices;
49 namespace WallpaperMgrService {
50 constexpr int32_t MIN_TIME = 0;
51 constexpr int32_t MAX_TIME = 5000;
52 constexpr int32_t MAX_VIDEO_SIZE = 104857600;
53 constexpr int32_t MAX_RETRY_TIMES = 10;
54 constexpr int32_t TIME_INTERVAL = 500000;
55 
56 using namespace OHOS::Media;
57 
WallpaperManager()58 WallpaperManager::WallpaperManager()
59 {
60 }
~WallpaperManager()61 WallpaperManager::~WallpaperManager()
62 {
63     std::map<int32_t, int32_t>::iterator iter = wallpaperFdMap_.begin();
64     while (iter != wallpaperFdMap_.end()) {
65         close(iter->second);
66         ++iter;
67     }
68 }
GetInstance()69 WallpaperManager &WallpaperManager::GetInstance()
70 {
71     static WallpaperManager wallpaperManager;
72     return wallpaperManager;
73 }
74 
DeathRecipient()75 WallpaperManager::DeathRecipient::DeathRecipient()
76 {
77 }
~DeathRecipient()78 WallpaperManager::DeathRecipient::~DeathRecipient()
79 {
80 }
ResetService(const wptr<IRemoteObject> &remote)81 void WallpaperManager::ResetService(const wptr<IRemoteObject> &remote)
82 {
83     HILOG_INFO("Remote is dead, reset service instance.");
84     std::lock_guard<std::mutex> lock(wallpaperProxyLock_);
85     if (wallpaperProxy_ != nullptr) {
86         sptr<IRemoteObject> object = wallpaperProxy_->AsObject();
87         if ((object != nullptr) && (remote == object)) {
88             object->RemoveDeathRecipient(deathRecipient_);
89             wallpaperProxy_ = nullptr;
90         }
91     }
92 }
93 
GetService()94 sptr<IWallpaperService> WallpaperManager::GetService()
95 {
96     std::lock_guard<std::mutex> lock(wallpaperProxyLock_);
97     if (wallpaperProxy_ != nullptr) {
98         return wallpaperProxy_;
99     }
100 
101     sptr<ISystemAbilityManager> samgr = SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager();
102     if (samgr == nullptr) {
103         HILOG_ERROR("Get samgr failed!");
104         return nullptr;
105     }
106     sptr<IRemoteObject> object = samgr->GetSystemAbility(WALLPAPER_MANAGER_SERVICE_ID);
107     if (object == nullptr) {
108         HILOG_ERROR("Get wallpaper object from samgr failed!");
109         return nullptr;
110     }
111 
112     if (deathRecipient_ == nullptr) {
113         deathRecipient_ = new DeathRecipient();
114     }
115 
116     if ((object->IsProxyObject()) && (!object->AddDeathRecipient(deathRecipient_))) {
117         HILOG_ERROR("Failed to add death recipient!");
118     }
119 
120     wallpaperProxy_ = iface_cast<WallpaperServiceProxy>(object);
121     if (wallpaperProxy_ == nullptr) {
122         HILOG_ERROR("iface_cast failed!");
123     }
124     return wallpaperProxy_;
125 }
126 
OnRemoteDied(const wptr<IRemoteObject> &remote)127 void WallpaperManager::DeathRecipient::OnRemoteDied(const wptr<IRemoteObject> &remote)
128 {
129     WallpaperManager::GetInstance().ResetService(remote);
130     int32_t times = 0;
131     bool result = false;
132     do {
133         times++;
134         result = WallpaperManager::GetInstance().RegisterWallpaperListener();
135         if (result != true) {
136             usleep(TIME_INTERVAL);
137         }
138     } while (result != true && times < MAX_RETRY_TIMES);
139     HILOG_INFO("Register WallpaperListener result:%{public}d.", result);
140 }
141 
CallService(F func, Args &&...args)142 template<typename F, typename... Args> ErrCode WallpaperManager::CallService(F func, Args &&...args)
143 {
144     auto service = GetService();
145     if (service == nullptr) {
146         HILOG_ERROR("get service failed!");
147         return ERR_DEAD_OBJECT;
148     }
149 
150     ErrCode result = (service->*func)(std::forward<Args>(args)...);
151     if (SUCCEEDED(result)) {
152         return ERR_OK;
153     }
154 
155     // Reset service instance if 'ERR_DEAD_OBJECT' happened.
156     if (result == ERR_DEAD_OBJECT) {
157         ResetService(service);
158     }
159 
160     HILOG_ERROR("Callservice failed with: %{public}d.", result);
161     return result;
162 }
163 
GetColors(int32_t wallpaperType, const ApiInfo &apiInfo, std::vector<uint64_t> &colors)164 ErrorCode WallpaperManager::GetColors(int32_t wallpaperType, const ApiInfo &apiInfo, std::vector<uint64_t> &colors)
165 {
166     auto wallpaperServerProxy = GetService();
167     if (wallpaperServerProxy == nullptr) {
168         HILOG_ERROR("Get proxy failed!");
169         return E_DEAL_FAILED;
170     }
171     if (apiInfo.isSystemApi) {
172         return wallpaperServerProxy->GetColorsV9(wallpaperType, colors);
173     }
174     return wallpaperServerProxy->GetColors(wallpaperType, colors);
175 }
176 
GetFile(int32_t wallpaperType, int32_t &wallpaperFd)177 ErrorCode WallpaperManager::GetFile(int32_t wallpaperType, int32_t &wallpaperFd)
178 {
179     auto wallpaperServerProxy = GetService();
180     if (wallpaperServerProxy == nullptr) {
181         HILOG_ERROR("Get proxy failed!");
182         return E_DEAL_FAILED;
183     }
184     std::lock_guard<std::mutex> lock(wallpaperFdLock_);
185     std::map<int32_t, int32_t>::iterator iter = wallpaperFdMap_.find(wallpaperType);
186     if (iter != wallpaperFdMap_.end() && fcntl(iter->second, F_GETFL) != -1) {
187         close(iter->second);
188         wallpaperFdMap_.erase(iter);
189     }
190     ErrorCode wallpaperErrorCode = wallpaperServerProxy->GetFile(wallpaperType, wallpaperFd);
191     if (wallpaperErrorCode == E_OK && wallpaperFd != -1) {
192         wallpaperFdMap_.insert(std::pair<int32_t, int32_t>(wallpaperType, wallpaperFd));
193     }
194     return wallpaperErrorCode;
195 }
196 
SetWallpaper(std::string uri, int32_t wallpaperType, const ApiInfo &apiInfo)197 ErrorCode WallpaperManager::SetWallpaper(std::string uri, int32_t wallpaperType, const ApiInfo &apiInfo)
198 {
199     auto wallpaperServerProxy = GetService();
200     if (wallpaperServerProxy == nullptr) {
201         HILOG_ERROR("Get proxy failed!");
202         return E_DEAL_FAILED;
203     }
204     std::string fileRealPath;
205     if (!FileDeal::GetRealPath(uri, fileRealPath)) {
206         HILOG_ERROR("get real path file failed, len = %{public}zu.", uri.size());
207         return E_FILE_ERROR;
208     }
209 
210     long length = 0;
211     ErrorCode wallpaperErrorCode = CheckWallpaperFormat(fileRealPath, false, length);
212     if (wallpaperErrorCode != E_OK) {
213         HILOG_ERROR("Check wallpaper format failed!");
214         return wallpaperErrorCode;
215     }
216 
217     int32_t fd = open(fileRealPath.c_str(), O_RDONLY, 0660);
218     if (fd < 0) {
219         HILOG_ERROR("open file failed, errno %{public}d!", errno);
220         ReporterFault(FaultType::SET_WALLPAPER_FAULT, FaultCode::RF_FD_INPUT_FAILED);
221         return E_FILE_ERROR;
222     }
223     StartAsyncTrace(HITRACE_TAG_MISC, "SetWallpaper", static_cast<int32_t>(TraceTaskId::SET_WALLPAPER));
224     if (apiInfo.isSystemApi) {
225         wallpaperErrorCode = wallpaperServerProxy->SetWallpaperV9(fd, wallpaperType, length);
226     } else {
227         wallpaperErrorCode = wallpaperServerProxy->SetWallpaper(fd, wallpaperType, length);
228     }
229     close(fd);
230     if (wallpaperErrorCode == E_OK) {
231         CloseWallpaperFd(wallpaperType);
232     }
233     FinishAsyncTrace(HITRACE_TAG_MISC, "SetWallpaper", static_cast<int32_t>(TraceTaskId::SET_WALLPAPER));
234     return wallpaperErrorCode;
235 }
236 
SetWallpaper( std::shared_ptr<OHOS::Media::PixelMap> pixelMap, int32_t wallpaperType, const ApiInfo &apiInfo)237 ErrorCode WallpaperManager::SetWallpaper(
238     std::shared_ptr<OHOS::Media::PixelMap> pixelMap, int32_t wallpaperType, const ApiInfo &apiInfo)
239 {
240     auto wallpaperServerProxy = GetService();
241     if (wallpaperServerProxy == nullptr) {
242         HILOG_ERROR("Get proxy failed!");
243         return E_DEAL_FAILED;
244     }
245 
246     ErrorCode wallpaperErrorCode = E_UNKNOWN;
247     if (apiInfo.isSystemApi) {
248         wallpaperErrorCode = wallpaperServerProxy->SetWallpaperV9ByPixelMap(pixelMap, wallpaperType);
249     } else {
250         wallpaperErrorCode = wallpaperServerProxy->SetWallpaperByPixelMap(pixelMap, wallpaperType);
251     }
252     if (wallpaperErrorCode == static_cast<int32_t>(E_OK)) {
253         CloseWallpaperFd(wallpaperType);
254     }
255     return wallpaperErrorCode;
256 }
257 
SetVideo(const std::string &uri, const int32_t wallpaperType)258 ErrorCode WallpaperManager::SetVideo(const std::string &uri, const int32_t wallpaperType)
259 {
260     auto wallpaperServerProxy = GetService();
261     if (wallpaperServerProxy == nullptr) {
262         HILOG_ERROR("Get proxy failed!");
263         return E_DEAL_FAILED;
264     }
265     std::string fileRealPath;
266     if (!FileDeal::GetRealPath(uri, fileRealPath)) {
267         HILOG_ERROR("Get real path failed, uri: %{public}s!", uri.c_str());
268         return E_FILE_ERROR;
269     }
270 
271     long length = 0;
272     ErrorCode wallpaperErrorCode = CheckWallpaperFormat(fileRealPath, true, length);
273     if (wallpaperErrorCode != E_OK) {
274         HILOG_ERROR("Check wallpaper format failed!");
275         return wallpaperErrorCode;
276     }
277     int32_t fd = open(fileRealPath.c_str(), O_RDONLY, 0660);
278     if (fd < 0) {
279         HILOG_ERROR("Open file failed, errno %{public}d!", errno);
280         ReporterFault(FaultType::SET_WALLPAPER_FAULT, FaultCode::RF_FD_INPUT_FAILED);
281         return E_FILE_ERROR;
282     }
283     StartAsyncTrace(HITRACE_TAG_MISC, "SetVideo", static_cast<int32_t>(TraceTaskId::SET_VIDEO));
284     wallpaperErrorCode = wallpaperServerProxy->SetVideo(fd, wallpaperType, length);
285     close(fd);
286     FinishAsyncTrace(HITRACE_TAG_MISC, "SetVideo", static_cast<int32_t>(TraceTaskId::SET_VIDEO));
287     return wallpaperErrorCode;
288 }
289 
SetCustomWallpaper(const std::string &uri, const int32_t wallpaperType)290 ErrorCode WallpaperManager::SetCustomWallpaper(const std::string &uri, const int32_t wallpaperType)
291 {
292     auto wallpaperServerProxy = GetService();
293     if (wallpaperServerProxy == nullptr) {
294         HILOG_ERROR("Get proxy failed!");
295         return E_DEAL_FAILED;
296     }
297     std::string fileRealPath;
298     if (!FileDeal::GetRealPath(uri, fileRealPath)) {
299         HILOG_ERROR("Get real path failed, uri: %{public}s!", uri.c_str());
300         return E_FILE_ERROR;
301     }
302     if (!FileDeal::IsZipFile(uri)) {
303         return E_FILE_ERROR;
304     }
305     long length = 0;
306     ErrorCode wallpaperErrorCode = CheckWallpaperFormat(fileRealPath, false, length);
307     if (wallpaperErrorCode != E_OK) {
308         HILOG_ERROR("Check wallpaper format failed!");
309         return wallpaperErrorCode;
310     }
311     int32_t fd = open(fileRealPath.c_str(), O_RDONLY, 0660);
312     if (fd < 0) {
313         HILOG_ERROR("Open file failed, errno %{public}d!", errno);
314         ReporterFault(FaultType::SET_WALLPAPER_FAULT, FaultCode::RF_FD_INPUT_FAILED);
315         return E_FILE_ERROR;
316     }
317     StartAsyncTrace(HITRACE_TAG_MISC, "SetCustomWallpaper", static_cast<int32_t>(TraceTaskId::SET_CUSTOM_WALLPAPER));
318     wallpaperErrorCode = wallpaperServerProxy->SetCustomWallpaper(fd, wallpaperType, length);
319     close(fd);
320     FinishAsyncTrace(HITRACE_TAG_MISC, "SetCustomWallpaper", static_cast<int32_t>(TraceTaskId::SET_CUSTOM_WALLPAPER));
321     return wallpaperErrorCode;
322 }
323 
GetPixelMap( int32_t wallpaperType, const ApiInfo &apiInfo, std::shared_ptr<OHOS::Media::PixelMap> &pixelMap)324 ErrorCode WallpaperManager::GetPixelMap(
325     int32_t wallpaperType, const ApiInfo &apiInfo, std::shared_ptr<OHOS::Media::PixelMap> &pixelMap)
326 {
327     HILOG_INFO("FrameWork GetPixelMap Start by FD.");
328     auto wallpaperServerProxy = GetService();
329     if (wallpaperServerProxy == nullptr) {
330         HILOG_ERROR("Get proxy failed!");
331         return E_SA_DIED;
332     }
333     IWallpaperService::FdInfo fdInfo;
334     ErrorCode wallpaperErrorCode = E_UNKNOWN;
335     if (apiInfo.isSystemApi) {
336         wallpaperErrorCode = wallpaperServerProxy->GetPixelMapV9(wallpaperType, fdInfo);
337     } else {
338         wallpaperErrorCode = wallpaperServerProxy->GetPixelMap(wallpaperType, fdInfo);
339     }
340     if (wallpaperErrorCode != E_OK) {
341         return wallpaperErrorCode;
342     }
343     // current wallpaper is live video, not image
344     if (fdInfo.size == 0 && fdInfo.fd == -1) { // 0: empty file size; -1: invalid file description
345         pixelMap = nullptr;
346         return E_OK;
347     }
348     wallpaperErrorCode = CreatePixelMapByFd(fdInfo.fd, fdInfo.size, pixelMap);
349     if (wallpaperErrorCode != E_OK) {
350         pixelMap = nullptr;
351         return wallpaperErrorCode;
352     }
353     return wallpaperErrorCode;
354 }
355 
356 // mock
GetCorrespondWallpaper(int32_t wallpaperType, int32_t foldState, int32_t rotateState, const ApiInfo &apiInfo, std::shared_ptr<OHOS::Media::PixelMap> &pixelMap)357 ErrorCode WallpaperManager::GetCorrespondWallpaper(int32_t wallpaperType, int32_t foldState, int32_t rotateState,
358     const ApiInfo &apiInfo, std::shared_ptr<OHOS::Media::PixelMap> &pixelMap)
359 {
360     return E_OK;
361 }
362 
CreatePixelMapByFd( int32_t fd, int32_t size, std::shared_ptr<OHOS::Media::PixelMap> &pixelMap)363 ErrorCode WallpaperManager::CreatePixelMapByFd(
364     int32_t fd, int32_t size, std::shared_ptr<OHOS::Media::PixelMap> &pixelMap)
365 {
366     if (size <= 0 && fd < 0) {
367         HILOG_ERROR("Size or fd error!");
368         return E_IMAGE_ERRCODE;
369     }
370     uint8_t *buffer = new uint8_t[size];
371     ssize_t bytesRead = read(fd, buffer, size);
372     if (bytesRead < 0) {
373         HILOG_ERROR("Read fd to buffer fail!");
374         delete[] buffer;
375         close(fd);
376         return E_IMAGE_ERRCODE;
377     }
378     uint32_t errorCode = 0;
379     OHOS::Media::SourceOptions opts;
380     opts.formatHint = "image/jpeg";
381     std::unique_ptr<OHOS::Media::ImageSource> imageSource =
382         OHOS::Media::ImageSource::CreateImageSource(buffer, size, opts, errorCode);
383     if (errorCode != 0 || imageSource == nullptr) {
384         HILOG_ERROR("ImageSource::CreateImageSource failed, errcode= %{public}d!", errorCode);
385         delete[] buffer;
386         close(fd);
387         return E_IMAGE_ERRCODE;
388     }
389     OHOS::Media::DecodeOptions decodeOpts;
390     pixelMap = imageSource->CreatePixelMap(decodeOpts, errorCode);
391     if (errorCode != 0) {
392         HILOG_ERROR("ImageSource::CreatePixelMap failed, errcode= %{public}d!", errorCode);
393         delete[] buffer;
394         close(fd);
395         return E_IMAGE_ERRCODE;
396     }
397     delete[] buffer;
398     close(fd);
399     return E_OK;
400 }
401 
GetWallpaperId(int32_t wallpaperType)402 int32_t WallpaperManager::GetWallpaperId(int32_t wallpaperType)
403 {
404     auto wallpaperServerProxy = GetService();
405     if (wallpaperServerProxy == nullptr) {
406         HILOG_ERROR("Get proxy failed!");
407         return -1;
408     }
409     return wallpaperServerProxy->GetWallpaperId(wallpaperType);
410 }
411 
GetWallpaperMinHeight(const ApiInfo &apiInfo, int32_t &minHeight)412 ErrorCode WallpaperManager::GetWallpaperMinHeight(const ApiInfo &apiInfo, int32_t &minHeight)
413 {
414     auto display = Rosen::DisplayManager::GetInstance().GetDefaultDisplay();
415     if (display == nullptr) {
416         HILOG_ERROR("GetDefaultDisplay is nullptr.");
417         return E_DEAL_FAILED;
418     }
419     minHeight = display->GetHeight();
420     return E_OK;
421 }
422 
GetWallpaperMinWidth(const ApiInfo &apiInfo, int32_t &minWidth)423 ErrorCode WallpaperManager::GetWallpaperMinWidth(const ApiInfo &apiInfo, int32_t &minWidth)
424 {
425     auto display = Rosen::DisplayManager::GetInstance().GetDefaultDisplay();
426     if (display == nullptr) {
427         HILOG_ERROR("GetDefaultDisplay is nullptr.");
428         return E_DEAL_FAILED;
429     }
430     minWidth = display->GetWidth();
431     return E_OK;
432 }
433 
IsChangePermitted()434 bool WallpaperManager::IsChangePermitted()
435 {
436     auto wallpaperServerProxy = GetService();
437     if (wallpaperServerProxy == nullptr) {
438         HILOG_ERROR("Get proxy failed!");
439         return false;
440     }
441     return wallpaperServerProxy->IsChangePermitted();
442 }
443 
IsOperationAllowed()444 bool WallpaperManager::IsOperationAllowed()
445 {
446     auto wallpaperServerProxy = GetService();
447     if (wallpaperServerProxy == nullptr) {
448         HILOG_ERROR("Get proxy failed!");
449         return false;
450     }
451     return wallpaperServerProxy->IsOperationAllowed();
452 }
ResetWallpaper(std::int32_t wallpaperType, const ApiInfo &apiInfo)453 ErrorCode WallpaperManager::ResetWallpaper(std::int32_t wallpaperType, const ApiInfo &apiInfo)
454 {
455     auto wallpaperServerProxy = GetService();
456     if (wallpaperServerProxy == nullptr) {
457         HILOG_ERROR("Get proxy failed!");
458         return E_SA_DIED;
459     }
460     ErrorCode wallpaperErrorCode = E_UNKNOWN;
461     if (apiInfo.isSystemApi) {
462         wallpaperErrorCode = wallpaperServerProxy->ResetWallpaperV9(wallpaperType);
463     } else {
464         wallpaperErrorCode = wallpaperServerProxy->ResetWallpaper(wallpaperType);
465     }
466     if (wallpaperErrorCode == E_OK) {
467         CloseWallpaperFd(wallpaperType);
468     }
469     return wallpaperErrorCode;
470 }
471 
On(const std::string &type, std::shared_ptr<WallpaperEventListener> listener)472 ErrorCode WallpaperManager::On(const std::string &type, std::shared_ptr<WallpaperEventListener> listener)
473 {
474     HILOG_DEBUG("WallpaperManager::On in.");
475     auto wallpaperServerProxy = GetService();
476     if (wallpaperServerProxy == nullptr) {
477         HILOG_ERROR("Get proxy failed!");
478         return E_SA_DIED;
479     }
480     if (listener == nullptr) {
481         HILOG_ERROR("listener is nullptr.");
482         return E_DEAL_FAILED;
483     }
484     sptr<WallpaperEventListenerClient> ipcListener = new (std::nothrow) WallpaperEventListenerClient(listener);
485     if (ipcListener == nullptr) {
486         HILOG_ERROR("new WallpaperEventListenerClient failed!");
487         return E_NO_MEMORY;
488     }
489     {
490         std::lock_guard<std::mutex> lock(listenerMapLock_);
491         listenerMap_.insert_or_assign(type, ipcListener);
492     }
493     return wallpaperServerProxy->On(type, ipcListener);
494 }
495 
Off(const std::string &type, std::shared_ptr<WallpaperEventListener> listener)496 ErrorCode WallpaperManager::Off(const std::string &type, std::shared_ptr<WallpaperEventListener> listener)
497 {
498     HILOG_DEBUG("WallpaperManager::Off in.");
499     auto wallpaperServerProxy = GetService();
500     if (wallpaperServerProxy == nullptr) {
501         HILOG_ERROR("Get proxy failed!");
502         return E_SA_DIED;
503     }
504     sptr<WallpaperEventListenerClient> ipcListener = nullptr;
505     if (listener != nullptr) {
506         ipcListener = new (std::nothrow) WallpaperEventListenerClient(listener);
507         if (ipcListener == nullptr) {
508             HILOG_ERROR("new WallpaperEventListenerClient failed!");
509             return E_NO_MEMORY;
510         }
511     }
512     return wallpaperServerProxy->Off(type, ipcListener);
513 }
514 
GetCallback()515 JScallback WallpaperManager::GetCallback()
516 {
517     return callback;
518 }
519 
SetCallback(JScallback cb)520 void WallpaperManager::SetCallback(JScallback cb)
521 {
522     callback = cb;
523 }
524 
RegisterWallpaperCallback(JScallback callback)525 bool WallpaperManager::RegisterWallpaperCallback(JScallback callback)
526 {
527     HILOG_INFO("  WallpaperManager::RegisterWallpaperCallback statrt.");
528     SetCallback(callback);
529     auto wallpaperServerProxy = GetService();
530     if (wallpaperServerProxy == nullptr) {
531         HILOG_ERROR("Get proxy failed");
532         return false;
533     }
534 
535     if (callback == nullptr) {
536         HILOG_ERROR("callback is NULL.");
537         return false;
538     }
539 
540     bool status = wallpaperServerProxy->RegisterWallpaperCallback(new WallpaperServiceCbStub());
541     if (!status) {
542         HILOG_ERROR("off failed code=%d.", ERR_NONE);
543         return false;
544     }
545     return true;
546 }
547 
ReporterFault(FaultType faultType, FaultCode faultCode)548 void WallpaperManager::ReporterFault(FaultType faultType, FaultCode faultCode)
549 {
550     MiscServices::FaultMsg msg;
551     msg.faultType = faultType;
552     msg.errorCode = faultCode;
553     FaultReporter::ReportRuntimeFault(msg);
554 }
555 
CloseWallpaperFd(int32_t wallpaperType)556 void WallpaperManager::CloseWallpaperFd(int32_t wallpaperType)
557 {
558     std::lock_guard<std::mutex> lock(wallpaperFdLock_);
559     std::map<int32_t, int32_t>::iterator iter = wallpaperFdMap_.find(wallpaperType);
560     if (iter != wallpaperFdMap_.end() && fcntl(iter->second, F_GETFL) != -1) {
561         close(iter->second);
562         wallpaperFdMap_.erase(iter);
563     }
564 }
565 
RegisterWallpaperListener()566 bool WallpaperManager::RegisterWallpaperListener()
567 {
568     auto service = GetService();
569     if (service == nullptr) {
570         HILOG_ERROR("Get proxy failed!");
571         return false;
572     }
573 
574     std::lock_guard<std::mutex> lock(listenerMapLock_);
575     for (const auto &iter : listenerMap_) {
576         auto ret = service->On(iter.first, iter.second);
577         if (ret != E_OK) {
578             HILOG_ERROR(
579                 "Register WallpaperListener failed type:%{public}s, errcode:%{public}d", iter.first.c_str(), ret);
580             return false;
581         }
582     }
583     return true;
584 }
SendEvent(const std::string &eventType)585 ErrorCode WallpaperManager::SendEvent(const std::string &eventType)
586 {
587     auto wallpaperServerProxy = GetService();
588     if (wallpaperServerProxy == nullptr) {
589         HILOG_ERROR("Get proxy failed!");
590         return E_DEAL_FAILED;
591     }
592     return wallpaperServerProxy->SendEvent(eventType);
593 }
594 
CheckVideoFormat(const std::string &fileName)595 bool WallpaperManager::CheckVideoFormat(const std::string &fileName)
596 {
597     int32_t videoFd = -1;
598     int64_t length = 0;
599     if (!OpenFile(fileName, videoFd, length)) {
600         HILOG_ERROR("Open file: %{public}s failed!", fileName.c_str());
601         return false;
602     }
603     std::shared_ptr<Media::AVMetadataHelper> helper = Media::AVMetadataHelperFactory::CreateAVMetadataHelper();
604     if (helper == nullptr) {
605         HILOG_ERROR("Create metadata helper failed!");
606         close(videoFd);
607         return false;
608     }
609     int32_t offset = 0;
610     int32_t errorCode = helper->SetSource(videoFd, offset, length);
611     if (errorCode != 0) {
612         HILOG_ERROR("Set helper source failed!");
613         close(videoFd);
614         return false;
615     }
616     auto metaData = helper->ResolveMetadata();
617     if (metaData.find(Media::AV_KEY_MIME_TYPE) != metaData.end()) {
618         if (metaData[Media::AV_KEY_MIME_TYPE] != "video/mp4") {
619             HILOG_ERROR("Video mime type is not video/mp4!");
620             close(videoFd);
621             return false;
622         }
623     } else {
624         HILOG_ERROR("Cannot get video mime type!");
625         close(videoFd);
626         return false;
627     }
628 
629     if (metaData.find(Media::AV_KEY_DURATION) != metaData.end()) {
630         int32_t videoDuration = std::stoi(metaData[Media::AV_KEY_DURATION]);
631         if (videoDuration < MIN_TIME || videoDuration > MAX_TIME) {
632             HILOG_ERROR("The durations of this vodeo is not between 0s ~ 5s!");
633             close(videoFd);
634             return false;
635         }
636     } else {
637         HILOG_ERROR("Cannot get the duration of this video!");
638         close(videoFd);
639         return false;
640     }
641     close(videoFd);
642     return true;
643 }
644 
OpenFile(const std::string &fileName, int32_t &fd, int64_t &fileSize)645 bool WallpaperManager::OpenFile(const std::string &fileName, int32_t &fd, int64_t &fileSize)
646 {
647     if (!OHOS::FileExists(fileName)) {
648         HILOG_ERROR("File is not exist, file: %{public}s.", fileName.c_str());
649         return false;
650     }
651 
652     fd = open(fileName.c_str(), O_RDONLY);
653     if (fd <= 0) {
654         HILOG_ERROR("Get video fd failed!");
655         return false;
656     }
657     struct stat64 st;
658     if (fstat64(fd, &st) != 0) {
659         HILOG_ERROR("Failed to fstat64!");
660         close(fd);
661         return false;
662     }
663     fileSize = static_cast<int64_t>(st.st_size);
664     return true;
665 }
666 
CheckWallpaperFormat(const std::string &realPath, bool isLive, long &length)667 ErrorCode WallpaperManager::CheckWallpaperFormat(const std::string &realPath, bool isLive, long &length)
668 {
669     if (isLive && (FileDeal::GetExtension(realPath) != ".mp4" || !CheckVideoFormat(realPath))) {
670         HILOG_ERROR("Check live wallpaper file failed!");
671         return E_PARAMETERS_INVALID;
672     }
673 
674     FILE *file = std::fopen(realPath.c_str(), "rb");
675     if (file == nullptr) {
676         HILOG_ERROR("Fopen failed, %{public}s, %{public}s!", realPath.c_str(), strerror(errno));
677         return E_FILE_ERROR;
678     }
679 
680     int32_t fend = fseek(file, 0, SEEK_END);
681     length = ftell(file);
682     int32_t fset = fseek(file, 0, SEEK_SET);
683     if (length <= 0 || (isLive && length > MAX_VIDEO_SIZE) || fend != 0 || fset != 0) {
684         HILOG_ERROR("ftell file failed or fseek file failed, errno %{public}d!", errno);
685         fclose(file);
686         return E_FILE_ERROR;
687     }
688     fclose(file);
689     return E_OK;
690 }
691 
SetAllWallpapers(const std::vector<WallpaperInfo> &wallpaperInfos, std::int32_t wallpaperType)692 ErrorCode WallpaperManager::SetAllWallpapers(const std::vector<WallpaperInfo> &wallpaperInfos,
693     std::int32_t wallpaperType)
694 {
695     return E_OK;
696 }
697 
698 } // namespace WallpaperMgrService
699 } // namespace OHOS