1 /*
2  * Copyright (c) 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_ui_service_proxy.h"
17 #include "ability_business_error.h"
18 #include "hilog_tag_wrapper.h"
19 #include "js_error_utils.h"
20 #include "napi_common_want.h"
21 
22 namespace OHOS {
23 namespace AAFwk {
24 using namespace AbilityRuntime;
25 
26 static constexpr int32_t INDEX_ZERO = 0;
27 static constexpr int32_t ARGC_ONE = 1;
28 
CreateJsUIServiceProxy(napi_env env,const sptr<IRemoteObject> & impl,int64_t connectionId,const sptr<IRemoteObject> & hostProxy)29 napi_value JsUIServiceProxy::CreateJsUIServiceProxy(napi_env env, const sptr<IRemoteObject>& impl,
30     int64_t connectionId, const sptr<IRemoteObject>& hostProxy)
31 {
32     TAG_LOGI(AAFwkTag::UISERVC_EXT, "called");
33     napi_value object = nullptr;
34     napi_create_object(env, &object);
35     if (object == nullptr) {
36         TAG_LOGE(AAFwkTag::UISERVC_EXT, "napi_create_object, object is null");
37         return CreateJsUndefined(env);
38     }
39 
40     std::unique_ptr<JsUIServiceProxy> proxy = std::make_unique<JsUIServiceProxy>(impl, hostProxy);
41     proxy->SetConnectionId(connectionId);
42     napi_wrap(env, object, proxy.release(), Finalizer, nullptr, nullptr);
43 
44     const char *moduleName = "JsUIServiceProxy";
45     BindNativeFunction(env, object, "sendData", moduleName, JsUIServiceProxy::SendData);
46     return object;
47 }
48 
Finalizer(napi_env env,void * data,void * hint)49 void JsUIServiceProxy::Finalizer(napi_env env, void* data, void* hint)
50 {
51     TAG_LOGI(AAFwkTag::UISERVC_EXT, "called");
52     std::unique_ptr<JsUIServiceProxy>(static_cast<JsUIServiceProxy*>(data));
53 }
54 
JsUIServiceProxy(const sptr<IRemoteObject> & impl,const sptr<IRemoteObject> & hostProxy)55 JsUIServiceProxy::JsUIServiceProxy(const sptr<IRemoteObject>& impl, const sptr<IRemoteObject>& hostProxy)
56 {
57     TAG_LOGI(AAFwkTag::UISERVC_EXT, "called");
58     proxy_ = iface_cast<OHOS::AAFwk::IUIService>(impl);
59     hostProxy_ = hostProxy;
60     if (proxy_ == nullptr) {
61         TAG_LOGI(AAFwkTag::UISERVC_EXT, "iface_cast return null");
62     }
63 }
64 
~JsUIServiceProxy()65 JsUIServiceProxy::~JsUIServiceProxy()
66 {
67     TAG_LOGI(AAFwkTag::UISERVC_EXT, "called");
68     proxy_ = nullptr;
69     hostProxy_ = nullptr;
70 }
71 
SendData(napi_env env,napi_callback_info info)72 napi_value JsUIServiceProxy::SendData(napi_env env, napi_callback_info info)
73 {
74     GET_NAPI_INFO_AND_CALL(env, info, JsUIServiceProxy, OnSendData);
75 }
76 
OnSendData(napi_env env,NapiCallbackInfo & info)77 napi_value JsUIServiceProxy::OnSendData(napi_env env, NapiCallbackInfo& info)
78 {
79     if (proxy_ == nullptr || hostProxy_ == nullptr) {
80         TAG_LOGE(AAFwkTag::UISERVC_EXT, "proxy_ or hostProxy_ is null");
81         ThrowError(env, AbilityErrorCode::ERROR_CODE_INNER);
82         return CreateJsUndefined(env);
83     }
84     if (info.argc < ARGC_ONE) {
85         TAG_LOGE(AAFwkTag::UISERVC_EXT, "failed, not enough params.");
86         ThrowTooFewParametersError(env);
87         return CreateJsUndefined(env);
88     }
89     AAFwk::WantParams params;
90     bool result = AppExecFwk::UnwrapWantParams(env, info.argv[INDEX_ZERO], params);
91     if (!result) {
92         TAG_LOGW(AAFwkTag::UISERVC_EXT, "UnwrapWantParams failed");
93         ThrowError(env, static_cast<int32_t>(AbilityErrorCode::ERROR_CODE_INVALID_PARAM), "Data verification failed");
94         return CreateJsUndefined(env);
95     }
96 
97     int32_t ret = proxy_->SendData(hostProxy_, params);
98     if (ret != static_cast<int32_t>(AbilityErrorCode::ERROR_OK)) {
99         TAG_LOGW(AAFwkTag::UISERVC_EXT, "proxy_->SendData failed");
100         ThrowError(env, AbilityErrorCode::ERROR_CODE_INNER);
101     }
102     return CreateJsUndefined(env);
103 }
104 }
105 }
106