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