1 /*
2  * Copyright (c) 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 "core/components/camera/large_system/camera.h"
17 
18 #include <sstream>
19 #include "base/log/log.h"
20 
21 namespace OHOS::Ace {
22 namespace {
23 
24 const char CAMERA_PARAM_TEXTURE[] = "texture";
25 const char CAMERA_OEPN_CAMERA[] = "openCamera";
26 const char CAMERA_TAKE_PHOTO[] = "takePhoto";
27 const char CAMERA_ON_TAKE_PHOTO[] = "onTakePhoto";
28 const char DEVICE_POSITION[] = "devicePosition";
29 const char CACHE_FILE_PATH[] = "cacheFilePath";
30 const char CAMERA_FLASH_MODE[] = "flashMode";
31 const char CAMERA_SET_FLASH_MODE[] = "setFlashMode";
32 const char CAMERA_PERMISSION[] = "cameraPermission";
33 const char CAMERA_BUFFER_WIDTH[] = "bufferWidth";
34 const char CAMERA_BUFFER_HEIGHT[] = "bufferHeight";
35 const char ERROR_MSG[] = "errormsg";
36 const char ERROR_CODE[] = "errorcode";
37 const char CAMERA_GRANT_RESULT[] = "grantResult";
38 const char ORIENTATION[] = "orientation";
39 const char CAMERA_PREVIEW_WIDTH[] = "preViewSizeWidth";
40 const char CAMERA_PREVIEW_HEIGHT[] = "preViewSizeHeight";
41 const char CAMERA_SET_PREVIEW_SIZE[] = "setPreViewSize";
42 const char CAMERA_QUALITY[] = "quality";
43 const char CAMERA_ON_PREPARE[] = "onPrepare";
44 const char CAMERA_CHANGE_COMPONENT_ID_FUNCTION[] = "changeCameraComponentId";
45 const char CAMERA_CHANGE_COMPONENT_ID[] = "compenentId";
46 const char CAMERA_CHANGE_TYPE[] = "changeType";
47 
48 }
49 
Release(const std::function<void (bool)> & onRelease)50 void Camera::Release(const std::function<void(bool)>& onRelease)
51 {
52     UnRegisterEvent();
53     Resource::Release(onRelease);
54 }
55 
Create(const std::function<void (int64_t)> & onCreate)56 void Camera::Create(const std::function<void(int64_t)>& onCreate)
57 {
58     auto context = context_.Upgrade();
59     if (!context) {
60         LOGE("fail to get context to create Camera");
61         return;
62     }
63 
64     auto platformTaskExecutor =
65         SingleTaskExecutor::Make(context->GetTaskExecutor(), TaskExecutor::TaskType::PLATFORM);
66 
67     platformTaskExecutor.PostTask([weak = WeakClaim(this), onCreate] {
68         auto camera = weak.Upgrade();
69         if (camera) {
70             camera->CreateCamera(onCreate);
71         }
72     }, "ArkUICameraCreate");
73 }
74 
CreateCamera(const std::function<void (int64_t)> & onCreate)75 void Camera::CreateCamera(const std::function<void(int64_t)>& onCreate)
76 {
77     auto context = context_.Upgrade();
78     if (!context) {
79         return;
80     }
81 
82     auto resRegister = context->GetPlatformResRegister();
83     if (!resRegister) {
84         LOGE("fail to get platform resRegister");
85         return;
86     }
87 
88     std::stringstream paramStream;
89     paramStream << CAMERA_PARAM_TEXTURE << PARAM_EQUALS << textureId_ << PARAM_AND << CAMERA_BUFFER_WIDTH
90                 << PARAM_EQUALS << bufferSize_.Width() << PARAM_AND << CAMERA_BUFFER_HEIGHT << PARAM_EQUALS
91                 << bufferSize_.Height();
92     std::string param = paramStream.str();
93     id_ = resRegister->CreateResource(type_, param);
94     if (id_ == INVALID_ID) {
95         LOGE("Camera: create camera fail");
96         return;
97     }
98     hash_ = MakeResourceHash();
99     if (onCreate) {
100         onCreate(id_);
101     }
102     resRegister->RegisterEvent(
103         MakeEventHash(CAMERA_ON_TAKE_PHOTO), [weak = WeakClaim(this)](const std::string& param) {
104         auto camera = weak.Upgrade();
105         if (camera) {
106             camera->OnTakePhoto(param);
107         }
108     });
109     resRegister->RegisterEvent(
110         MakeEventHash(CAMERA_PERMISSION), [weak = WeakClaim(this)](const std::string& param) {
111         auto camera = weak.Upgrade();
112         if (camera) {
113             camera->OnError(param);
114         }
115     });
116     resRegister->RegisterEvent(
117         MakeEventHash(CAMERA_ON_PREPARE), [weak = WeakClaim(this)](const std::string& param) {
118         auto camera = weak.Upgrade();
119         if (camera) {
120             camera->OnPrepare(param);
121         }
122     });
123     OpenCamera();
124 }
125 
UnRegisterEvent()126 void Camera::UnRegisterEvent()
127 {
128     auto context = context_.Upgrade();
129     if (!context) {
130         LOGE("fail to get context");
131         return;
132     }
133     auto resRegister = context->GetPlatformResRegister();
134     if (resRegister == nullptr) {
135         return;
136     }
137     resRegister->UnregisterEvent(MakeEventHash(CAMERA_ON_TAKE_PHOTO));
138     resRegister->UnregisterEvent(MakeEventHash(CAMERA_PERMISSION));
139     resRegister->UnregisterEvent(MakeEventHash(CAMERA_ON_PREPARE));
140 }
141 
AddTakePhotoListener(TakePhotoListener && listener)142 void Camera::AddTakePhotoListener(TakePhotoListener&& listener)
143 {
144     auto context = context_.Upgrade();
145     if (!context) {
146         LOGE("fail to get context");
147         return;
148     }
149 
150     auto platformTaskExecutor =
151         SingleTaskExecutor::Make(context->GetTaskExecutor(), TaskExecutor::TaskType::PLATFORM);
152     platformTaskExecutor.PostTask([weak = WeakClaim(this), listener = std::move(listener)]() mutable {
153         auto camera = weak.Upgrade();
154         if (camera) {
155             camera->OnAddTakePhotoListener(std::move(listener));
156         }
157     }, "ArkUICameraAddTakePhotoListener");
158 }
159 
OnAddTakePhotoListener(TakePhotoListener && listener)160 void Camera::OnAddTakePhotoListener(TakePhotoListener&& listener)
161 {
162     takePhotoListener_ = std::move(listener);
163 }
164 
AddErrorListener(ErrorListener && listener)165 void Camera::AddErrorListener(ErrorListener&& listener)
166 {
167     auto context = context_.Upgrade();
168     if (!context) {
169         LOGE("fail to get context");
170         return;
171     }
172 
173     auto platformTaskExecutor =
174         SingleTaskExecutor::Make(context->GetTaskExecutor(), TaskExecutor::TaskType::PLATFORM);
175     platformTaskExecutor.PostTask([weak = WeakClaim(this), listener = std::move(listener)]() mutable {
176         auto camera = weak.Upgrade();
177         if (camera) {
178             camera->OnAddErrorListener(std::move(listener));
179         }
180     }, "ArkUICameraAddErrorListener");
181 }
182 
OnAddErrorListener(ErrorListener && listener)183 void Camera::OnAddErrorListener(ErrorListener&& listener)
184 {
185     onErrorListener_ = std::move(listener);
186 }
187 
TakePhoto(int32_t quality)188 void Camera::TakePhoto(int32_t quality)
189 {
190     std::stringstream paramStream;
191     paramStream << CAMERA_QUALITY << PARAM_EQUALS << quality;
192     std::string param = paramStream.str();
193     CallResRegisterMethod(MakeMethodHash(CAMERA_TAKE_PHOTO), param, nullptr);
194 }
195 
SetFlashMode(FlashType flash)196 void Camera::SetFlashMode(FlashType flash)
197 {
198     std::stringstream paramStream;
199     paramStream << CAMERA_FLASH_MODE << PARAM_EQUALS << static_cast<int32_t>(flash);
200     std::string param = paramStream.str();
201     CallResRegisterMethod(MakeMethodHash(CAMERA_SET_FLASH_MODE), param, nullptr);
202 }
203 
OnTakePhoto(const std::string & param)204 void Camera::OnTakePhoto(const std::string& param)
205 {
206     std::map<std::string, std::string> result = Resource::ParseMapFromString(param);
207     if (takePhotoListener_) {
208         takePhotoListener_(result);
209     }
210     result.clear();
211 }
212 
OnError(const std::string & param)213 void Camera::OnError(const std::string& param)
214 {
215     if (!onErrorListener_) {
216         return;
217     }
218 
219     auto result = Resource::ParseMapFromString(param);
220     auto iter = result.find(CAMERA_GRANT_RESULT);
221     if (iter != result.end() && iter->second == "-1") {
222         onErrorListener_(result[ERROR_CODE], result[ERROR_MSG]);
223     }
224 }
225 
OpenCamera()226 void Camera::OpenCamera()
227 {
228     auto context = AceType::DynamicCast<PipelineContext>(context_.Upgrade());
229     if (!context) {
230         LOGE("fail to get context");
231         return;
232     }
233 
234     std::stringstream paramStream;
235     paramStream << DEVICE_POSITION << PARAM_EQUALS << static_cast<int32_t>(devicePosition_) << PARAM_AND
236                 << CACHE_FILE_PATH << PARAM_EQUALS << context->GetPhotoCachePath() << PARAM_AND << ORIENTATION
237                 << PARAM_EQUALS << (isPortrait_ ? "1" : "0");
238     std::string param = paramStream.str();
239     CallResRegisterMethod(MakeMethodHash(CAMERA_OEPN_CAMERA), param, nullptr);
240 }
241 
AddPreViewSizeChang(SizeChangeListener && listener)242 void Camera::AddPreViewSizeChang(SizeChangeListener&& listener)
243 {
244     onSizeChangeListener_ = std::move(listener);
245 }
246 
OnPreViewSizeChang(const std::string & param)247 void Camera::OnPreViewSizeChang(const std::string& param)
248 {
249     int32_t preViewWidth = GetIntParam(param, CAMERA_PREVIEW_WIDTH);
250     int32_t preViewHeight = GetIntParam(param, CAMERA_PREVIEW_HEIGHT);
251     if (onSizeChangeListener_) {
252         onSizeChangeListener_(preViewWidth, preViewHeight);
253     }
254 }
255 
AddPrepareEventListener(PrepareEventListener && listener)256 void Camera::AddPrepareEventListener(PrepareEventListener&& listener)
257 {
258     prepareEventListener_ = std::move(listener);
259 }
260 
OnPrepare(const std::string & param)261 void Camera::OnPrepare(const std::string& param)
262 {
263     if (prepareEventListener_) {
264         prepareEventListener_();
265     }
266 }
267 
SetPreViewSize(int32_t width,int32_t height)268 void Camera::SetPreViewSize(int32_t width, int32_t height)
269 {
270     std::stringstream paramStream;
271     paramStream << CAMERA_PREVIEW_WIDTH << PARAM_EQUALS << width << PARAM_AND
272                 << CAMERA_PREVIEW_HEIGHT << PARAM_EQUALS << height;
273     std::string param = paramStream.str();
274     CallResRegisterMethod(
275         MakeMethodHash(CAMERA_SET_PREVIEW_SIZE), param, [weak = WeakClaim(this)](std::string& result) {
276             auto camera = weak.Upgrade();
277             if (camera) {
278                 camera->OnPreViewSizeChang(result);
279             }
280         });
281 }
282 
ChangeCameraComponentId(bool changType,std::string id)283 void Camera::ChangeCameraComponentId(bool changType, std::string id)
284 {
285     LOGI("ChangeCameraComponentId: changType %{private}d.", changType);
286     std::stringstream paramStream;
287     paramStream << CAMERA_CHANGE_COMPONENT_ID << PARAM_EQUALS << id << PARAM_AND << CAMERA_CHANGE_TYPE
288                 << PARAM_EQUALS << (changType ? "1" : "0");
289     std::string param = paramStream.str();
290     CallResRegisterMethod(MakeMethodHash(CAMERA_CHANGE_COMPONENT_ID_FUNCTION), param, nullptr);
291 }
292 
293 } // namespace OHOS::Ace
294