• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 }