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_client.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 "exif_metadata.h"
26 #include "image_type.h"
27 #include "image_utils.h"
28 #include "medialibrary_db_const.h"
29 #include "medialibrary_errno.h"
30 #include "medialibrary_napi_utils.h"
31 #include "media_column.h"
32 #include "media_file_utils.h"
33 #include "media_log.h"
34 #include "pixel_yuv.h"
35 #include "pixel_yuv_ext.h"
36 #include "userfilemgr_uri.h"
37 #include "userfile_client.h"
38 #include <fstream>
39 
40 namespace OHOS {
41 namespace Media {
42 const int32_t MAX_VALUE = 100000000;
RequestPicture(const int32_t & fileId)43 std::shared_ptr<Media::Picture> PictureHandlerClient::RequestPicture(const int32_t &fileId)
44 {
45     MEDIA_DEBUG_LOG("PictureHandlerClient::RequestPicture fileId: %{public}d", fileId);
46     std::string uri = PhotoColumn::PHOTO_REQUEST_PICTURE;
47     MediaFileUtils::UriAppendKeyValue(uri, MediaColumn::MEDIA_ID, std::to_string(fileId));
48     Uri requestUri(uri);
49     int32_t fd = UserFileClient::OpenFile(requestUri, MEDIA_FILEMODE_READONLY);
50     if (fd < 0) {
51         MEDIA_DEBUG_LOG("PictureHandlerClient::RequestPicture picture not exist");
52         return nullptr;
53     }
54     std::shared_ptr<Media::Picture> picture = nullptr;
55     ReadPicture(fd, fileId, picture);
56     FinishRequestPicture(fileId);
57     close(fd);
58     return picture;
59 }
60 
FinishRequestPicture(const int32_t & fileId)61 void PictureHandlerClient::FinishRequestPicture(const int32_t &fileId)
62 {
63     MEDIA_DEBUG_LOG("PictureHandlerClient::FinishRequestPicture fileId: %{public}d", fileId);
64     std::string uri = PAH_FINISH_REQUEST_PICTURE;
65     MediaLibraryNapiUtils::UriAppendKeyValue(uri, API_VERSION, std::to_string(MEDIA_API_VERSION_V10));
66     Uri finishRequestPictureUri(uri);
67 
68     DataShare::DataShareValuesBucket valuesBucket;
69     valuesBucket.Put(PhotoColumn::MEDIA_ID, fileId);
70     UserFileClient::Insert(finishRequestPictureUri, valuesBucket);
71 }
72 
ReadPicture(const int32_t & fd,const int32_t & fileId,std::shared_ptr<Media::Picture> & picture)73 int32_t PictureHandlerClient::ReadPicture(const int32_t &fd, const int32_t &fileId,
74     std::shared_ptr<Media::Picture> &picture)
75 {
76     MEDIA_DEBUG_LOG("PictureHandlerClient::ReadPicture fd: %{public}d", fd);
77     // 获取消息总长度
78     void *msgLenAddr = mmap(nullptr, UINT32_LEN, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
79     uint32_t msgLen = *((uint32_t*)msgLenAddr);
80     munmap(msgLenAddr, UINT32_LEN);
81     MEDIA_DEBUG_LOG("PictureHandlerClient::ReadPicture msgLen: %{public}d", msgLen);
82 
83     // 获取消息
84     uint8_t *addr = (uint8_t*)mmap(nullptr, msgLen, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
85     uint32_t readoffset = UINT32_LEN;
86 
87     // 读取dataSize
88     uint32_t dataSize = *reinterpret_cast<const uint32_t*>(addr + readoffset);
89     readoffset += UINT32_LEN;
90     MEDIA_DEBUG_LOG("PictureHandlerClient::ReadPicture dataSize: %{public}d", dataSize);
91     if (dataSize == 0) {
92         MEDIA_DEBUG_LOG("PictureHandlerClient::ReadPicture picture is not exists");
93         munmap(addr, msgLen);
94         return E_NO_SUCH_FILE;
95     }
96 
97     // 读取auxiliaryPictureSize
98     uint32_t auxiliaryPictureSize =  *reinterpret_cast<const uint32_t*>(addr + readoffset);
99     readoffset += UINT32_LEN;
100     MEDIA_DEBUG_LOG("PictureHandlerClient::ReadPicture auxiliaryPictureSize: %{public}d",
101         auxiliaryPictureSize);
102     uint8_t *pictureParcelData = static_cast<uint8_t *>(malloc(dataSize));
103     if (pictureParcelData == nullptr) {
104         munmap(addr, msgLen);
105         return E_ERR;
106     }
107     if (memcpy_s((void*)pictureParcelData, dataSize, addr+readoffset, dataSize)) {
108         MEDIA_ERR_LOG("PictureHandlerService::ReadPicture memcpy_s pictureParcel failed!");
109         free(pictureParcelData);
110         munmap(addr, msgLen);
111         return E_ERR;
112     }
113     MessageParcel pictureParcel;
114     pictureParcel.ParseFrom(reinterpret_cast<uintptr_t>(pictureParcelData), dataSize);
115 
116     MEDIA_DEBUG_LOG("PictureHandlerClient::ReadPicture read mainPixelMap");
117     std::shared_ptr<PixelMap> mainPixelMap = ReadPixelMap(pictureParcel);
118     std::unique_ptr<Media::Picture> picturePtr = Picture::Create(mainPixelMap);
119     if (picturePtr == nullptr) {
120         MEDIA_ERR_LOG("PictureHandlerService::ReadPicture picturePtr is nullptr!");
121         munmap(addr, msgLen);
122         return E_ERR;
123     }
124 
125     ReadExifMetadata(pictureParcel, picturePtr);
126     ReadMaintenanceData(pictureParcel, picturePtr);
127 
128     for (size_t i = 1; i <= auxiliaryPictureSize; i++) {
129         MEDIA_DEBUG_LOG("PictureHandlerClient::ReadPicture read auxiliaryPicture, index:%{public}zu", i);
130         ReadAuxiliaryPicture(pictureParcel, picturePtr);
131     }
132     picture.reset(picturePtr.get());
133     picturePtr.release();
134     munmap(addr, msgLen);
135     return E_OK;
136 }
137 
ReadPixelMap(MessageParcel & data)138 std::shared_ptr<PixelMap> PictureHandlerClient::ReadPixelMap(MessageParcel &data)
139 {
140     ImageInfo imageInfo;
141     ReadImageInfo(data, imageInfo);
142 
143     bool isYuv = data.ReadBool();
144     MEDIA_DEBUG_LOG("PictureHandlerClient::ReadPixelMap isYuv:%{public}d", isYuv);
145     YUVDataInfo yuvInfo;
146     if (isYuv) {
147         ReadYuvDataInfo(data, yuvInfo);
148     }
149 
150     bool editable = data.ReadBool();
151     MEDIA_DEBUG_LOG("PictureHandlerClient::ReadPixelMap editable:%{public}d", editable);
152 
153     std::unique_ptr<PixelMap> pixelMap;
154     if (isYuv) {
155 #ifdef EXT_PIXEL
156         pixelMap = std::make_unique<PixelYuvExt>();
157 #else
158         pixelMap = std::make_unique<PixelYuv>();
159 #endif
160     } else {
161         pixelMap = std::make_unique<PixelMap>();
162     }
163     pixelMap->SetImageInfo(imageInfo);
164     pixelMap->SetImageYUVInfo(yuvInfo);
165 
166     MEDIA_DEBUG_LOG("PictureHandlerClient::ReadPixelMap read surface buffer");
167     ReadSurfaceBuffer(data, pixelMap);
168 
169     return pixelMap;
170 }
171 
ReadAuxiliaryPicture(MessageParcel & data,std::unique_ptr<Media::Picture> & picture)172 bool PictureHandlerClient::ReadAuxiliaryPicture(MessageParcel &data, std::unique_ptr<Media::Picture> &picture)
173 {
174     AuxiliaryPictureInfo auxiliaryPictureInfo;
175     ReadAuxiliaryPictureInfo(data, auxiliaryPictureInfo);
176 
177     std::shared_ptr<PixelMap> pixelMap = ReadPixelMap(data);
178     std::unique_ptr<AuxiliaryPicture> uptr = AuxiliaryPicture::Create(pixelMap,
179         auxiliaryPictureInfo.auxiliaryPictureType, auxiliaryPictureInfo.size);
180     std::shared_ptr<AuxiliaryPicture> auxiliaryPicture;
181     auxiliaryPicture.reset(uptr.get());
182     uptr.release();
183 
184     auxiliaryPicture->SetAuxiliaryPictureInfo(auxiliaryPictureInfo);
185 
186     int32_t metadataSize = 0;
187     if (data.ReadInt32(metadataSize) && metadataSize >= 0 && metadataSize < MAX_VALUE) {
188         MEDIA_DEBUG_LOG("PictureHandlerClient::ReadAuxiliaryPicture metadataSize: %{public}d", metadataSize);
189         for (int i = 0; i < metadataSize; i++) {
190             MetadataType type = static_cast<MetadataType>(data.ReadInt32());
191             MEDIA_DEBUG_LOG("PictureHandlerClient::ReadAuxiliaryPicture type: %{public}d", type);
192             std::shared_ptr<ImageMetadata> metadataPtr(nullptr);
193             metadataPtr.reset(ExifMetadata::Unmarshalling(data));
194             auxiliaryPicture->SetMetadata(type, metadataPtr);
195         }
196     } else {
197         MEDIA_ERR_LOG("PictureHandlerClient::ReadAuxiliaryPicture metadataSize failed");
198     }
199     picture->SetAuxiliaryPicture(auxiliaryPicture);
200     MEDIA_DEBUG_LOG("PictureHandler::ReadAuxiliaryPicture end");
201     return true;
202 }
203 
ReadAuxiliaryPictureInfo(MessageParcel & data,AuxiliaryPictureInfo & auxiliaryPictureInfo)204 bool PictureHandlerClient::ReadAuxiliaryPictureInfo(MessageParcel &data, AuxiliaryPictureInfo &auxiliaryPictureInfo)
205 {
206     auxiliaryPictureInfo.auxiliaryPictureType = static_cast<AuxiliaryPictureType>(data.ReadInt32());
207     MEDIA_DEBUG_LOG("PictureHandlerClient::ReadAuxiliaryPictureInfo auxiliaryPictureType: %{public}d",
208         auxiliaryPictureInfo.auxiliaryPictureType);
209 
210     auxiliaryPictureInfo.colorSpace = static_cast<ColorSpace>(data.ReadInt32());
211     MEDIA_DEBUG_LOG("PictureHandlerClient::ReadAuxiliaryPictureInfo colorSpace: %{public}d",
212         auxiliaryPictureInfo.colorSpace);
213 
214     auxiliaryPictureInfo.pixelFormat = static_cast<PixelFormat>(data.ReadInt32());
215     MEDIA_DEBUG_LOG("PictureHandlerClient::ReadAuxiliaryPictureInfo pixelFormat: %{public}d",
216         auxiliaryPictureInfo.pixelFormat);
217 
218     auxiliaryPictureInfo.rowStride = static_cast<uint32_t>(data.ReadInt32());
219     MEDIA_DEBUG_LOG("PictureHandlerClient::ReadAuxiliaryPictureInfo rowStride: %{public}d",
220         auxiliaryPictureInfo.rowStride);
221 
222     auxiliaryPictureInfo.size.height = data.ReadInt32();
223     MEDIA_DEBUG_LOG("PictureHandlerClient::ReadAuxiliaryPictureInfo height: %{public}d",
224         auxiliaryPictureInfo.size.height);
225 
226     auxiliaryPictureInfo.size.width = data.ReadInt32();
227     MEDIA_DEBUG_LOG("PictureHandlerClient::ReadAuxiliaryPictureInfo width: %{public}d",
228         auxiliaryPictureInfo.size.width);
229 
230     return true;
231 }
232 
ReadImageInfo(MessageParcel & data,ImageInfo & imageInfo)233 bool PictureHandlerClient::ReadImageInfo(MessageParcel &data, ImageInfo &imageInfo)
234 {
235     imageInfo.size.width = data.ReadInt32();
236     MEDIA_DEBUG_LOG("PictureHandlerClient::ReadImageInfo width: %{public}d", imageInfo.size.width);
237     imageInfo.size.height = data.ReadInt32();
238     MEDIA_DEBUG_LOG("PictureHandlerClient::ReadImageInfo height: %{public}d", imageInfo.size.height);
239     imageInfo.pixelFormat = static_cast<PixelFormat>(data.ReadInt32());
240     MEDIA_DEBUG_LOG("PictureHandlerClient::ReadImageInfo pixelFormat: %{public}d", imageInfo.pixelFormat);
241     imageInfo.colorSpace = static_cast<ColorSpace>(data.ReadInt32());
242     MEDIA_DEBUG_LOG("PictureHandlerClient::ReadImageInfo colorSpace: %{public}d", imageInfo.colorSpace);
243     imageInfo.alphaType = static_cast<AlphaType>(data.ReadInt32());
244     MEDIA_DEBUG_LOG("PictureHandlerClient::ReadImageInfo alphaType: %{public}d", imageInfo.alphaType);
245     imageInfo.baseDensity = data.ReadInt32();
246     MEDIA_DEBUG_LOG("PictureHandlerClient::ReadImageInfo baseDensity: %{public}d", imageInfo.baseDensity);
247     return true;
248 }
249 
ReadYuvDataInfo(MessageParcel & data,YUVDataInfo & info)250 bool PictureHandlerClient::ReadYuvDataInfo(MessageParcel &data, YUVDataInfo &info)
251 {
252     info.imageSize.width = data.ReadInt32();
253     MEDIA_DEBUG_LOG("PictureHandlerClient::ReadYuvDataInfo width: %{public}d", info.imageSize.width);
254     info.imageSize.height = data.ReadInt32();
255     MEDIA_DEBUG_LOG("PictureHandlerClient::ReadYuvDataInfo height: %{public}d", info.imageSize.height);
256     info.yWidth = data.ReadUint32();
257     MEDIA_DEBUG_LOG("PictureHandlerClient::ReadYuvDataInfo yWidth: %{public}d", info.yWidth);
258     info.yHeight = data.ReadUint32();
259     MEDIA_DEBUG_LOG("PictureHandlerClient::ReadYuvDataInfo yHeight: %{public}d", info.yHeight);
260     info.uvWidth = data.ReadUint32();
261     MEDIA_DEBUG_LOG("PictureHandlerClient::ReadYuvDataInfo uvWidth: %{public}d", info.uvWidth);
262     info.uvHeight = data.ReadUint32();
263     MEDIA_DEBUG_LOG("PictureHandlerClient::ReadYuvDataInfo uvHeight: %{public}d", info.uvHeight);
264     info.yStride = data.ReadUint32();
265     MEDIA_DEBUG_LOG("PictureHandlerClient::ReadYuvDataInfo yStride: %{public}d", info.yStride);
266     info.uStride = data.ReadUint32();
267     MEDIA_DEBUG_LOG("PictureHandlerClient::ReadYuvDataInfo uStride: %{public}d", info.uStride);
268     info.vStride = data.ReadUint32();
269     MEDIA_DEBUG_LOG("PictureHandlerClient::ReadYuvDataInfo vStride: %{public}d", info.vStride);
270     info.uvStride = data.ReadUint32();
271     MEDIA_DEBUG_LOG("PictureHandlerClient::ReadYuvDataInfo uvStride: %{public}d", info.uvStride);
272     info.yOffset = data.ReadUint32();
273     MEDIA_DEBUG_LOG("PictureHandlerClient::ReadYuvDataInfo yOffset: %{public}d", info.yOffset);
274     info.uOffset = data.ReadUint32();
275     MEDIA_DEBUG_LOG("PictureHandlerClient::ReadYuvDataInfo uOffset: %{public}d", info.uOffset);
276     info.vOffset = data.ReadUint32();
277     MEDIA_DEBUG_LOG("PictureHandlerClient::ReadYuvDataInfo vOffset: %{public}d", info.vOffset);
278     info.uvOffset = data.ReadUint32();
279     MEDIA_DEBUG_LOG("PictureHandlerClient::ReadYuvDataInfo uvOffset: %{public}d", info.uvOffset);
280     return true;
281 }
282 
ReadSurfaceBuffer(MessageParcel & data,std::unique_ptr<PixelMap> & pixelMap)283 bool PictureHandlerClient::ReadSurfaceBuffer(MessageParcel &data, std::unique_ptr<PixelMap> &pixelMap)
284 {
285     bool hasBufferHandle = data.ReadBool();
286     MEDIA_DEBUG_LOG("PictureHandlerClient::ReadSurfaceBuffer hasBufferHandle: %{public}d", hasBufferHandle);
287     if (!hasBufferHandle) {
288         return false;
289     }
290     sptr<SurfaceBuffer> surfaceBuffer = SurfaceBuffer::Create();
291     ReadBufferHandle(data, surfaceBuffer);
292     void* nativeBuffer = surfaceBuffer.GetRefPtr();
293     OHOS::RefBase *ref = reinterpret_cast<OHOS::RefBase *>(nativeBuffer);
294     ref->IncStrongRef(ref);
295     pixelMap->SetPixelsAddr(static_cast<uint8_t*>(surfaceBuffer->GetVirAddr()), nativeBuffer,
296         pixelMap->GetByteCount(), AllocatorType::DMA_ALLOC, nullptr);
297     MEDIA_DEBUG_LOG("PictureHandlerClient::ReadSurfaceBuffer end");
298     return true;
299 }
300 
ReadBufferHandle(MessageParcel & data,sptr<SurfaceBuffer> & surfaceBuffer)301 bool PictureHandlerClient::ReadBufferHandle(MessageParcel &data, sptr<SurfaceBuffer> &surfaceBuffer)
302 {
303     uint32_t reserveFds = 0;
304     bool readReserveFdsRet = data.ReadUint32(reserveFds);
305     if (reserveFds < 0 || reserveFds > static_cast<uint32_t>(MAX_VALUE)) {
306         return false;
307     }
308     MEDIA_DEBUG_LOG("PictureHandlerClient::ReadBufferHandle reserveFds: %{public}d", reserveFds);
309     uint32_t reserveInts = 0;
310     bool reserveIntsRet = data.ReadUint32(reserveInts);
311     if (reserveInts < 0 || reserveInts > static_cast<uint32_t>(MAX_VALUE)) {
312         return false;
313     }
314     MEDIA_DEBUG_LOG("PictureHandlerClient::ReadBufferHandle reserveInts: %{public}d", reserveInts);
315 
316     size_t handleSize = sizeof(BufferHandle) + (sizeof(int32_t) * (reserveFds + reserveInts));
317     BufferHandle *handle = static_cast<BufferHandle *>(malloc(handleSize));
318     if (handle == nullptr) {
319         MEDIA_ERR_LOG("PictureHandlerClient::ReadBufferHandle malloc BufferHandle failed");
320         return false;
321     }
322     memset_s(handle, handleSize, 0, handleSize);
323 
324     handle->reserveFds = reserveFds;
325     handle->reserveInts = reserveInts;
326     handle->width = data.ReadInt32();
327     MEDIA_DEBUG_LOG("PictureHandlerClient::ReadBufferHandle width: %{public}d", handle->width);
328     handle->stride = data.ReadInt32();
329     MEDIA_DEBUG_LOG("PictureHandlerClient::ReadBufferHandle stride: %{public}d", handle->stride);
330     handle->height = data.ReadInt32();
331     MEDIA_DEBUG_LOG("PictureHandlerClient::ReadBufferHandle height: %{public}d", handle->height);
332     handle->size = data.ReadInt32();
333     MEDIA_DEBUG_LOG("PictureHandlerClient::ReadBufferHandle size: %{public}d", handle->size);
334     handle->format = data.ReadInt32();
335     MEDIA_DEBUG_LOG("PictureHandlerClient::ReadBufferHandle format: %{public}d", handle->format);
336     handle->usage = data.ReadUint64();
337     handle->phyAddr = data.ReadUint64();
338 
339     int32_t fd = RequestBufferHandlerFd(data.ReadInt32());
340     MEDIA_DEBUG_LOG("PictureHandlerClient::ReadBufferHandle fd: %{public}d", fd);
341     handle->fd = dup(fd);
342     close(fd);
343     MEDIA_DEBUG_LOG("PictureHandlerClient::ReadBufferHandle handle->fd: %{public}d", handle->fd);
344     if (readReserveFdsRet) {
345         for (uint32_t i = 0; i < reserveFds; i++) {
346             int32_t reserveFd = RequestBufferHandlerFd(data.ReadInt32());
347             MEDIA_DEBUG_LOG("PictureHandlerClient::ReadBufferHandle reserve[%{public}d]: %{public}d", i, reserveFd);
348             handle->reserve[i] = dup(reserveFd);
349             MEDIA_DEBUG_LOG("PictureHandlerClient::ReadBufferHandle handle->reserve[%{public}d]: %{public}d",
350                 i, handle->reserve[i]);
351             close(reserveFd);
352         }
353     }
354 
355     if (reserveIntsRet) {
356         for (uint32_t j = 0; j < handle->reserveInts; j++) {
357             handle->reserve[reserveFds + j] = data.ReadInt32();
358         }
359     }
360     surfaceBuffer->SetBufferHandle(handle);
361     return true;
362 }
363 
ReadExifMetadata(MessageParcel & data,std::unique_ptr<Media::Picture> & picture)364 bool PictureHandlerClient::ReadExifMetadata(MessageParcel &data, std::unique_ptr<Media::Picture> &picture)
365 {
366     bool hasExifMetadata = data.ReadBool();
367     MEDIA_DEBUG_LOG("PictureHandlerClient::ReadExifMetadata hasExifMetadata:%{public}d", hasExifMetadata);
368     if (!hasExifMetadata) {
369         return true;
370     }
371     ExifMetadata *exifMetadataPtr = ExifMetadata::Unmarshalling(data);
372     auto exifMetadata = std::shared_ptr<ExifMetadata>(exifMetadataPtr);
373     picture->SetExifMetadata(exifMetadata);
374     return true;
375 }
376 
ReadMaintenanceData(MessageParcel & data,std::unique_ptr<Media::Picture> & picture)377 bool PictureHandlerClient::ReadMaintenanceData(MessageParcel &data, std::unique_ptr<Media::Picture> &picture)
378 {
379     bool hasMaintenanceData = data.ReadBool();
380     MEDIA_DEBUG_LOG("PictureHandlerClient::ReadMaintenanceData hasMaintenanceData:%{public}d", hasMaintenanceData);
381     if (!hasMaintenanceData) {
382         return true;
383     }
384     sptr<SurfaceBuffer> surfaceBuffer = SurfaceBuffer::Create();
385     ReadBufferHandle(data, surfaceBuffer);
386     return picture->SetMaintenanceData(surfaceBuffer);
387 }
388 
RequestBufferHandlerFd(const int32_t & fd)389 int32_t PictureHandlerClient::RequestBufferHandlerFd(const int32_t &fd)
390 {
391     std::string uri = PhotoColumn::PHOTO_REQUEST_PICTURE_BUFFER;
392     MediaFileUtils::UriAppendKeyValue(uri, "fd", std::to_string(fd));
393     MEDIA_DEBUG_LOG("PictureHandlerClient::RequestBufferHandlerFd uri: %{public}s", uri.c_str());
394     Uri requestUri(uri);
395     return UserFileClient::OpenFile(requestUri, MEDIA_FILEMODE_READONLY);
396 }
397 }
398 }