1 /*
2  * Copyright (c) 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 "core/components_ng/pattern/patternlock/patternlock_napi.h"
17 
18 #include "base/utils/utils.h"
19 #include "core/components_ng/base/view_abstract.h"
20 #include "core/components_ng/common_napi_utils/common_napi_utils.h"
21 #include "core/components_ng/pattern/patternlock/pattern_lock_controller.h"
22 #include "core/components_ng/pattern/patternlock/patternlock_model_ng.h"
23 #include "core/components_v2/pattern_lock/pattern_lock_component.h"
24 #include "core/components_v2/pattern_lock/pattern_lock_theme.h"
25 
26 extern const char _binary_arkui_patternlock_js_start[];
27 extern const char _binary_arkui_patternlock_abc_start[];
28 #if !defined(IOS_PLATFORM)
29 extern const char _binary_arkui_patternlock_js_end[];
30 extern const char _binary_arkui_patternlock_abc_end[];
31 #else
32 extern const char* _binary_arkui_patternlock_js_end;
33 extern const char* _binary_arkui_patternlock_abc_end;
34 #endif
35 
36 namespace OHOS::Ace {
37 namespace {
38 static constexpr const size_t MAX_ARG_NUM = 10;
39 } // namespace
40 std::unique_ptr<PatternLockModel> PatternLockModel::instance_ = nullptr;
41 std::mutex PatternLockModel::mutex_;
42 
43 template<typename T>
GetTheme()44 RefPtr<T> GetTheme()
45 {
46     auto pipelineContext = PipelineBase::GetCurrentContext();
47     CHECK_NULL_RETURN(pipelineContext, nullptr);
48     auto themeManager = pipelineContext->GetThemeManager();
49     CHECK_NULL_RETURN(themeManager, nullptr);
50     return themeManager->GetTheme<T>();
51 }
52 
GetInstance()53 PatternLockModel* PatternLockModel::GetInstance()
54 {
55     if (!instance_) {
56         std::lock_guard<std::mutex> lock(mutex_);
57         if (!instance_) {
58             instance_.reset(new NG::PatternLockModelNG());
59         }
60     }
61     return instance_.get();
62 }
63 
AutoResetResult(napi_env env,napi_value value)64 bool AutoResetResult(napi_env env, napi_value value)
65 {
66     bool autoReset = true;
67     napi_valuetype valueType = CommonNapiUtils::GetValueType(env, value);
68     if (valueType == napi_boolean) {
69         autoReset = CommonNapiUtils::GetBool(env, value);
70     }
71 
72     return autoReset;
73 }
74 
Create(napi_env env,napi_callback_info info)75 napi_value Create(napi_env env, napi_callback_info info)
76 {
77     size_t argc = MAX_ARG_NUM;
78     napi_value argv[MAX_ARG_NUM] = { nullptr };
79     NAPI_CALL(env, napi_get_cb_info(env, info, &argc, argv, nullptr, nullptr));
80     NAPI_ASSERT(env, argc >= 1, "Wrong number of arguments");
81     PatternLockController* wrapper = nullptr;
82     napi_unwrap(env, argv[0], (void**)&wrapper);
83     auto controller = PatternLockModel::GetInstance()->Create();
84     if (controller) {
85         wrapper->SetController(controller);
86     }
87     return CommonNapiUtils::CreateNull(env);
88 }
89 
SideLength(napi_env env,napi_callback_info info)90 napi_value SideLength(napi_env env, napi_callback_info info)
91 {
92     size_t argc = MAX_ARG_NUM;
93     napi_value thisVal = nullptr;
94     napi_value argv[MAX_ARG_NUM] = { nullptr };
95     NAPI_CALL(env, napi_get_cb_info(env, info, &argc, argv, &thisVal, nullptr));
96     NAPI_ASSERT(env, argc >= 1, "Wrong number of arguments");
97 
98     CalcDimension sideLength;
99     if (!CommonNapiUtils::GetDimensionResult(env, argv[0], sideLength)) {
100         RefPtr<V2::PatternLockTheme> patternLockTheme = GetTheme<V2::PatternLockTheme>();
101         CHECK_NULL_RETURN(patternLockTheme, CommonNapiUtils::CreateNull(env));
102         sideLength = patternLockTheme->GetSideLength();
103     }
104     PatternLockModel::GetInstance()->SetSideLength(sideLength);
105     return CommonNapiUtils::CreateNull(env);
106 }
107 
CircleRadius(napi_env env,napi_callback_info info)108 napi_value CircleRadius(napi_env env, napi_callback_info info)
109 {
110     size_t argc = MAX_ARG_NUM;
111     napi_value thisVal = nullptr;
112     napi_value argv[MAX_ARG_NUM] = { nullptr };
113     NAPI_CALL(env, napi_get_cb_info(env, info, &argc, argv, &thisVal, nullptr));
114     NAPI_ASSERT(env, argc >= 1, "Wrong number of arguments");
115 
116     CalcDimension radius;
117     if (!CommonNapiUtils::GetDimensionResult(env, argv[0], radius) || radius.IsNonPositive()) {
118         RefPtr<V2::PatternLockTheme> patternLockTheme = GetTheme<V2::PatternLockTheme>();
119         CHECK_NULL_RETURN(patternLockTheme, CommonNapiUtils::CreateNull(env));
120         radius = patternLockTheme->GetCircleRadius();
121     }
122     PatternLockModel::GetInstance()->SetCircleRadius(radius);
123     return CommonNapiUtils::CreateNull(env);
124 }
125 
PathStrokeWidth(napi_env env,napi_callback_info info)126 napi_value PathStrokeWidth(napi_env env, napi_callback_info info)
127 {
128     size_t argc = MAX_ARG_NUM;
129     napi_value thisVal = nullptr;
130     napi_value argv[MAX_ARG_NUM] = { nullptr };
131     NAPI_CALL(env, napi_get_cb_info(env, info, &argc, argv, &thisVal, nullptr));
132     NAPI_ASSERT(env, argc >= 1, "Wrong number of arguments");
133 
134     CalcDimension lineWidth;
135     if (!CommonNapiUtils::GetDimensionResult(env, argv[0], lineWidth)) {
136         RefPtr<V2::PatternLockTheme> patternLockTheme = GetTheme<V2::PatternLockTheme>();
137         CHECK_NULL_RETURN(patternLockTheme, CommonNapiUtils::CreateNull(env));
138         lineWidth = patternLockTheme->GetPathStrokeWidth();
139     }
140     PatternLockModel::GetInstance()->SetStrokeWidth(lineWidth);
141     return CommonNapiUtils::CreateNull(env);
142 }
143 
ActiveColor(napi_env env,napi_callback_info info)144 napi_value ActiveColor(napi_env env, napi_callback_info info)
145 {
146     size_t argc = MAX_ARG_NUM;
147     napi_value thisVal = nullptr;
148     napi_value argv[MAX_ARG_NUM] = { nullptr };
149     NAPI_CALL(env, napi_get_cb_info(env, info, &argc, argv, &thisVal, nullptr));
150     NAPI_ASSERT(env, argc >= 1, "PatternLockModelNapi activeColor wrong number of arguments");
151 
152     Color activeColor;
153     if (!CommonNapiUtils::ParseColor(env, argv[0], activeColor)) {
154         RefPtr<V2::PatternLockTheme> patternLockTheme = GetTheme<V2::PatternLockTheme>();
155         CHECK_NULL_RETURN(patternLockTheme, CommonNapiUtils::CreateNull(env));
156         activeColor = patternLockTheme->GetActiveColor();
157     }
158     PatternLockModel::GetInstance()->SetActiveColor(activeColor);
159     return CommonNapiUtils::CreateNull(env);
160 }
161 
SelectedColor(napi_env env,napi_callback_info info)162 napi_value SelectedColor(napi_env env, napi_callback_info info)
163 {
164     size_t argc = MAX_ARG_NUM;
165     napi_value thisVal = nullptr;
166     napi_value argv[MAX_ARG_NUM] = { nullptr };
167     NAPI_CALL(env, napi_get_cb_info(env, info, &argc, argv, &thisVal, nullptr));
168     NAPI_ASSERT(env, argc >= 1, "PatternLockModelNapi selectedColor Wrong number of arguments");
169 
170     Color selectedColor;
171     if (!CommonNapiUtils::ParseColor(env, argv[0], selectedColor)) {
172         RefPtr<V2::PatternLockTheme> patternLockTheme = GetTheme<V2::PatternLockTheme>();
173         CHECK_NULL_RETURN(patternLockTheme, CommonNapiUtils::CreateNull(env));
174         selectedColor = patternLockTheme->GetSelectedColor();
175     }
176     PatternLockModel::GetInstance()->SetSelectedColor(selectedColor);
177     return CommonNapiUtils::CreateNull(env);
178 }
179 
PathColor(napi_env env,napi_callback_info info)180 napi_value PathColor(napi_env env, napi_callback_info info)
181 {
182     size_t argc = MAX_ARG_NUM;
183     napi_value thisVal = nullptr;
184     napi_value argv[MAX_ARG_NUM] = { nullptr };
185     NAPI_CALL(env, napi_get_cb_info(env, info, &argc, argv, &thisVal, nullptr));
186     NAPI_ASSERT(env, argc >= 1, "PatternLockModelNapi pathColor Wrong number of arguments");
187 
188     Color pathColor;
189     if (!CommonNapiUtils::ParseColor(env, argv[0], pathColor)) {
190         RefPtr<V2::PatternLockTheme> patternLockTheme = GetTheme<V2::PatternLockTheme>();
191         CHECK_NULL_RETURN(patternLockTheme, CommonNapiUtils::CreateNull(env));
192         pathColor = patternLockTheme->GetPathColor();
193     }
194     PatternLockModel::GetInstance()->SetPathColor(pathColor);
195     return CommonNapiUtils::CreateNull(env);
196 }
197 
RegularColor(napi_env env,napi_callback_info info)198 napi_value RegularColor(napi_env env, napi_callback_info info)
199 {
200     size_t argc = MAX_ARG_NUM;
201     napi_value thisVal = nullptr;
202     napi_value argv[MAX_ARG_NUM] = { nullptr };
203     NAPI_CALL(env, napi_get_cb_info(env, info, &argc, argv, &thisVal, nullptr));
204     NAPI_ASSERT(env, argc >= 1, "PatternLockModelNapi regularColor Wrong number of arguments");
205     Color regularColor;
206     if (!CommonNapiUtils::ParseColor(env, argv[0], regularColor)) {
207         RefPtr<V2::PatternLockTheme> patternLockTheme = GetTheme<V2::PatternLockTheme>();
208         CHECK_NULL_RETURN(patternLockTheme, CommonNapiUtils::CreateNull(env));
209         regularColor = patternLockTheme->GetRegularColor();
210     }
211     PatternLockModel::GetInstance()->SetRegularColor(regularColor);
212     return CommonNapiUtils::CreateNull(env);
213 }
214 
AutoReset(napi_env env,napi_callback_info info)215 napi_value AutoReset(napi_env env, napi_callback_info info)
216 {
217     size_t argc = MAX_ARG_NUM;
218     napi_value thisVal = nullptr;
219     napi_value argv[MAX_ARG_NUM] = { nullptr };
220     NAPI_CALL(env, napi_get_cb_info(env, info, &argc, argv, &thisVal, nullptr));
221     NAPI_ASSERT(env, argc >= 1, "PatternLockModelNapi autoReset Wrong number of arguments");
222 
223     bool autoReset = AutoResetResult(env, argv[0]);
224     PatternLockModel::GetInstance()->SetAutoReset(autoReset);
225     return CommonNapiUtils::CreateNull(env);
226 }
227 
OnPatternComplete(napi_env env,napi_callback_info info)228 napi_value OnPatternComplete(napi_env env, napi_callback_info info)
229 {
230     size_t argc = MAX_ARG_NUM;
231     napi_value thisVal = nullptr;
232     napi_value argv[MAX_ARG_NUM] = { nullptr };
233     NAPI_CALL(env, napi_get_cb_info(env, info, &argc, argv, &thisVal, nullptr));
234     NAPI_ASSERT(env, argc >= 1, "Wrong number of arguments");
235     napi_ref callback = nullptr;
236     napi_valuetype valuetype;
237     NAPI_CALL(env, napi_typeof(env, argv[0], &valuetype));
238     NAPI_ASSERT(env, valuetype == napi_function, "Wrong argument type. Function expected.");
239     auto asyncEvent = std::make_shared<NapiAsyncEvnet>(env, argv[0]);
240     auto onComplete = [asyncEvent](const BaseEventInfo* info) {
241         napi_value arrayValue;
242         const auto* eventInfo = TypeInfoHelper::DynamicCast<V2::PatternCompleteEvent>(info);
243         CHECK_NULL_VOID(eventInfo);
244         arrayValue = CommonNapiUtils::CreateArray(asyncEvent->GetEnv());
245         std::vector<int> arr = eventInfo->GetInput();
246         for (size_t i = 0; i < arr.size(); i++) {
247             CommonNapiUtils::SetSelementToArray(
248                 asyncEvent->GetEnv(), arrayValue, i, CommonNapiUtils::CreateInt32(asyncEvent->GetEnv(), arr.at(i)));
249         }
250         napi_value argv[1] = { arrayValue };
251         asyncEvent->Call(1, argv);
252     };
253     PatternLockModel::GetInstance()->SetPatternComplete(std::move(onComplete));
254     return CommonNapiUtils::CreateNull(env);
255 }
256 
Reset(napi_env env,napi_callback_info info)257 napi_value Reset(napi_env env, napi_callback_info info)
258 {
259     napi_value thisVar = nullptr;
260     NAPI_CALL(env, napi_get_cb_info(env, info, nullptr, nullptr, &thisVar, NULL));
261     PatternLockController* wrapper = nullptr;
262     napi_unwrap(env, thisVar, (void**)&wrapper);
263     if (wrapper == nullptr) {
264         return CommonNapiUtils::CreateNull(env);
265     }
266     wrapper->Reset();
267     return CommonNapiUtils::CreateNull(env);
268 }
269 
PatternLockControllerConstructor(napi_env env,napi_callback_info info)270 napi_value PatternLockControllerConstructor(napi_env env, napi_callback_info info)
271 {
272     napi_value thisVar = nullptr;
273     NAPI_CALL(env, napi_get_cb_info(env, info, nullptr, nullptr, &thisVar, nullptr));
274     auto wrapper = new (std::nothrow) PatternLockController();
275     if (wrapper == nullptr) {
276         return CommonNapiUtils::CreateNull(env);
277     }
278     napi_wrap(
279         env, thisVar, wrapper,
280         [](napi_env env, void* data, void* hint) {
281             auto* wrapper = reinterpret_cast<PatternLockController*>(data);
282             delete wrapper;
283             wrapper = nullptr;
284         },
285         nullptr, nullptr);
286     return thisVar;
287 }
288 
Init(napi_env env,napi_value exports)289 napi_value Init(napi_env env, napi_value exports)
290 {
291     static napi_property_descriptor desc[] = { DECLARE_NAPI_FUNCTION("create", Create),
292         DECLARE_NAPI_FUNCTION("sideLength", SideLength), DECLARE_NAPI_FUNCTION("circleRadius", CircleRadius),
293         DECLARE_NAPI_FUNCTION("pathStrokeWidth", PathStrokeWidth), DECLARE_NAPI_FUNCTION("activeColor", ActiveColor),
294         DECLARE_NAPI_FUNCTION("selectedColor", SelectedColor), DECLARE_NAPI_FUNCTION("pathColor", PathColor),
295         DECLARE_NAPI_FUNCTION("regularColor", RegularColor), DECLARE_NAPI_FUNCTION("autoReset", AutoReset),
296         DECLARE_NAPI_FUNCTION("onPatternComplete", OnPatternComplete) };
297     NAPI_CALL(env, napi_define_properties(env, exports, sizeof(desc) / sizeof(desc[0]), desc));
298     return exports;
299 }
300 
InitController(napi_env env,napi_value exports)301 napi_value InitController(napi_env env, napi_value exports)
302 {
303     napi_value patternLockControllerClass = nullptr;
304     napi_property_descriptor properties[] = {
305         DECLARE_NAPI_FUNCTION("reset", Reset),
306     };
307     NAPI_CALL(env, napi_define_class(env, "PatternLockController", NAPI_AUTO_LENGTH, PatternLockControllerConstructor,
308                        nullptr, sizeof(properties) / sizeof(*properties), properties, &patternLockControllerClass));
309     NAPI_CALL(env, napi_set_named_property(env, exports, "PatternLockController", patternLockControllerClass));
310     return exports;
311 }
312 } // namespace OHOS::Ace
313 
NAPI_arkui_patternlock_GetJSCode(const char ** buf,int * bufLen)314 extern "C" __attribute__((visibility("default"))) void NAPI_arkui_patternlock_GetJSCode(const char** buf, int* bufLen)
315 {
316     if (buf != nullptr) {
317         *buf = _binary_arkui_patternlock_js_start;
318     }
319 
320     if (bufLen != nullptr) {
321         *bufLen = _binary_arkui_patternlock_js_end - _binary_arkui_patternlock_js_start;
322     }
323 }
324 
325 // arkui_patternlock JS register
NAPI_arkui_patternlock_GetABCCode(const char ** buf,int * buflen)326 extern "C" __attribute__((visibility("default"))) void NAPI_arkui_patternlock_GetABCCode(const char** buf, int* buflen)
327 {
328     if (buf != nullptr) {
329         *buf = _binary_arkui_patternlock_abc_start;
330     }
331     if (buflen != nullptr) {
332         *buflen = _binary_arkui_patternlock_abc_end - _binary_arkui_patternlock_abc_start;
333     }
334 }
335 
336 static napi_module_with_js modules = {
337     .nm_filename = "arkui/libpatternlock.z.so/arkui_patternlock.js",
338     .nm_version = 1,
339     .nm_flags = 0,
340     .nm_register_func = OHOS::Ace::Init,
341     .nm_modname = "arkui.patternlock",
342     .nm_priv = ((void*)0),
343     .nm_get_abc_code = NAPI_arkui_patternlock_GetABCCode,
344     .nm_get_js_code = NAPI_arkui_patternlock_GetJSCode,
345 };
346 
347 static napi_module patternLockControllerModule = {
348     .nm_version = 1,
349     .nm_flags = 0,
350     .nm_filename = nullptr,
351     .nm_register_func = OHOS::Ace::InitController,
352     .nm_modname = "arkui.patternlockcontroller",
353     .nm_priv = ((void*)0),
354     .reserved = { 0 },
355 };
356 
RegisterModule()357 extern "C" __attribute__((constructor)) void RegisterModule()
358 {
359     napi_module_register(&patternLockControllerModule);
360     napi_module_with_js_register(&modules);
361 }
362