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_insight_intent_page.h"
17
18 #include <want_params.h>
19
20 #include "execute_ohmurl_operator.h"
21 #include "hilog_tag_wrapper.h"
22 #include "insight_intent_constant.h"
23 #include "insight_intent_execute_result.h"
24 #include "js_insight_intent_utils.h"
25 #include "js_runtime.h"
26 #include "js_runtime_utils.h"
27 #include "napi_common_execute_result.h"
28 #include "napi_common_util.h"
29 #include "napi_common_want.h"
30 #include "native_reference.h"
31
32 #undef STATE_PATTERN_NAIVE_H
33 #define STATE_PATTERN_NAIVE_STATE state_
34 #include "state_pattern_naive.h"
35
36 namespace OHOS {
37 namespace AbilityRuntime {
38 namespace {
39 constexpr char INSIGHT_INTENT_DOT_BUNDLE_NAME[] = "ohos.insightIntent.bundleName";
40 constexpr char INSIGHT_INTENT_DOT_MODULE_NAME[] = "ohos.insightIntent.moduleName";
41 constexpr char INSIGHT_INTENT_DOT_HAP_PATH[] = "ohos.insightIntent.hapPath";
42 } // namespace
43
Create(JsRuntime & runtime)44 std::shared_ptr<JsInsightIntentPage> JsInsightIntentPage::Create(JsRuntime& runtime)
45 {
46 return std::make_shared<JsInsightIntentPage>(runtime);
47 }
48
JsInsightIntentPage(JsRuntime & runtime)49 JsInsightIntentPage::JsInsightIntentPage(JsRuntime& runtime) : runtime_(runtime)
50 {
51 TAG_LOGD(AAFwkTag::INTENT, "constructor");
52 }
53
~JsInsightIntentPage()54 JsInsightIntentPage::~JsInsightIntentPage()
55 {
56 state_ = State::DESTROYED;
57 TAG_LOGI(AAFwkTag::INTENT, "destructor");
58 }
59
Init(const InsightIntentExecutorInfo & insightIntentInfo)60 bool JsInsightIntentPage::Init(const InsightIntentExecutorInfo& insightIntentInfo)
61 {
62 TAG_LOGD(AAFwkTag::INTENT, "Init");
63 STATE_PATTERN_NAIVE_ACCEPT(State::CREATED, false);
64 state_ = State::INITIALIZED;
65 InsightIntentExecutor::Init(insightIntentInfo);
66
67 HandleScope handleScope(runtime_);
68 bool ret = JsInsightIntentPage::LoadJsCode(insightIntentInfo, runtime_);
69 if (!ret) {
70 TAG_LOGE(AAFwkTag::INTENT, "load js failed");
71 STATE_PATTERN_NAIVE_STATE_SET_AND_RETURN(State::INVALID, false);
72 }
73
74 return true;
75 }
76
HandleExecuteIntent(std::shared_ptr<InsightIntentExecuteParam> executeParam,const std::shared_ptr<NativeReference> & pageLoader,std::unique_ptr<InsightIntentExecutorAsyncCallback> callback,bool & isAsync)77 bool JsInsightIntentPage::HandleExecuteIntent(
78 std::shared_ptr<InsightIntentExecuteParam> executeParam,
79 const std::shared_ptr<NativeReference>& pageLoader,
80 std::unique_ptr<InsightIntentExecutorAsyncCallback> callback,
81 bool& isAsync)
82 {
83 STATE_PATTERN_NAIVE_ACCEPT(State::INITIALIZED, false);
84 state_ = State::EXECUTING;
85
86 if (callback == nullptr || callback->IsEmpty()) {
87 TAG_LOGE(AAFwkTag::INTENT, "null callback");
88 STATE_PATTERN_NAIVE_STATE_SET_AND_RETURN(State::INVALID, false);
89 }
90
91 if (executeParam == nullptr || executeParam->insightIntentParam_ == nullptr) {
92 TAG_LOGE(AAFwkTag::INTENT, "invalid execute param");
93 STATE_PATTERN_NAIVE_STATE_SET_AND_RETURN(State::INVALID, false);
94 }
95
96 callback_ = std::move(callback);
97 auto name = executeParam->insightIntentName_;
98 auto param = executeParam->insightIntentParam_;
99 TAG_LOGD(AAFwkTag::INTENT, "execute intent %{public}s", name.c_str());
100 bool successful = ExecuteInsightIntent(name, *param);
101 isAsync = false;
102 return successful;
103 }
104
LoadJsCode(const InsightIntentExecutorInfo & info,JsRuntime & runtime)105 bool JsInsightIntentPage::LoadJsCode(const InsightIntentExecutorInfo& info, JsRuntime& runtime)
106 {
107 TAG_LOGD(AAFwkTag::INTENT, "load module");
108 auto executeParam = info.executeParam;
109 if (executeParam == nullptr) {
110 TAG_LOGE(AAFwkTag::INTENT, "null executeParam");
111 return false;
112 }
113
114 std::string moduleName(executeParam->moduleName_);
115 std::string hapPath(info.hapPath);
116 std::string srcEntrance(executeParam->srcEntrance_);
117 TAG_LOGD(AAFwkTag::INTENT, "moduleName %{public}s, hapPath %{private}s, srcEntrance %{private}s",
118 moduleName.c_str(), hapPath.c_str(), srcEntrance.c_str());
119
120 return runtime.ExecuteSecureWithOhmUrl(moduleName, hapPath, srcEntrance);
121 }
122
ReplyFailedInner(InsightIntentInnerErr innerErr)123 void JsInsightIntentPage::ReplyFailedInner(InsightIntentInnerErr innerErr)
124 {
125 TAG_LOGD(AAFwkTag::INTENT, "reply failed");
126 state_ = State::INVALID;
127 auto* callback = callback_.release();
128 JsInsightIntentUtils::ReplyFailed(callback, innerErr);
129 }
130
ReplySucceededInner(std::shared_ptr<AppExecFwk::InsightIntentExecuteResult> resultCpp)131 void JsInsightIntentPage::ReplySucceededInner(std::shared_ptr<AppExecFwk::InsightIntentExecuteResult> resultCpp)
132 {
133 TAG_LOGD(AAFwkTag::INTENT, "reply succeed");
134 state_ = State::EXECUTATION_DONE;
135 auto* callback = callback_.release();
136 JsInsightIntentUtils::ReplySucceeded(callback, resultCpp);
137 }
138
ExecuteInsightIntent(const std::string & name,const AAFwk::WantParams & param)139 bool JsInsightIntentPage::ExecuteInsightIntent(
140 const std::string& name,
141 const AAFwk::WantParams& param)
142 {
143 TAG_LOGD(AAFwkTag::INTENT, "execute insight intent page");
144 auto result = std::make_shared<AppExecFwk::InsightIntentExecuteResult>();
145 ReplySucceededInner(result);
146 return true;
147 }
148
SetInsightIntentParam(JsRuntime & runtime,const std::string & hapPath,const AAFwk::Want & want,wptr<Rosen::Window> window,bool coldStart)149 void JsInsightIntentPage::SetInsightIntentParam(JsRuntime& runtime, const std::string &hapPath,
150 const AAFwk::Want &want, wptr<Rosen::Window> window, bool coldStart)
151 {
152 TAG_LOGD(AAFwkTag::INTENT, "set intent param");
153 auto windowSptr = window.promote();
154 if (windowSptr == nullptr) {
155 TAG_LOGE(AAFwkTag::INTENT, "invalid window");
156 return;
157 }
158
159 // parse want and get insight intent info
160 auto executeParam = std::make_shared<InsightIntentExecuteParam>();
161 auto ret = InsightIntentExecuteParam::GenerateFromWant(want, *executeParam);
162 if (!ret) {
163 TAG_LOGE(AAFwkTag::INTENT, "invalid params");
164 return;
165 }
166
167 Want newWant;
168 auto insightIntentParam = executeParam->insightIntentParam_;
169 if (insightIntentParam != nullptr) {
170 sptr<AAFwk::IWantParams> pExecuteParams = AAFwk::WantParamWrapper::Box(*insightIntentParam);
171 if (pExecuteParams != nullptr) {
172 WantParams wantParams;
173 wantParams.SetParam(AppExecFwk::INSIGHT_INTENT_EXECUTE_PARAM_PARAM, pExecuteParams);
174 newWant.SetParams(wantParams);
175 }
176 }
177 // param of page insight intent
178 newWant.SetParam(AppExecFwk::INSIGHT_INTENT_PAGE_PARAM_PAGEPATH, executeParam->pagePath_);
179 newWant.SetParam(AppExecFwk::INSIGHT_INTENT_PAGE_PARAM_NAVIGATIONID, executeParam->navigationId_);
180 newWant.SetParam(AppExecFwk::INSIGHT_INTENT_PAGE_PARAM_NAVDESTINATIONNAME, executeParam->navDestinationName_);
181
182 // param of common
183 newWant.SetParam(INSIGHT_INTENT_DOT_BUNDLE_NAME, executeParam->bundleName_);
184 newWant.SetParam(INSIGHT_INTENT_DOT_MODULE_NAME, executeParam->moduleName_);
185 newWant.SetParam(INSIGHT_INTENT_DOT_HAP_PATH, hapPath);
186
187 auto* env = runtime.GetNapiEnv();
188 if (env == nullptr) {
189 TAG_LOGE(AAFwkTag::INTENT, "env nullptr");
190 return;
191 }
192 napi_value paramNapiVal = AppExecFwk::WrapWantParams(env, newWant.GetParams());
193 std::string paramStr = JsInsightIntentUtils::StringifyObject(env, paramNapiVal);
194 TAG_LOGD(AAFwkTag::INTENT, "param string %{private}s", paramStr.c_str());
195
196 Rosen::WMError wmRet = windowSptr->SetIntentParam(paramStr,
197 ExecuteOhmUrlOperator(runtime, executeParam->moduleName_, hapPath, executeParam->pagePath_), coldStart);
198 if (wmRet != Rosen::WMError::WM_OK) {
199 TAG_LOGE(AAFwkTag::INTENT, "Set intent param failed %{public}d", wmRet);
200 }
201 }
202 } // namespace AbilityRuntime
203 } // namespace OHOS
204