1/*
2 * Copyright (c) 2020 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 "camera_server.h"
17#include <cstdio>
18#include <list>
19#include <string>
20#include "camera_device.h"
21#include "camera_service.h"
22#include "camera_type.h"
23#include "media_log.h"
24#include "meta_data.h"
25#include "surface.h"
26#include "surface_impl.h"
27#include "rpc_errno.h"
28
29using namespace std;
30namespace OHOS {
31namespace Media {
32CameraServer *CameraServer::GetInstance()
33{
34    static CameraServer server;
35    return &server;
36}
37
38void CameraServer::CameraServerRequestHandle(int funcId, void *origin, IpcIo *req, IpcIo *reply)
39{
40    switch (funcId) {
41        case CAMERA_SERVER_GET_CAMERA_ABILITY:
42            CameraServer::GetInstance()->GetCameraAbility(req, reply);
43            break;
44        case CAMERA_SERVER_GET_CAMERA_INFO:
45            CameraServer::GetInstance()->GetCameraInfo(req, reply);
46            break;
47        case CAMERA_SERVER_GET_CAMERAIDLIST:
48            CameraServer::GetInstance()->GetCameraIdList(req, reply);
49            break;
50        case CAMERA_SERVER_CREATE_CAMERA:
51            CameraServer::GetInstance()->CreateCamera(req, reply);
52            break;
53        case CAMERA_SERVER_CLOSE_CAMERA:
54            CameraServer::GetInstance()->CloseCamera(req, reply);
55            break;
56        case CAMERA_SERVER_SET_CAMERA_CONFIG:
57            CameraServer::GetInstance()->SetCameraConfig(req, reply);
58            break;
59        case CAMERA_SERVER_TRIGGER_LOOPING_CAPTURE:
60            CameraServer::GetInstance()->TriggerLoopingCapture(req, reply);
61            break;
62        case CAMERA_SERVER_STOP_LOOPING_CAPTURE:
63            CameraServer::GetInstance()->StopLoopingCapture(req, reply);
64            break;
65        case CAMERA_SERVER_TRIGGER_SINGLE_CAPTURE:
66            CameraServer::GetInstance()->TriggerSingleCapture(req, reply);
67            break;
68        case CAMERA_SERVER_SET_CAMERA_CALLBACK:
69            CameraServer::GetInstance()->SetCameraCallback(req, reply);
70            break;
71        case CAMERA_SERVER_SET_CAMERA_MODE_NUM:
72            CameraServer::GetInstance()->SetCameraMode(req, reply);
73            break;
74        case CAMERA_SERVER_GET_CAMERA_MODE_NUM:
75            CameraServer::GetInstance()->GetCameraModeNum(req, reply);
76            break;
77        default:
78            MEDIA_ERR_LOG("code not support:%d!", funcId);
79            break;
80    }
81}
82void CameraServer::InitCameraServer()
83{
84    CameraService *service = CameraService::GetInstance();
85    service->Initialize();
86}
87
88void CameraServer::GetCameraAbility(IpcIo *req, IpcIo *reply)
89{
90    size_t sz;
91    string cameraId((const char*)(ReadString(req, &sz)));
92    CameraAbility *ability = CameraService::GetInstance()->GetCameraAbility(cameraId);
93    if (ability == nullptr) {
94        return;
95    }
96    list<CameraPicSize> supportSizeList = ability->GetSupportedSizes(CAM_FORMAT_YVU420);
97    uint32_t supportProperties = 0;
98    WriteUint32(reply, supportProperties);
99    uint32_t listSize = supportSizeList.size();
100    WriteUint32(reply, listSize);
101    for (auto supportSizeItem : supportSizeList) {
102        bool ret = WriteRawData(reply, &supportSizeItem, sizeof(CameraPicSize));
103        if (!ret) {
104            return;
105        }
106    }
107    // af
108    list<int32_t> afModeList = ability->GetSupportedAfModes();
109    uint32_t afListSize = afModeList.size();
110    WriteUint32(reply, afListSize);
111    for (auto supportAfMode : afModeList) {
112        WriteInt32(reply, supportAfMode);
113    }
114    // ae
115    list<int32_t> aeModeList = ability->GetSupportedAeModes();
116    uint32_t aeListSize = aeModeList.size();
117    WriteUint32(reply, aeListSize);
118    for (auto supportAeMode : aeModeList) {
119        WriteInt32(reply, supportAeMode);
120    }
121}
122
123void CameraServer::GetCameraInfo(IpcIo *req, IpcIo *reply)
124{
125    size_t sz;
126    string cameraId((const char*)(ReadString(req, &sz)));
127    CameraInfo *info = CameraService::GetInstance()->GetCameraInfo(cameraId);
128    if (info == nullptr) {
129        return;
130    }
131    WriteInt32(reply, info->GetCameraType());
132    WriteInt32(reply, info->GetCameraFacingType());
133}
134
135void CameraServer::GetCameraIdList(IpcIo *req, IpcIo *reply)
136{
137    list<string> cameraIdList = CameraService::GetInstance()->GetCameraIdList();
138    WriteUint32(reply, cameraIdList.size());
139    for (string cameraId : cameraIdList) {
140        WriteString(reply, cameraId.c_str());
141    }
142}
143
144void CameraServer::GetCameraModeNum(IpcIo *req, IpcIo *reply)
145{
146    uint8_t num = CameraService::GetInstance()->GetCameraModeNum();
147    WriteUint8(reply, num);
148}
149
150void CameraServer::CreateCamera(IpcIo *req, IpcIo *reply)
151{
152    size_t sz;
153    string cameraId((const char*)(ReadString(req, &sz)));
154    int32_t cameraStatus = CameraService::GetInstance()->CreateCamera(cameraId);
155    SvcIdentity sid;
156    bool ret = ReadRemoteObject(req, &sid);
157    if (!ret) {
158        MEDIA_ERR_LOG("sid is null, failed.");
159        return;
160    }
161    OnCameraStatusChange(cameraStatus, &sid);
162}
163
164void CameraServer::CloseCamera(IpcIo *req, IpcIo *reply)
165{
166    size_t sz;
167    string cameraId((const char*)(ReadString(req, &sz)));
168    int32_t cameraStatus = CameraService::GetInstance()->CloseCamera(cameraId);
169    SvcIdentity sid;
170    bool ret = ReadRemoteObject(req, &sid);
171    if (!ret) {
172        MEDIA_ERR_LOG("sid is null, failed.");
173        return;
174    }
175    OnCameraStatusChange(cameraStatus, &sid);
176}
177
178void CameraServer::SetCameraConfig(IpcIo *req, IpcIo *reply)
179{
180    size_t sz;
181    string cameraId((const char*)(ReadString(req, &sz)));
182    CameraDevice *device_ = CameraService::GetInstance()->GetCameraDevice(cameraId);
183    int32_t setStatus = device_->SetCameraConfig();
184    WriteInt32(reply, setStatus);
185    OnCameraConfigured(setStatus);
186}
187
188void CameraServer::SetCameraCallback(IpcIo *req, IpcIo *reply)
189{
190    SvcIdentity sid;
191    bool ret = ReadRemoteObject(req, &sid);
192    if (!ret) {
193        MEDIA_ERR_LOG("sid is null, failed.");
194        return;
195    }
196    sid_ = sid;
197}
198
199FrameConfig *DeserializeFrameConfig(IpcIo &io)
200{
201    int32_t type;
202    ReadInt32(&io, &type);
203    auto fc = new FrameConfig(type);
204
205    uint32_t surfaceNum;
206    ReadUint32(&io, &surfaceNum);
207    for (uint32_t i = 0; i < surfaceNum; i++) {
208        Surface *surface = SurfaceImpl::GenericSurfaceByIpcIo(io);
209        if (surface == nullptr) {
210            MEDIA_ERR_LOG("Camera server receive null surface.");
211            delete fc;
212            return nullptr;
213        }
214        fc->AddSurface(*surface);
215    }
216
217    int32_t qfactor;
218    ReadInt32(&io, &qfactor);
219    if (qfactor >= 0) {
220        fc->SetParameter(PARAM_KEY_IMAGE_ENCODE_QFACTOR, qfactor);
221    }
222    int32_t streamFps = 0;
223    ReadInt32(&io, &streamFps);
224    fc->SetParameter(CAM_FRAME_FPS, streamFps);
225    int32_t invertMode = 0;
226    ReadInt32(&io, &invertMode);
227    fc->SetParameter(CAM_IMAGE_INVERT_MODE, invertMode);
228    CameraRect streamCrop;
229    ReadInt32(&io, &streamCrop.x);
230    ReadInt32(&io, &streamCrop.y);
231    ReadInt32(&io, &streamCrop.w);
232    ReadInt32(&io, &streamCrop.h);
233    fc->SetParameter(CAM_IMAGE_CROP_RECT, streamCrop);
234    int32_t streamFormat;
235    ReadInt32(&io, &streamFormat);
236    fc->SetParameter(CAM_IMAGE_FORMAT, streamFormat);
237    MEDIA_INFO_LOG("streamFormat is %d", streamFormat);
238
239    if (type != FRAME_CONFIG_RECORD) {
240        uint32_t len;
241        ReadUint32(&io, &len);
242        uint8_t *dataBuff = (uint8_t *)ReadBuffer(&io, len);
243        fc->SetVendorParameter(dataBuff, len);
244    }
245    return fc;
246}
247
248void CameraServer::SetFrameConfig(IpcIo *req, IpcIo *reply)
249{
250    size_t sz;
251    ReadString(req, &sz);
252    int32_t streamId;
253    ReadInt32(req, &streamId);
254    MEDIA_ERR_LOG("SetFrameConfig streamId(%d).", streamId);
255    FrameConfig *fc = DeserializeFrameConfig(*req);
256    if (fc == nullptr) {
257        MEDIA_ERR_LOG("Deserialize frame config failed.");
258        return;
259    }
260    delete fc;
261}
262
263
264void CameraServer::TriggerLoopingCapture(IpcIo *req, IpcIo *reply)
265{
266    size_t sz;
267    string cameraId((const char*)(ReadString(req, &sz)));
268    CameraDevice *device_ = CameraService::GetInstance()->GetCameraDevice(cameraId);
269    FrameConfig *fc = DeserializeFrameConfig(*req);
270    if (fc == nullptr) {
271        MEDIA_ERR_LOG("Deserialize frame config failed.");
272        return;
273    }
274    uint32_t streamId = 0;
275    int32_t loopingCaptureStatus = device_->TriggerLoopingCapture(*fc, &streamId);
276    OnTriggerLoopingCaptureFinished(loopingCaptureStatus, streamId);
277    delete fc;
278}
279
280void CameraServer::TriggerSingleCapture(IpcIo *req, IpcIo *reply)
281{
282    size_t sz;
283    string cameraId((const char *)(ReadString(req, &sz)));
284    CameraDevice *device_ = CameraService::GetInstance()->GetCameraDevice(cameraId);
285    FrameConfig *fc = DeserializeFrameConfig(*req);
286    if (fc == nullptr) {
287        MEDIA_ERR_LOG("Deserialize frame config failed.");
288        return;
289    }
290    uint32_t streamId = 0;
291    int32_t singleCaptureStatus = device_->TriggerSingleCapture(*fc, &streamId);
292    OnTriggerSingleCaptureFinished(singleCaptureStatus);
293    delete fc;
294}
295
296void CameraServer::StopLoopingCapture(IpcIo *req, IpcIo *reply)
297{
298    size_t sz;
299    string cameraId((const char *)(ReadString(req, &sz)));
300    CameraDevice *device_ = CameraService::GetInstance()->GetCameraDevice(cameraId);
301    if (device_ == nullptr) {
302        MEDIA_INFO_LOG("device_ is  null in camera_server.cpp!");
303        return;
304    }
305
306    int32_t type;
307    ReadInt32(req, &type);
308    device_->StopLoopingCapture(type);
309}
310
311void CameraServer::OnCameraStatusChange(int32_t ret, SvcIdentity *sid)
312{
313    IpcIo io;
314    uint8_t tmpData[DEFAULT_IPC_SIZE];
315    IpcIoInit(&io, tmpData, DEFAULT_IPC_SIZE, 0);
316    WriteInt32(&io, ret);
317    MessageOption option;
318    MessageOptionInit(&option);
319    option.flags = TF_OP_ASYNC;
320    int32_t result = SendRequest(*sid, ON_CAMERA_STATUS_CHANGE, &io, nullptr, option, nullptr);
321    if (result != ERR_NONE) {
322        MEDIA_ERR_LOG("Create camera callback : on camera status change failed.");
323    }
324}
325
326void CameraServer::OnTriggerSingleCaptureFinished(int32_t ret)
327{
328    IpcIo io;
329    uint8_t tmpData[DEFAULT_IPC_SIZE];
330    IpcIoInit(&io, tmpData, DEFAULT_IPC_SIZE, 0);
331    WriteInt32(&io, ret);
332    MessageOption option;
333    MessageOptionInit(&option);
334    option.flags = TF_OP_ASYNC;
335    int32_t result = SendRequest(sid_, ON_TRIGGER_SINGLE_CAPTURE_FINISHED, &io, nullptr, option, nullptr);
336    if (result != ERR_NONE) {
337        MEDIA_ERR_LOG("Trigger single capture callback : on trigger single capture frame finished failed.");
338        return;
339    }
340}
341
342void CameraServer::OnTriggerLoopingCaptureFinished(int32_t ret, int32_t streamId)
343{
344    IpcIo io;
345    uint8_t tmpData[DEFAULT_IPC_SIZE];
346    IpcIoInit(&io, tmpData, DEFAULT_IPC_SIZE, 0);
347    WriteInt32(&io, ret);
348    MessageOption option;
349    MessageOptionInit(&option);
350    option.flags = TF_OP_ASYNC;
351    int32_t result = SendRequest(sid_, ON_TRIGGER_LOOPING_CAPTURE_FINISHED, &io, nullptr, option, nullptr);
352    if (result != ERR_NONE) {
353        MEDIA_ERR_LOG("Trigger looping capture callback : on trigger looping capture finished failed.");
354    }
355}
356
357void CameraServer::OnCameraConfigured(int32_t ret)
358{
359    IpcIo io;
360    uint8_t tmpData[DEFAULT_IPC_SIZE];
361    IpcIoInit(&io, tmpData, DEFAULT_IPC_SIZE, 0);
362    WriteInt32(&io, ret);
363    MessageOption option;
364    MessageOptionInit(&option);
365    option.flags = TF_OP_ASYNC;
366    int32_t result = SendRequest(sid_, ON_CAMERA_CONFIGURED, &io, nullptr, option, nullptr);
367    if (result != ERR_NONE) {
368        MEDIA_ERR_LOG("Camera config callback : on trigger looping capture finished failed.");
369    }
370}
371
372void CameraServer::SetCameraMode(IpcIo *req, IpcIo *reply)
373{
374    uint8_t modeIndex;
375    ReadUint8(req, &modeIndex);
376    int32_t cameraStatus = CameraService::GetInstance()->SetCameraMode(modeIndex);
377    WriteInt32(reply, cameraStatus);
378}
379} // namespace Media
380} // namespace OHOS