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