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