• 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 <mutex>
16 #include <fstream>
17 #include <unistd.h>
18 #include <sys/types.h>
19 #include <sys/stat.h>
20 #include <fcntl.h>
21 #include <cstdlib>
22 #include <iostream>
23 #include <sstream>
24 #include <cstdio>
25 #include <cstring>
26 #include <cerrno>
27 #include "hilog_wrapper.h"
28 #include "wallpaper_service_proxy.h"
29 #include "if_system_ability_manager.h"
30 #include "iservice_registry.h"
31 #include "system_ability_definition.h"
32 #include "i_wallpaper_service.h"
33 #include "permission.h"
34 #include "image_source.h"
35 #include "image_type.h"
36 #include "image_packer.h"
37 #include "file_ex.h"
38 #include "file_deal.h"
39 #include "file_util.h"
40 #include "wallpaper_service_cb_stub.h"
41 #include "wallpaper_manager.h"
42 
43 namespace OHOS {
44 namespace WallpaperMgrService {
45 constexpr int OPTION_QUALITY = 100;
WallpaperManager()46 WallpaperManager::WallpaperManager() {}
~WallpaperManager()47 WallpaperManager::~WallpaperManager() {}
48 
ResetService(const wptr<IRemoteObject> & remote)49 void WallpaperManager::ResetService(const wptr<IRemoteObject>& remote)
50 {
51     HILOG_INFO("Remote is dead, reset service instance");
52     std::lock_guard<std::mutex> lock(wpProxyLock_);
53     if (wpProxy_ != nullptr) {
54         sptr<IRemoteObject> object = wpProxy_->AsObject();
55         if ((object != nullptr) && (remote == object)) {
56             object->RemoveDeathRecipient(deathRecipient_);
57             wpProxy_ = nullptr;
58         }
59     }
60 }
61 
GetService()62 sptr<IWallpaperService> WallpaperManager::GetService()
63 {
64     std::lock_guard<std::mutex> lock(wpProxyLock_);
65     if (wpProxy_ != nullptr) {
66         return wpProxy_;
67     }
68 
69     sptr<ISystemAbilityManager> samgr = SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager();
70     if (samgr == nullptr) {
71         HILOG_ERROR("Get samgr failed");
72         return nullptr;
73     }
74     sptr<IRemoteObject> object = samgr->GetSystemAbility(WALLPAPER_MANAGER_SERVICE_ID);
75     if (object == nullptr) {
76         HILOG_ERROR("Get wallpaper object from samgr failed");
77         return nullptr;
78     }
79 
80     if (deathRecipient_ == nullptr) {
81         deathRecipient_ = new DeathRecipient();
82     }
83 
84     if ((object->IsProxyObject()) && (!object->AddDeathRecipient(deathRecipient_))) {
85         HILOG_ERROR("Failed to add death recipient");
86     }
87 
88     HILOG_INFO("get remote object ok");
89     wpProxy_ = iface_cast<WallpaperServiceProxy>(object);
90     if (wpProxy_ == nullptr) {
91         HILOG_ERROR("iface_cast failed");
92     }
93     return wpProxy_;
94 }
95 
OnRemoteDied(const wptr<IRemoteObject> & remote)96 void WallpaperManager::DeathRecipient::OnRemoteDied(const wptr<IRemoteObject>& remote)
97 {
98     DelayedRefSingleton<WallpaperManager>::GetInstance().ResetService(remote);
99 }
100 
101 template<typename F, typename... Args>
CallService(F func,Args &&...args)102 ErrCode WallpaperManager::CallService(F func, Args&&... args)
103 {
104     auto service = GetService();
105     if (service == nullptr) {
106         HILOG_ERROR("get service failed");
107         return ERR_DEAD_OBJECT;
108     }
109 
110     ErrCode result = (service->*func)(std::forward<Args>(args)...);
111     if (SUCCEEDED(result)) {
112         return ERR_OK;
113     }
114 
115     // Reset service instance if 'ERR_DEAD_OBJECT' happened.
116     if (result == ERR_DEAD_OBJECT) {
117         ResetService(service);
118     }
119 
120     HILOG_ERROR("Callservice failed with: %{public}d", result);
121     return result;
122 }
123 
GetColors(int wallpaperType)124 std::vector<RgbaColor> WallpaperManager::GetColors(int wallpaperType)
125 {
126     std::vector<RgbaColor> tmp;
127     auto wpServerProxy = GetService();
128     if (wpServerProxy == nullptr) {
129         HILOG_ERROR("Get proxy failed");
130         return tmp;
131     }
132     return wpServerProxy->GetColors(wallpaperType);
133 }
134 
SetWallpaper(std::string url,int wallpaperType)135 bool WallpaperManager::SetWallpaper(std::string url, int wallpaperType)
136 {
137     auto wpServerProxy = GetService();
138     if (wpServerProxy == nullptr) {
139         HILOG_ERROR("Get proxy failed");
140         return false;
141     }
142     if (!OHOS::FileExists(url)) {
143         HILOG_ERROR("file is not exist!");
144         HILOG_ERROR("file is not exist! %{public}s", url.c_str());
145         return false;
146     }
147     FILE *pixMap = std::fopen(url.c_str(), "rb");
148     if (pixMap == nullptr) {
149         HILOG_ERROR("fopen faild, %{public}s", strerror(errno));
150         HILOG_ERROR("fopen faild, %{public}s", url.c_str());
151         return false;
152     }
153     int fend = fseek(pixMap, 0, SEEK_END);
154     if (fend != 0) {
155         HILOG_ERROR("fseek faild");
156         return false;
157     }
158     int length = ftell(pixMap);
159     if (length <= 0) {
160         HILOG_ERROR("ftell faild");
161         return false;
162     }
163     int fset = fseek(pixMap, 0, SEEK_SET);
164     if (fset != 0) {
165         HILOG_ERROR("fseek faild");
166         return false;
167     }
168     int closeRes = fclose(pixMap);
169     if (closeRes != 0) {
170         HILOG_ERROR("fclose faild");
171         return false;
172     }
173 
174     int fd = open(url.c_str(), O_RDONLY, 0660);
175     if (fd < 0) {
176         HILOG_ERROR("open file failed");
177         return false;
178     }
179     return wpServerProxy->SetWallpaperByFD(fd, wallpaperType, length);
180 }
181 
SetWallpaper(std::unique_ptr<OHOS::Media::PixelMap> & pixelMap,int wallpaperType)182 bool WallpaperManager::SetWallpaper(std::unique_ptr<OHOS::Media::PixelMap> &pixelMap, int wallpaperType)
183 {
184     auto wpServerProxy = GetService();
185     std::string urlRet = "";
186     if (wpServerProxy == nullptr) {
187         HILOG_ERROR("Get proxy failed");
188         return false;
189     }
190 
191     std::stringbuf stringBuf;
192     std::ostream ostream(&stringBuf);
193     int mapSize = WritePixelMapToStream(ostream, std::move(pixelMap));
194     if (mapSize <= 0) {
195         HILOG_ERROR("WritePixelMapToStream faild");
196         return false;
197     }
198     char *buffer = new (std::nothrow) char[mapSize]();
199     if (buffer == nullptr) {
200         return false;
201     }
202     stringBuf.sgetn(buffer, mapSize);
203 
204     int fd[2];
205     pipe(fd);
206     fcntl(fd[1], F_SETPIPE_SZ, mapSize);
207     fcntl(fd[0], F_SETPIPE_SZ, mapSize);
208     int32_t writeSize = write(fd[1], buffer, mapSize);
209     if (writeSize != mapSize) {
210         HILOG_ERROR("write to fd faild");
211         return false;
212     }
213     close(fd[1]);
214     return wpServerProxy->SetWallpaperByMap(fd[0], wallpaperType, mapSize);
215 }
WritePixelMapToStream(std::ostream & outputStream,std::unique_ptr<OHOS::Media::PixelMap> pixelMap)216 int64_t WallpaperManager::WritePixelMapToStream(std::ostream &outputStream,
217     std::unique_ptr< OHOS::Media::PixelMap> pixelMap)
218 {
219     OHOS::Media::ImagePacker imagePacker;
220     OHOS::Media::PackOption option;
221     option.format = "image/jpeg";
222     option.quality = OPTION_QUALITY;
223     option.numberHint = 1;
224     std::set<std::string> formats;
225     uint32_t ret = imagePacker.GetSupportedFormats(formats);
226     if (ret != 0) {
227         HILOG_ERROR("image packer get supported format failed, ret=%{public}u.", ret);
228     }
229 
230     imagePacker.StartPacking(outputStream, option);
231     imagePacker.AddImage(*pixelMap);
232     int64_t packedSize = 0;
233     imagePacker.FinalizePacking(packedSize);
234     HILOG_INFO("FrameWork WritePixelMapToFile End! packedSize=%{public}lld.", static_cast<long long>(packedSize));
235     return packedSize;
236 }
237 
WritePixelMapToFile(const std::string & filePath,std::unique_ptr<OHOS::Media::PixelMap> pixelMap)238 int64_t WallpaperManager::WritePixelMapToFile(const std::string &filePath,
239     std::unique_ptr< OHOS::Media::PixelMap> pixelMap)
240 {
241     OHOS::Media::ImagePacker imagePacker;
242     OHOS::Media::PackOption option;
243     option.format = "image/jpeg";
244     option.quality = OPTION_QUALITY;
245     option.numberHint = 1;
246     std::set<std::string> formats;
247     uint32_t ret = imagePacker.GetSupportedFormats(formats);
248     if (ret != 0) {
249         HILOG_ERROR("image packer get supported format failed, ret=%{public}u.", ret);
250     }
251     imagePacker.StartPacking(filePath, option);
252     imagePacker.AddImage(*pixelMap);
253     int64_t packedSize = 0;
254     imagePacker.FinalizePacking(packedSize);
255     HILOG_INFO("FrameWork WritePixelMapToFile End! packedSize=%{public}lld.", static_cast<long long>(packedSize));
256     return packedSize;
257 }
GetPixelMap(int wallpaperType)258 std::shared_ptr<OHOS::Media::PixelMap> WallpaperManager::GetPixelMap(int wallpaperType)
259 {
260     std::unique_ptr<OHOS::Media::PixelMap> tmp = std::make_unique<OHOS::Media::PixelMap>();
261     HILOG_INFO("FrameWork GetPixelMap Start by FD");
262     auto wpServerProxy = GetService();
263     if (wpServerProxy == nullptr) {
264         HILOG_ERROR("Get proxy failed");
265         return nullptr;
266     }
267     IWallpaperService::mapFD mapFd = wpServerProxy->GetPixelMap(wallpaperType);
268     uint32_t errorCode = 0;
269     OHOS::Media::SourceOptions opts;
270     opts.formatHint = "image/jpeg";
271     HILOG_INFO(" CreateImageSource by FD");
272     std::unique_ptr<OHOS::Media::ImageSource> imageSource =
273         OHOS::Media::ImageSource::CreateImageSource(mapFd.fd, opts, errorCode);
274     if (errorCode != 0) {
275         HILOG_ERROR("ImageSource::CreateImageSource failed,errcode= %{public}d", errorCode);
276         return nullptr;
277     }
278     OHOS::Media::DecodeOptions decodeOpts;
279     HILOG_INFO(" CreatePixelMap");
280     tmp = imageSource->CreatePixelMap(decodeOpts, errorCode);
281     if (errorCode != 0) {
282         HILOG_ERROR("ImageSource::CreatePixelMap failed,errcode= %{public}d", errorCode);
283         return nullptr;
284     }
285     close(mapFd.fd);
286     return tmp;
287 }
288 
GetWallpaperId(int wallpaperType)289 int  WallpaperManager::GetWallpaperId(int wallpaperType)
290 {
291     auto wpServerProxy = GetService();
292     if (wpServerProxy == nullptr) {
293         HILOG_ERROR("Get proxy failed");
294         return -1;
295     }
296     return wpServerProxy->GetWallpaperId(wallpaperType);
297 }
298 
GetWallpaperMinHeight()299 int  WallpaperManager::GetWallpaperMinHeight()
300 {
301     auto wpServerProxy = GetService();
302     if (wpServerProxy == nullptr) {
303         HILOG_ERROR("Get proxy failed");
304         return -1;
305     }
306     return wpServerProxy->GetWallpaperMinHeight();
307 }
308 
GetWallpaperMinWidth()309 int  WallpaperManager::GetWallpaperMinWidth()
310 {
311     auto wpServerProxy = GetService();
312     if (wpServerProxy == nullptr) {
313         HILOG_ERROR("Get proxy failed");
314         return -1;
315     }
316     return wpServerProxy->GetWallpaperMinWidth();
317 }
318 
IsChangePermitted()319 bool WallpaperManager::IsChangePermitted()
320 {
321     auto wpServerProxy = GetService();
322     if (wpServerProxy == nullptr) {
323         HILOG_ERROR("Get proxy failed");
324         return false;
325     }
326     return wpServerProxy->IsChangePermitted();
327 }
328 
IsOperationAllowed()329 bool WallpaperManager::IsOperationAllowed()
330 {
331     auto wpServerProxy = GetService();
332     if (wpServerProxy == nullptr) {
333         HILOG_ERROR("Get proxy failed");
334         return false;
335     }
336     return wpServerProxy->IsOperationAllowed();
337 }
ResetWallpaper(std::int32_t wallpaperType)338 bool WallpaperManager::ResetWallpaper(std::int32_t wallpaperType)
339 {
340     auto wpServerProxy = GetService();
341     if (wpServerProxy == nullptr) {
342         HILOG_ERROR("Get proxy failed");
343         return false;
344     }
345     return wpServerProxy->ResetWallpaper(wallpaperType);
346 }
ScreenshotLiveWallpaper(int wallpaperType,OHOS::Media::PixelMap pixelMap)347 bool WallpaperManager::ScreenshotLiveWallpaper(int wallpaperType, OHOS::Media::PixelMap pixelMap)
348 {
349     auto wpServerProxy = GetService();
350     if (wpServerProxy == nullptr) {
351         HILOG_ERROR("Get proxy failed");
352         return false;
353     }
354     return wpServerProxy->ScreenshotLiveWallpaper(wallpaperType, pixelMap);
355 }
356 
On(std::shared_ptr<WallpaperColorChangeListener> listener)357 bool WallpaperManager::On(std::shared_ptr<WallpaperColorChangeListener> listener)
358 {
359     HILOG_DEBUG("WallpaperManager::On in");
360     auto wpServerProxy = GetService();
361     if (wpServerProxy == nullptr) {
362         HILOG_ERROR("Get proxy failed");
363         return false;
364     }
365     if (listener == nullptr) {
366         HILOG_ERROR("listener is nullptr.");
367         return false;
368     }
369     std::lock_guard<std::mutex> lck(listenerMapMutex_);
370 
371     if (registeredListeners_.count(listener.get()) == 1) {
372         HILOG_ERROR("already listened");
373         return false;
374     }
375 
376     sptr<WallpaperColorChangeListenerClient> ipcListener =
377             new (std::nothrow) WallpaperColorChangeListenerClient(listener);
378     if (ipcListener == nullptr) {
379         HILOG_ERROR("new WallpaperColorChangeListenerClient failed");
380         return false;
381     }
382     bool status = wpServerProxy->On(ipcListener);
383     if (status == false) {
384         const auto temp = registeredListeners_.insert({ listener.get(), ipcListener });
385         if (!temp.second) {
386             HILOG_ERROR("local insert error");
387             return false;
388         }
389     }
390     HILOG_DEBUG("WallpaperManager::On out");
391     return true;
392 }
393 
Off(std::shared_ptr<WallpaperColorChangeListener> listener)394 bool WallpaperManager::Off(std::shared_ptr<WallpaperColorChangeListener> listener)
395 {
396     HILOG_DEBUG("WallpaperManager::Off in");
397     auto wpServerProxy = GetService();
398     if (wpServerProxy == nullptr) {
399         HILOG_ERROR("Get proxy failed");
400         return false;
401     }
402     if (listener == nullptr) {
403         HILOG_ERROR("listener is nullptr.");
404         return false;
405     }
406     std::lock_guard<std::mutex> lck(listenerMapMutex_);
407     auto it = registeredListeners_.find(listener.get());
408     if (it == registeredListeners_.end()) {
409         HILOG_ERROR("never listened");
410         return true;
411     }
412     bool status = wpServerProxy->Off(it->second);
413     if (status == false) {
414         HILOG_ERROR("off failed code=%d.", ERR_NONE);
415         return false;
416     }
417     registeredListeners_.erase(it);
418     HILOG_DEBUG("WallpaperManager::Off out");
419     return true;
420 }
421 
GetCallback()422 JScallback WallpaperManager::GetCallback()
423 {
424     return callback;
425 }
426 
SetCallback(bool (* cb)(int))427 void WallpaperManager::SetCallback(bool (*cb) (int))
428 {
429     callback = cb;
430 }
431 
RegisterWallpaperCallback(bool (* callback)(int))432 bool WallpaperManager::RegisterWallpaperCallback(bool (*callback) (int))
433 {
434     HILOG_ERROR("  WallpaperManager::RegisterWallpaperCallback statrt");
435     SetCallback(callback);
436     auto wpServerProxy = GetService();
437     if (wpServerProxy == nullptr) {
438         HILOG_ERROR("Get proxy failed");
439         return false;
440     }
441 
442     if (callback == NULL) {
443         HILOG_ERROR("callback is NULL.");
444         return false;
445     }
446     HILOG_INFO("  WallpaperManager::RegisterWallpaperCallback");
447 
448     bool status = wpServerProxy->RegisterWallpaperCallback(new WallpaperServiceCbStub());
449     if (status == false) {
450         HILOG_ERROR("off failed code=%d.", ERR_NONE);
451         return false;
452     }
453 
454     return 0;
455 }
456 }
457 }
458