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