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_router.h"
17 
18 #include "ace_log.h"
19 #if ((OHOS_ACELITE_PRODUCT_WATCH == 1) || (FEATURE_CUSTOM_ENTRY_PAGE == 1))
20 #include "dft_impl.h"
21 #endif
22 #include "async_task_manager.h"
23 #include "js_page_state_machine.h"
24 #include "js_profiler.h"
25 
26 namespace OHOS {
27 namespace ACELite {
ReplaceAsync(void * data)28 static void ReplaceAsync(void *data)
29 {
30     if (data == nullptr) {
31         HILOG_ERROR(HILOG_MODULE_ACE, "replace async failed with null input parameter");
32         return;
33     }
34     // void* can not be dynamically_casted from
35     auto router = static_cast<Router *>(data);
36     router->ReplaceSync();
37     OUTPUT_TRACE();
38 }
39 
Replace(jerry_value_t object,bool async)40 jerry_value_t Router::Replace(jerry_value_t object, bool async)
41 {
42     if (newSm_ != nullptr) {
43         HILOG_ERROR(HILOG_MODULE_ACE, "router is replacing, can not handle the new request");
44         return UNDEFINED;
45     }
46     StateMachine *newSm = new StateMachine();
47     if (newSm == nullptr) {
48         HILOG_ERROR(HILOG_MODULE_ACE, "malloc state machine memory heap failed.");
49         return UNDEFINED;
50     }
51     // init new state machine
52     jerry_value_t jsRes = jerry_create_undefined();
53     bool res = newSm->Init(object, jsRes);
54     if (!res) {
55         delete newSm;
56         return jsRes;
57     }
58     newSm_ = newSm;
59     // dispatch the new page rendering to the async handling as the current context of
60     // router.replace need to be released, which need to return out from the scope
61     if (async) {
62         if (DISPATCH_FAILURE == AsyncTaskManager::GetInstance().Dispatch(ReplaceAsync, this)) {
63             // request replacing failed, no chance to do it, release the new state machine
64             HILOG_ERROR(HILOG_MODULE_ACE, "dispatch replacing request failed");
65             delete newSm_;
66             newSm_ = nullptr;
67         }
68     } else {
69         // for the first startup of application, no need to do the async replace
70         ReplaceSync();
71     }
72     return jsRes;
73 }
74 
ReplaceSync()75 void Router::ReplaceSync()
76 {
77     if (newSm_ == nullptr) {
78         HILOG_ERROR(HILOG_MODULE_ACE, "replace sync failed, new sm should be prepared");
79         return;
80     }
81     START_TRACING(ROUTER_REPLACE);
82     // new state machine run successfully to show new page, then need to release old state machine.
83     if (currentSm_ != nullptr) {
84         delete currentSm_;
85         currentSm_ = nullptr;
86     }
87     // new state machine should to be current.
88     currentSm_ = newSm_;
89     newSm_ = nullptr;
90     currentSm_->SetHiddenFlag(hidden_);
91     // run state machine and start to jump to init state.
92     currentSm_->ChangeState(INIT_STATE);
93     if (hidden_) {
94         HILOG_DEBUG(HILOG_MODULE_ACE, "the whole application is in background, move to HIDE state directly");
95         // the whole app is in background, move to HIDE state immediately
96         currentSm_->ChangeState(BACKGROUND_STATE);
97     } else {
98         // above call will move sm into ready state, than let the page show
99         currentSm_->ChangeState(SHOW_STATE);
100     }
101 #if ((OHOS_ACELITE_PRODUCT_WATCH == 1) || (FEATURE_CUSTOM_ENTRY_PAGE == 1))
102     DftImpl::GetInstance()->CallbackPageReplaced(currentSm_->GetCurrentState());
103 #endif
104     STOP_TRACING();
105 }
106 
Show()107 void Router::Show()
108 {
109     if (currentSm_ == nullptr) {
110         HILOG_ERROR(HILOG_MODULE_ACE, "no SM when performing show");
111         return;
112     }
113 
114     hidden_ = false;
115     currentSm_->SetHiddenFlag(hidden_);
116     currentSm_->ChangeState(SHOW_STATE);
117 }
118 
Hide()119 void Router::Hide()
120 {
121     if (currentSm_ == nullptr) {
122         HILOG_ERROR(HILOG_MODULE_ACE, "no SM when performing background");
123         return;
124     }
125 
126     currentSm_->ChangeState(BACKGROUND_STATE);
127     hidden_ = true;
128     currentSm_->SetHiddenFlag(hidden_);
129 }
130 } // namespace ACELite
131 } // namespace OHOS
132