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 "if_system_ability_manager.h"
37 #include "image_packer.h"
38 #include "image_source.h"
39 #include "image_type.h"
40 #include "iservice_registry.h"
41 #include "iwallpaper_service.h"
42 #include "system_ability_definition.h"
43 #include "wallpaper_manager.h"
44 #include "wallpaper_picture_info_by_parcel.h"
45 #include "wallpaper_rawdata.h"
46 #include "wallpaper_service_cb_stub.h"
47 #include "wallpaper_service_proxy.h"
48 namespace OHOS {
49 using namespace MiscServices;
50 namespace WallpaperMgrService {
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 constexpr int32_t BASE_NUMBER = 10;
57 constexpr mode_t MODE = 0660;
58
59 using namespace OHOS::Media;
60
WallpaperManager()61 WallpaperManager::WallpaperManager()
62 {
63 }
~WallpaperManager()64 WallpaperManager::~WallpaperManager()
65 {
66 std::map<int32_t, int32_t>::iterator iter = wallpaperFdMap_.begin();
67 while (iter != wallpaperFdMap_.end()) {
68 close(iter->second);
69 ++iter;
70 }
71 }
GetInstance()72 WallpaperManager &WallpaperManager::GetInstance()
73 {
74 static WallpaperManager wallpaperManager;
75 return wallpaperManager;
76 }
77
DeathRecipient()78 WallpaperManager::DeathRecipient::DeathRecipient()
79 {
80 }
~DeathRecipient()81 WallpaperManager::DeathRecipient::~DeathRecipient()
82 {
83 }
ResetService(const wptr<IRemoteObject> & remote)84 void WallpaperManager::ResetService(const wptr<IRemoteObject> &remote)
85 {
86 HILOG_INFO("Remote is dead, reset service instance.");
87 std::lock_guard<std::mutex> lock(wallpaperProxyLock_);
88 if (wallpaperProxy_ != nullptr) {
89 sptr<IRemoteObject> object = wallpaperProxy_->AsObject();
90 if ((object != nullptr) && (remote == object)) {
91 object->RemoveDeathRecipient(deathRecipient_);
92 wallpaperProxy_ = nullptr;
93 }
94 }
95 }
96
GetService()97 sptr<IWallpaperService> WallpaperManager::GetService()
98 {
99 std::lock_guard<std::mutex> lock(wallpaperProxyLock_);
100 if (wallpaperProxy_ != nullptr) {
101 return wallpaperProxy_;
102 }
103
104 sptr<ISystemAbilityManager> samgr = SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager();
105 if (samgr == nullptr) {
106 HILOG_ERROR("Get samgr failed!");
107 return nullptr;
108 }
109 sptr<IRemoteObject> object = samgr->GetSystemAbility(WALLPAPER_MANAGER_SERVICE_ID);
110 if (object == nullptr) {
111 HILOG_ERROR("Get wallpaper object from samgr failed!");
112 return nullptr;
113 }
114
115 if (deathRecipient_ == nullptr) {
116 deathRecipient_ = new DeathRecipient();
117 }
118
119 if ((object->IsProxyObject()) && (!object->AddDeathRecipient(deathRecipient_))) {
120 HILOG_ERROR("Failed to add death recipient!");
121 }
122
123 wallpaperProxy_ = iface_cast<WallpaperServiceProxy>(object);
124 if (wallpaperProxy_ == nullptr) {
125 HILOG_ERROR("iface_cast failed!");
126 }
127 return wallpaperProxy_;
128 }
129
OnRemoteDied(const wptr<IRemoteObject> & remote)130 void WallpaperManager::DeathRecipient::OnRemoteDied(const wptr<IRemoteObject> &remote)
131 {
132 WallpaperManager::GetInstance().ResetService(remote);
133 int32_t times = 0;
134 bool result = false;
135 do {
136 times++;
137 result = WallpaperManager::GetInstance().RegisterWallpaperListener();
138 if (result != true) {
139 usleep(TIME_INTERVAL);
140 }
141 } while (result != true && times < MAX_RETRY_TIMES);
142 HILOG_INFO("Register WallpaperListener result:%{public}d.", result);
143 }
144
CallService(F func,Args &&...args)145 template<typename F, typename... Args> ErrCode WallpaperManager::CallService(F func, Args &&...args)
146 {
147 auto service = GetService();
148 if (service == nullptr) {
149 HILOG_ERROR("get service failed!");
150 return ERR_DEAD_OBJECT;
151 }
152
153 ErrCode result = (service->*func)(std::forward<Args>(args)...);
154 if (SUCCEEDED(result)) {
155 return ERR_OK;
156 }
157
158 // Reset service instance if 'ERR_DEAD_OBJECT' happened.
159 if (result == ERR_DEAD_OBJECT) {
160 ResetService(service);
161 }
162
163 HILOG_ERROR("Callservice failed with: %{public}d.", result);
164 return result;
165 }
166
GetColors(int32_t wallpaperType,const ApiInfo & apiInfo,std::vector<uint64_t> & colors)167 ErrorCode WallpaperManager::GetColors(int32_t wallpaperType, const ApiInfo &apiInfo, std::vector<uint64_t> &colors)
168 {
169 auto wallpaperServerProxy = GetService();
170 if (wallpaperServerProxy == nullptr) {
171 HILOG_ERROR("Get proxy failed!");
172 return E_DEAL_FAILED;
173 }
174 if (apiInfo.isSystemApi) {
175 return ConvertIntToErrorCode(wallpaperServerProxy->GetColorsV9(wallpaperType, colors));
176 }
177 return ConvertIntToErrorCode(wallpaperServerProxy->GetColors(wallpaperType, colors));
178 }
179
GetFile(int32_t wallpaperType,int32_t & wallpaperFd)180 ErrorCode WallpaperManager::GetFile(int32_t wallpaperType, int32_t &wallpaperFd)
181 {
182 auto wallpaperServerProxy = GetService();
183 if (wallpaperServerProxy == nullptr) {
184 HILOG_ERROR("Get proxy failed!");
185 return E_DEAL_FAILED;
186 }
187 std::lock_guard<std::mutex> lock(wallpaperFdLock_);
188 std::map<int32_t, int32_t>::iterator iter = wallpaperFdMap_.find(wallpaperType);
189 if (iter != wallpaperFdMap_.end() && fcntl(iter->second, F_GETFL) != -1) {
190 close(iter->second);
191 wallpaperFdMap_.erase(iter);
192 }
193 ErrorCode wallpaperErrorCode = ConvertIntToErrorCode(wallpaperServerProxy->GetFile(wallpaperType, wallpaperFd));
194 if (wallpaperErrorCode == E_OK && wallpaperFd != -1) {
195 wallpaperFdMap_.insert(std::pair<int32_t, int32_t>(wallpaperType, wallpaperFd));
196 }
197 return wallpaperErrorCode;
198 }
199
SetWallpaper(std::string uri,int32_t wallpaperType,const ApiInfo & apiInfo)200 ErrorCode WallpaperManager::SetWallpaper(std::string uri, int32_t wallpaperType, const ApiInfo &apiInfo)
201 {
202 auto wallpaperServerProxy = GetService();
203 if (wallpaperServerProxy == nullptr) {
204 HILOG_ERROR("Get proxy failed!");
205 return E_DEAL_FAILED;
206 }
207 std::string fileRealPath;
208 if (!FileDeal::GetRealPath(uri, fileRealPath)) {
209 HILOG_ERROR("get real path file failed, len = %{public}zu.", uri.size());
210 return E_PARAMETERS_INVALID;
211 }
212
213 long length = 0;
214 ErrorCode wallpaperErrorCode = CheckWallpaperFormat(fileRealPath, false, length);
215 if (wallpaperErrorCode != E_OK) {
216 HILOG_ERROR("Check wallpaper format failed!");
217 return wallpaperErrorCode;
218 }
219
220 int32_t fd = open(fileRealPath.c_str(), O_RDONLY, MODE);
221 if (fd < 0) {
222 HILOG_ERROR("open file failed, errno %{public}d!", errno);
223 ReporterFault(FaultType::SET_WALLPAPER_FAULT, FaultCode::RF_FD_INPUT_FAILED);
224 return E_FILE_ERROR;
225 }
226 fdsan_exchange_owner_tag(fd, 0, WP_DOMAIN);
227 StartAsyncTrace(HITRACE_TAG_MISC, "SetWallpaper", static_cast<int32_t>(TraceTaskId::SET_WALLPAPER));
228 if (apiInfo.isSystemApi) {
229 wallpaperErrorCode = ConvertIntToErrorCode(wallpaperServerProxy->SetWallpaperV9(fd, wallpaperType, length));
230 } else {
231 wallpaperErrorCode = ConvertIntToErrorCode(wallpaperServerProxy->SetWallpaper(fd, wallpaperType, length));
232 }
233 fdsan_close_with_tag(fd, WP_DOMAIN);
234 if (wallpaperErrorCode == E_OK) {
235 CloseWallpaperFd(wallpaperType);
236 }
237 FinishAsyncTrace(HITRACE_TAG_MISC, "SetWallpaper", static_cast<int32_t>(TraceTaskId::SET_WALLPAPER));
238 return wallpaperErrorCode;
239 }
240
SetWallpaper(std::shared_ptr<OHOS::Media::PixelMap> pixelMap,int32_t wallpaperType,const ApiInfo & apiInfo)241 ErrorCode WallpaperManager::SetWallpaper(
242 std::shared_ptr<OHOS::Media::PixelMap> pixelMap, int32_t wallpaperType, const ApiInfo &apiInfo)
243 {
244 auto wallpaperServerProxy = GetService();
245 if (wallpaperServerProxy == nullptr) {
246 HILOG_ERROR("Get proxy failed!");
247 return E_DEAL_FAILED;
248 }
249
250 ErrorCode wallpaperErrorCode = E_UNKNOWN;
251 if (pixelMap == nullptr) {
252 HILOG_ERROR("pixelMap is nullptr!");
253 return E_DEAL_FAILED;
254 }
255 std::vector<std::uint8_t> value;
256 if (!pixelMap->EncodeTlv(value)) {
257 HILOG_ERROR("pixelMap encode failed!");
258 return E_DEAL_FAILED;
259 }
260 WallpaperRawData wallpaperRawData;
261 wallpaperRawData.size = value.size();
262 wallpaperRawData.data = value.data();
263 if (apiInfo.isSystemApi) {
264 wallpaperErrorCode =
265 ConvertIntToErrorCode(wallpaperServerProxy->SetWallpaperV9ByPixelMap(wallpaperRawData, wallpaperType));
266 } else {
267 wallpaperErrorCode =
268 ConvertIntToErrorCode(wallpaperServerProxy->SetWallpaperByPixelMap(wallpaperRawData, wallpaperType));
269 }
270 if (wallpaperErrorCode == static_cast<int32_t>(E_OK)) {
271 CloseWallpaperFd(wallpaperType);
272 }
273 return wallpaperErrorCode;
274 }
275
SetVideo(const std::string & uri,const int32_t wallpaperType)276 ErrorCode WallpaperManager::SetVideo(const std::string &uri, const int32_t wallpaperType)
277 {
278 auto wallpaperServerProxy = GetService();
279 if (wallpaperServerProxy == nullptr) {
280 HILOG_ERROR("Get proxy failed!");
281 return E_DEAL_FAILED;
282 }
283 std::string fileRealPath;
284 if (!FileDeal::GetRealPath(uri, fileRealPath)) {
285 HILOG_ERROR("Get real path failed, uri: %{public}s!", uri.c_str());
286 return E_PARAMETERS_INVALID;
287 }
288
289 long length = 0;
290 ErrorCode wallpaperErrorCode = CheckWallpaperFormat(fileRealPath, true, length);
291 if (wallpaperErrorCode != E_OK) {
292 HILOG_ERROR("Check wallpaper format failed!");
293 return wallpaperErrorCode;
294 }
295 int32_t fd = open(fileRealPath.c_str(), O_RDONLY, MODE);
296 if (fd < 0) {
297 HILOG_ERROR("Open file failed, errno %{public}d!", errno);
298 ReporterFault(FaultType::SET_WALLPAPER_FAULT, FaultCode::RF_FD_INPUT_FAILED);
299 return E_FILE_ERROR;
300 }
301 fdsan_exchange_owner_tag(fd, 0, WP_DOMAIN);
302 StartAsyncTrace(HITRACE_TAG_MISC, "SetVideo", static_cast<int32_t>(TraceTaskId::SET_VIDEO));
303 wallpaperErrorCode = ConvertIntToErrorCode(wallpaperServerProxy->SetVideo(fd, wallpaperType, length));
304 fdsan_close_with_tag(fd, WP_DOMAIN);
305 FinishAsyncTrace(HITRACE_TAG_MISC, "SetVideo", static_cast<int32_t>(TraceTaskId::SET_VIDEO));
306 return wallpaperErrorCode;
307 }
308
SetCustomWallpaper(const std::string & uri,const int32_t wallpaperType)309 ErrorCode WallpaperManager::SetCustomWallpaper(const std::string &uri, const int32_t wallpaperType)
310 {
311 auto wallpaperServerProxy = GetService();
312 if (wallpaperServerProxy == nullptr) {
313 HILOG_ERROR("Get proxy failed!");
314 return E_DEAL_FAILED;
315 }
316 std::string fileRealPath;
317 if (!FileDeal::GetRealPath(uri, fileRealPath)) {
318 HILOG_ERROR("Get real path failed, uri: %{public}s!", uri.c_str());
319 return E_PARAMETERS_INVALID;
320 }
321 if (!FileDeal::IsZipFile(uri)) {
322 return E_FILE_ERROR;
323 }
324 long length = 0;
325 ErrorCode wallpaperErrorCode = CheckWallpaperFormat(fileRealPath, false, length);
326 if (wallpaperErrorCode != E_OK) {
327 HILOG_ERROR("Check wallpaper format failed!");
328 return wallpaperErrorCode;
329 }
330 int32_t fd = open(fileRealPath.c_str(), O_RDONLY, MODE);
331 if (fd < 0) {
332 HILOG_ERROR("Open file failed, errno %{public}d!", errno);
333 ReporterFault(FaultType::SET_WALLPAPER_FAULT, FaultCode::RF_FD_INPUT_FAILED);
334 return E_FILE_ERROR;
335 }
336 fdsan_exchange_owner_tag(fd, 0, WP_DOMAIN);
337 StartAsyncTrace(HITRACE_TAG_MISC, "SetCustomWallpaper", static_cast<int32_t>(TraceTaskId::SET_CUSTOM_WALLPAPER));
338 wallpaperErrorCode = ConvertIntToErrorCode(wallpaperServerProxy->SetCustomWallpaper(fd, wallpaperType, length));
339 fdsan_close_with_tag(fd, WP_DOMAIN);
340 FinishAsyncTrace(HITRACE_TAG_MISC, "SetCustomWallpaper", static_cast<int32_t>(TraceTaskId::SET_CUSTOM_WALLPAPER));
341 return wallpaperErrorCode;
342 }
343
GetPixelMap(int32_t wallpaperType,const ApiInfo & apiInfo,std::shared_ptr<OHOS::Media::PixelMap> & pixelMap)344 ErrorCode WallpaperManager::GetPixelMap(
345 int32_t wallpaperType, const ApiInfo &apiInfo, std::shared_ptr<OHOS::Media::PixelMap> &pixelMap)
346 {
347 HILOG_INFO("FrameWork GetPixelMap Start by FD.");
348 auto wallpaperServerProxy = GetService();
349 if (wallpaperServerProxy == nullptr) {
350 HILOG_ERROR("Get proxy failed!");
351 return E_SA_DIED;
352 }
353 ErrorCode wallpaperErrorCode = E_UNKNOWN;
354 int32_t size = 0;
355 int32_t fd = -1;
356 if (apiInfo.isSystemApi) {
357 wallpaperErrorCode = ConvertIntToErrorCode(wallpaperServerProxy->GetPixelMapV9(wallpaperType, size, fd));
358 } else {
359 wallpaperErrorCode = ConvertIntToErrorCode(wallpaperServerProxy->GetPixelMap(wallpaperType, size, fd));
360 }
361 if (wallpaperErrorCode != E_OK) {
362 return wallpaperErrorCode;
363 }
364 // current wallpaper is live video, not image
365 if (size == 0 && fd == -1) { // 0: empty file size; -1: invalid file description
366 pixelMap = nullptr;
367 return E_OK;
368 }
369 wallpaperErrorCode = CreatePixelMapByFd(fd, size, pixelMap);
370 if (wallpaperErrorCode != E_OK) {
371 pixelMap = nullptr;
372 return wallpaperErrorCode;
373 }
374 return wallpaperErrorCode;
375 }
376
CreatePixelMapByFd(int32_t fd,int32_t size,std::shared_ptr<OHOS::Media::PixelMap> & pixelMap)377 ErrorCode WallpaperManager::CreatePixelMapByFd(
378 int32_t fd, int32_t size, std::shared_ptr<OHOS::Media::PixelMap> &pixelMap)
379 {
380 if (size <= 0 || fd < 0) {
381 HILOG_ERROR("Size or fd error!");
382 return E_IMAGE_ERRCODE;
383 }
384 uint8_t *buffer = new uint8_t[size];
385 ssize_t bytesRead = read(fd, buffer, size);
386 if (bytesRead < 0) {
387 HILOG_ERROR("Read fd to buffer fail!");
388 delete[] buffer;
389 close(fd);
390 return E_IMAGE_ERRCODE;
391 }
392 uint32_t errorCode = 0;
393 OHOS::Media::SourceOptions opts;
394 opts.formatHint = "image/jpeg";
395 std::unique_ptr<OHOS::Media::ImageSource> imageSource =
396 OHOS::Media::ImageSource::CreateImageSource(buffer, size, opts, errorCode);
397 if (errorCode != 0 || imageSource == nullptr) {
398 HILOG_ERROR("ImageSource::CreateImageSource failed, errcode= %{public}d!", errorCode);
399 delete[] buffer;
400 close(fd);
401 return E_IMAGE_ERRCODE;
402 }
403 OHOS::Media::DecodeOptions decodeOpts;
404 pixelMap = imageSource->CreatePixelMap(decodeOpts, errorCode);
405 if (errorCode != 0) {
406 HILOG_ERROR("ImageSource::CreatePixelMap failed, errcode= %{public}d!", errorCode);
407 delete[] buffer;
408 close(fd);
409 return E_IMAGE_ERRCODE;
410 }
411 delete[] buffer;
412 close(fd);
413 return E_OK;
414 }
415
GetWallpaperId(int32_t wallpaperType)416 int32_t WallpaperManager::GetWallpaperId(int32_t wallpaperType)
417 {
418 auto wallpaperServerProxy = GetService();
419 if (wallpaperServerProxy == nullptr) {
420 HILOG_ERROR("Get proxy failed!");
421 return -1;
422 }
423 return wallpaperServerProxy->GetWallpaperId(wallpaperType);
424 }
425
GetWallpaperMinHeight(const ApiInfo & apiInfo,int32_t & minHeight)426 ErrorCode WallpaperManager::GetWallpaperMinHeight(const ApiInfo &apiInfo, int32_t &minHeight)
427 {
428 auto display = Rosen::DisplayManager::GetInstance().GetDefaultDisplay();
429 if (display == nullptr) {
430 HILOG_ERROR("GetDefaultDisplay is nullptr.");
431 return E_DEAL_FAILED;
432 }
433 minHeight = display->GetHeight();
434 return E_OK;
435 }
436
GetWallpaperMinWidth(const ApiInfo & apiInfo,int32_t & minWidth)437 ErrorCode WallpaperManager::GetWallpaperMinWidth(const ApiInfo &apiInfo, int32_t &minWidth)
438 {
439 auto display = Rosen::DisplayManager::GetInstance().GetDefaultDisplay();
440 if (display == nullptr) {
441 HILOG_ERROR("GetDefaultDisplay is nullptr.");
442 return E_DEAL_FAILED;
443 }
444 minWidth = display->GetWidth();
445 return E_OK;
446 }
447
IsChangePermitted()448 bool WallpaperManager::IsChangePermitted()
449 {
450 auto wallpaperServerProxy = GetService();
451 if (wallpaperServerProxy == nullptr) {
452 HILOG_ERROR("Get proxy failed!");
453 return false;
454 }
455 bool isChangePermitted = false;
456 wallpaperServerProxy->IsChangePermitted(isChangePermitted);
457 return isChangePermitted;
458 }
459
IsOperationAllowed()460 bool WallpaperManager::IsOperationAllowed()
461 {
462 auto wallpaperServerProxy = GetService();
463 if (wallpaperServerProxy == nullptr) {
464 HILOG_ERROR("Get proxy failed!");
465 return false;
466 }
467 bool isOperationAllowed = false;
468 wallpaperServerProxy->IsOperationAllowed(isOperationAllowed);
469 return isOperationAllowed;
470 }
ResetWallpaper(std::int32_t wallpaperType,const ApiInfo & apiInfo)471 ErrorCode WallpaperManager::ResetWallpaper(std::int32_t wallpaperType, const ApiInfo &apiInfo)
472 {
473 auto wallpaperServerProxy = GetService();
474 if (wallpaperServerProxy == nullptr) {
475 HILOG_ERROR("Get proxy failed!");
476 return E_SA_DIED;
477 }
478 ErrorCode wallpaperErrorCode = E_UNKNOWN;
479 if (apiInfo.isSystemApi) {
480 wallpaperErrorCode = ConvertIntToErrorCode(wallpaperServerProxy->ResetWallpaperV9(wallpaperType));
481 } else {
482 wallpaperErrorCode = ConvertIntToErrorCode(wallpaperServerProxy->ResetWallpaper(wallpaperType));
483 }
484 if (wallpaperErrorCode == E_OK) {
485 CloseWallpaperFd(wallpaperType);
486 }
487 return wallpaperErrorCode;
488 }
489
On(const std::string & type,std::shared_ptr<WallpaperEventListener> listener)490 ErrorCode WallpaperManager::On(const std::string &type, std::shared_ptr<WallpaperEventListener> listener)
491 {
492 HILOG_DEBUG("WallpaperManager::On in.");
493 auto wallpaperServerProxy = GetService();
494 if (wallpaperServerProxy == nullptr) {
495 HILOG_ERROR("Get proxy failed!");
496 return E_SA_DIED;
497 }
498 if (listener == nullptr) {
499 HILOG_ERROR("listener is nullptr.");
500 return E_DEAL_FAILED;
501 }
502 sptr<WallpaperEventListenerClient> ipcListener = new (std::nothrow) WallpaperEventListenerClient(listener);
503 if (ipcListener == nullptr) {
504 HILOG_ERROR("new WallpaperEventListenerClient failed!");
505 return E_NO_MEMORY;
506 }
507 {
508 std::lock_guard<std::mutex> lock(listenerMapLock_);
509 listenerMap_.insert_or_assign(type, ipcListener);
510 }
511 return ConvertIntToErrorCode(wallpaperServerProxy->On(type, ipcListener));
512 }
513
Off(const std::string & type,std::shared_ptr<WallpaperEventListener> listener)514 ErrorCode WallpaperManager::Off(const std::string &type, std::shared_ptr<WallpaperEventListener> listener)
515 {
516 HILOG_DEBUG("WallpaperManager::Off in.");
517 auto wallpaperServerProxy = GetService();
518 if (wallpaperServerProxy == nullptr) {
519 HILOG_ERROR("Get proxy failed!");
520 return E_SA_DIED;
521 }
522 sptr<WallpaperEventListenerClient> ipcListener = nullptr;
523 ipcListener = new (std::nothrow) WallpaperEventListenerClient(listener);
524 if (ipcListener == nullptr) {
525 HILOG_ERROR("new WallpaperEventListenerClient failed!");
526 return E_NO_MEMORY;
527 }
528 return ConvertIntToErrorCode(wallpaperServerProxy->Off(type, ipcListener));
529 }
530
GetCallback()531 JScallback WallpaperManager::GetCallback()
532 {
533 return callback;
534 }
535
SetCallback(JScallback cb)536 void WallpaperManager::SetCallback(JScallback cb)
537 {
538 callback = cb;
539 }
540
RegisterWallpaperCallback(JScallback callback)541 bool WallpaperManager::RegisterWallpaperCallback(JScallback callback)
542 {
543 HILOG_INFO(" WallpaperManager::RegisterWallpaperCallback statrt.");
544 SetCallback(callback);
545 auto wallpaperServerProxy = GetService();
546 if (wallpaperServerProxy == nullptr) {
547 HILOG_ERROR("Get proxy failed");
548 return false;
549 }
550
551 if (callback == nullptr) {
552 HILOG_ERROR("callback is NULL.");
553 return false;
554 }
555 bool registerWallpaperCallback = false;
556 wallpaperServerProxy->RegisterWallpaperCallback(new WallpaperServiceCbStub(), registerWallpaperCallback);
557 if (!registerWallpaperCallback) {
558 HILOG_ERROR("off failed code=%d.", ERR_NONE);
559 return false;
560 }
561 return registerWallpaperCallback;
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 = ConvertIntToErrorCode(service->On(iter.first, iter.second));
593 if (ret != E_OK) {
594 HILOG_ERROR(
595 "Register WallpaperListener failed type:%{public}s, errcode:%{public}d", iter.first.c_str(), 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 ConvertIntToErrorCode(wallpaperServerProxy->SendEvent(eventType));
609 }
610
CheckVideoFormat(const std::string & fileName)611 bool WallpaperManager::CheckVideoFormat(const std::string &fileName)
612 {
613 int32_t fd = -1;
614 int64_t length = 0;
615 FILE *wallpaperFile = OpenFile(fileName, fd, length);
616 if (wallpaperFile == nullptr) {
617 HILOG_ERROR("Open file: %{public}s failed!", fileName.c_str());
618 return false;
619 }
620 std::shared_ptr<Media::AVMetadataHelper> helper = Media::AVMetadataHelperFactory::CreateAVMetadataHelper();
621 if (helper == nullptr) {
622 HILOG_ERROR("Create metadata helper failed!");
623 fclose(wallpaperFile);
624 return false;
625 }
626 int32_t offset = 0;
627 int32_t errorCode = helper->SetSource(fd, offset, length);
628 if (errorCode != 0) {
629 HILOG_ERROR("Set helper source failed!");
630 fclose(wallpaperFile);
631 return false;
632 }
633 auto metaData = helper->ResolveMetadata();
634 if (metaData.find(Media::AV_KEY_MIME_TYPE) != metaData.end()) {
635 if (metaData[Media::AV_KEY_MIME_TYPE] != "video/mp4") {
636 HILOG_ERROR("Video mime type is not video/mp4!");
637 fclose(wallpaperFile);
638 return false;
639 }
640 } else {
641 HILOG_ERROR("Cannot get video mime type!");
642 fclose(wallpaperFile);
643 return false;
644 }
645
646 if (metaData.find(Media::AV_KEY_DURATION) != metaData.end()) {
647 int32_t videoDuration = ConverString2Int(metaData[Media::AV_KEY_DURATION]);
648 if (videoDuration < MIN_TIME || videoDuration > MAX_TIME) {
649 HILOG_ERROR("The durations of this vodeo is not between 0s ~ 5s!");
650 fclose(wallpaperFile);
651 return false;
652 }
653 } else {
654 HILOG_ERROR("Cannot get the duration of this video!");
655 fclose(wallpaperFile);
656 return false;
657 }
658 fclose(wallpaperFile);
659 return true;
660 }
661
OpenFile(const std::string & fileName,int & fd,int64_t & fileSize)662 FILE *WallpaperManager::OpenFile(const std::string &fileName, int &fd, int64_t &fileSize)
663 {
664 if (!OHOS::FileExists(fileName)) {
665 HILOG_ERROR("File is not exist, file: %{public}s.", fileName.c_str());
666 return nullptr;
667 }
668
669 FILE *file = fopen(fileName.c_str(), "r");
670 if (file == nullptr) {
671 HILOG_ERROR("Get video file failed!");
672 return nullptr;
673 }
674 fd = fileno(file);
675 if (fd < 0) {
676 HILOG_ERROR("Get video videoFd failed!");
677 fclose(file);
678 return nullptr;
679 }
680 struct stat64 st;
681 if (fstat64(fd, &st) != 0) {
682 HILOG_ERROR("Failed to fstat64!");
683 fclose(file);
684 return nullptr;
685 }
686 fileSize = static_cast<int64_t>(st.st_size);
687 return file;
688 }
689
CheckWallpaperFormat(const std::string & realPath,bool isLive,long & length)690 ErrorCode WallpaperManager::CheckWallpaperFormat(const std::string &realPath, bool isLive, long &length)
691 {
692 if (isLive && (FileDeal::GetExtension(realPath) != ".mp4" || !CheckVideoFormat(realPath))) {
693 HILOG_ERROR("Check live wallpaper file failed!");
694 return E_PARAMETERS_INVALID;
695 }
696
697 FILE *file = std::fopen(realPath.c_str(), "rb");
698 if (file == nullptr) {
699 HILOG_ERROR("Fopen failed, %{public}s, %{public}s!", realPath.c_str(), strerror(errno));
700 return E_FILE_ERROR;
701 }
702
703 int32_t fend = fseek(file, 0, SEEK_END);
704 length = ftell(file);
705 int32_t fset = fseek(file, 0, SEEK_SET);
706 if (length <= 0 || (isLive && length > MAX_VIDEO_SIZE) || fend != 0 || fset != 0) {
707 HILOG_ERROR("ftell file failed or fseek file failed, errno %{public}d!", errno);
708 fclose(file);
709 return E_FILE_ERROR;
710 }
711 fclose(file);
712 return E_OK;
713 }
714
SetAllWallpapers(std::vector<WallpaperInfo> allWallpaperInfos,int32_t wallpaperType)715 ErrorCode WallpaperManager::SetAllWallpapers(std::vector<WallpaperInfo> allWallpaperInfos, int32_t wallpaperType)
716 {
717 auto wallpaperServerProxy = GetService();
718 if (wallpaperServerProxy == nullptr) {
719 HILOG_ERROR("Get proxy failed!");
720 return E_DEAL_FAILED;
721 }
722 WallpaperPictureInfoByParcel wallpaperPictureInfoByParcel;
723 WallpaperPictureInfo wallpaperPictureInfo;
724 std::vector<int32_t> fdVector;
725 ErrorCode wallpaperCode;
726 for (const auto &wallpaperInfo : allWallpaperInfos) {
727 std::string fileRealPath;
728 if (!FileDeal::GetRealPath(wallpaperInfo.source, fileRealPath)) {
729 HILOG_ERROR("get real path file failed, len = %{public}zu.", wallpaperInfo.source.size());
730 return E_PARAMETERS_INVALID;
731 }
732 wallpaperCode = GetFdByPath(wallpaperInfo, wallpaperPictureInfo, fileRealPath);
733 if (wallpaperCode != E_OK) {
734 CloseWallpaperInfoFd(wallpaperPictureInfoByParcel.wallpaperPictureInfo_);
735 HILOG_ERROR("PathConvertFd failed");
736 return wallpaperCode;
737 }
738 wallpaperPictureInfoByParcel.wallpaperPictureInfo_.push_back(wallpaperPictureInfo);
739 fdVector.push_back(wallpaperPictureInfo.fd);
740 }
741
742 StartAsyncTrace(HITRACE_TAG_MISC, "SetAllWallpapers", static_cast<int32_t>(TraceTaskId::SET_ALL_WALLPAPERS));
743 ErrorCode wallpaperErrorCode = ConvertIntToErrorCode(
744 wallpaperServerProxy->SetAllWallpapers(wallpaperPictureInfoByParcel, wallpaperType, fdVector));
745 if (wallpaperErrorCode == E_OK) {
746 CloseWallpaperFd(wallpaperType);
747 }
748 CloseWallpaperInfoFd(wallpaperPictureInfoByParcel.wallpaperPictureInfo_);
749 FinishAsyncTrace(HITRACE_TAG_MISC, "SetAllWallpapers", static_cast<int32_t>(TraceTaskId::SET_ALL_WALLPAPERS));
750 return wallpaperErrorCode;
751 }
752
GetFdByPath(const WallpaperInfo & wallpaperInfo,WallpaperPictureInfo & wallpaperPictureInfo,std::string fileRealPath)753 ErrorCode WallpaperManager::GetFdByPath(
754 const WallpaperInfo &wallpaperInfo, WallpaperPictureInfo &wallpaperPictureInfo, std::string fileRealPath)
755 {
756 wallpaperPictureInfo.foldState = wallpaperInfo.foldState;
757 wallpaperPictureInfo.rotateState = wallpaperInfo.rotateState;
758 wallpaperPictureInfo.fd = open(fileRealPath.c_str(), O_RDONLY, MODE);
759 if (wallpaperPictureInfo.fd < 0) {
760 HILOG_ERROR("open file failed, errno %{public}d!", errno);
761 ReporterFault(FaultType::SET_WALLPAPER_FAULT, FaultCode::RF_FD_INPUT_FAILED);
762 return E_FILE_ERROR;
763 }
764 fdsan_exchange_owner_tag(wallpaperPictureInfo.fd, 0, WP_DOMAIN);
765 ErrorCode wallpaperErrorCode = CheckWallpaperFormat(fileRealPath, false, wallpaperPictureInfo.length);
766 if (wallpaperErrorCode != E_OK) {
767 HILOG_ERROR("Check wallpaper format failed!");
768 return wallpaperErrorCode;
769 }
770 uint32_t errorCode = 0;
771 OHOS::Media::SourceOptions opts;
772 std::unique_ptr<OHOS::Media::ImageSource> imageSource =
773 OHOS::Media::ImageSource::CreateImageSource(fileRealPath, opts, errorCode);
774 if (errorCode != 0 || imageSource == nullptr) {
775 HILOG_ERROR("CreateImageSource failed!");
776 return E_PARAMETERS_INVALID;
777 }
778 ImageInfo imageInfo;
779 if (imageSource->GetImageInfo(imageInfo) != 0) {
780 HILOG_ERROR("GetImageInfo failed!");
781 return E_PARAMETERS_INVALID;
782 }
783 return wallpaperErrorCode;
784 }
785
GetCorrespondWallpaper(int32_t wallpaperType,int32_t foldState,int32_t rotateState,std::shared_ptr<OHOS::Media::PixelMap> & pixelMap)786 ErrorCode WallpaperManager::GetCorrespondWallpaper(
787 int32_t wallpaperType, int32_t foldState, int32_t rotateState, std::shared_ptr<OHOS::Media::PixelMap> &pixelMap)
788 {
789 HILOG_INFO("GetCorrespondWallpaper start.");
790 auto wallpaperServerProxy = GetService();
791 if (wallpaperServerProxy == nullptr) {
792 HILOG_ERROR("Get proxy failed!");
793 return E_SA_DIED;
794 }
795 ErrorCode wallpaperErrorCode = E_UNKNOWN;
796 int32_t size = 0;
797 int32_t fd = -1;
798 wallpaperErrorCode = ConvertIntToErrorCode(
799 wallpaperServerProxy->GetCorrespondWallpaper(wallpaperType, foldState, rotateState, size, fd));
800 if (wallpaperErrorCode != E_OK) {
801 return wallpaperErrorCode;
802 }
803 // current wallpaper is live video, not image
804 if (size == 0 && fd == -1) { // 0: empty file size; -1: invalid file description
805 pixelMap = nullptr;
806 return E_OK;
807 }
808 wallpaperErrorCode = CreatePixelMapByFd(fd, size, pixelMap);
809 if (wallpaperErrorCode != E_OK) {
810 pixelMap = nullptr;
811 return wallpaperErrorCode;
812 }
813 return wallpaperErrorCode;
814 }
815
CloseWallpaperInfoFd(std::vector<WallpaperPictureInfo> wallpaperPictureInfos)816 void WallpaperManager::CloseWallpaperInfoFd(std::vector<WallpaperPictureInfo> wallpaperPictureInfos)
817 {
818 for (auto &wallpaperInfo : wallpaperPictureInfos) {
819 if (wallpaperInfo.fd >= 0) {
820 fdsan_close_with_tag(wallpaperInfo.fd, WP_DOMAIN);
821 }
822 }
823 }
824
IsDefaultWallpaperResource(int32_t userId,int32_t wallpaperType)825 bool WallpaperManager::IsDefaultWallpaperResource(int32_t userId, int32_t wallpaperType)
826 {
827 auto wallpaperServerProxy = GetService();
828 if (wallpaperServerProxy == nullptr) {
829 HILOG_ERROR("Get proxy failed!");
830 return false;
831 }
832 bool isDefaultWallpaperResource = false;
833 wallpaperServerProxy->IsDefaultWallpaperResource(userId, wallpaperType, isDefaultWallpaperResource);
834 return isDefaultWallpaperResource;
835 }
836
ConverString2Int(const std::string & value)837 int32_t WallpaperManager::ConverString2Int(const std::string &value)
838 {
839 int32_t result = -1;
840 if (!value.empty() && std::all_of(value.begin(), value.end(), ::isdigit)) {
841 char *endPtr = nullptr;
842 result = strtol(value.c_str(), &endPtr, BASE_NUMBER);
843 if (*endPtr != '\0') {
844 return -1;
845 }
846 }
847 return result;
848 }
849
850 std::unordered_map<int32_t, ErrorCode> errorCodeMap = {
851 { static_cast<int32_t>(NO_ERROR), E_OK },
852 { static_cast<int32_t>(E_OK), E_OK },
853 { static_cast<int32_t>(E_SA_DIED), E_SA_DIED },
854 { static_cast<int32_t>(E_READ_PARCEL_ERROR), E_READ_PARCEL_ERROR },
855 { static_cast<int32_t>(E_WRITE_PARCEL_ERROR), E_WRITE_PARCEL_ERROR },
856 { static_cast<int32_t>(E_PUBLISH_FAIL), E_PUBLISH_FAIL },
857 { static_cast<int32_t>(E_TRANSACT_ERROR), E_TRANSACT_ERROR },
858 { static_cast<int32_t>(E_DEAL_FAILED), E_DEAL_FAILED },
859 { static_cast<int32_t>(E_PARAMETERS_INVALID), E_PARAMETERS_INVALID },
860 { static_cast<int32_t>(E_SET_RTC_FAILED), E_SET_RTC_FAILED },
861 { static_cast<int32_t>(E_NOT_FOUND), E_NOT_FOUND },
862 { static_cast<int32_t>(E_NO_PERMISSION), E_NO_PERMISSION },
863 { static_cast<int32_t>(E_FILE_ERROR), E_FILE_ERROR },
864 { static_cast<int32_t>(E_IMAGE_ERRCODE), E_IMAGE_ERRCODE },
865 { static_cast<int32_t>(E_NO_MEMORY), E_NO_MEMORY },
866 { static_cast<int32_t>(E_NOT_SYSTEM_APP), E_NOT_SYSTEM_APP },
867 { static_cast<int32_t>(E_USER_IDENTITY_ERROR), E_USER_IDENTITY_ERROR },
868 { static_cast<int32_t>(E_CHECK_DESCRIPTOR_ERROR), E_CHECK_DESCRIPTOR_ERROR },
869 };
870
ConvertIntToErrorCode(int32_t errorCode)871 ErrorCode WallpaperManager::ConvertIntToErrorCode(int32_t errorCode)
872 {
873 auto it = errorCodeMap.find(errorCode);
874 if (it == errorCodeMap.end()) {
875 return E_UNKNOWN;
876 }
877 return it->second;
878 }
879
880 } // namespace WallpaperMgrService
881 } // namespace OHOS