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, &para, 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, &para, 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, &para, 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, &para, 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, &para, 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