• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2024 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 
17 #include "interfaces/napi/kits/utils/napi_utils.h"
18 
19 #include "frameworks/bridge/common/utils/engine_helper.h"
20 
21 namespace OHOS::Ace::Napi {
22 namespace {
23 constexpr size_t STR_BUFFER_SIZE = 1024;
24 constexpr size_t ARGC_ACTIVATE_PARAMTER = 2;
25 }
26 
JSClearFocus(napi_env env,napi_callback_info info)27 static napi_value JSClearFocus(napi_env env, napi_callback_info info)
28 {
29     auto delegate = EngineHelper::GetCurrentDelegateSafely();
30     if (!delegate) {
31         return nullptr;
32     }
33     delegate->ResetFocus();
34     return nullptr;
35 }
36 
JSRequestFocus(napi_env env,napi_callback_info info)37 static napi_value JSRequestFocus(napi_env env, napi_callback_info info)
38 {
39     size_t argc = 1;
40     napi_value argv = nullptr;
41     napi_value thisVar = nullptr;
42     void* data = nullptr;
43     napi_get_cb_info(env, info, &argc, &argv, &thisVar, &data);
44     NAPI_ASSERT(env, argc == 1, "requires 1 parameter");
45     napi_valuetype type = napi_undefined;
46     napi_typeof(env, argv, &type);
47     NAPI_ASSERT(env, type == napi_string, "the type of arg is not string");
48     char outBuffer[STR_BUFFER_SIZE] = { 0 };
49     size_t outSize = 0;
50     napi_get_value_string_utf8(env, argv, outBuffer, STR_BUFFER_SIZE, &outSize);
51     std::string key = std::string(outBuffer);
52 
53     napi_value obj = nullptr;
54     auto delegate = EngineHelper::GetCurrentDelegateSafely();
55     if (!delegate) {
56         napi_get_boolean(env, false, &obj);
57         return obj;
58     }
59     auto focusCallback = [env](NG::RequestFocusResult result) {
60         switch (result) {
61             case NG::RequestFocusResult::NON_FOCUSABLE:
62                 NapiThrow(env, "This component is not focusable.", ERROR_CODE_NON_FOCUSABLE);
63                 break;
64             case NG::RequestFocusResult::NON_FOCUSABLE_ANCESTOR:
65                 NapiThrow(env, "This component has unfocusable ancestor.", ERROR_CODE_NON_FOCUSABLE_ANCESTOR);
66                 break;
67             case NG::RequestFocusResult::NON_EXIST:
68                 NapiThrow(env,
69                     "The component doesn't exist, is currently invisible, or has been disabled.",
70                     ERROR_CODE_NON_EXIST);
71                 break;
72             default:
73                 NapiThrow(env, "An internal error occurred.", ERROR_CODE_INTERNAL_ERROR);
74                 break;
75         }
76     };
77     delegate->SetRequestFocusCallback(focusCallback);
78     delegate->RequestFocus(key, true);
79     delegate->ResetRequestFocusCallback();
80     napi_get_null(env, &obj);
81     return obj;
82 }
83 
JsSetAutoFocusTransfer(napi_env env,napi_callback_info info)84 static napi_value JsSetAutoFocusTransfer(napi_env env, napi_callback_info info)
85 {
86     auto delegate = EngineHelper::GetCurrentDelegateSafely();
87     if (!delegate) {
88         return nullptr;
89     }
90     napi_value argv[1] = { 0 };
91     napi_valuetype valueType = napi_undefined;
92     if (!GetSingleParam(env, info, argv, valueType) || (valueType != napi_boolean)) {
93         return nullptr;
94     }
95     bool isAutoFocusTransfer = true;
96     napi_get_value_bool(env, argv[0], &isAutoFocusTransfer);
97     delegate->SetAutoFocusTransfer(isAutoFocusTransfer);
98     return nullptr;
99 }
100 
JsConfigWindowMask(napi_env env,napi_callback_info info)101 static napi_value JsConfigWindowMask(napi_env env, napi_callback_info info)
102 {
103     auto delegate = EngineHelper::GetCurrentDelegateSafely();
104     if (!delegate) {
105         return nullptr;
106     }
107     napi_value argv[1] = { 0 };
108     napi_valuetype valueType = napi_undefined;
109     if (!GetSingleParam(env, info, argv, valueType) || (valueType != napi_boolean)) {
110         return nullptr;
111     }
112     bool enable = true;
113     napi_get_value_bool(env, argv[0], &enable);
114     delegate->ConfigWindowMask(enable);
115     return nullptr;
116 }
117 
JSActivate(napi_env env,napi_callback_info info)118 static napi_value JSActivate(napi_env env, napi_callback_info info)
119 {
120     size_t argc = ARGC_ACTIVATE_PARAMTER;
121     napi_value argv[ARGC_ACTIVATE_PARAMTER] = { nullptr };
122     napi_value thisVar = nullptr;
123     void* data = nullptr;
124     napi_get_cb_info(env, info, &argc, argv, &thisVar, &data);
125     NAPI_ASSERT(env, argc >= 1, "requires at least 1 parameter");
126     napi_valuetype type = napi_undefined;
127     napi_typeof(env, argv[0], &type);
128     NAPI_ASSERT(env, type == napi_boolean, "the type of argv[0] is not bool");
129     bool isActive = false;
130     napi_get_value_bool(env, argv[0], &isActive);
131 
132     bool autoInactive = true;
133     if (argc == ARGC_ACTIVATE_PARAMTER) {
134         napi_typeof(env, argv[1], &type);
135         NAPI_ASSERT(env, type == napi_boolean, "the type of argv[1] is not bool");
136         napi_get_value_bool(env, argv[1], &autoInactive);
137     }
138 
139     napi_value obj = nullptr;
140     auto delegate = EngineHelper::GetCurrentDelegateSafely();
141     if (!delegate) {
142         napi_get_boolean(env, false, &obj);
143         return obj;
144     }
145     delegate->Activate(isActive, autoInactive);
146     napi_get_null(env, &obj);
147     return obj;
148 }
149 
JsSetKeyProcessingMode(napi_env env,napi_callback_info info)150 static napi_value JsSetKeyProcessingMode(napi_env env, napi_callback_info info)
151 {
152     auto delegate = EngineHelper::GetCurrentDelegateSafely();
153     if (!delegate) {
154         return nullptr;
155     }
156     napi_value argv[1] = { 0 };
157     napi_valuetype valueType = napi_undefined;
158     if (!GetSingleParam(env, info, argv, valueType) || (valueType != napi_number)) {
159         return nullptr;
160     }
161     int32_t keyProcessingMode = 0;
162     napi_get_value_int32(env, argv[0], &keyProcessingMode);
163     delegate->SetKeyProcessingMode(keyProcessingMode);
164     return nullptr;
165 }
166 
registerFunc(napi_env env,napi_value exports)167 static napi_value registerFunc(napi_env env, napi_value exports)
168 {
169     napi_property_descriptor animatorDesc[] = {
170         DECLARE_NAPI_FUNCTION("clearFocus", JSClearFocus),
171         DECLARE_NAPI_FUNCTION("requestFocus", JSRequestFocus),
172         DECLARE_NAPI_FUNCTION("activate", JSActivate),
173         DECLARE_NAPI_FUNCTION("setAutoFocusTransfer", JsSetAutoFocusTransfer),
174         DECLARE_NAPI_FUNCTION("configWindowMask", JsConfigWindowMask),
175         DECLARE_NAPI_FUNCTION("setKeyProcessingMode", JsSetKeyProcessingMode),
176     };
177     NAPI_CALL(env, napi_define_properties(env, exports, sizeof(animatorDesc) / sizeof(animatorDesc[0]), animatorDesc));
178     return exports;
179 }
180 
181 static napi_module focusControllerModule = {
182     .nm_version = 1,
183     .nm_flags = 0,
184     .nm_filename = nullptr,
185     .nm_register_func = registerFunc,
186     .nm_modname = "arkui.focusController",
187     .nm_priv = ((void*)0),
188     .reserved = { 0 },
189 };
190 
FocusControllerRegister()191 extern "C" __attribute__((constructor)) void FocusControllerRegister()
192 {
193     napi_module_register(&focusControllerModule);
194 }
195 } // namespace OHOS::Ace::Napi