• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2023-2024 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_context.h"
17 
18 #include "ability_window_configuration.h"
19 #include "hilog_tag_wrapper.h"
20 #include "hitrace_meter.h"
21 #include "js_error_utils.h"
22 #include "napi_common_want.h"
23 
24 namespace OHOS {
25 namespace AbilityRuntime {
26 namespace {
27 constexpr static char CONTEXT_MODULE_NAME[] = "InsightIntentContext";
28 }
29 
Finalizer(napi_env env,void * data,void * hint)30 void JsInsightIntentContext::Finalizer(napi_env env, void* data, void* hint)
31 {
32     TAG_LOGI(AAFwkTag::INTENT, "called");
33     std::unique_ptr<JsInsightIntentContext>(static_cast<JsInsightIntentContext*>(data));
34 }
35 
StartAbiity(napi_env env,napi_callback_info info)36 napi_value JsInsightIntentContext::StartAbiity(napi_env env, napi_callback_info info)
37 {
38     HITRACE_METER_NAME(HITRACE_TAG_ABILITY_MANAGER, __PRETTY_FUNCTION__);
39     GET_NAPI_INFO_AND_CALL(env, info, JsInsightIntentContext, OnStartAbility);
40 }
41 
OnStartAbility(napi_env env,NapiCallbackInfo & info)42 napi_value JsInsightIntentContext::OnStartAbility(napi_env env, NapiCallbackInfo& info)
43 {
44     TAG_LOGD(AAFwkTag::INTENT, "called");
45     HITRACE_METER_NAME(HITRACE_TAG_ABILITY_MANAGER, __PRETTY_FUNCTION__);
46 
47     // unwrap want
48     AAFwk::Want want;
49 
50     bool checkParamResult = CheckStartAbilityParam(env, info, want);
51     if (!checkParamResult) {
52         TAG_LOGE(AAFwkTag::INTENT, "check startAbility param failed");
53         return CreateJsUndefined(env);
54     }
55 
56     auto context = context_.lock();
57     if (context == nullptr) {
58         TAG_LOGE(AAFwkTag::INTENT, "invalid context");
59         ThrowError(env, AbilityErrorCode::ERROR_CODE_INNER);
60         return CreateJsUndefined(env);
61     }
62 
63     // verify if bundleName is empty or invalid
64     auto bundleNameFromWant = want.GetElement().GetBundleName();
65     if (bundleNameFromWant.empty() || bundleNameFromWant != context->GetBundleName()) {
66         TAG_LOGE(AAFwkTag::INTENT, "bundleName is empty or invalid");
67         ThrowError(env, AbilityErrorCode::ERROR_CODE_OPERATION_NOT_SUPPORTED);
68         return CreateJsUndefined(env);
69     }
70     // modify windowmode setting
71     auto windowMode = context->GetCurrentWindowMode();
72     if (windowMode == AAFwk::AbilityWindowConfiguration::MULTI_WINDOW_DISPLAY_PRIMARY ||
73         windowMode == AAFwk::AbilityWindowConfiguration::MULTI_WINDOW_DISPLAY_SECONDARY) {
74         want.SetParam(AAFwk::Want::PARAM_RESV_WINDOW_MODE, windowMode);
75     }
76 
77     auto innerErrCode = std::make_shared<ErrCode>(ERR_OK);
78     // create execute task
79     NapiAsyncTask::ExecuteCallback execute = [weak = context_, want, innerErrCode]() {
80         auto context = weak.lock();
81         if (!context) {
82             TAG_LOGE(AAFwkTag::INTENT, "context is released");
83             *innerErrCode = static_cast<int>(AbilityErrorCode::ERROR_CODE_INVALID_CONTEXT);
84             return;
85         }
86         *innerErrCode = context->StartAbilityByInsightIntent(want);
87     };
88     // create complete task
89     NapiAsyncTask::CompleteCallback complete = [innerErrCode](napi_env env, NapiAsyncTask& task, int32_t status) {
90         if (*innerErrCode == ERR_OK) {
91             task.Resolve(env, CreateJsUndefined(env));
92         } else {
93             task.Reject(env, CreateJsErrorByNativeErr(env, *innerErrCode));
94         }
95     };
96 
97     napi_value lastParam = (info.argc > 1) ? info.argv[1] : nullptr;
98     napi_value result = nullptr;
99     NapiAsyncTask::ScheduleHighQos("JsInsightIntentContext::OnStartAbility", env,
100         CreateAsyncTaskWithLastParam(env, lastParam, std::move(execute), std::move(complete), &result));
101     TAG_LOGD(AAFwkTag::INTENT, "end");
102     return result;
103 }
104 
CreateJsInsightIntentContext(napi_env env,const std::shared_ptr<InsightIntentContext> & context)105 napi_value CreateJsInsightIntentContext(napi_env env, const std::shared_ptr<InsightIntentContext>& context)
106 {
107     TAG_LOGD(AAFwkTag::INTENT, "called");
108     napi_value contextObj;
109     napi_create_object(env, &contextObj);
110 
111     std::unique_ptr<JsInsightIntentContext> jsInsightIntentContext = std::make_unique<JsInsightIntentContext>(context);
112     napi_wrap(env, contextObj, jsInsightIntentContext.release(), JsInsightIntentContext::Finalizer, nullptr, nullptr);
113 
114     BindNativeFunction(env, contextObj, "startAbility", CONTEXT_MODULE_NAME, JsInsightIntentContext::StartAbiity);
115     TAG_LOGD(AAFwkTag::INTENT, "end");
116     return contextObj;
117 }
118 
CheckStartAbilityParam(napi_env env,NapiCallbackInfo & info,AAFwk::Want & want)119 bool CheckStartAbilityParam(napi_env env, NapiCallbackInfo& info, AAFwk::Want& want)
120 {
121     if (info.argc == 0) {
122         TAG_LOGE(AAFwkTag::INTENT, "invalid argc");
123         ThrowTooFewParametersError(env);
124         return false;
125     }
126 
127     // unwrap want
128     bool unwrapWantFlag = OHOS::AppExecFwk::UnwrapWant(env, info.argv[0], want);
129     if (!unwrapWantFlag) {
130         TAG_LOGE(AAFwkTag::INTENT, "parse want fail");
131         ThrowInvalidParamError(env, "Parameter error: Failed to parse want, must be a Want.");
132         return false;
133     }
134     return true;
135 }
136 } // namespace AbilityRuntime
137 } // namespace OHOS
138