1 /*
2 * Copyright (C) 2024 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 "picture_handle_service.h"
17
18 #include <cstdlib>
19 #include <fcntl.h>
20 #include <libexif/exif-entry.h>
21 #include <securec.h>
22 #include <sys/mman.h>
23 #include <unistd.h>
24
25 #include "ashmem.h"
26 #include "exif_metadata.h"
27 #include "image_type.h"
28 #include "metadata.h"
29 #include "medialibrary_errno.h"
30 #include "medialibrary_photo_operations.h"
31 #include "media_log.h"
32
33 namespace OHOS {
34 namespace Media {
35
OpenPicture(const std::string & fileId,int32_t & fd)36 bool PictureHandlerService::OpenPicture(const std::string &fileId, int32_t &fd)
37 {
38 MEDIA_DEBUG_LOG("PictureHandlerService OpenPicture fileId: %{public}s", fileId.c_str());
39 MessageParcel data;
40 // 辅图数量
41 uint32_t auxiliaryPictureSize = 0;
42 WritePicture(std::atoi(fileId.c_str()), data, auxiliaryPictureSize);
43
44 uint32_t dataSize = data.GetDataSize();
45
46 // 消息长度
47 uint32_t msgLen = 0;
48 msgLen += UINT32_LEN; // msgLen长度
49 msgLen += UINT32_LEN; // dataSize长度
50 msgLen += UINT32_LEN; // auxiliaryPictureSize长度
51 msgLen += dataSize; // data长度
52
53 // 封装消息
54 MessageParcel msgParcel;
55 msgParcel.WriteUint32(msgLen);
56 MEDIA_DEBUG_LOG("PictureHandlerService::OpenPicture msgLen: %{public}d", msgLen);
57 msgParcel.WriteUint32(dataSize);
58 MEDIA_DEBUG_LOG("PictureHandlerService::OpenPicture dataSize: %{public}d", dataSize);
59 msgParcel.WriteUint32(auxiliaryPictureSize);
60 MEDIA_DEBUG_LOG("PictureHandlerService::OpenPicture auxiliaryPictureSize: %{public}d", auxiliaryPictureSize);
61 msgParcel.WriteBuffer((void*)data.GetData(), dataSize);
62
63 // 创建共享内存
64 std::string name = PICTURE_ASHMEM_NAME + fileId;
65 fd = AshmemCreate(name.c_str(), msgParcel.GetDataSize());
66 MEDIA_DEBUG_LOG("PictureHandlerService::OpenPicture fd: %{public}d", fd);
67 CHECK_AND_RETURN_RET_LOG(fd >= 0, false,
68 "PictureHandlerService::OpenPicture AshmemCreate failed, name: %{public}s, fd: %{public}d", name.c_str(), fd);
69
70 int result = AshmemSetProt(fd, PROT_READ | PROT_WRITE);
71 if (result < 0) {
72 MEDIA_ERR_LOG("PictureHandlerService::OpenPicture AshmemSetProt failed, result: %{public}d", result);
73 close(fd);
74 return false;
75 }
76
77 void *addr = mmap(nullptr, msgParcel.GetDataSize(), PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
78 if (addr == MAP_FAILED) {
79 MEDIA_ERR_LOG("PictureHandlerService::OpenPicture mmap failed!");
80 close(fd);
81 return false;
82 }
83
84 if (memcpy_s(addr, msgParcel.GetDataSize(), (void*)msgParcel.GetData(), msgParcel.GetDataSize())) {
85 MEDIA_ERR_LOG("PictureHandlerService::OpenPicture memcpy_s failed!");
86 close(fd);
87 munmap(addr, msgParcel.GetDataSize());
88 return false;
89 }
90 munmap(addr, msgParcel.GetDataSize());
91 MEDIA_INFO_LOG("PictureHandlerService::OpenPicture end");
92 return true;
93 }
94
WritePicture(const int32_t & fileId,MessageParcel & data,uint32_t & auxiliaryPictureSize)95 bool PictureHandlerService::WritePicture(const int32_t &fileId, MessageParcel &data,
96 uint32_t &auxiliaryPictureSize)
97 {
98 MEDIA_DEBUG_LOG("PictureHandlerService WritePicture enter, fileId: %{public}d", fileId);
99 std::shared_ptr<Media::Picture> picture;
100 std::string photoId;
101 bool isHighQualityPicture = false;
102 int32_t ret = MediaLibraryPhotoOperations::GetPicture(fileId, picture, false, photoId, isHighQualityPicture);
103 CHECK_AND_RETURN_RET_LOG(ret == E_OK, false,
104 "PictureHandlerService::GetPicture picture is not exist, fileId: %{public}d", fileId);
105
106 std::shared_ptr<PixelMap> mainPixel = picture->GetMainPixel();
107 CHECK_AND_RETURN_RET_LOG(mainPixel != nullptr, false,
108 "PictureHandlerService::GetPicture mainPixel is not exist, fileId: %{public}d", fileId);
109
110 WritePixelMap(data, mainPixel);
111
112 WriteExifMetadata(data, picture);
113 WriteMaintenanceData(data, picture);
114
115 for (size_t i = 0; i <= AUXILIARY_PICTURE_TYPE_COUNT; i++) {
116 if (!picture->HasAuxiliaryPicture(static_cast<AuxiliaryPictureType>(i))) {
117 continue;
118 }
119 AuxiliaryPictureType type = static_cast<AuxiliaryPictureType>(i);
120 MEDIA_DEBUG_LOG("PictureHandlerService::WriteAuxiliaryPicture type: %{public}d", type);
121 std::shared_ptr<AuxiliaryPicture> auxiliaryPicture = picture->GetAuxiliaryPicture(
122 static_cast<AuxiliaryPictureType>(i));
123 if (auxiliaryPicture == nullptr) {
124 MEDIA_DEBUG_LOG("PictureHandlerService::WritePicture auxiliaryPicture is null, type: %{public}d", type);
125 continue;
126 }
127
128 auxiliaryPictureSize ++;
129 WriteAuxiliaryPicture(data, auxiliaryPicture);
130 }
131 return true;
132 }
133
WritePixelMap(MessageParcel & data,std::shared_ptr<PixelMap> & pixelMap)134 bool PictureHandlerService::WritePixelMap(MessageParcel &data, std::shared_ptr<PixelMap> &pixelMap)
135 {
136 WriteProperties(data, pixelMap);
137 MEDIA_DEBUG_LOG("PictureHandlerService WritePixelMap write surface buffer");
138 WriteSurfaceBuffer(data, pixelMap);
139 return true;
140 }
141
WriteProperties(MessageParcel & data,std::shared_ptr<PixelMap> & pixelMap)142 bool PictureHandlerService::WriteProperties(MessageParcel &data, std::shared_ptr<PixelMap> &pixelMap)
143 {
144 bool isYuv = false;
145 WriteImageInfo(data, pixelMap, isYuv);
146 MEDIA_DEBUG_LOG("PictureHandlerService::WriteProperties isYuv:%{public}d", isYuv);
147 data.WriteBool(isYuv);
148 if (isYuv) {
149 WriteYuvDataInfo(data, pixelMap);
150 }
151 MEDIA_DEBUG_LOG("PictureHandlerService::WriteProperties editable:%{public}d", pixelMap->IsEditable());
152 data.WriteBool(pixelMap->IsEditable());
153 return true;
154 }
155
WriteImageInfo(MessageParcel & data,std::shared_ptr<PixelMap> & pixelMap,bool & isYuv)156 bool PictureHandlerService::WriteImageInfo(MessageParcel &data, std::shared_ptr<PixelMap> &pixelMap, bool &isYuv)
157 {
158 ImageInfo imageInfo;
159 pixelMap->GetImageInfo(imageInfo);
160
161 MEDIA_DEBUG_LOG("PictureHandlerService::WriteImageInfo width: %{public}d", imageInfo.size.width);
162 data.WriteInt32(imageInfo.size.width);
163
164 MEDIA_DEBUG_LOG("PictureHandlerService::WriteImageInfo height: %{public}d", imageInfo.size.height);
165 data.WriteInt32(imageInfo.size.height);
166
167 MEDIA_DEBUG_LOG("PictureHandlerService::WriteImageInfo pixelFormat: %{public}d", imageInfo.pixelFormat);
168 data.WriteInt32(static_cast<int32_t>(imageInfo.pixelFormat));
169 isYuv = (imageInfo.pixelFormat == PixelFormat::NV21 || imageInfo.pixelFormat == PixelFormat::NV12);
170
171 MEDIA_DEBUG_LOG("PictureHandlerService::WriteImageInfo colorSpace: %{public}d", imageInfo.colorSpace);
172 data.WriteInt32(static_cast<int32_t>(imageInfo.colorSpace));
173
174 MEDIA_DEBUG_LOG("PictureHandlerService::WriteImageInfo alphaType: %{public}d", imageInfo.alphaType);
175 data.WriteInt32(static_cast<int32_t>(imageInfo.alphaType));
176
177 MEDIA_DEBUG_LOG("PictureHandlerService::WriteImageInfo baseDensity: %{public}d", imageInfo.baseDensity);
178 data.WriteInt32(imageInfo.baseDensity);
179 return true;
180 }
181
WriteYuvDataInfo(MessageParcel & data,std::shared_ptr<PixelMap> & pixelMap)182 bool PictureHandlerService::WriteYuvDataInfo(MessageParcel &data, std::shared_ptr<PixelMap> &pixelMap)
183 {
184 YUVDataInfo yuvInfo;
185 pixelMap->GetImageYUVInfo(yuvInfo);
186
187 MEDIA_DEBUG_LOG("PictureHandlerService::WriteYuvDataInfo width: %{public}d", yuvInfo.imageSize.width);
188 data.WriteInt32(static_cast<int32_t>(yuvInfo.imageSize.width));
189
190 MEDIA_DEBUG_LOG("PictureHandlerService::WriteYuvDataInfo height: %{public}d", yuvInfo.imageSize.height);
191 data.WriteInt32(static_cast<int32_t>(yuvInfo.imageSize.height));
192
193 MEDIA_DEBUG_LOG("PictureHandlerService::WriteYuvDataInfo yWidth: %{public}d", yuvInfo.yWidth);
194 data.WriteInt32(static_cast<int32_t>(yuvInfo.yWidth));
195
196 MEDIA_DEBUG_LOG("PictureHandlerService::WriteYuvDataInfo yHeight: %{public}d", yuvInfo.yHeight);
197 data.WriteInt32(static_cast<int32_t>(yuvInfo.yHeight));
198
199 MEDIA_DEBUG_LOG("PictureHandlerService::WriteYuvDataInfo uvWidth: %{public}d", yuvInfo.uvWidth);
200 data.WriteInt32(static_cast<int32_t>(yuvInfo.uvWidth));
201
202 MEDIA_DEBUG_LOG("PictureHandlerService::WriteYuvDataInfo uvHeight: %{public}d", yuvInfo.uvHeight);
203 data.WriteInt32(static_cast<int32_t>(yuvInfo.uvHeight));
204
205 MEDIA_DEBUG_LOG("PictureHandlerService::WriteYuvDataInfo yStride: %{public}d", yuvInfo.yStride);
206 data.WriteInt32(static_cast<int32_t>(yuvInfo.yStride));
207
208 MEDIA_DEBUG_LOG("PictureHandlerService::WriteYuvDataInfo uStride: %{public}d", yuvInfo.uStride);
209 data.WriteInt32(static_cast<int32_t>(yuvInfo.uStride));
210
211 MEDIA_DEBUG_LOG("PictureHandlerService::WriteYuvDataInfo vStride: %{public}d", yuvInfo.vStride);
212 data.WriteInt32(static_cast<int32_t>(yuvInfo.vStride));
213
214 MEDIA_DEBUG_LOG("PictureHandlerService::WriteYuvDataInfo uvStride: %{public}d", yuvInfo.uvStride);
215 data.WriteInt32(static_cast<int32_t>(yuvInfo.uvStride));
216
217 MEDIA_DEBUG_LOG("PictureHandlerService::WriteYuvDataInfo yOffset: %{public}d", yuvInfo.yOffset);
218 data.WriteInt32(static_cast<int32_t>(yuvInfo.yOffset));
219
220 MEDIA_DEBUG_LOG("PictureHandlerService::WriteYuvDataInfo uOffset: %{public}d", yuvInfo.uOffset);
221 data.WriteInt32(static_cast<int32_t>(yuvInfo.uOffset));
222
223 MEDIA_DEBUG_LOG("PictureHandlerService::WriteYuvDataInfo vOffset: %{public}d", yuvInfo.vOffset);
224 data.WriteInt32(static_cast<int32_t>(yuvInfo.vOffset));
225
226 MEDIA_DEBUG_LOG("PictureHandlerService::WriteYuvDataInfo uvOffset: %{public}d", yuvInfo.uvOffset);
227 data.WriteInt32(static_cast<int32_t>(yuvInfo.uvOffset));
228
229 return true;
230 }
231
WriteSurfaceBuffer(MessageParcel & data,std::shared_ptr<PixelMap> & pixelMap)232 bool PictureHandlerService::WriteSurfaceBuffer(MessageParcel &data, std::shared_ptr<PixelMap> &pixelMap)
233 {
234 // surfaceBuffer 序列化
235 SurfaceBuffer *surfaceBuffer = reinterpret_cast<SurfaceBuffer*> (pixelMap->GetFd());
236 if (surfaceBuffer == nullptr) {
237 MEDIA_DEBUG_LOG("PictureHandlerService::WriteSurfaceBuffer surfaceBuffer is null");
238 return false;
239 }
240
241 BufferHandle *handle = surfaceBuffer->GetBufferHandle();
242 bool hasBufferHandle = (handle != nullptr);
243 MEDIA_DEBUG_LOG("PictureHandlerService::WriteSurfaceBuffer hasBufferHandle: %{public}d", hasBufferHandle);
244 data.WriteBool(hasBufferHandle);
245 CHECK_AND_RETURN_RET(hasBufferHandle, false);
246 return WriteBufferHandler(data, *handle);
247 }
248
WriteBufferHandler(MessageParcel & data,BufferHandle & handle)249 bool PictureHandlerService ::WriteBufferHandler(MessageParcel &data, BufferHandle &handle)
250 {
251 MEDIA_DEBUG_LOG("PictureHandlerService::WriteBufferHandler reserveFds: %{public}d", handle.reserveFds);
252 data.WriteUint32(handle.reserveFds);
253
254 MEDIA_DEBUG_LOG("PictureHandlerService::WriteBufferHandler reserveInts: %{public}d", handle.reserveInts);
255 data.WriteUint32(handle.reserveInts);
256
257 MEDIA_DEBUG_LOG("PictureHandlerService::WriteBufferHandler width: %{public}d", handle.width);
258 data.WriteInt32(handle.width);
259
260 MEDIA_DEBUG_LOG("PictureHandlerService::WriteBufferHandler stride: %{public}d", handle.stride);
261 data.WriteInt32(handle.stride);
262
263 MEDIA_DEBUG_LOG("PictureHandlerService::WriteBufferHandler height: %{public}d", handle.height);
264 data.WriteInt32(handle.height);
265
266 MEDIA_DEBUG_LOG("PictureHandlerService::WriteBufferHandler size: %{public}d", handle.size);
267 data.WriteInt32(handle.size);
268
269 MEDIA_DEBUG_LOG("PictureHandlerService::WriteBufferHandler format: %{public}d", handle.format);
270 data.WriteInt32(handle.format);
271
272 data.WriteUint64(handle.usage);
273
274 data.WriteUint64(handle.phyAddr);
275
276 MEDIA_DEBUG_LOG("PictureHandlerService::WriteBufferHandler fd: %{public}d.", handle.fd);
277 data.WriteInt32(handle.fd);
278
279 for (uint32_t i = 0; i < handle.reserveFds; i++) {
280 MEDIA_DEBUG_LOG("PictureHandlerService::WriteBufferHandler reserve[%{public}d]: %{public}d",
281 i, handle.reserve[i]);
282 data.WriteInt32(handle.reserve[i]);
283 }
284 for (uint32_t j = 0; j < handle.reserveInts; j++) {
285 data.WriteInt32(handle.reserve[handle.reserveFds + j]);
286 }
287
288 return true;
289 }
290
WriteExifMetadata(MessageParcel & data,std::shared_ptr<Media::Picture> & picture)291 bool PictureHandlerService::WriteExifMetadata(MessageParcel &data, std::shared_ptr<Media::Picture> &picture)
292 {
293 // 序列化ExifMetadata
294 std::shared_ptr<ExifMetadata> exifMetadata = picture->GetExifMetadata();
295 bool hasExifMetadata = (exifMetadata != nullptr);
296 MEDIA_DEBUG_LOG("PictureHandlerService WriteExifMetadata hasExifMetadata :%{public}d", hasExifMetadata);
297 data.WriteBool(hasExifMetadata);
298 CHECK_AND_RETURN_RET(hasExifMetadata, true);
299 return exifMetadata->Marshalling(data);
300 }
301
WriteMaintenanceData(MessageParcel & data,std::shared_ptr<Media::Picture> & picture)302 bool PictureHandlerService::WriteMaintenanceData(MessageParcel &data, std::shared_ptr<Media::Picture> &picture)
303 {
304 sptr<SurfaceBuffer> surfaceBuffer = picture->GetMaintenanceData();
305 bool hasMaintenanceData = (surfaceBuffer != nullptr);
306 MEDIA_DEBUG_LOG("PictureHandlerService WriteMaintenanceData hasMaintenanceData :%{public}d", hasMaintenanceData);
307 data.WriteBool(hasMaintenanceData);
308 CHECK_AND_RETURN_RET(hasMaintenanceData, true);
309 BufferHandle *handle = surfaceBuffer->GetBufferHandle();
310 return WriteBufferHandler(data, *handle);
311 }
312
WriteAuxiliaryPicture(MessageParcel & data,std::shared_ptr<AuxiliaryPicture> & auxiliaryPicture)313 bool PictureHandlerService::WriteAuxiliaryPicture(MessageParcel &data,
314 std::shared_ptr<AuxiliaryPicture> &auxiliaryPicture)
315 {
316 MEDIA_DEBUG_LOG("PictureHandlerService WriteAuxiliaryPicture enter");
317
318 WriteAuxiliaryPictureInfo(data, auxiliaryPicture);
319
320 std::shared_ptr<PixelMap> pixelMap = auxiliaryPicture->GetContentPixel();
321 if (pixelMap != nullptr) {
322 WritePixelMap(data, pixelMap);
323 }
324
325 WriteAuxiliaryMetadata(data, auxiliaryPicture);
326
327 return true;
328 }
329
WriteAuxiliaryPictureInfo(MessageParcel & data,std::shared_ptr<AuxiliaryPicture> & auxiliaryPicture)330 bool PictureHandlerService::WriteAuxiliaryPictureInfo(MessageParcel &data,
331 std::shared_ptr<AuxiliaryPicture> &auxiliaryPicture)
332 {
333 AuxiliaryPictureInfo auxiliaryPictureInfo = auxiliaryPicture->GetAuxiliaryPictureInfo();
334
335 MEDIA_DEBUG_LOG("PictureHandlerService::WriteAuxiliaryPictureInfo auxiliaryPictureType: %{public}d",
336 auxiliaryPictureInfo.auxiliaryPictureType);
337 data.WriteInt32(static_cast<int32_t>(auxiliaryPictureInfo.auxiliaryPictureType));
338
339 MEDIA_DEBUG_LOG("PictureHandlerService::WriteAuxiliaryPictureInfo colorSpace: %{public}d",
340 auxiliaryPictureInfo.colorSpace);
341 data.WriteInt32(static_cast<int32_t>(auxiliaryPictureInfo.colorSpace));
342
343 MEDIA_DEBUG_LOG("PictureHandlerService::WriteAuxiliaryPictureInfo pixelFormat: %{public}d",
344 auxiliaryPictureInfo.pixelFormat);
345 data.WriteInt32(static_cast<int32_t>(auxiliaryPictureInfo.pixelFormat));
346
347 MEDIA_DEBUG_LOG("PictureHandlerService::WriteAuxiliaryPictureInfo rowStride: %{public}d",
348 auxiliaryPictureInfo.rowStride);
349 data.WriteInt32(auxiliaryPictureInfo.rowStride);
350
351 MEDIA_DEBUG_LOG("PictureHandlerService::WriteAuxiliaryPictureInfo height: %{public}d",
352 auxiliaryPictureInfo.size.height);
353 data.WriteInt32(auxiliaryPictureInfo.size.height);
354
355 MEDIA_DEBUG_LOG("PictureHandlerService::WriteAuxiliaryPictureInfo width: %{public}d",
356 auxiliaryPictureInfo.size.width);
357 data.WriteInt32(auxiliaryPictureInfo.size.width);
358
359 return true;
360 }
361
WriteAuxiliaryMetadata(MessageParcel & data,std::shared_ptr<AuxiliaryPicture> & auxiliaryPicture)362 bool PictureHandlerService::WriteAuxiliaryMetadata(MessageParcel &data,
363 std::shared_ptr<AuxiliaryPicture> &auxiliaryPicture)
364 {
365 int32_t metadataSize = 0;
366 bool hasExif = auxiliaryPicture->HasMetadata(MetadataType::EXIF);
367 bool hasFragment = auxiliaryPicture->HasMetadata(MetadataType::FRAGMENT);
368 if (hasExif) {
369 metadataSize ++;
370 }
371 if (hasFragment) {
372 metadataSize ++;
373 }
374 MEDIA_DEBUG_LOG("PictureHandlerService::WriteAuxiliaryMetadata metadataSize: %{public}d", metadataSize);
375 data.WriteInt32(metadataSize);
376 if (hasExif) {
377 data.WriteInt32(static_cast<int32_t>(MetadataType::EXIF));
378 if (auxiliaryPicture->GetMetadata(MetadataType::EXIF) != nullptr) {
379 auxiliaryPicture->GetMetadata(MetadataType::EXIF)->Marshalling(data);
380 }
381 }
382 if (hasFragment) {
383 data.WriteInt32(static_cast<int32_t>(MetadataType::FRAGMENT));
384 if (auxiliaryPicture->GetMetadata(MetadataType::FRAGMENT) != nullptr) {
385 auxiliaryPicture->GetMetadata(MetadataType::FRAGMENT)->Marshalling(data);
386 }
387 }
388 return true;
389 }
390
RequestBufferHandlerFd(const std::string fd)391 int32_t PictureHandlerService::RequestBufferHandlerFd(const std::string fd)
392 {
393 MEDIA_DEBUG_LOG("PictureHandlerService RequestBufferHandlerFd fd: %{public}s", fd.c_str());
394 int dupFd = dup(std::atoi(fd.c_str()));
395 MEDIA_DEBUG_LOG("PictureHandlerService::RequestBufferHandlerFd dupFd: %{public}d", dupFd);
396 return dupFd;
397 }
398 }
399 }