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 #include "camera_service_client.h"
16 #include "media_log.h"
17 #include "samgr_lite.h"
18 #include "camera_type.h"
19 #include "camera_manager.h"
20 #include "meta_data.h"
21 #include "camera_client.h"
22
23 #include <string>
24 #include <cstdio>
25
26 using namespace std;
27 namespace OHOS {
28 namespace Media {
29 static IpcObjectStub objectStub_;
30
GetInstance()31 CameraServiceClient *CameraServiceClient::GetInstance()
32 {
33 static CameraServiceClient client;
34 return &client;
35 }
36
CameraServiceClient()37 CameraServiceClient::CameraServiceClient()
38 {
39 cameraClient_ = CameraClient::GetInstance();
40 }
41
~CameraServiceClient()42 CameraServiceClient::~CameraServiceClient()
43 {
44 if (para_ != nullptr) {
45 delete para_;
46 para_ = nullptr;
47 }
48 }
49
InitCameraServiceClient(CameraServiceCallback * callback)50 void CameraServiceClient::InitCameraServiceClient(CameraServiceCallback *callback)
51 {
52 if (callback == nullptr) {
53 MEDIA_INFO_LOG("Camera client initialize fail,empty callback.");
54 return;
55 }
56 cameraServiceCb_ = callback;
57 if (cameraClient_->InitCameraClient()) {
58 MEDIA_INFO_LOG("Camera client initialize success.");
59 proxy_ = cameraClient_->GetIClientProxy();
60 list<string> cameraList = CameraServiceClient::GetInstance()->GetCameraIdList();
61 cameraServiceCb_->OnCameraServiceInitialized(cameraList);
62 }
63 }
64
Callback(void * owner,int code,IpcIo * reply)65 int CameraServiceClient::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_GET_CAMERA_ABILITY: {
77 CameraServiceClient *client = static_cast<CameraServiceClient*>(para->data);
78 // Get supported resolution.
79 uint32_t supportProperties;
80 ReadUint32(reply, &supportProperties);
81 uint32_t listSize;
82 ReadUint32(reply, &listSize);
83 list<CameraPicSize> supportSizeList;
84 for (uint32_t i = 0; i < listSize; i++) {
85 CameraPicSize *cameraPicSize = static_cast<CameraPicSize*>(ReadRawData(reply, sizeof(CameraPicSize)));
86 if (cameraPicSize != nullptr) {
87 supportSizeList.emplace_back(*cameraPicSize);
88 }
89 }
90 // Get supported AfModes.
91 uint32_t afListSize;
92 ReadUint32(reply, &afListSize);
93 list<int32_t> afModeList;
94 for (uint32_t i = 0; i < afListSize; i++) {
95 int32_t temp;
96 ReadInt32(reply, &temp);
97 afModeList.emplace_back(temp);
98 }
99 // Get supported AeModes.
100 uint32_t aeListSize;
101 ReadUint32(reply, &aeListSize);
102 list<int32_t> aeModeList;
103 for (uint32_t i = 0; i < aeListSize; i++) {
104 int32_t temp;
105 ReadInt32(reply, &temp);
106 aeModeList.emplace_back(temp);
107 }
108
109 CameraAbility *cameraAbility = new (nothrow) CameraAbility;
110 if (cameraAbility != nullptr) {
111 cameraAbility->SetParameterRange(CAM_IMAGE_YUV420, supportSizeList);
112 cameraAbility->SetParameterRange(CAM_FORMAT_JPEG, supportSizeList);
113 cameraAbility->SetParameterRange(CAM_FORMAT_H264, supportSizeList);
114 cameraAbility->SetParameterRange(CAM_FORMAT_H265, supportSizeList);
115 cameraAbility->SetParameterRange(CAM_AF_MODE, afModeList);
116 cameraAbility->SetParameterRange(CAM_AE_MODE, aeModeList);
117 client->deviceAbilityMap_.insert(
118 pair<string, CameraAbility *>(client->cameraIdForAbility, cameraAbility));
119 } else {
120 MEDIA_ERR_LOG("Callback : cameraAbility construct failed.");
121 }
122 break;
123 }
124 case CAMERA_SERVER_GET_CAMERA_INFO: {
125 CameraServiceClient *client = static_cast<CameraServiceClient*>(para->data);
126 int32_t cameraType;
127 int32_t cameraFacingType;
128 ReadInt32(reply, &cameraType);
129 ReadInt32(reply, &cameraFacingType);
130 CameraInfo *cameraInfo = new (nothrow) CameraInfoImpl(cameraType, cameraFacingType);
131 if (cameraInfo != nullptr) {
132 client->deviceInfoMap_.insert(pair<string, CameraInfo*>(client->cameraIdForInfo, cameraInfo));
133 } else {
134 MEDIA_ERR_LOG("Callback : cameraAbility construct failed.");
135 }
136 break;
137 }
138 case CAMERA_SERVER_GET_CAMERAIDLIST: {
139 CameraServiceClient *client = static_cast<CameraServiceClient*>(para->data);
140 uint32_t listSize;
141 ReadUint32(reply, &listSize);
142 for (uint32_t i = 0; i < listSize; i++) {
143 size_t sz;
144 string cameraId((const char*)(ReadString(reply, &sz)));
145 client->list_.emplace_back(cameraId);
146 MEDIA_INFO_LOG("Callback : cameraId %s", cameraId.c_str());
147 }
148 break;
149 }
150 case CAMERA_SERVER_GET_CAMERA_MODE_NUM: {
151 CameraServiceClient *client = static_cast<CameraServiceClient*>(para->data);
152 ReadUint8(reply, &client->cameraModeNum);
153 break;
154 }
155 case CAMERA_SERVER_SET_CAMERA_MODE_NUM: {
156 CameraServiceClient *client = static_cast<CameraServiceClient*>(para->data);
157 ReadInt32(reply, &client->ret_);
158 break;
159 }
160 default:
161 MEDIA_ERR_LOG("unsupport funcId.");
162 break;
163 }
164 return 0;
165 }
166
GetCameraIdList()167 list<string> CameraServiceClient::GetCameraIdList()
168 {
169 if (list_.empty()) {
170 IpcIo io;
171 uint8_t tmpData[DEFAULT_IPC_SIZE];
172 IpcIoInit(&io, tmpData, DEFAULT_IPC_SIZE, 0);
173 CallBackPara para = {};
174 para.funcId = CAMERA_SERVER_GET_CAMERAIDLIST;
175 para.data = this;
176 uint32_t ret = proxy_->Invoke(proxy_, CAMERA_SERVER_GET_CAMERAIDLIST, &io, ¶, Callback);
177 if (ret != 0) {
178 MEDIA_ERR_LOG("Get cameraId list ipc transmission failed. (ret=%d)", ret);
179 }
180 }
181 return list_;
182 }
183
GetCameraModeNum()184 uint8_t CameraServiceClient::GetCameraModeNum()
185 {
186 IpcIo io;
187 uint8_t tmpData[DEFAULT_IPC_SIZE];
188 IpcIoInit(&io, tmpData, DEFAULT_IPC_SIZE, 0);
189 CallBackPara para = {};
190 para.funcId = CAMERA_SERVER_GET_CAMERA_MODE_NUM;
191 para.data = this;
192 uint32_t ret = proxy_->Invoke(proxy_, CAMERA_SERVER_GET_CAMERA_MODE_NUM, &io, ¶, Callback);
193 if (ret != 0) {
194 MEDIA_ERR_LOG("Get camera mode num failed. (ret=%d)", ret);
195 }
196 return this->cameraModeNum;
197 }
198
GetCameraAbility(string & cameraId)199 CameraAbility *CameraServiceClient::GetCameraAbility(string &cameraId)
200 {
201 std::map<string, CameraAbility*>::iterator iter = deviceAbilityMap_.find(cameraId);
202 if (iter != deviceAbilityMap_.end()) {
203 return iter->second;
204 }
205 cameraIdForAbility = cameraId;
206 IpcIo io;
207 uint8_t tmpData[DEFAULT_IPC_SIZE];
208 IpcIoInit(&io, tmpData, DEFAULT_IPC_SIZE, 0);
209 WriteString(&io, cameraId.c_str());
210 CallBackPara para = {};
211 para.funcId = CAMERA_SERVER_GET_CAMERA_ABILITY;
212 para.data = this;
213
214 // wait for callback.
215 uint32_t ret = proxy_->Invoke(proxy_, CAMERA_SERVER_GET_CAMERA_ABILITY, &io, ¶, Callback);
216 if (ret != 0) {
217 MEDIA_ERR_LOG("Get camera ability ipc transmission failed. (ret=%d)", ret);
218 }
219 // find cameraAbility again.
220 iter = deviceAbilityMap_.find(cameraId);
221 if (iter != deviceAbilityMap_.end()) {
222 return iter->second;
223 }
224 MEDIA_ERR_LOG("Get cameraAbility of camera %s from cameraService failed", cameraId.c_str());
225 return nullptr;
226 }
227
GetCameraInfo(string & cameraId)228 CameraInfo *CameraServiceClient::GetCameraInfo(string &cameraId)
229 {
230 std::map<string, CameraInfo*>::iterator iter = deviceInfoMap_.find(cameraId);
231 if (iter != deviceInfoMap_.end()) {
232 return iter->second;
233 }
234 cameraIdForInfo = cameraId;
235 IpcIo io;
236 uint8_t tmpData[DEFAULT_IPC_SIZE];
237 IpcIoInit(&io, tmpData, DEFAULT_IPC_SIZE, 0);
238 WriteString(&io, cameraId.c_str());
239 CallBackPara para = {};
240 para.funcId = CAMERA_SERVER_GET_CAMERA_INFO;
241 para.data = this;
242 // wait for callback.
243 uint32_t ret = proxy_->Invoke(proxy_, CAMERA_SERVER_GET_CAMERA_INFO, &io, ¶, Callback);
244 if (ret != 0) {
245 MEDIA_ERR_LOG("Get camera info ipc transmission failed. (ret=%d)", ret);
246 }
247
248 iter = deviceInfoMap_.find(cameraId);
249 if (iter != deviceInfoMap_.end()) {
250 return iter->second;
251 }
252 MEDIA_ERR_LOG("Get cameraInfo of camera %s from cameraService failed", cameraId.c_str());
253 return nullptr;
254 }
255
ServiceClientCallback(uint32_t code,IpcIo * data,IpcIo * reply,MessageOption option)256 int32_t CameraServiceClient::ServiceClientCallback(uint32_t code, IpcIo *data, IpcIo *reply, MessageOption option)
257 {
258 if (option.args == nullptr) {
259 MEDIA_ERR_LOG("call back error, option.args is null\n");
260 return MEDIA_ERR;
261 }
262 CallBackPara* para = static_cast<CallBackPara *>(option.args);
263 CameraServiceClient *client = static_cast<CameraServiceClient*>(para->data);
264 MEDIA_INFO_LOG("ServiceClientCallback, funcId=%d", code);
265 switch (code) {
266 case ON_CAMERA_STATUS_CHANGE: {
267 int status;
268 ReadInt32(data, &status);
269 CameraServiceCallback::CameraStatus cameraStatus =
270 static_cast<CameraServiceCallback::CameraStatus>(status);
271 string cameraId = para->cameraId;
272 client->cameraServiceCb_->OnCameraStatusChange(cameraId, cameraStatus);
273 break;
274 }
275 default: {
276 MEDIA_ERR_LOG("unsupport funId\n");
277 break;
278 }
279 }
280 return MEDIA_OK;
281 }
282
SetCameraMode(uint8_t modeIndex)283 int32_t CameraServiceClient::SetCameraMode(uint8_t modeIndex)
284 {
285 IpcIo io;
286 uint8_t tmpData[DEFAULT_IPC_SIZE];
287 IpcIoInit(&io, tmpData, DEFAULT_IPC_SIZE, 0);
288 WriteUint8(&io, modeIndex);
289 CallBackPara para = {};
290 para.funcId = CAMERA_SERVER_SET_CAMERA_MODE_NUM;
291 para.data = this;
292 uint32_t ret = proxy_->Invoke(proxy_, CAMERA_SERVER_SET_CAMERA_MODE_NUM, &io, ¶, Callback);
293 if (ret != 0) {
294 MEDIA_ERR_LOG("Set camera mode failed.(ret=%d)", ret);
295 return ret;
296 }
297 return this->ret_;
298 }
299
CreateCamera(string cameraId)300 void CameraServiceClient::CreateCamera(string cameraId)
301 {
302 para_ = new (nothrow) CallBackPara;
303 if (para_ == nullptr) {
304 MEDIA_ERR_LOG("para_ is null, failed.");
305 return;
306 }
307 para_->cameraId = cameraId;
308 para_->data = this;
309 para_->funcId = CAMERA_SERVER_CREATE_CAMERA;
310
311 objectStub_.func = CameraServiceClient::ServiceClientCallback;
312 objectStub_.args = (void*)para_;
313 objectStub_.isRemote = false;
314 sid_.handle = IPC_INVALID_HANDLE;
315 sid_.token = SERVICE_TYPE_ANONYMOUS;
316 sid_.cookie = reinterpret_cast<uintptr_t>(&objectStub_);
317
318 IpcIo io;
319 uint8_t tmpData[DEFAULT_IPC_SIZE];
320 IpcIoInit(&io, tmpData, DEFAULT_IPC_SIZE, 1);
321 WriteString(&io, cameraId.c_str());
322 bool writeRemote = WriteRemoteObject(&io, &sid_);
323 if (!writeRemote) {
324 return;
325 }
326 uint32_t ans = proxy_->Invoke(proxy_, CAMERA_SERVER_CREATE_CAMERA, &io, para_, Callback);
327 if (ans != 0) {
328 MEDIA_ERR_LOG("Create camera ipc transmission failed. (ret=%d)", ans);
329 }
330 }
331 } // namespace Media
332 } // namespace OHOS
333