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 }