• 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 #include "bridge/arkts_frontend/arkts_plugin_frontend.h"
16 
17 #include <ani.h>
18 
19 #include "interfaces/inner_api/ace/constants.h"
20 #include "bridge/arkts_frontend/arkts_ani_utils.h"
21 #include "bridge/arkts_frontend/entry/arkts_entry_loader.h"
22 #include "core/pipeline/pipeline_context.h"
23 
24 namespace OHOS::Ace {
25 namespace {
26 /* copied from arkcompiler_ets_frontend vmloader.cc*/
27 struct AppInfo {
28     const char* className;
29     const char* createMethodName;
30     const char* createMethodSig;
31     const char* startMethodName;
32     const char* startMethodSig;
33     const char* enterMethodName;
34     const char* enterMethodSig;
35     const char* emitEventMethodName;
36     const char* emitEventMethodSig;
37 };
38 /* copied from arkcompiler_ets_frontend vmloader.cc*/
39 const AppInfo KOALA_APP_INFO = {
40     "Larkui/ArkUIEntry/Application;",
41     "createApplication",
42     "Lstd/core/String;Lstd/core/String;ZLstd/core/String;Larkui/UserView/UserView;Larkui/UserView/EntryPoint;"
43     ":Larkui/ArkUIEntry/Application;",
44     "start",
45     ":J",
46     "enter",
47     "IIJ:Z",
48     "emitEvent",
49     "IIII:V",
50 };
51 
RunArkoalaEventLoop(ani_env * env,ani_ref app)52 void RunArkoalaEventLoop(ani_env* env, ani_ref app)
53 {
54     ani_class appClass;
55     ANI_CALL(env, FindClass(KOALA_APP_INFO.className, &appClass), return);
56 
57     ani_method enter = nullptr;
58     ANI_CALL(env, Class_FindMethod(
59         appClass, KOALA_APP_INFO.enterMethodName, KOALA_APP_INFO.enterMethodSig, &enter), return);
60 
61     ani_int arg0 = 0;
62     ani_int arg1 = 0;
63     ani_boolean result;
64     ANI_CALL(env, Object_CallMethod_Boolean(
65         static_cast<ani_object>(app), enter, &result, arg0, arg1, nullptr), return);
66 }
67 } // namespace
68 
RunPage(const std::shared_ptr<std::vector<uint8_t>> & content,const std::string & params)69 UIContentErrorCode ArktsPluginFrontend::RunPage(
70     const std::shared_ptr<std::vector<uint8_t>>& content, const std::string& params)
71 {
72     return UIContentErrorCode::NO_ERRORS;
73 }
74 
RunPage(const std::string & url,const std::string & params)75 UIContentErrorCode ArktsPluginFrontend::RunPage(const std::string& url, const std::string& params)
76 {
77     std::vector<uint8_t> abcContent;
78     if (!Framework::GetAssetContentImpl(assetManager_, "ets/modules_static.abc", abcContent)) {
79         LOGE("GetAssetContent fail: ets/modules_static.abc");
80         return UIContentErrorCode::INVALID_URL;
81     }
82 
83     ani_class appClass{};
84     ANI_CALL(env_, FindClass(KOALA_APP_INFO.className, &appClass), return UIContentErrorCode::INVALID_URL);
85 
86     ani_static_method create;
87     ANI_CALL(env_, Class_FindStaticMethod(appClass, KOALA_APP_INFO.createMethodName, KOALA_APP_INFO.createMethodSig,
88         &create), return UIContentErrorCode::INVALID_URL);
89 
90     std::string appUrl = url.substr(0, url.rfind(".js"));
91 
92     ani_string aniUrl{};
93     env_->String_NewUTF8(appUrl.c_str(), appUrl.size(), &aniUrl);
94 
95     ani_string aniParams{};
96     env_->String_NewUTF8(params.c_str(), params.size(), &aniParams);
97 
98     NG::EntryLoader entryLoader {env_, abcContent};
99     if (!entryLoader) {
100         return UIContentErrorCode::INVALID_URL;
101     }
102 
103     std::string entryPath = pluginModuleName_ + "/src/main/ets/" + appUrl + "/__EntryWrapper";
104     ani_object entryPointObj = entryLoader.GetPageEntryObj(entryPath);
105 
106     std::string legacyEntryPath = pluginModuleName_ + "/src/main/ets/" + appUrl + "/ComExampleTrivialApplication";
107     ani_object legacyEntryPointObj = entryPointObj ? nullptr : entryLoader.GetPageEntryObj(legacyEntryPath);
108 
109     ani_string module{};
110     env_->String_NewUTF8(pluginModuleName_.c_str(), pluginModuleName_.size(), &module);
111 
112     ani_ref appLocal{};
113     ANI_CALL(env_, Class_CallStaticMethod_Ref(appClass, create, &appLocal, aniUrl, aniParams, false, module,
114         legacyEntryPointObj, entryPointObj), return UIContentErrorCode::INVALID_URL);
115 
116     env_->GlobalReference_Create(appLocal, &app_);
117 
118     ani_method start;
119     ANI_CALL(env_, Class_FindMethod(appClass, KOALA_APP_INFO.startMethodName, KOALA_APP_INFO.startMethodSig, &start),
120         return UIContentErrorCode::INVALID_URL);
121 
122     ani_long result;
123     ANI_CALL(env_, Object_CallMethod_Long(static_cast<ani_object>(app_), start, &result),
124         return UIContentErrorCode::INVALID_URL);
125 
126     CHECK_NULL_RETURN(pipeline_, UIContentErrorCode::NULL_POINTER);
127     pipeline_->SetVsyncListener([env = env_, app = app_]() { RunArkoalaEventLoop(env, app); });
128 
129     return UIContentErrorCode::NO_ERRORS;
130 }
131 
AttachPipelineContext(const RefPtr<PipelineBase> & context)132 void ArktsPluginFrontend::AttachPipelineContext(const RefPtr<PipelineBase>& context)
133 {
134     pipeline_ = DynamicCast<PipelineContext>(context);
135     if (accessibilityManager_) {
136         accessibilityManager_->SetPipelineContext(context);
137         accessibilityManager_->InitializeCallback();
138     }
139 }
140 
Destroy()141 void ArktsPluginFrontend::Destroy()
142 {
143     CHECK_NULL_VOID(env_);
144     env_->GlobalReference_Delete(app_);
145 }
146 
147 } // namespace OHOS::Ace
148