• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2025 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 "js_ability_vertical_panel.h"
17 
18 #include "hilog_tag_wrapper.h"
19 #include "ipc_skeleton.h"
20 #include "js_panel_start_callback.h"
21 #include "js_error_utils.h"
22 #include "js_runtime_utils.h"
23 #include "napi_base_context.h"
24 #include "napi_common_util.h"
25 #include "napi_common_want.h"
26 #include "native_engine/native_value.h"
27 #include "screen_config.h"
28 #include "start_vertical_panel.h"
29 #include "tokenid_kit.h"
30 
31 namespace OHOS {
32 namespace AbilityRuntime {
33 constexpr int32_t INDEX_ZERO = 0;
34 constexpr int32_t INDEX_ONE = 1;
35 constexpr int32_t INDEX_TWO = 2;
36 constexpr int32_t INDEX_THREE = 3;
37 constexpr size_t ARGC_FOUR = 4;
38 
SetNamedProperty(napi_env env,napi_value dstObj,const char * objName,const char * propName)39 static void SetNamedProperty(napi_env env, napi_value dstObj, const char *objName, const char *propName)
40 {
41     TAG_LOGD(AAFwkTag::VERTICAL_PANEL, "SetNamedProperty called");
42     napi_value prop = nullptr;
43     napi_create_string_utf8(env, objName, NAPI_AUTO_LENGTH, &prop);
44     napi_set_named_property(env, dstObj, propName, prop);
45 }
46 
47 class JsAbilityVerticalPanel {
48 public:
49     JsAbilityVerticalPanel() = default;
50     ~JsAbilityVerticalPanel() = default;
51 
Finalizer(napi_env env,void * data,void * hint)52     static void Finalizer(napi_env env, void *data, void *hint)
53     {
54         TAG_LOGI(AAFwkTag::VERTICAL_PANEL, "finalizer");
55         std::unique_ptr<JsAbilityVerticalPanel>(static_cast<JsAbilityVerticalPanel*>(data));
56     }
57 
StartVerticalPanel(napi_env env,napi_callback_info info)58     static napi_value StartVerticalPanel(napi_env env, napi_callback_info info)
59     {
60         GET_NAPI_INFO_AND_CALL(env, info, JsAbilityVerticalPanel, OnStartVerticalPanel);
61     }
62 
63 private:
GetContext(napi_env env,napi_value value,std::shared_ptr<OHOS::AbilityRuntime::AbilityContext> & abilityContext)64     static bool GetContext(napi_env env, napi_value value,
65         std::shared_ptr<OHOS::AbilityRuntime::AbilityContext> &abilityContext)
66     {
67         bool stageMode = false;
68         napi_status status = OHOS::AbilityRuntime::IsStageContext(env, value, stageMode);
69         if (status != napi_ok || !stageMode) {
70             TAG_LOGE(AAFwkTag::VERTICAL_PANEL, "Get context It is not a stage mode");
71             return false;
72         }
73 
74         auto context = AbilityRuntime::GetStageModeContext(env, value);
75         if (context == nullptr) {
76             TAG_LOGE(AAFwkTag::VERTICAL_PANEL, "Get context GetStageModeContext failed");
77             return false;
78         }
79 
80         abilityContext = AbilityRuntime::Context::ConvertTo<AbilityRuntime::AbilityContext>(context);
81         if (abilityContext == nullptr || abilityContext->GetApplicationInfo() == nullptr) {
82             TAG_LOGE(AAFwkTag::VERTICAL_PANEL, "Get context failed");
83             return false;
84         }
85 
86         return true;
87     }
88 
UnwrapScreenConfig(napi_env env,napi_value param,AAFwk::ScreenConfig & screenConfig)89     static bool UnwrapScreenConfig(napi_env env, napi_value param, AAFwk::ScreenConfig &screenConfig)
90     {
91         if (!AppExecFwk::IsTypeForNapiValue(env, param, napi_object)) {
92             TAG_LOGE(AAFwkTag::VERTICAL_PANEL, "UnwrapScreenConfig param IsTypeForNapiValue failed");
93             return false;
94         }
95 
96         napi_value type = nullptr;
97         napi_get_named_property(env, param, "type", &type);
98         if (type == nullptr || !ConvertFromJsValue(env, type, screenConfig.type)) {
99             TAG_LOGE(AAFwkTag::VERTICAL_PANEL, "parse UnwrapScreenConfig failed: type");
100             return false;
101         }
102 
103         napi_value sourceAppInfo = nullptr;
104         napi_get_named_property(env, param, "sourceAppInfo", &sourceAppInfo);
105         if (sourceAppInfo == nullptr || !AppExecFwk::IsTypeForNapiValue(env, sourceAppInfo, napi_object)) {
106             TAG_LOGE(AAFwkTag::VERTICAL_PANEL, "parse UnwrapScreenConfig failed: sourceAppInfo");
107             return false;
108         }
109 
110         napi_valuetype jsValueType = napi_undefined;
111         napi_value jsProNameList = nullptr;
112         uint32_t jsProCount = 0;
113 
114         NAPI_CALL_BASE(env, napi_get_property_names(env, sourceAppInfo, &jsProNameList), false);
115         NAPI_CALL_BASE(env, napi_get_array_length(env, jsProNameList, &jsProCount), false);
116 
117         napi_value jsProName = nullptr;
118         napi_value jsProValue = nullptr;
119         for (uint32_t index = 0; index < jsProCount; index++) {
120             NAPI_CALL_BASE(env, napi_get_element(env, jsProNameList, index, &jsProName), false);
121 
122             std::string strProName = AppExecFwk::UnwrapStringFromJS(env, jsProName);
123             TAG_LOGD(AAFwkTag::VERTICAL_PANEL, "property name=%{public}s", strProName.c_str());
124             NAPI_CALL_BASE(env, napi_get_named_property(env, sourceAppInfo, strProName.c_str(), &jsProValue), false);
125             NAPI_CALL_BASE(env, napi_typeof(env, jsProValue, &jsValueType), false);
126 
127             std::string natValue = AppExecFwk::UnwrapStringFromJS(env, jsProValue);
128             screenConfig.sourceAppInfo[strProName] = natValue;
129         }
130         return true;
131     }
132 
ExecuteStartVerticalPanel(napi_env env,std::shared_ptr<OHOS::AbilityRuntime::AbilityContext> abilityContext,const AAFwk::WantParams & wantParam,const AAFwk::ScreenConfig & screenConfig,std::shared_ptr<JsPanelStartCallback> callback)133     napi_value ExecuteStartVerticalPanel(napi_env env,
134         std::shared_ptr<OHOS::AbilityRuntime::AbilityContext> abilityContext,
135         const AAFwk::WantParams &wantParam,
136         const AAFwk::ScreenConfig &screenConfig,
137         std::shared_ptr<JsPanelStartCallback> callback)
138     {
139         auto innerErrCode = std::make_shared<ErrCode>(ERR_OK);
140         NapiAsyncTask::ExecuteCallback execute =
141             [abilityContext, wantParamCopy = wantParam, screenConfig, callback, innerErrCode]() mutable {
142 #ifdef SUPPORT_SCREEN
143                 *innerErrCode = OHOS::AbilityRuntime::StartVerticalPanel(
144                     abilityContext, wantParamCopy, screenConfig, callback);
145 #endif
146             };
147         NapiAsyncTask::CompleteCallback complete =
148             [innerErrCode](napi_env env, NapiAsyncTask& task, int32_t status) {
149                 if (*innerErrCode == ERR_OK) {
150                     task.ResolveWithNoError(env, CreateJsUndefined(env));
151                 } else {
152                     task.Reject(env, CreateJsErrorByNativeErr(env, *innerErrCode));
153                 }
154             };
155         napi_value result = nullptr;
156         NapiAsyncTask::ScheduleHighQos("JsAbilityVerticalPanel::OnStartVerticalPanel",
157             env, CreateAsyncTaskWithLastParam(env, nullptr, std::move(execute), std::move(complete), &result));
158         return result;
159     }
160 
OnStartVerticalPanel(napi_env env,NapiCallbackInfo & info)161     napi_value OnStartVerticalPanel(napi_env env, NapiCallbackInfo &info)
162     {
163         TAG_LOGD(AAFwkTag::VERTICAL_PANEL, "OnStartVerticalPanel call");
164 
165         auto selfToken = IPCSkeleton::GetSelfTokenID();
166         if (!Security::AccessToken::TokenIdKit::IsSystemAppByFullTokenID(selfToken)) {
167             TAG_LOGE(AAFwkTag::VERTICAL_PANEL, "This application is not system-app,"
168                 "can not use system-api");
169             ThrowNotSystemAppError(env);
170             return CreateJsUndefined(env);
171         }
172 
173         if (info.argc < ARGC_FOUR) {
174             TAG_LOGE(AAFwkTag::VERTICAL_PANEL, "OnStartVerticalPanel invalid params");
175             ThrowTooFewParametersError(env);
176             return CreateJsUndefined(env);
177         }
178 
179         std::shared_ptr<OHOS::AbilityRuntime::AbilityContext> abilityContext;
180         if (!GetContext(env, info.argv[INDEX_ZERO], abilityContext)) {
181             TAG_LOGE(AAFwkTag::VERTICAL_PANEL, "OnStartVerticalPanel parse context failed");
182             ThrowInvalidParamError(env, "Parse param context failed, context must be UIAbilityContext.");
183             return CreateJsUndefined(env);
184         }
185 
186         AAFwk::WantParams wantParam;
187         if (!AppExecFwk::UnwrapWantParams(env, info.argv[INDEX_ONE], wantParam)) {
188             TAG_LOGE(AAFwkTag::VERTICAL_PANEL, "OnStartVerticalPanel parse wantParam failed");
189             ThrowInvalidParamError(env, "Parse param want failed, want must be Want.");
190             return CreateJsUndefined(env);
191         }
192 
193         AAFwk::ScreenConfig screenConfig;
194         if (!UnwrapScreenConfig(env, info.argv[INDEX_TWO], screenConfig)) {
195             TAG_LOGE(AAFwkTag::VERTICAL_PANEL, "OnStartVerticalPanel parse screenConfig failed");
196             ThrowInvalidParamError(env, "Parse param screenConfig failed, screenConfig must be ScreenConfig.");
197             return CreateJsUndefined(env);
198         }
199 
200         std::shared_ptr<JsPanelStartCallback> callback = std::make_shared<JsPanelStartCallback>(env);
201         callback->SetJsCallbackObject(info.argv[INDEX_THREE]);
202         return ExecuteStartVerticalPanel(env, abilityContext, wantParam, screenConfig, callback);
203     }
204 };
205 
JsAbilityVerticalPanelInit(napi_env env,napi_value exportObj)206 napi_value JsAbilityVerticalPanelInit(napi_env env, napi_value exportObj)
207 {
208     if (env == nullptr || exportObj == nullptr) {
209         TAG_LOGE(AAFwkTag::VERTICAL_PANEL, "null env or exportObj");
210         return nullptr;
211     }
212 
213     napi_value verticalType = nullptr;
214     napi_create_object(env, &verticalType);
215     SetNamedProperty(env, verticalType, "navigation", "NAVIGATION");
216 
217     napi_value bundleName = nullptr;
218     napi_create_string_utf8(env, "bundleName", NAPI_AUTO_LENGTH, &bundleName);
219     napi_value moduleNameProp = nullptr;
220     napi_create_string_utf8(env, "moduleName", NAPI_AUTO_LENGTH, &moduleNameProp);
221     napi_value abilityName = nullptr;
222     napi_create_string_utf8(env, "abilityName", NAPI_AUTO_LENGTH, &abilityName);
223     napi_value windowId = nullptr;
224     napi_create_string_utf8(env, "windowId", NAPI_AUTO_LENGTH, &windowId);
225     napi_value screenMode = nullptr;
226     napi_create_string_utf8(env, "screenMode", NAPI_AUTO_LENGTH, &screenMode);
227 
228     napi_property_descriptor exportFuncs[] = {
229         DECLARE_NAPI_PROPERTY("VerticalType", verticalType),
230         DECLARE_NAPI_PROPERTY("SOURCE_APP_BUNDLE_NAME", bundleName),
231         DECLARE_NAPI_PROPERTY("SOURCE_APP_MODULE_NAME", moduleNameProp),
232         DECLARE_NAPI_PROPERTY("SOURCE_APP_ABILITY_NAME", abilityName),
233         DECLARE_NAPI_PROPERTY("SOURCE_APP_WINDOW_ID", windowId),
234         DECLARE_NAPI_PROPERTY("SOURCE_APP_SCREEN_MODE", screenMode),
235     };
236     napi_define_properties(env, exportObj, sizeof(exportFuncs) / sizeof(*exportFuncs), exportFuncs);
237 
238     auto jsAbilityVerticalPanel = std::make_unique<JsAbilityVerticalPanel>();
239     napi_wrap(env, exportObj, jsAbilityVerticalPanel.release(),
240         JsAbilityVerticalPanel::Finalizer, nullptr, nullptr);
241 
242     const char *moduleName = "JsAbilityVerticalPanel";
243     BindNativeFunction(env, exportObj, "startVerticalPanel", moduleName, JsAbilityVerticalPanel::StartVerticalPanel);
244     TAG_LOGD(AAFwkTag::VERTICAL_PANEL, "end");
245     return CreateJsUndefined(env);
246 }
247 } // namespace AbilityRuntime
248 } // namespace OHOS