1 /*
2 * Copyright (c) 2021-2023 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 "bridge/declarative_frontend/jsview/js_pattern_lock.h"
17
18 #include "bridge/declarative_frontend/jsview/models/patternlock_model_impl.h"
19 #include "bridge/declarative_frontend/view_stack_processor.h"
20 #include "core/components_ng/base/view_stack_processor.h"
21 #include "core/components_ng/pattern/patternlock/patternlock_model_ng.h"
22 #include "core/components_v2/pattern_lock/pattern_lock_component.h"
23
24 namespace OHOS::Ace {
25
26 std::unique_ptr<PatternLockModel> PatternLockModel::instance_ = nullptr;
27 std::mutex PatternLockModel::mutex_;
28 const std::vector<V2::PatternLockChallengeResult> CHALLENGE_RESULT = { V2::PatternLockChallengeResult::CORRECT,
29 V2::PatternLockChallengeResult::WRONG };
30
GetInstance()31 PatternLockModel* PatternLockModel::GetInstance()
32 {
33 if (!instance_) {
34 std::lock_guard<std::mutex> lock(mutex_);
35 if (!instance_) {
36 #ifdef NG_BUILD
37 instance_.reset(new NG::PatternLockModelNG());
38 #else
39 if (Container::IsCurrentUseNewPipeline()) {
40 instance_.reset(new NG::PatternLockModelNG());
41 } else {
42 instance_.reset(new Framework::PatternLockModelImpl());
43 }
44 #endif
45 }
46 }
47 return instance_.get();
48 }
49
50 } // namespace OHOS::Ace
51
52 namespace OHOS::Ace::Framework {
ChoosePointToJSValue(std::vector<int> input)53 JSRef<JSArray> JSPatternLock::ChoosePointToJSValue(std::vector<int> input)
54 {
55 JSRef<JSArray> arr = JSRef<JSArray>::New();
56 for (size_t i = 0; i < input.size(); i++) {
57 arr->SetValueAt(i, ConvertToJSValue(input[i]));
58 }
59 return arr;
60 }
Create(const JSCallbackInfo & info)61 void JSPatternLock::Create(const JSCallbackInfo& info)
62 {
63 auto controller = PatternLockModel::GetInstance()->Create();
64
65 if (info.Length() > 0 && info[0]->IsObject()) {
66 auto* jsController = JSRef<JSObject>::Cast(info[0])->Unwrap<JSPatternLockController>();
67 if (jsController) {
68 jsController->SetController(controller);
69 }
70 }
71 }
JSBind(BindingTarget globalObj)72 void JSPatternLock::JSBind(BindingTarget globalObj)
73 {
74 JSClass<JSPatternLock>::Declare("PatternLock");
75 MethodOptions opt = MethodOptions::NONE;
76 JSClass<JSPatternLock>::StaticMethod("create", &JSPatternLock::Create, opt);
77 JSClass<JSPatternLock>::StaticMethod("onPatternComplete", &JSPatternLock::SetPatternComplete);
78 JSClass<JSPatternLock>::StaticMethod("regularColor", &JSPatternLock::SetRegularColor, MethodOptions::NONE);
79 JSClass<JSPatternLock>::StaticMethod("selectedColor", &JSPatternLock::SetSelectedColor, MethodOptions::NONE);
80 JSClass<JSPatternLock>::StaticMethod("activeColor", &JSPatternLock::SetActiveColor, MethodOptions::NONE);
81 JSClass<JSPatternLock>::StaticMethod("pathColor", &JSPatternLock::SetPathColor, MethodOptions::NONE);
82 JSClass<JSPatternLock>::StaticMethod("pathStrokeWidth", &JSPatternLock::SetPathStrokeWidth);
83 JSClass<JSPatternLock>::StaticMethod("circleRadius", &JSPatternLock::SetCircleRadius, MethodOptions::NONE);
84 JSClass<JSPatternLock>::StaticMethod("sideLength", &JSPatternLock::SetSideLength, MethodOptions::NONE);
85 JSClass<JSPatternLock>::StaticMethod("autoReset", &JSPatternLock::SetAutoReset, MethodOptions::NONE);
86 JSClass<JSPatternLock>::StaticMethod("onDotConnect", &JSPatternLock::SetDotConnect);
87 JSClass<JSPatternLock>::StaticMethod("onDisAppear", &JSInteractableView::JsOnDisAppear);
88 JSClass<JSPatternLock>::StaticMethod("onAppear", &JSInteractableView::JsOnAppear);
89 JSClass<JSPatternLock>::StaticMethod("onTouch", &JSInteractableView::JsOnTouch);
90 JSClass<JSPatternLock>::InheritAndBind<JSViewAbstract>(globalObj);
91 }
SetDefaultTheme(OHOS::Ace::RefPtr<OHOS::Ace::V2::PatternLockComponent> & patternLock)92 void JSPatternLock::SetDefaultTheme(OHOS::Ace::RefPtr<OHOS::Ace::V2::PatternLockComponent>& patternLock)
93 {
94 auto lockTheme = GetTheme<V2::PatternLockTheme>();
95 if (!lockTheme) {
96 return;
97 }
98 patternLock->SetRegularColor(lockTheme->GetRegularColor());
99 patternLock->SetSelectedColor(lockTheme->GetSelectedColor());
100 patternLock->SetActiveColor(lockTheme->GetActiveColor());
101 patternLock->SetPathColor(lockTheme->GetPathColor());
102 }
103
SetPatternComplete(const JSCallbackInfo & args)104 void JSPatternLock::SetPatternComplete(const JSCallbackInfo& args)
105 {
106 if (!args[0]->IsFunction()) {
107 return;
108 }
109
110 auto onComplete = [execCtx = args.GetExecutionContext(), func = JSRef<JSFunc>::Cast(args[0])](
111 const BaseEventInfo* event) {
112 JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
113 const auto* eventInfo = TypeInfoHelper::DynamicCast<V2::PatternCompleteEvent>(event);
114 CHECK_NULL_VOID(eventInfo);
115 JSRef<JSVal> params[] = { ChoosePointToJSValue(eventInfo->GetInput()) };
116 func->Call(JSRef<JSObject>(), ArraySize(params), params);
117 };
118
119 PatternLockModel::GetInstance()->SetPatternComplete(std::move(onComplete));
120 }
SetSelectedColor(const JSCallbackInfo & info)121 void JSPatternLock::SetSelectedColor(const JSCallbackInfo& info)
122 {
123 if (info.Length() < 1) {
124 return;
125 }
126 Color selectedColor;
127 if (!ParseJsColor(info[0], selectedColor)) {
128 RefPtr<V2::PatternLockTheme> patternLockTheme = GetTheme<V2::PatternLockTheme>();
129 CHECK_NULL_VOID(patternLockTheme);
130 selectedColor = patternLockTheme->GetSelectedColor();
131 }
132
133 PatternLockModel::GetInstance()->SetSelectedColor(selectedColor);
134 }
SetAutoReset(const JSCallbackInfo & info)135 void JSPatternLock::SetAutoReset(const JSCallbackInfo& info)
136 {
137 if (info.Length() < 1) {
138 return;
139 }
140 if (!info[0]->IsBoolean()) {
141 PatternLockModel::GetInstance()->SetAutoReset(true);
142 return;
143 }
144 PatternLockModel::GetInstance()->SetAutoReset(info[0]->ToBoolean());
145 }
146
SetPathColor(const JSCallbackInfo & info)147 void JSPatternLock::SetPathColor(const JSCallbackInfo& info)
148 {
149 if (info.Length() < 1) {
150 return;
151 }
152 Color pathColor;
153 if (!ParseJsColor(info[0], pathColor)) {
154 RefPtr<V2::PatternLockTheme> patternLockTheme = GetTheme<V2::PatternLockTheme>();
155 CHECK_NULL_VOID(patternLockTheme);
156 pathColor = patternLockTheme->GetPathColor();
157 }
158
159 PatternLockModel::GetInstance()->SetPathColor(pathColor);
160 }
SetActiveColor(const JSCallbackInfo & info)161 void JSPatternLock::SetActiveColor(const JSCallbackInfo& info)
162 {
163 if (info.Length() < 1) {
164 return;
165 }
166 Color activeColor;
167 if (!ParseJsColor(info[0], activeColor)) {
168 RefPtr<V2::PatternLockTheme> patternLockTheme = GetTheme<V2::PatternLockTheme>();
169 CHECK_NULL_VOID(patternLockTheme);
170 activeColor = patternLockTheme->GetActiveColor();
171 }
172
173 PatternLockModel::GetInstance()->SetActiveColor(activeColor);
174 }
SetRegularColor(const JSCallbackInfo & info)175 void JSPatternLock::SetRegularColor(const JSCallbackInfo& info)
176 {
177 if (info.Length() < 1) {
178 return;
179 }
180 Color regularColor;
181 if (!ParseJsColor(info[0], regularColor)) {
182 RefPtr<V2::PatternLockTheme> patternLockTheme = GetTheme<V2::PatternLockTheme>();
183 CHECK_NULL_VOID(patternLockTheme);
184 regularColor = patternLockTheme->GetRegularColor();
185 }
186
187 PatternLockModel::GetInstance()->SetRegularColor(regularColor);
188 }
SetCircleRadius(const JSCallbackInfo & info)189 void JSPatternLock::SetCircleRadius(const JSCallbackInfo& info)
190 {
191 if (info.Length() < 1) {
192 return;
193 }
194 CalcDimension radius;
195 if (Container::LessThanAPIVersion(PlatformVersion::VERSION_TEN)) {
196 if (!ParseJsDimensionVp(info[0], radius)) {
197 return;
198 }
199 if (radius.IsNonNegative()) {
200 PatternLockModel::GetInstance()->SetCircleRadius(radius);
201 }
202 } else {
203 if (!ParseJsDimensionVp(info[0], radius) || radius.IsNonPositive()) {
204 RefPtr<V2::PatternLockTheme> patternLockTheme = GetTheme<V2::PatternLockTheme>();
205 CHECK_NULL_VOID(patternLockTheme);
206 radius = patternLockTheme->GetCircleRadius();
207 }
208 PatternLockModel::GetInstance()->SetCircleRadius(radius);
209 }
210 }
SetSideLength(const JSCallbackInfo & info)211 void JSPatternLock::SetSideLength(const JSCallbackInfo& info)
212 {
213 if (info.Length() < 1) {
214 return;
215 }
216 CalcDimension sideLength;
217 if (!ParseJsDimensionVp(info[0], sideLength)) {
218 RefPtr<V2::PatternLockTheme> patternLockTheme = GetTheme<V2::PatternLockTheme>();
219 CHECK_NULL_VOID(patternLockTheme);
220 sideLength = patternLockTheme->GetSideLength();
221 }
222
223 PatternLockModel::GetInstance()->SetSideLength(sideLength);
224 }
SetPathStrokeWidth(const JSCallbackInfo & info)225 void JSPatternLock::SetPathStrokeWidth(const JSCallbackInfo& info)
226 {
227 if (info.Length() < 1) {
228 return;
229 }
230 CalcDimension lineWidth;
231 if (!ParseJsDimensionVp(info[0], lineWidth)) {
232 RefPtr<V2::PatternLockTheme> patternLockTheme = GetTheme<V2::PatternLockTheme>();
233 CHECK_NULL_VOID(patternLockTheme);
234 lineWidth = patternLockTheme->GetPathStrokeWidth();
235 }
236
237 PatternLockModel::GetInstance()->SetStrokeWidth(lineWidth);
238 }
SetDotConnect(const JSCallbackInfo & args)239 void JSPatternLock::SetDotConnect(const JSCallbackInfo& args)
240 {
241 if (!args[0]->IsFunction()) {
242 return;
243 }
244
245 auto jsFunc = AceType::MakeRefPtr<JsFunction>(JSRef<JSObject>(), JSRef<JSFunc>::Cast(args[0]));
246 WeakPtr<NG::FrameNode> targetNode = NG::ViewStackProcessor::GetInstance()->GetMainFrameNode();
247 auto onDotConnect = [execCtx = args.GetExecutionContext(), func = std::move(jsFunc), node = targetNode](
248 int32_t code) {
249 JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
250 PipelineContext::SetCallBackNode(node);
251 JSRef<JSVal> newJSVal = JSRef<JSVal>::Make(ToJSValue(code));
252 func->ExecuteJS(1, &newJSVal);
253 };
254
255 PatternLockModel::GetInstance()->SetDotConnect(std::move(onDotConnect));
256 }
JSBind(BindingTarget globalObj)257 void JSPatternLockController::JSBind(BindingTarget globalObj)
258 {
259 JSClass<JSPatternLockController>::Declare("PatternLockController");
260 JSClass<JSPatternLockController>::CustomMethod("reset", &JSPatternLockController::Reset);
261 JSClass<JSPatternLockController>::CustomMethod("setChallengeResult", &JSPatternLockController::SetChallengeResult);
262 JSClass<JSPatternLockController>::Bind(
263 globalObj, JSPatternLockController::Constructor, JSPatternLockController::Destructor);
264 }
Reset(const JSCallbackInfo & args)265 void JSPatternLockController::Reset(const JSCallbackInfo& args)
266 {
267 if (controller_) {
268 controller_->Reset();
269 }
270 }
SetChallengeResult(const JSCallbackInfo & args)271 void JSPatternLockController::SetChallengeResult(const JSCallbackInfo& args)
272 {
273 if (controller_) {
274 if (!args[0]->IsNumber()) {
275 return;
276 }
277 int32_t value = args[0]->ToNumber<int32_t>();
278 if (value >= 1 && value <= static_cast<int32_t>(CHALLENGE_RESULT.size())) {
279 controller_->SetChallengeResult(CHALLENGE_RESULT[value - 1]);
280 }
281 }
282 }
Constructor(const JSCallbackInfo & args)283 void JSPatternLockController::Constructor(const JSCallbackInfo& args)
284 {
285 auto controller = Referenced::MakeRefPtr<JSPatternLockController>();
286 controller->IncRefCount();
287 args.SetReturnValue(Referenced::RawPtr(controller));
288 }
Destructor(JSPatternLockController * controller)289 void JSPatternLockController::Destructor(JSPatternLockController* controller)
290 {
291 if (controller != nullptr) {
292 controller->DecRefCount();
293 }
294 }
295 } // namespace OHOS::Ace::Framework
296