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 "frameworks/bridge/common/dom/dom_camera.h"
17 
18 namespace OHOS::Ace::Framework {
19 namespace {
20 
21 const char CALLBACK_SUCCESS[] = "success";
22 const char CALLBACK_FAIL[] = "fail";
23 const char CALLBACK_COMPLETE[] = "complete";
24 const char QUALITY[] = "quality";
25 const char DEVICE_POSITION_FRONT[] = "front";
26 const char FLUSH_ON[] = "on";
27 const char FLUSH_OFF[] = "off";
28 const char FLUSH_TORCH[] = "torch";
29 const char FLUSH_AUTO[] = "auto";
30 const char START_STR[] = "[\"";
31 
32 } // namespace
33 
DOMCamera(NodeId nodeId,const std::string & nodeName)34 DOMCamera::DOMCamera(NodeId nodeId, const std::string& nodeName) : DOMNode(nodeId, nodeName)
35 {
36     cameraComponent_ = AceType::MakeRefPtr<CameraComponent>();
37 #if defined(PREVIEW)
38     if (IsRightToLeft()) {
39         cameraComponent_->SetTextDirection(TextDirection::RTL);
40     }
41 #endif
42 }
43 
SetSpecializedAttr(const std::pair<std::string,std::string> & attr)44 bool DOMCamera::SetSpecializedAttr(const std::pair<std::string, std::string>& attr)
45 {
46     // Operator map for attr
47     static const std::unordered_map<std::string, void (*)(const RefPtr<CameraComponent>&, const std::string&)>
48         attrOperators = {
49             { DOM_CAMERA_FLASH,
50                 [](const RefPtr<CameraComponent>& cameraComponent, const std::string& val) {
51                     cameraComponent->SetFlash(GetFlashType(val));
52                 } },
53             { DOM_CAMERA_DEVICE_POSITION,
54                 [](const RefPtr<CameraComponent>& cameraComponent, const std::string& val) {
55                     cameraComponent->SetDevicePosition(GetDevicePosition(val));
56                 } },
57         };
58     auto operatorIter = attrOperators.find(attr.first);
59     if (operatorIter != attrOperators.end()) {
60         operatorIter->second(cameraComponent_, attr.second);
61         return true;
62     }
63     return false;
64 }
65 
AddSpecializedEvent(int32_t pageId,const std::string & event)66 bool DOMCamera::AddSpecializedEvent(int32_t pageId, const std::string& event)
67 {
68     // Operator map for event
69     static const std::unordered_map<std::string, void (*)(const RefPtr<CameraComponent>&, const EventMarker&)>
70         eventOperators = {
71             { DOM_ERROR,
72                 [](const RefPtr<CameraComponent>& cameraComponent, const EventMarker& event) {
73                     cameraComponent->SetErrorEventId(event);
74                 } },
75         };
76     auto operatorIter = eventOperators.find(event);
77     if (operatorIter != eventOperators.end()) {
78         operatorIter->second(cameraComponent_, EventMarker(GetNodeIdForEvent(), event, pageId));
79         return true;
80     }
81     return false;
82 }
83 
CallSpecializedMethod(const std::string & method,const std::string & args)84 void DOMCamera::CallSpecializedMethod(const std::string& method, const std::string& args)
85 {
86     LOGI("DOMCamera: method: %{public}s args: %{public}s", method.c_str(), args.c_str());
87     if (method == DOM_TAKE_PHOTO) {
88         auto controller = cameraComponent_->GetCameraController();
89         if (controller) {
90             controller->TakePhoto(GetParamFromJson(args));
91         }
92     }
93 
94     if (method == DOM_CAMERA_START_RECORD) {
95         auto controller = cameraComponent_->GetCameraController();
96         if (controller) {
97             controller->StartRecord();
98         }
99     }
100 
101     if (method == DOM_CAMERA_CLOSE_RECORDER) {
102         auto controller = cameraComponent_->GetCameraController();
103         if (controller) {
104             controller->CloseRecorder(GetRecorderParam(args));
105         }
106     }
107 }
108 
GetParamFromJson(const std::string & args) const109 TakePhotoParams DOMCamera::GetParamFromJson(const std::string& args) const
110 {
111     std::unique_ptr<JsonValue> argsValue = JsonUtil::ParseJsonString(args);
112 
113     TakePhotoParams takePhotoParams;
114     if (!argsValue || !argsValue->IsArray() || argsValue->GetArraySize() == 0) {
115         return takePhotoParams;
116     }
117     std::unique_ptr<JsonValue> firstItem = argsValue->GetArrayItem(0);
118     std::string quality = firstItem->GetString(QUALITY);
119     if (!quality.empty()) {
120         takePhotoParams.quality = quality;
121     }
122 
123     std::string successId = firstItem->GetString(CALLBACK_SUCCESS);
124     if (!successId.empty()) {
125         takePhotoParams.success = successId;
126     }
127 
128     std::string failId = firstItem->GetString(CALLBACK_FAIL);
129     if (!failId.empty()) {
130         takePhotoParams.fail = failId;
131     }
132 
133     std::string completeId = firstItem->GetString(CALLBACK_COMPLETE);
134     if (!completeId.empty()) {
135         takePhotoParams.complete = completeId;
136     }
137 
138     return takePhotoParams;
139 }
140 
GetRecorderParam(const std::string & args) const141 std::string DOMCamera::GetRecorderParam(const std::string& args) const
142 {
143     size_t len = args.length();
144     size_t pos = args.find(START_STR);
145     size_t strLen = sizeof(START_STR) - 1;
146     int32_t result = 0;
147 
148     if (pos == std::string::npos || (pos + strLen) >= len) {
149         return std::string();
150     }
151     std::stringstream ss;
152     ss << args.substr(pos + strLen);
153     ss >> result;
154 
155     return std::to_string(result);
156 }
157 
GetFlashType(const std::string & val)158 FlashType DOMCamera::GetFlashType(const std::string& val)
159 {
160     static const std::unordered_map<std::string, FlashType> flashTypes = {
161         { FLUSH_ON, FlashType::ON },
162         { FLUSH_OFF, FlashType::OFF },
163         { FLUSH_TORCH, FlashType::TORCH },
164         { FLUSH_AUTO, FlashType::AUTO },
165     };
166     auto operatorIter = flashTypes.find(val);
167     if (operatorIter != flashTypes.end()) {
168         return operatorIter->second;
169     }
170     return FlashType::AUTO;
171 }
172 
GetDevicePosition(const std::string & val)173 DevicePosition DOMCamera::GetDevicePosition(const std::string& val)
174 {
175     if (val == DEVICE_POSITION_FRONT) {
176         return DevicePosition::CAMERA_FACING_FRONT;
177     } else {
178         return DevicePosition::CAMERA_FACING_BACK;
179     }
180 }
181 
182 } // namespace OHOS::Ace::Framework