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