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