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 16#include <unistd.h> 17 18#include "ashmem.h" 19#include "hilog_wrapper.h" 20#include "ipc_skeleton.h" 21#include "memory_guard.h" 22#include "parcel.h" 23#include "pixel_map.h" 24#include "wallpaper_common.h" 25#include "wallpaper_service_ipc_interface_code.h" 26#include "wallpaper_service_stub.h" 27 28namespace OHOS { 29namespace WallpaperMgrService { 30using namespace OHOS::HiviewDFX; 31using namespace OHOS::Media; 32 33WallpaperServiceStub::WallpaperServiceStub(bool serialInvokeFlag) : IRemoteStub(serialInvokeFlag) 34{ 35 requestHandlers = { 36 { static_cast<uint32_t>(WallpaperServiceIpcInterfaceCode::SET_WALLPAPER), 37 [this](MessageParcel &data, MessageParcel &reply) { return OnSetWallpaper(data, reply); } }, 38 { static_cast<uint32_t>(WallpaperServiceIpcInterfaceCode::GET_PIXELMAP), 39 [this](MessageParcel &data, MessageParcel &reply) { return OnGetPixelMap(data, reply); } }, 40 { static_cast<uint32_t>(WallpaperServiceIpcInterfaceCode::GET_COLORS), 41 [this](MessageParcel &data, MessageParcel &reply) { return OnGetColors(data, reply); } }, 42 { static_cast<uint32_t>(WallpaperServiceIpcInterfaceCode::GET_WALLPAPER_ID), 43 [this](MessageParcel &data, MessageParcel &reply) { return OnGetWallpaperId(data, reply); } }, 44 { static_cast<uint32_t>(WallpaperServiceIpcInterfaceCode::GET_FILE), 45 [this](MessageParcel &data, MessageParcel &reply) { return OnGetFile(data, reply); } }, 46 { static_cast<uint32_t>(WallpaperServiceIpcInterfaceCode::ON), 47 [this](MessageParcel &data, MessageParcel &reply) { return OnWallpaperOn(data, reply); } }, 48 { static_cast<uint32_t>(WallpaperServiceIpcInterfaceCode::OFF), 49 [this](MessageParcel &data, MessageParcel &reply) { return OnWallpaperOff(data, reply); } }, 50 { static_cast<uint32_t>(WallpaperServiceIpcInterfaceCode::IS_CHANGE_PERMITTED), 51 [this](MessageParcel &data, MessageParcel &reply) { return OnIsChangePermitted(data, reply); } }, 52 { static_cast<uint32_t>(WallpaperServiceIpcInterfaceCode::IS_OPERATION_ALLOWED), 53 [this](MessageParcel &data, MessageParcel &reply) { return OnIsOperationAllowed(data, reply); } }, 54 { static_cast<uint32_t>(WallpaperServiceIpcInterfaceCode::RESET_WALLPAPER), 55 [this](MessageParcel &data, MessageParcel &reply) { return OnResetWallpaper(data, reply); } }, 56 { static_cast<uint32_t>(WallpaperServiceIpcInterfaceCode::REGISTER_CALLBACK), 57 [this](MessageParcel &data, MessageParcel &reply) { return OnRegisterWallpaperCallback(data, reply); } }, 58 { static_cast<uint32_t>(WallpaperServiceIpcInterfaceCode::SET_WALLPAPER_V9), 59 [this](MessageParcel &data, MessageParcel &reply) { return OnSetWallpaperV9(data, reply); } }, 60 { static_cast<uint32_t>(WallpaperServiceIpcInterfaceCode::GET_PIXELMAP_V9), 61 [this](MessageParcel &data, MessageParcel &reply) { return OnGetPixelMapV9(data, reply); } }, 62 { static_cast<uint32_t>(WallpaperServiceIpcInterfaceCode::GET_COLORS_V9), 63 [this](MessageParcel &data, MessageParcel &reply) { return OnGetColorsV9(data, reply); } }, 64 { static_cast<uint32_t>(WallpaperServiceIpcInterfaceCode::RESET_WALLPAPER_V9), 65 [this](MessageParcel &data, MessageParcel &reply) { return OnResetWallpaperV9(data, reply); } }, 66 { static_cast<uint32_t>(WallpaperServiceIpcInterfaceCode::SET_VIDEO), 67 [this](MessageParcel &data, MessageParcel &reply) { return OnSetVideo(data, reply); } }, 68 { static_cast<uint32_t>(WallpaperServiceIpcInterfaceCode::SET_CUSTOM), 69 [this](MessageParcel &data, MessageParcel &reply) { return OnSetCustomWallpaper(data, reply); } }, 70 { static_cast<uint32_t>(WallpaperServiceIpcInterfaceCode::SEND_EVENT), 71 [this](MessageParcel &data, MessageParcel &reply) { return OnSendEvent(data, reply); } }, 72 { static_cast<uint32_t>(WallpaperServiceIpcInterfaceCode::SET_WALLPAPER_PIXELMAP), 73 [this](MessageParcel &data, MessageParcel &reply) { return OnSetWallpaperByPixelMap(data, reply); } }, 74 { static_cast<uint32_t>(WallpaperServiceIpcInterfaceCode::SET_WALLPAPER_PIXELMAP_V9), 75 [this](MessageParcel &data, MessageParcel &reply) { return OnSetWallpaperV9ByPixelMap(data, reply); } }, 76 }; 77} 78 79WallpaperServiceStub::~WallpaperServiceStub() 80{ 81} 82 83int32_t WallpaperServiceStub::OnRemoteRequest( 84 uint32_t code, MessageParcel &data, MessageParcel &reply, MessageOption &option) 85{ 86 MemoryGuard cacheGuard; 87 std::u16string myDescriptor = WallpaperServiceStub::GetDescriptor(); 88 std::u16string remoteDescriptor = data.ReadInterfaceToken(); 89 if (myDescriptor != remoteDescriptor) { 90 HILOG_ERROR("Remote descriptor not the same as local descriptor."); 91 return E_CHECK_DESCRIPTOR_ERROR; 92 } 93 return HandleWallpaperRequest(code, data, reply, option); 94} 95 96WallpaperRequestHandler WallpaperServiceStub::GetWallpaperRequestHandler(uint32_t code) 97{ 98 auto it = requestHandlers.find(code); 99 if (it != requestHandlers.end()) { 100 return it->second; 101 } 102 return nullptr; 103} 104 105int32_t WallpaperServiceStub::HandleWallpaperRequest( 106 uint32_t code, MessageParcel &data, MessageParcel &reply, MessageOption &option) 107{ 108 WallpaperRequestHandler handler = GetWallpaperRequestHandler(code); 109 if (handler) { 110 return handler(data, reply); 111 } 112 HILOG_ERROR("remote request unhandled: %{public}d", code); 113 return IPCObjectStub::OnRemoteRequest(code, data, reply, option); 114} 115 116int32_t WallpaperServiceStub::OnSetWallpaper(MessageParcel &data, MessageParcel &reply) 117{ 118 return OnSetWallpaperInner(data, reply, false); 119} 120 121int32_t WallpaperServiceStub::OnSetWallpaperV9(MessageParcel &data, MessageParcel &reply) 122{ 123 return OnSetWallpaperInner(data, reply, true); 124} 125 126int32_t WallpaperServiceStub::OnSetWallpaperInner(MessageParcel &data, MessageParcel &reply, bool isSystemApi) 127{ 128 HILOG_DEBUG("WallpaperServiceStub::SetWallpaper start."); 129 int32_t fd = data.ReadFileDescriptor(); 130 if (fd < 0) { 131 HILOG_ERROR("ReadFileDescriptor fail. fd[%{public}d]", fd); 132 return IPC_STUB_INVALID_DATA_ERR; 133 } 134 int32_t wallpaperType = data.ReadInt32(); 135 int32_t length = data.ReadInt32(); 136 ErrorCode wallpaperErrorCode = E_UNKNOWN; 137 if (isSystemApi) { 138 wallpaperErrorCode = SetWallpaperV9(fd, wallpaperType, length); 139 } else { 140 wallpaperErrorCode = SetWallpaper(fd, wallpaperType, length); 141 } 142 close(fd); 143 if (!reply.WriteInt32(static_cast<int32_t>(wallpaperErrorCode))) { 144 HILOG_ERROR("WriteInt32 fail!"); 145 return IPC_STUB_WRITE_PARCEL_ERR; 146 } 147 return ERR_NONE; 148} 149 150int32_t WallpaperServiceStub::OnSetWallpaperByPixelMap(MessageParcel &data, MessageParcel &reply) 151{ 152 return OnSetWallpaperInnerByPixelMap(data, reply, false); 153} 154 155int32_t WallpaperServiceStub::OnSetWallpaperV9ByPixelMap(MessageParcel &data, MessageParcel &reply) 156{ 157 return OnSetWallpaperInnerByPixelMap(data, reply, true); 158} 159 160int32_t WallpaperServiceStub::OnSetWallpaperInnerByPixelMap(MessageParcel &data, MessageParcel &reply, bool isSystemApi) 161{ 162 HILOG_DEBUG("WallpaperServiceStub::SetWallpaper start."); 163 int32_t vectorPixelMapSize = data.ReadInt32(); 164 if (vectorPixelMapSize <= 0) { 165 HILOG_ERROR("ReadInt32 fail!"); 166 return IPC_STUB_INVALID_DATA_ERR; 167 } 168 auto *rawData = (uint8_t *)data.ReadRawData(vectorPixelMapSize); 169 if (rawData == nullptr) { 170 HILOG_ERROR("ReadRawData fail!"); 171 return IPC_STUB_INVALID_DATA_ERR; 172 } 173 std::vector<uint8_t> VectorPixelMap(rawData, rawData + vectorPixelMapSize); 174 int32_t wallpaperType = data.ReadInt32(); 175 std::shared_ptr<OHOS::Media::PixelMap> pixelMap = VectorToPixelMap(VectorPixelMap); 176 if (pixelMap == nullptr) { 177 HILOG_ERROR("VectorToPixelMap fail!"); 178 return IPC_STUB_INVALID_DATA_ERR; 179 } 180 ErrorCode wallpaperErrorCode = E_UNKNOWN; 181 if (isSystemApi) { 182 wallpaperErrorCode = SetWallpaperV9ByPixelMap(pixelMap, wallpaperType); 183 } else { 184 wallpaperErrorCode = SetWallpaperByPixelMap(pixelMap, wallpaperType); 185 } 186 if (!reply.WriteInt32(static_cast<int32_t>(wallpaperErrorCode))) { 187 HILOG_ERROR("WriteInt32 fail!"); 188 return IPC_STUB_WRITE_PARCEL_ERR; 189 } 190 return ERR_NONE; 191} 192 193int32_t WallpaperServiceStub::OnGetPixelMap(MessageParcel &data, MessageParcel &reply) 194{ 195 return OnGetPixelMapInner(data, reply, false); 196} 197 198int32_t WallpaperServiceStub::OnSetVideo(MessageParcel &data, MessageParcel &reply) 199{ 200 HILOG_DEBUG("WallpaperServiceStub::OnSetVideo start."); 201 int32_t fd = data.ReadFileDescriptor(); 202 int32_t wallpaperType = data.ReadInt32(); 203 int32_t length = data.ReadInt32(); 204 ErrorCode wallpaperErrorCode = SetVideo(fd, wallpaperType, length); 205 close(fd); 206 if (!reply.WriteInt32(static_cast<int32_t>(wallpaperErrorCode))) { 207 HILOG_ERROR("Write int is failed!"); 208 return IPC_STUB_WRITE_PARCEL_ERR; 209 } 210 return ERR_NONE; 211} 212 213int32_t WallpaperServiceStub::OnSetCustomWallpaper(MessageParcel &data, MessageParcel &reply) 214{ 215 HILOG_DEBUG("WallpaperServiceStub::SetCustomWallpaper start."); 216 auto fd = data.ReadFileDescriptor(); 217 int32_t wallpaperType = data.ReadInt32(); 218 int32_t length = data.ReadInt32(); 219 ErrorCode wallpaperErrorCode = SetCustomWallpaper(fd, wallpaperType, length); 220 close(fd); 221 if (!reply.WriteInt32(static_cast<int32_t>(wallpaperErrorCode))) { 222 HILOG_ERROR("Write int is failed!"); 223 return IPC_STUB_WRITE_PARCEL_ERR; 224 } 225 return ERR_NONE; 226} 227 228int32_t WallpaperServiceStub::OnGetPixelMapV9(MessageParcel &data, MessageParcel &reply) 229{ 230 return OnGetPixelMapInner(data, reply, true); 231} 232 233int32_t WallpaperServiceStub::OnGetPixelMapInner(MessageParcel &data, MessageParcel &reply, bool isSystemApi) 234{ 235 HILOG_DEBUG("WallpaperServiceStub::GetPixelMap start."); 236 int32_t wallpaperType = data.ReadInt32(); 237 IWallpaperService::FdInfo fdInfo; 238 ErrorCode wallpaperErrorCode = E_UNKNOWN; 239 if (isSystemApi) { 240 wallpaperErrorCode = GetPixelMapV9(wallpaperType, fdInfo); 241 } else { 242 wallpaperErrorCode = GetPixelMap(wallpaperType, fdInfo); 243 } 244 HILOG_INFO(" OnGetPixelMap wallpaperErrorCode = %{public}d", wallpaperErrorCode); 245 if (!reply.WriteInt32(static_cast<int32_t>(wallpaperErrorCode))) { 246 HILOG_ERROR("WriteInt32 fail!"); 247 close(fdInfo.fd); 248 return IPC_STUB_WRITE_PARCEL_ERR; 249 } 250 if (wallpaperErrorCode == E_OK) { 251 if (!reply.WriteInt32(fdInfo.size)) { 252 HILOG_ERROR("WriteInt32 fail!"); 253 close(fdInfo.fd); 254 return IPC_STUB_WRITE_PARCEL_ERR; 255 } 256 if (!reply.WriteFileDescriptor(fdInfo.fd)) { 257 HILOG_ERROR("WriteFileDescriptor fail!"); 258 close(fdInfo.fd); 259 return IPC_STUB_WRITE_PARCEL_ERR; 260 } 261 } 262 close(fdInfo.fd); 263 return ERR_NONE; 264} 265 266int32_t WallpaperServiceStub::OnGetColors(MessageParcel &data, MessageParcel &reply) 267{ 268 return OnGetColorsInner(data, reply, false); 269} 270 271int32_t WallpaperServiceStub::OnGetColorsV9(MessageParcel &data, MessageParcel &reply) 272{ 273 return OnGetColorsInner(data, reply, true); 274} 275 276int32_t WallpaperServiceStub::OnGetColorsInner(MessageParcel &data, MessageParcel &reply, bool isSystemApi) 277{ 278 HILOG_DEBUG("WallpaperServiceStub::OnGetColors start."); 279 int32_t wallpaperType = data.ReadInt32(); 280 std::vector<uint64_t> vecWallpaperColors; 281 ErrorCode wallpaperErrorCode = E_UNKNOWN; 282 if (isSystemApi) { 283 wallpaperErrorCode = GetColorsV9(wallpaperType, vecWallpaperColors); 284 } else { 285 wallpaperErrorCode = GetColors(wallpaperType, vecWallpaperColors); 286 } 287 auto size = vecWallpaperColors.size(); 288 if (!reply.WriteInt32(static_cast<int32_t>(wallpaperErrorCode))) { 289 HILOG_ERROR("WriteInt32 fail!"); 290 return IPC_STUB_WRITE_PARCEL_ERR; 291 } 292 if (wallpaperErrorCode == E_OK) { 293 if (!reply.WriteUInt64Vector(vecWallpaperColors)) { 294 HILOG_ERROR("WallpaperServiceStub::OnGetColors WriteUInt64Vector error!"); 295 return IPC_STUB_WRITE_PARCEL_ERR; 296 } 297 } 298 return (size == 0) ? IPC_STUB_INVALID_DATA_ERR : ERR_NONE; 299} 300 301int32_t WallpaperServiceStub::OnGetFile(MessageParcel &data, MessageParcel &reply) 302{ 303 HILOG_DEBUG("WallpaperServiceStub::OnGetFile start."); 304 int32_t wallpaperType = data.ReadInt32(); 305 int32_t wallpaperFd = INVALID_FD; 306 ErrorCode wallpaperErrorCode = GetFile(wallpaperType, wallpaperFd); 307 if (!reply.WriteInt32(static_cast<int32_t>(wallpaperErrorCode))) { 308 HILOG_ERROR("WriteInt32 fail!"); 309 if (wallpaperFd > INVALID_FD) { 310 close(wallpaperFd); 311 } 312 return IPC_STUB_WRITE_PARCEL_ERR; 313 } 314 if (wallpaperErrorCode == E_OK && !reply.WriteFileDescriptor(wallpaperFd)) { 315 HILOG_ERROR("WriteFileDescriptor fail!"); 316 close(wallpaperFd); 317 return IPC_STUB_WRITE_PARCEL_ERR; 318 } 319 if (wallpaperFd > INVALID_FD) { 320 close(wallpaperFd); 321 } 322 return ERR_NONE; 323} 324 325int32_t WallpaperServiceStub::OnGetWallpaperId(MessageParcel &data, MessageParcel &reply) 326{ 327 HILOG_DEBUG("WallpaperServiceStub::OnGetWallpaperId start."); 328 int32_t wallpaperType = data.ReadInt32(); 329 int32_t wallpaperId = GetWallpaperId(wallpaperType); 330 if (!reply.WriteInt32(wallpaperId)) { 331 HILOG_ERROR("Write result data failed!"); 332 return IPC_STUB_WRITE_PARCEL_ERR; 333 } 334 HILOG_INFO("End. Id[%{public}d]", wallpaperId); 335 return ERR_NONE; 336} 337 338int32_t WallpaperServiceStub::OnIsChangePermitted(MessageParcel &data, MessageParcel &reply) 339{ 340 HILOG_DEBUG("WallpaperServiceStub::OnIsChangePermitted start."); 341 auto bResult = IsChangePermitted(); 342 if (!reply.WriteBool(bResult)) { 343 HILOG_ERROR("Write result data failed!"); 344 return IPC_STUB_WRITE_PARCEL_ERR; 345 } 346 return ERR_NONE; 347} 348 349int32_t WallpaperServiceStub::OnIsOperationAllowed(MessageParcel &data, MessageParcel &reply) 350{ 351 HILOG_DEBUG("WallpaperServiceStub::OnIsOperationAllowed start."); 352 auto bResult = IsOperationAllowed(); 353 if (!reply.WriteBool(bResult)) { 354 HILOG_ERROR("Write result data failed!"); 355 return IPC_STUB_WRITE_PARCEL_ERR; 356 } 357 return ERR_NONE; 358} 359 360int32_t WallpaperServiceStub::OnResetWallpaper(MessageParcel &data, MessageParcel &reply) 361{ 362 return OnResetWallpaperInner(data, reply, false); 363} 364 365int32_t WallpaperServiceStub::OnResetWallpaperV9(MessageParcel &data, MessageParcel &reply) 366{ 367 return OnResetWallpaperInner(data, reply, true); 368} 369 370int32_t WallpaperServiceStub::OnResetWallpaperInner(MessageParcel &data, MessageParcel &reply, bool isSystemApi) 371{ 372 HILOG_DEBUG("WallpaperServiceStub::OnResetWallpaper start."); 373 int32_t wallpaperType = data.ReadInt32(); 374 ErrorCode wallpaperErrorCode = E_UNKNOWN; 375 if (isSystemApi) { 376 wallpaperErrorCode = ResetWallpaperV9(wallpaperType); 377 } else { 378 wallpaperErrorCode = ResetWallpaper(wallpaperType); 379 } 380 if (!reply.WriteInt32(static_cast<int32_t>(wallpaperErrorCode))) { 381 HILOG_ERROR("Write result data failed!"); 382 return IPC_STUB_WRITE_PARCEL_ERR; 383 } 384 return ERR_NONE; 385} 386 387int32_t WallpaperServiceStub::OnWallpaperOn(MessageParcel &data, MessageParcel &reply) 388{ 389 HILOG_DEBUG("WallpaperServiceStub::OnWallpaperOn in."); 390 std::string type = data.ReadString(); 391 if (type.empty()) { 392 HILOG_ERROR("OnWallpaperOn type is empty after ipc."); 393 return IPC_STUB_INVALID_DATA_ERR; 394 } 395 sptr<IRemoteObject> remote = data.ReadRemoteObject(); 396 if (remote == nullptr) { 397 HILOG_ERROR("OnWallpaperOn nullptr after ipc."); 398 return IPC_STUB_INVALID_DATA_ERR; 399 } 400 401 sptr<IWallpaperEventListener> wallpaperListenerProxy = iface_cast<IWallpaperEventListener>(remote); 402 ErrorCode errorCode = On(type, std::move(wallpaperListenerProxy)); 403 int32_t ret = static_cast<int32_t>(errorCode); 404 if (!reply.WriteInt32(ret)) { 405 HILOG_ERROR("WriteInt32 failed!"); 406 return IPC_STUB_WRITE_PARCEL_ERR; 407 } 408 return ERR_NONE; 409} 410 411int32_t WallpaperServiceStub::OnWallpaperOff(MessageParcel &data, MessageParcel &reply) 412{ 413 HILOG_DEBUG("WallpaperServiceStub::OnWallpaperOff in."); 414 std::string type = data.ReadString(); 415 if (type.empty()) { 416 HILOG_ERROR("OnWallpaperOff type is empty after ipc."); 417 return IPC_STUB_INVALID_DATA_ERR; 418 } 419 sptr<IRemoteObject> remote = data.ReadRemoteObject(); 420 ErrorCode errorCode = E_UNKNOWN; 421 if (remote == nullptr) { 422 errorCode = Off(type, nullptr); 423 } else { 424 sptr<IWallpaperEventListener> wallpaperListenerProxy = iface_cast<IWallpaperEventListener>(remote); 425 errorCode = Off(type, std::move(wallpaperListenerProxy)); 426 } 427 int32_t ret = static_cast<int32_t>(errorCode); 428 if (!reply.WriteInt32(ret)) { 429 HILOG_ERROR("WriteInt32 failed!"); 430 return IPC_STUB_WRITE_PARCEL_ERR; 431 } 432 return ERR_NONE; 433} 434 435int32_t WallpaperServiceStub::OnSendEvent(MessageParcel &data, MessageParcel &reply) 436{ 437 HILOG_DEBUG("WallpaperServiceStub::OnSendEvent start."); 438 std::string eventType = data.ReadString(); 439 auto result = SendEvent(eventType); 440 if (!reply.WriteInt32(result)) { 441 HILOG_ERROR("Write int is failed!"); 442 return IPC_STUB_WRITE_PARCEL_ERR; 443 } 444 return ERR_NONE; 445} 446 447int32_t WallpaperServiceStub::OnRegisterWallpaperCallback(MessageParcel &data, MessageParcel &reply) 448{ 449 HILOG_DEBUG("WallpaperServiceStub::OnRegisterWallpaperCallback start."); 450 sptr<IRemoteObject> object = data.ReadRemoteObject(); 451 bool status = false; 452 if (object == nullptr) { 453 HILOG_ERROR("RegisterWallpaperCallback failed!"); 454 return IPC_STUB_INVALID_DATA_ERR; 455 } 456 sptr<IWallpaperCallback> callbackProxy = iface_cast<IWallpaperCallback>(object); 457 458 status = RegisterWallpaperCallback(callbackProxy); 459 int32_t ret = status ? static_cast<int32_t>(E_OK) : static_cast<int32_t>(E_DEAL_FAILED); 460 if (!reply.WriteInt32(ret)) { 461 HILOG_ERROR("WriteInt32 failed!"); 462 return IPC_STUB_WRITE_PARCEL_ERR; 463 } 464 return ERR_NONE; 465} 466 467std::shared_ptr<OHOS::Media::PixelMap> WallpaperServiceStub::VectorToPixelMap(std::vector<std::uint8_t> value) 468{ 469 HILOG_DEBUG("VectorToPixelMap start.!"); 470 if (value.size() == 0) { 471 return nullptr; 472 } 473 return std::shared_ptr<PixelMap>(PixelMap::DecodeTlv(value)); 474} 475} // namespace WallpaperMgrService 476} // namespace OHOS