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
CreatePixelMapByFd(int32_t fd,int32_t size,std::shared_ptr<OHOS::Media::PixelMap> & pixelMap)356 ErrorCode WallpaperManager::CreatePixelMapByFd(
357 int32_t fd, int32_t size, std::shared_ptr<OHOS::Media::PixelMap> &pixelMap)
358 {
359 if (size <= 0 && fd < 0) {
360 HILOG_ERROR("Size or fd error!");
361 return E_IMAGE_ERRCODE;
362 }
363 uint8_t *buffer = new uint8_t[size];
364 ssize_t bytesRead = read(fd, buffer, size);
365 if (bytesRead < 0) {
366 HILOG_ERROR("Read fd to buffer fail!");
367 delete[] buffer;
368 close(fd);
369 return E_IMAGE_ERRCODE;
370 }
371 uint32_t errorCode = 0;
372 OHOS::Media::SourceOptions opts;
373 opts.formatHint = "image/jpeg";
374 std::unique_ptr<OHOS::Media::ImageSource> imageSource =
375 OHOS::Media::ImageSource::CreateImageSource(buffer, size, opts, errorCode);
376 if (errorCode != 0 || imageSource == nullptr) {
377 HILOG_ERROR("ImageSource::CreateImageSource failed, errcode= %{public}d!", errorCode);
378 delete[] buffer;
379 close(fd);
380 return E_IMAGE_ERRCODE;
381 }
382 OHOS::Media::DecodeOptions decodeOpts;
383 pixelMap = imageSource->CreatePixelMap(decodeOpts, errorCode);
384 if (errorCode != 0) {
385 HILOG_ERROR("ImageSource::CreatePixelMap failed, errcode= %{public}d!", errorCode);
386 delete[] buffer;
387 close(fd);
388 return E_IMAGE_ERRCODE;
389 }
390 delete[] buffer;
391 close(fd);
392 return E_OK;
393 }
394
GetWallpaperId(int32_t wallpaperType)395 int32_t WallpaperManager::GetWallpaperId(int32_t wallpaperType)
396 {
397 auto wallpaperServerProxy = GetService();
398 if (wallpaperServerProxy == nullptr) {
399 HILOG_ERROR("Get proxy failed!");
400 return -1;
401 }
402 return wallpaperServerProxy->GetWallpaperId(wallpaperType);
403 }
404
GetWallpaperMinHeight(const ApiInfo & apiInfo,int32_t & minHeight)405 ErrorCode WallpaperManager::GetWallpaperMinHeight(const ApiInfo &apiInfo, int32_t &minHeight)
406 {
407 auto display = Rosen::DisplayManager::GetInstance().GetDefaultDisplay();
408 if (display == nullptr) {
409 HILOG_ERROR("GetDefaultDisplay is nullptr.");
410 return E_DEAL_FAILED;
411 }
412 minHeight = display->GetHeight();
413 return E_OK;
414 }
415
GetWallpaperMinWidth(const ApiInfo & apiInfo,int32_t & minWidth)416 ErrorCode WallpaperManager::GetWallpaperMinWidth(const ApiInfo &apiInfo, int32_t &minWidth)
417 {
418 auto display = Rosen::DisplayManager::GetInstance().GetDefaultDisplay();
419 if (display == nullptr) {
420 HILOG_ERROR("GetDefaultDisplay is nullptr.");
421 return E_DEAL_FAILED;
422 }
423 minWidth = display->GetWidth();
424 return E_OK;
425 }
426
IsChangePermitted()427 bool WallpaperManager::IsChangePermitted()
428 {
429 auto wallpaperServerProxy = GetService();
430 if (wallpaperServerProxy == nullptr) {
431 HILOG_ERROR("Get proxy failed!");
432 return false;
433 }
434 return wallpaperServerProxy->IsChangePermitted();
435 }
436
IsOperationAllowed()437 bool WallpaperManager::IsOperationAllowed()
438 {
439 auto wallpaperServerProxy = GetService();
440 if (wallpaperServerProxy == nullptr) {
441 HILOG_ERROR("Get proxy failed!");
442 return false;
443 }
444 return wallpaperServerProxy->IsOperationAllowed();
445 }
ResetWallpaper(std::int32_t wallpaperType,const ApiInfo & apiInfo)446 ErrorCode WallpaperManager::ResetWallpaper(std::int32_t wallpaperType, const ApiInfo &apiInfo)
447 {
448 auto wallpaperServerProxy = GetService();
449 if (wallpaperServerProxy == nullptr) {
450 HILOG_ERROR("Get proxy failed!");
451 return E_SA_DIED;
452 }
453 ErrorCode wallpaperErrorCode = E_UNKNOWN;
454 if (apiInfo.isSystemApi) {
455 wallpaperErrorCode = wallpaperServerProxy->ResetWallpaperV9(wallpaperType);
456 } else {
457 wallpaperErrorCode = wallpaperServerProxy->ResetWallpaper(wallpaperType);
458 }
459 if (wallpaperErrorCode == E_OK) {
460 CloseWallpaperFd(wallpaperType);
461 }
462 return wallpaperErrorCode;
463 }
464
On(const std::string & type,std::shared_ptr<WallpaperEventListener> listener)465 ErrorCode WallpaperManager::On(const std::string &type, std::shared_ptr<WallpaperEventListener> listener)
466 {
467 HILOG_DEBUG("WallpaperManager::On in.");
468 auto wallpaperServerProxy = GetService();
469 if (wallpaperServerProxy == nullptr) {
470 HILOG_ERROR("Get proxy failed!");
471 return E_SA_DIED;
472 }
473 if (listener == nullptr) {
474 HILOG_ERROR("listener is nullptr.");
475 return E_DEAL_FAILED;
476 }
477 sptr<WallpaperEventListenerClient> ipcListener = new (std::nothrow) WallpaperEventListenerClient(listener);
478 if (ipcListener == nullptr) {
479 HILOG_ERROR("new WallpaperEventListenerClient failed!");
480 return E_NO_MEMORY;
481 }
482 {
483 std::lock_guard<std::mutex> lock(listenerMapLock_);
484 listenerMap_.insert_or_assign(type, ipcListener);
485 }
486 return wallpaperServerProxy->On(type, ipcListener);
487 }
488
Off(const std::string & type,std::shared_ptr<WallpaperEventListener> listener)489 ErrorCode WallpaperManager::Off(const std::string &type, std::shared_ptr<WallpaperEventListener> listener)
490 {
491 HILOG_DEBUG("WallpaperManager::Off in.");
492 auto wallpaperServerProxy = GetService();
493 if (wallpaperServerProxy == nullptr) {
494 HILOG_ERROR("Get proxy failed!");
495 return E_SA_DIED;
496 }
497 sptr<WallpaperEventListenerClient> ipcListener = nullptr;
498 if (listener != nullptr) {
499 ipcListener = new (std::nothrow) WallpaperEventListenerClient(listener);
500 if (ipcListener == nullptr) {
501 HILOG_ERROR("new WallpaperEventListenerClient failed!");
502 return E_NO_MEMORY;
503 }
504 }
505 return wallpaperServerProxy->Off(type, ipcListener);
506 }
507
GetCallback()508 JScallback WallpaperManager::GetCallback()
509 {
510 return callback;
511 }
512
SetCallback(JScallback cb)513 void WallpaperManager::SetCallback(JScallback cb)
514 {
515 callback = cb;
516 }
517
RegisterWallpaperCallback(JScallback callback)518 bool WallpaperManager::RegisterWallpaperCallback(JScallback callback)
519 {
520 HILOG_INFO(" WallpaperManager::RegisterWallpaperCallback statrt.");
521 SetCallback(callback);
522 auto wallpaperServerProxy = GetService();
523 if (wallpaperServerProxy == nullptr) {
524 HILOG_ERROR("Get proxy failed");
525 return false;
526 }
527
528 if (callback == nullptr) {
529 HILOG_ERROR("callback is NULL.");
530 return false;
531 }
532
533 bool status = wallpaperServerProxy->RegisterWallpaperCallback(new WallpaperServiceCbStub());
534 if (!status) {
535 HILOG_ERROR("off failed code=%d.", ERR_NONE);
536 return false;
537 }
538 return true;
539 }
540
ReporterFault(FaultType faultType,FaultCode faultCode)541 void WallpaperManager::ReporterFault(FaultType faultType, FaultCode faultCode)
542 {
543 MiscServices::FaultMsg msg;
544 msg.faultType = faultType;
545 msg.errorCode = faultCode;
546 FaultReporter::ReportRuntimeFault(msg);
547 }
548
CloseWallpaperFd(int32_t wallpaperType)549 void WallpaperManager::CloseWallpaperFd(int32_t wallpaperType)
550 {
551 std::lock_guard<std::mutex> lock(wallpaperFdLock_);
552 std::map<int32_t, int32_t>::iterator iter = wallpaperFdMap_.find(wallpaperType);
553 if (iter != wallpaperFdMap_.end() && fcntl(iter->second, F_GETFL) != -1) {
554 close(iter->second);
555 wallpaperFdMap_.erase(iter);
556 }
557 }
558
RegisterWallpaperListener()559 bool WallpaperManager::RegisterWallpaperListener()
560 {
561 auto service = GetService();
562 if (service == nullptr) {
563 HILOG_ERROR("Get proxy failed!");
564 return false;
565 }
566
567 std::lock_guard<std::mutex> lock(listenerMapLock_);
568 for (const auto &iter : listenerMap_) {
569 auto ret = service->On(iter.first, iter.second);
570 if (ret != E_OK) {
571 HILOG_ERROR(
572 "Register WallpaperListener failed type:%{public}s, errcode:%{public}d", iter.first.c_str(), ret);
573 return false;
574 }
575 }
576 return true;
577 }
SendEvent(const std::string & eventType)578 ErrorCode WallpaperManager::SendEvent(const std::string &eventType)
579 {
580 auto wallpaperServerProxy = GetService();
581 if (wallpaperServerProxy == nullptr) {
582 HILOG_ERROR("Get proxy failed!");
583 return E_DEAL_FAILED;
584 }
585 return wallpaperServerProxy->SendEvent(eventType);
586 }
587
CheckVideoFormat(const std::string & fileName)588 bool WallpaperManager::CheckVideoFormat(const std::string &fileName)
589 {
590 int32_t videoFd = -1;
591 int64_t length = 0;
592 if (!OpenFile(fileName, videoFd, length)) {
593 HILOG_ERROR("Open file: %{public}s failed!", fileName.c_str());
594 return false;
595 }
596 std::shared_ptr<Media::AVMetadataHelper> helper = Media::AVMetadataHelperFactory::CreateAVMetadataHelper();
597 if (helper == nullptr) {
598 HILOG_ERROR("Create metadata helper failed!");
599 close(videoFd);
600 return false;
601 }
602 int32_t offset = 0;
603 int32_t errorCode = helper->SetSource(videoFd, offset, length);
604 if (errorCode != 0) {
605 HILOG_ERROR("Set helper source failed!");
606 close(videoFd);
607 return false;
608 }
609 auto metaData = helper->ResolveMetadata();
610 if (metaData.find(Media::AV_KEY_MIME_TYPE) != metaData.end()) {
611 if (metaData[Media::AV_KEY_MIME_TYPE] != "video/mp4") {
612 HILOG_ERROR("Video mime type is not video/mp4!");
613 close(videoFd);
614 return false;
615 }
616 } else {
617 HILOG_ERROR("Cannot get video mime type!");
618 close(videoFd);
619 return false;
620 }
621
622 if (metaData.find(Media::AV_KEY_DURATION) != metaData.end()) {
623 int32_t videoDuration = std::stoi(metaData[Media::AV_KEY_DURATION]);
624 if (videoDuration < MIN_TIME || videoDuration > MAX_TIME) {
625 HILOG_ERROR("The durations of this vodeo is not between 0s ~ 5s!");
626 close(videoFd);
627 return false;
628 }
629 } else {
630 HILOG_ERROR("Cannot get the duration of this video!");
631 close(videoFd);
632 return false;
633 }
634 close(videoFd);
635 return true;
636 }
637
OpenFile(const std::string & fileName,int32_t & fd,int64_t & fileSize)638 bool WallpaperManager::OpenFile(const std::string &fileName, int32_t &fd, int64_t &fileSize)
639 {
640 if (!OHOS::FileExists(fileName)) {
641 HILOG_ERROR("File is not exist, file: %{public}s.", fileName.c_str());
642 return false;
643 }
644
645 fd = open(fileName.c_str(), O_RDONLY);
646 if (fd <= 0) {
647 HILOG_ERROR("Get video fd failed!");
648 return false;
649 }
650 struct stat64 st;
651 if (fstat64(fd, &st) != 0) {
652 HILOG_ERROR("Failed to fstat64!");
653 close(fd);
654 return false;
655 }
656 fileSize = static_cast<int64_t>(st.st_size);
657 return true;
658 }
659
CheckWallpaperFormat(const std::string & realPath,bool isLive,long & length)660 ErrorCode WallpaperManager::CheckWallpaperFormat(const std::string &realPath, bool isLive, long &length)
661 {
662 if (isLive && (FileDeal::GetExtension(realPath) != ".mp4" || !CheckVideoFormat(realPath))) {
663 HILOG_ERROR("Check live wallpaper file failed!");
664 return E_PARAMETERS_INVALID;
665 }
666
667 FILE *file = std::fopen(realPath.c_str(), "rb");
668 if (file == nullptr) {
669 HILOG_ERROR("Fopen failed, %{public}s, %{public}s!", realPath.c_str(), strerror(errno));
670 return E_FILE_ERROR;
671 }
672
673 int32_t fend = fseek(file, 0, SEEK_END);
674 length = ftell(file);
675 int32_t fset = fseek(file, 0, SEEK_SET);
676 if (length <= 0 || (isLive && length > MAX_VIDEO_SIZE) || fend != 0 || fset != 0) {
677 HILOG_ERROR("ftell file failed or fseek file failed, errno %{public}d!", errno);
678 fclose(file);
679 return E_FILE_ERROR;
680 }
681 fclose(file);
682 return E_OK;
683 }
684
685 } // namespace WallpaperMgrService
686 } // namespace OHOS