1 /*
2 * Copyright (c) 2020-2021 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_device_client.h"
17 #include "serializer.h"
18 #include "camera_type.h"
19 #include "media_log.h"
20 #include "camera_config.h"
21 #include "frame_config.h"
22 #include "surface.h"
23 #include "surface_impl.h"
24 #include "camera_impl.h"
25
26 #include <list>
27
28 using namespace std;
29 namespace OHOS {
30 namespace Media {
31 static IpcObjectStub objectStub_;
32
GetInstance()33 CameraDeviceClient *CameraDeviceClient::GetInstance()
34 {
35 static CameraDeviceClient client;
36 return &client;
37 }
38
CameraDeviceClient()39 CameraDeviceClient::CameraDeviceClient()
40 {
41 cameraClient_ = CameraClient::GetInstance();
42 if (cameraClient_->InitCameraClient()) {
43 proxy_ = cameraClient_->GetIClientProxy();
44 }
45 }
46
~CameraDeviceClient()47 CameraDeviceClient::~CameraDeviceClient()
48 {
49 if (para_ != nullptr) {
50 delete para_;
51 para_ = nullptr;
52 }
53 }
54
SetCameraId(string & cameraId)55 void CameraDeviceClient::SetCameraId(string &cameraId)
56 {
57 cameraId_ = cameraId;
58 }
59
SetCameraImpl(CameraImpl * cameraImpl)60 void CameraDeviceClient::SetCameraImpl(CameraImpl *cameraImpl)
61 {
62 cameraImpl_ = cameraImpl;
63 }
64
Callback(void * owner,int code,IpcIo * reply)65 int CameraDeviceClient::Callback(void* owner, int code, IpcIo *reply)
66 {
67 if (code != 0) {
68 MEDIA_ERR_LOG("Callback error. (code=%d)", code);
69 return -1;
70 }
71 if (owner == nullptr) {
72 return -1;
73 }
74 CallBackPara* para = (CallBackPara*)owner;
75 switch (para->funcId) {
76 case CAMERA_SERVER_SET_CAMERA_CALLBACK:
77 MEDIA_INFO_LOG("Camera server set callback success.");
78 break;
79 default:
80 break;
81 }
82 return 0;
83 }
84
SetCameraConfig(CameraConfig & cc)85 int32_t CameraDeviceClient::SetCameraConfig(CameraConfig &cc)
86 {
87 IpcIo io;
88 uint8_t tmpData[DEFAULT_IPC_SIZE];
89 IpcIoInit(&io, tmpData, DEFAULT_IPC_SIZE, 1);
90 if (cameraId_.empty()) {
91 MEDIA_ERR_LOG("no camera exist.");
92 return MEDIA_ERR;
93 }
94 WriteString(&io, cameraId_.c_str());
95 para_->data = this;
96 para_->cameraConfig = &cc;
97 CallBackPara para = {};
98 para.funcId = CAMERA_SERVER_SET_CAMERA_CONFIG;
99 para.data = this;
100 uint32_t ret = proxy_->Invoke(proxy_, CAMERA_SERVER_SET_CAMERA_CONFIG, &io, ¶, Callback);
101 if (ret != 0) {
102 MEDIA_ERR_LOG("Set camera config ipc transmission failed. (ret=%d)", ret);
103 return MEDIA_ERR;
104 }
105 return MEDIA_OK;
106 }
107
SerilizeFrameConfig(IpcIo & io,FrameConfig & fc,uint32_t maxSurfaceNum)108 int32_t SerilizeFrameConfig(IpcIo &io, FrameConfig &fc, uint32_t maxSurfaceNum)
109 {
110 WriteInt32(&io, fc.GetFrameConfigType());
111 list<Surface*> surfaceList = fc.GetSurfaces();
112 if (maxSurfaceNum < surfaceList.size()) {
113 MEDIA_ERR_LOG("Too many surfaces. (maxSurfaceNum=%u, sufaceNum=%d)", maxSurfaceNum, surfaceList.size());
114 return MEDIA_ERR;
115 }
116 WriteUint32(&io, surfaceList.size());
117 for (auto &surface : surfaceList) {
118 dynamic_cast<SurfaceImpl *>(surface)->WriteIoIpcIo(io);
119 MEDIA_DEBUG_LOG("Add surface");
120 }
121 int32_t qfactor = -1;
122 fc.GetParameter(PARAM_KEY_IMAGE_ENCODE_QFACTOR, qfactor);
123 WriteInt32(&io, qfactor);
124
125 int32_t streamFps = 0;
126 fc.GetParameter(CAM_FRAME_FPS, streamFps);
127 WriteInt32(&io, streamFps);
128
129 int32_t invertMode = 0;
130 fc.GetParameter(CAM_IMAGE_INVERT_MODE, invertMode);
131 WriteInt32(&io, invertMode);
132
133 CameraRect streamCrop;
134 fc.GetParameter(CAM_IMAGE_CROP_RECT, streamCrop);
135 WriteInt32(&io, streamCrop.x);
136 WriteInt32(&io, streamCrop.y);
137 WriteInt32(&io, streamCrop.w);
138 WriteInt32(&io, streamCrop.h);
139
140 int32_t format = -1;
141 fc.GetParameter(CAM_IMAGE_FORMAT, format);
142 WriteInt32(&io, format);
143 if (fc.GetFrameConfigType() != FRAME_CONFIG_RECORD) {
144 uint8_t data[PRIVATE_TAG_LEN];
145 fc.GetVendorParameter(data, sizeof(data));
146 WriteUint32(&io, (uint32_t)sizeof(data));
147 WriteBuffer(&io, (void *)data, sizeof(data));
148 }
149
150 return MEDIA_OK;
151 }
152
153
TriggerLoopingCapture(FrameConfig & fc)154 int32_t CameraDeviceClient::TriggerLoopingCapture(FrameConfig &fc)
155 {
156 IpcIo io;
157 uint8_t tmpData[DEFAULT_IPC_SIZE];
158 constexpr uint32_t maxSurfaceNum = 2; // 2 surfaces at most
159 /* serilize parameters */
160 IpcIoInit(&io, tmpData, DEFAULT_IPC_SIZE, maxSurfaceNum);
161 if (cameraId_.empty()) {
162 MEDIA_ERR_LOG("no camera exist.");
163 return MEDIA_ERR;
164 }
165 WriteString(&io, cameraId_.c_str());
166 if (SerilizeFrameConfig(io, fc, maxSurfaceNum) != MEDIA_OK) {
167 MEDIA_ERR_LOG("Serilize the frameconfig failed.");
168 return MEDIA_ERR;
169 }
170 para_->data = this;
171 CallBackPara para = {};
172 para.funcId = CAMERA_SERVER_TRIGGER_LOOPING_CAPTURE;
173 para.data = this;
174 uint32_t ret = proxy_->Invoke(proxy_, CAMERA_SERVER_TRIGGER_LOOPING_CAPTURE, &io, ¶, Callback);
175 if (ret != 0) {
176 MEDIA_ERR_LOG("Trigger looping capture ipc transmission failed. (ret=%d)", ret);
177 return MEDIA_ERR;
178 }
179 return ret_;
180 }
181
TriggerSingleCapture(FrameConfig & fc)182 int32_t CameraDeviceClient::TriggerSingleCapture(FrameConfig &fc)
183 {
184 IpcIo io;
185 uint8_t tmpData[DEFAULT_IPC_SIZE];
186 constexpr uint32_t maxSurfaceNum = 2; // 2 surfaces at most
187 IpcIoInit(&io, tmpData, DEFAULT_IPC_SIZE, maxSurfaceNum);
188
189 if (cameraId_.empty()) {
190 MEDIA_ERR_LOG("no camera exist.");
191 return MEDIA_ERR;
192 }
193 WriteString(&io, cameraId_.c_str());
194 if (SerilizeFrameConfig(io, fc, maxSurfaceNum) != MEDIA_OK) {
195 MEDIA_ERR_LOG("Serilize the frameconfig failed.");
196 return MEDIA_ERR;
197 }
198 para_->frameConfig = &fc;
199 para_->data = this;
200 CallBackPara para = {};
201 para.funcId = CAMERA_SERVER_TRIGGER_SINGLE_CAPTURE;
202 para.data = this;
203 uint32_t ret = proxy_->Invoke(proxy_, CAMERA_SERVER_TRIGGER_SINGLE_CAPTURE, &io, ¶, Callback);
204 if (ret != 0) {
205 MEDIA_ERR_LOG("Trigger single capture ipc transmission failed. (ret=%d)", ret);
206 return MEDIA_ERR;
207 }
208 return ret_;
209 }
210
StopLoopingCapture(int32_t type)211 void CameraDeviceClient::StopLoopingCapture(int32_t type)
212 {
213 IpcIo io;
214 uint8_t tmpData[DEFAULT_IPC_SIZE];
215 IpcIoInit(&io, tmpData, DEFAULT_IPC_SIZE, 0);
216 if (cameraId_.empty()) {
217 MEDIA_ERR_LOG("no camera exist.");
218 return;
219 }
220 WriteString(&io, cameraId_.c_str());
221 WriteInt32(&io, type);
222 CallBackPara para = {};
223 para.funcId = CAMERA_SERVER_STOP_LOOPING_CAPTURE;
224 para.data = this;
225 uint32_t ret = proxy_->Invoke(proxy_, CAMERA_SERVER_STOP_LOOPING_CAPTURE, &io, ¶, Callback);
226 if (ret != 0) {
227 MEDIA_ERR_LOG("Stop Looping capture ipc transmission failed. (ret=%d)", ret);
228 }
229 }
230
Release()231 void CameraDeviceClient::Release()
232 {
233 IpcIo io;
234 uint8_t tmpData[DEFAULT_IPC_SIZE];
235 IpcIoInit(&io, tmpData, DEFAULT_IPC_SIZE, 1);
236 if (cameraId_.empty()) {
237 MEDIA_ERR_LOG("no camera exist.");
238 return;
239 }
240 if (proxy_ == nullptr) {
241 return;
242 }
243 WriteString(&io, cameraId_.c_str());
244 bool writeRemote = WriteRemoteObject(&io, &sid_);
245 if (!writeRemote) {
246 return;
247 }
248 para_->data = this;
249 CallBackPara para = {};
250 para.funcId = CAMERA_SERVER_CLOSE_CAMERA;
251 para.data = this;
252 uint32_t ret = proxy_->Invoke(proxy_, CAMERA_SERVER_CLOSE_CAMERA, &io, ¶, Callback);
253 if (ret != 0) {
254 MEDIA_ERR_LOG("Stop Looping capture ipc transmission failed. (ret=%d)", ret);
255 }
256 }
257
SetCameraCallback()258 void CameraDeviceClient::SetCameraCallback()
259 {
260 para_ = new (nothrow) CallBackPara;
261 if (para_ == nullptr) {
262 MEDIA_ERR_LOG("para_ is null.");
263 return;
264 }
265 objectStub_.func = CameraDeviceClient::DeviceClientCallback;
266 objectStub_.args = para_;
267 objectStub_.isRemote = false;
268 sid_.handle = IPC_INVALID_HANDLE;
269 sid_.token = SERVICE_TYPE_ANONYMOUS;
270 sid_.cookie = reinterpret_cast<uintptr_t>(&objectStub_);
271
272 IpcIo io;
273 uint8_t tmpData[DEFAULT_IPC_SIZE];
274 IpcIoInit(&io, tmpData, DEFAULT_IPC_SIZE, 1);
275 bool writeRemote = WriteRemoteObject(&io, &sid_);
276 if (!writeRemote) {
277 return;
278 }
279
280 CallBackPara para = {};
281 para.funcId = CAMERA_SERVER_SET_CAMERA_CALLBACK;
282 uint32_t ans = proxy_->Invoke(proxy_, CAMERA_SERVER_SET_CAMERA_CALLBACK, &io, ¶, Callback);
283 if (ans != 0) {
284 MEDIA_ERR_LOG("Stop Looping capture ipc transmission failed. (ret=%d)", ans);
285 }
286 }
287
DeviceClientCallback(uint32_t code,IpcIo * data,IpcIo * reply,MessageOption option)288 int32_t CameraDeviceClient::DeviceClientCallback(uint32_t code, IpcIo *data, IpcIo *reply, MessageOption option)
289 {
290 if (data == nullptr) {
291 MEDIA_ERR_LOG("call back error, data is null\n");
292 return MEDIA_ERR;
293 }
294 if (option.args == nullptr) {
295 MEDIA_ERR_LOG("call back error, option.args is null\n");
296 return MEDIA_ERR;
297 }
298 CallBackPara *para = static_cast<CallBackPara *>(option.args);
299 CameraDeviceClient *client = static_cast<CameraDeviceClient*>(para->data);
300 MEDIA_INFO_LOG("DeviceCallback, funcId=%d", code);
301 switch (code) {
302 case ON_CAMERA_CONFIGURED: {
303 int32_t ret;
304 ReadInt32(data, &ret);
305 CameraConfig *cc = static_cast<CameraConfig*>(para->cameraConfig);
306 client->cameraImpl_->OnConfigured(ret, *cc);
307 break;
308 }
309 case ON_TRIGGER_SINGLE_CAPTURE_FINISHED: {
310 int32_t ret;
311 ReadInt32(data, &ret);
312 FrameConfig *fc = static_cast<FrameConfig*>(para->frameConfig);
313 client->cameraImpl_->OnFrameFinished(ret, *fc);
314 client->ret_ = ret;
315 break;
316 }
317 case ON_TRIGGER_LOOPING_CAPTURE_FINISHED: {
318 int32_t ret;
319 ReadInt32(data, &ret);
320 int32_t streamId;
321 ReadInt32(data, &streamId);
322 MEDIA_INFO_LOG("ON_TRIGGER_LOOPING_CAPTURE_FINISHED : (ret=%d, streamId=%d).", ret, streamId);
323 client->ret_ = ret;
324 break;
325 }
326 case ON_CAMERA_STATUS_CHANGE: {
327 int32_t ret;
328 ReadInt32(data, &ret);
329 MEDIA_INFO_LOG("ON_CAMERA_STATUS_CHANGE: ret=%d", ret);
330 break;
331 }
332 default: {
333 MEDIA_ERR_LOG("unsupport funId\n");
334 break;
335 }
336 }
337 return MEDIA_OK;
338 }
339 } // namespace Media
340 } // namespace OHOS
341