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