• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2020-2021 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_impl.h"
17 #include "ace_event_error_code.h"
18 #include "ace_log.h"
19 #include "component.h"
20 #include "component_utils.h"
21 #include "fatal_handler.h"
22 #include "js_app_context.h"
23 #include "js_app_environment.h"
24 #include "js_profiler.h"
25 #include "module_manager.h"
26 #include "presets/localization_module.h"
27 #include "presets/timer_module.h"
28 #include "securec.h"
29 
30 namespace OHOS {
31 namespace ACELite {
InitEnvironment(const char * const abilityPath,const char * const bundleName,uint16_t token)32 void JSAbilityImpl::InitEnvironment(const char * const abilityPath, const char * const bundleName, uint16_t token)
33 {
34     if ((abilityPath == nullptr) || strlen(abilityPath) == 0 || (bundleName == nullptr) || strlen(bundleName) == 0) {
35         HILOG_ERROR(HILOG_MODULE_ACE, "invalid input parameters");
36         return;
37     }
38 
39     if (isEnvInit_) {
40         HILOG_ERROR(HILOG_MODULE_ACE, "already initialized, return");
41         return;
42     }
43     // init engine && js fwk
44     JsAppEnvironment *appJsEnv = JsAppEnvironment::GetInstance();
45     appContext_ = JsAppContext::GetInstance();
46     // check if we should use snapshot mode, do this before everything,
47     // but after debugger config is set
48     appJsEnv->InitRuntimeMode();
49     appContext_->SetCurrentAbilityInfo(abilityPath, bundleName, token);
50     appContext_->SetTopJSAbilityImpl(this);
51     appJsEnv->InitJsFramework();
52     appContext_->LoadApiVersion();
53 
54     // initialize js object after engine started up
55     abilityModel_ = UNDEFINED;
56     nativeElement_ = UNDEFINED;
57     isEnvInit_ = true;
58 
59     // relocate app.js fullpath
60     const char * const appJSFileName = (appJsEnv->IsSnapshotMode()) ? "app.bc" : "app.js";
61     char *fileFullPath = RelocateJSSourceFilePath(abilityPath, appJSFileName);
62     if (fileFullPath == nullptr) {
63         HILOG_ERROR(HILOG_MODULE_ACE, "relocate js file failed");
64         ACE_ERROR_CODE_PRINT(EXCE_ACE_FWK_LAUNCH_FAILED, EXCE_ACE_APP_ENTRY_MISSING);
65         return;
66     }
67 
68     appContext_->SetAbilityState(TopAbilityState::ABILITY_INITIALIZED);
69     START_TRACING(APP_CODE_EVAL);
70     abilityModel_ = appContext_->Eval(fileFullPath, strlen(fileFullPath), true); // generate global.$app js object
71     STOP_TRACING();
72 
73     ace_free(fileFullPath);
74     fileFullPath = nullptr;
75     router_ = new Router();
76     if (router_ == nullptr) {
77         HILOG_ERROR(HILOG_MODULE_ACE, "malloc router heap memory failed.");
78         return;
79     }
80 }
81 
CleanUp()82 void JSAbilityImpl::CleanUp()
83 {
84     if (appContext_ == nullptr) {
85         return;
86     }
87     appContext_->SetAbilityState(TopAbilityState::ABILITY_DESTROYING);
88     if (!isEnvInit_) {
89         return;
90     }
91     START_TRACING(APP_ON_DESTROY);
92     // clean up user's js
93     InvokeOnDestroy();
94     STOP_TRACING();
95 
96     // delete router's resources about page
97     if (router_ != nullptr) {
98         delete router_;
99         router_ = nullptr;
100     }
101     TimersModule::Clear();
102     LocalModule::Clear();
103 
104     appContext_->ClearContext();
105 
106     ModuleManager::GetInstance()->OnTerminate();
107     JsAppEnvironment::GetInstance()->Cleanup();
108     isEnvInit_ = false;
109     appContext_->SetAbilityState(TopAbilityState::ABILITY_DESTROYED);
110     OUTPUT_TRACE();
111 }
112 
DeliverCreate(const char * param)113 void JSAbilityImpl::DeliverCreate(const char *param)
114 {
115     if (appContext_ == nullptr) {
116         return;
117     }
118     appContext_->SetAbilityState(TopAbilityState::ABILITY_LAUNCHING);
119     START_TRACING(APP_ON_CREATE);
120     // call InvokeOnCreate
121     InvokeOnCreate();
122     STOP_TRACING();
123     // if we have done the render or not initialized yet, don't call render
124     if (rendered_) {
125         ACE_ERROR_CODE_PRINT(EXCE_ACE_FWK_LAUNCH_FAILED, EXCE_ACE_APP_RENDER_FAILED);
126         return;
127     }
128     // call render to setup user interface
129     jerry_value_t object = UNDEFINED;
130     if (param == nullptr) {
131         object = jerry_create_object();
132         JerrySetStringProperty(object, ROUTER_PAGE_URI, PATH_DEFAULT);
133     } else {
134         object = jerry_json_parse(reinterpret_cast<const jerry_char_t *>(param), strlen(param));
135     }
136     if (router_) {
137         jerry_release_value(router_->Replace(object, false));
138         rendered_ = true;
139     }
140     jerry_release_value(object);
141     appContext_->SetAbilityState(TopAbilityState::ABILITY_LAUNCHDONE);
142 }
143 
Show() const144 void JSAbilityImpl::Show() const
145 {
146     if (appContext_ == nullptr) {
147         return;
148     }
149     if (router_ == nullptr) {
150         HILOG_ERROR(HILOG_MODULE_ACE, "no router instance to perform the show request");
151         return;
152     }
153     appContext_->SetAbilityState(TopAbilityState::ABILITY_SHOWING);
154     router_->Show();
155     FatalHandler::GetInstance().NotifyVisibleStatusChange(true);
156     appContext_->SetAbilityState(TopAbilityState::ABILITY_SHOWN);
157 }
158 
Hide() const159 void JSAbilityImpl::Hide() const
160 {
161     if (appContext_ == nullptr) {
162         return;
163     }
164     if (router_ == nullptr) {
165         HILOG_ERROR(HILOG_MODULE_ACE, "no router instance to perform the hide request");
166         return;
167     }
168     appContext_->SetAbilityState(TopAbilityState::ABILITY_HIDING);
169     router_->Hide();
170     FatalHandler::GetInstance().NotifyVisibleStatusChange(false);
171     appContext_->SetAbilityState(TopAbilityState::ABILITY_HIDDEN);
172 }
173 
NotifyBackPressed() const174 void JSAbilityImpl::NotifyBackPressed() const
175 {
176     if (appContext_ == nullptr) {
177         return;
178     }
179 
180     InvokeOnBackPressed();
181 
182     appContext_->TerminateAbility();
183 }
184 
InvokeOnCreate() const185 void JSAbilityImpl::InvokeOnCreate() const
186 {
187     if (IS_UNDEFINED(abilityModel_)) {
188         HILOG_ERROR(HILOG_MODULE_ACE, "view model is undefined when call user's init");
189         return;
190     }
191     jerry_value_t onCreateFunction = jerryx_get_property_str(abilityModel_, ABILITY_LIFECYCLE_CALLBACK_ON_CREATE);
192     if (IS_UNDEFINED(onCreateFunction)) {
193         // user does not set onInit method
194         return;
195     }
196     CallJSFunctionAutoRelease(onCreateFunction, abilityModel_, nullptr, 0);
197     jerry_release_value(onCreateFunction);
198 }
199 
InvokeOnDestroy() const200 void JSAbilityImpl::InvokeOnDestroy() const
201 {
202     InvokeMethodWithoutParameter(ABILITY_LIFECYCLE_CALLBACK_ON_DESTROY);
203     // release FeatureAbility object
204     jerry_release_value(abilityModel_);
205 }
206 
InvokeOnBackPressed() const207 void JSAbilityImpl::InvokeOnBackPressed() const
208 {
209     InvokeMethodWithoutParameter(BACK_PRESSED_NAME);
210 }
211 
InvokeMethodWithoutParameter(const char * const name) const212 void JSAbilityImpl::InvokeMethodWithoutParameter(const char * const name) const
213 {
214     if (FatalHandler::GetInstance().IsJSRuntimeFatal()) {
215         // can not continue to involve any JS object creating on engine in case runtime fatal
216         return;
217     }
218     if ((name == nullptr) || strlen(name) == 0) {
219         return;
220     }
221 
222     jerry_value_t function = jerryx_get_property_str(abilityModel_, name);
223     if (IS_UNDEFINED(function)) {
224         // user does not set onBackpress method
225         return;
226     }
227     CallJSFunctionAutoRelease(function, abilityModel_, nullptr, 0);
228     jerry_release_value(function);
229 }
230 } // namespace ACELite
231 } // namespace OHOS
232