napi_remote_object.cpp 57.7 KB
Newer Older
L
liangshenglin1 已提交
1
/*
S
shufewhx 已提交
2
 * Copyright (c) 2023 Huawei Device Co., Ltd.
L
liangshenglin1 已提交
3 4 5 6 7 8 9 10 11 12 13 14 15
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

S
shufewhx 已提交
16 17
#include "napi_remote_object_internal.h"

L
liangshenglin1 已提交
18
#include <uv.h>
S
shufewhx 已提交
19 20 21 22
#include <string_ex.h>
#include <hitrace_meter.h>

#include "iremote_invoker.h"
W
wanghaoxu 已提交
23
#include "ipc_debug.h"
L
liangshenglin1 已提交
24
#include "log_tags.h"
S
shufewhx 已提交
25
#include "napi_process_skeleton.h"
L
liangshenglin1 已提交
26
#include "napi_message_parcel.h"
27
#include "napi_message_sequence.h"
S
shufewhx 已提交
28 29
#include "napi_remote_object_holder.h"
#include "napi_remote_proxy_holder.h"
30
#include "napi_rpc_error.h"
S
shufewhx 已提交
31 32
#include "napi/native_api.h"
#include "napi/native_node_api.h"
马根堂 已提交
33
#include "native_engine/native_value.h"
L
liangshenglin1 已提交
34 35 36

namespace OHOS {
static constexpr OHOS::HiviewDFX::HiLogLabel LOG_LABEL = { LOG_CORE, LOG_ID_IPC, "napi_remoteObject" };
W
wanghaoxu 已提交
37

38 39 40 41
static const size_t ARGV_INDEX_0 = 0;
static const size_t ARGV_INDEX_1 = 1;
static const size_t ARGV_INDEX_2 = 2;
static const size_t ARGV_INDEX_3 = 3;
S
shufewhx 已提交
42
static const uint64_t HITRACE_TAG_RPC = (1ULL << 46); // RPC and IPC tag.
L
liangshenglin1 已提交
43

S
shufewhx 已提交
44 45
static std::atomic<int32_t> bytraceId = 1000;
static NapiError napiErr;
L
liangshenglin1 已提交
46

马根堂 已提交
47
template<class T>
S
shufewhx 已提交
48
inline T *ConvertNativeValueTo(NativeValue *value)
L
liangshenglin1 已提交
49
{
S
shufewhx 已提交
50
    return (value != nullptr) ? static_cast<T *>(value->GetInterface(T::INTERFACE_ID)) : nullptr;
L
liangshenglin1 已提交
51 52
}

53 54 55 56 57 58 59 60 61
static void RemoteObjectHolderFinalizeCb(napi_env env, void *data, void *hint)
{
    NAPIRemoteObjectHolder *holder = reinterpret_cast<NAPIRemoteObjectHolder *>(data);
    if (holder == nullptr) {
        ZLOGW(LOG_LABEL, "RemoteObjectHolderFinalizeCb null holder");
        return;
    }
    holder->Lock();
    int32_t curAttachCount = holder->DecAttachCount();
1
18392170496 已提交
62
    ZLOGD(LOG_LABEL, "NAPIRemoteObjectHolder destructed by js callback, curAttachCount:%{public}d", curAttachCount);
63 64 65 66 67
    if (curAttachCount == 0) {
        delete holder;
    }
}

1
18392170496 已提交
68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100
static void DecreaseJsObjectRef(napi_env env, napi_ref ref)
{
    if (ref == nullptr) {
        ZLOGI(LOG_LABEL, "ref is nullptr, do nothing");
        return;
    }

    uint32_t result;
    napi_status napiStatus = napi_reference_unref(env, ref, &result);
    NAPI_ASSERT_RETURN_VOID(env, napiStatus == napi_ok, "failed to decrease ref to js RemoteObject");
}

static void IncreaseJsObjectRef(napi_env env, napi_ref ref)
{
    uint32_t result;
    napi_status napiStatus = napi_reference_ref(env, ref, &result);
    NAPI_ASSERT_RETURN_VOID(env, napiStatus == napi_ok, "failed to increase ref to js RemoteObject");
}

static void RemoteObjectHolderRefCb(napi_env env, void *data, void *hint)
{
    NAPIRemoteObjectHolder *holder = reinterpret_cast<NAPIRemoteObjectHolder *>(data);
    if (holder == nullptr) {
        ZLOGW(LOG_LABEL, "RemoteObjectHolderRefCb holder is nullptr");
        return;
    }
    holder->Lock();
    int32_t curAttachCount = holder->DecAttachCount();
    holder->Unlock();
    ZLOGD(LOG_LABEL, "RemoteObjectHolderRefCb, curAttachCount:%{public}d", curAttachCount);

    napi_ref ref = holder->GetJsObjectRef();
    napi_env workerEnv = holder->GetJsObjectEnv();
1
18392170496 已提交
101
    if (ref == nullptr || workerEnv == nullptr) {
1
18392170496 已提交
102
        ZLOGE(LOG_LABEL, "ref or env is null");
1
18392170496 已提交
103 104
        return;
    }
1
18392170496 已提交
105 106 107 108
    uv_loop_s *loop = nullptr;
    napi_get_uv_event_loop(workerEnv, &loop);
    uv_work_t *work = new(std::nothrow) uv_work_t;
    NAPI_ASSERT_RETURN_VOID(workerEnv, work != nullptr, "cb failed to new work");
1
18392170496 已提交
109
    OperateJsRefParam *param = new OperateJsRefParam {
1
18392170496 已提交
110 111 112 113 114
        .env = workerEnv,
        .thisVarRef = ref
    };
    work->data = reinterpret_cast<void *>(param);
    uv_queue_work(loop, work, [](uv_work_t *work) {}, [](uv_work_t *work, int status) {
1
18392170496 已提交
115
        ZLOGI(LOG_LABEL, "decrease on uv work thread");
1
18392170496 已提交
116
        OperateJsRefParam *param = reinterpret_cast<OperateJsRefParam *>(work->data);
1
18392170496 已提交
117 118 119 120 121 122 123 124 125
        napi_handle_scope scope = nullptr;
        napi_open_handle_scope(param->env, &scope);
        DecreaseJsObjectRef(param->env, param->thisVarRef);
        napi_close_handle_scope(param->env, scope);
        delete param;
        delete work;
    });
}

126 127 128
static void *RemoteObjectDetachCb(NativeEngine *engine, void *value, void *hint)
{
    (void)hint;
1
18392170496 已提交
129 130 131 132 133 134 135
    napi_env env = reinterpret_cast<napi_env>(engine);
    NAPIRemoteObjectHolder *holder = reinterpret_cast<NAPIRemoteObjectHolder *>(value);
    napi_ref ref = holder->GetJsObjectRef();

    uint32_t result;
    napi_status napiStatus = napi_reference_ref(env, ref, &result);
    if (napiStatus != napi_ok) {
1
18392170496 已提交
136
        ZLOGE(LOG_LABEL, "RemoteObjectDetachCb, failed to increase ref");
1
18392170496 已提交
137 138
    } else {
        ZLOGI(LOG_LABEL, "RemoteObjectDetachCb, ref result:%{public}u", result);
1
18392170496 已提交
139
    }
140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176
    return value;
}

static NativeValue *RemoteObjectAttachCb(NativeEngine *engine, void *value, void *hint)
{
    (void)hint;
    NAPIRemoteObjectHolder *holder = reinterpret_cast<NAPIRemoteObjectHolder *>(value);
    if (holder == nullptr) {
        ZLOGE(LOG_LABEL, "holder is nullptr when attach");
        return nullptr;
    }
    holder->Lock();
    ZLOGI(LOG_LABEL, "create js remote object when attach");
    napi_env env = reinterpret_cast<napi_env>(engine);
    // retrieve js remote object constructor
    napi_value global = nullptr;
    napi_status status = napi_get_global(env, &global);
    NAPI_ASSERT(env, status == napi_ok, "get napi global failed");
    napi_value constructor = nullptr;
    status = napi_get_named_property(env, global, "IPCStubConstructor_", &constructor);
    NAPI_ASSERT(env, status == napi_ok, "get stub constructor failed");
    NAPI_ASSERT(env, constructor != nullptr, "failed to get js RemoteObject constructor");
    // retrieve descriptor and it's length
    std::u16string descriptor = holder->GetDescriptor();
    std::string desc = Str16ToStr8(descriptor);
    napi_value jsDesc = nullptr;
    napi_create_string_utf8(env, desc.c_str(), desc.length(), &jsDesc);
    // create a new js remote object
    size_t argc = 1;
    napi_value argv[1] = { jsDesc };
    napi_value jsRemoteObject = nullptr;
    status = napi_new_instance(env, constructor, argc, argv, &jsRemoteObject);
    NAPI_ASSERT(env, status == napi_ok, "failed to  construct js RemoteObject when attach");
    // retrieve and remove create holder
    NAPIRemoteObjectHolder *createHolder = nullptr;
    status = napi_remove_wrap(env, jsRemoteObject, (void **)&createHolder);
    NAPI_ASSERT(env, status == napi_ok && createHolder != nullptr, "failed to remove create holder when attach");
1
18392170496 已提交
177
    status = napi_wrap(env, jsRemoteObject, holder, RemoteObjectHolderRefCb, nullptr, nullptr);
178 179 180 181
    NAPI_ASSERT(env, status == napi_ok, "wrap js RemoteObject and native holder failed when attach");
    holder->IncAttachCount();
    holder->Unlock();
    return reinterpret_cast<NativeValue *>(jsRemoteObject);
马根堂 已提交
182
}
1
18392170496 已提交
183

1
18392170496 已提交
184 185 186 187 188 189 190
static void OnEnvCleanUp(void *data)
{
    if (data == nullptr) {
        ZLOGE(LOG_LABEL, "data is null");
        return;
    }
    NAPIRemoteObjectHolder *holder = reinterpret_cast<NAPIRemoteObjectHolder *>(data);
1
18392170496 已提交
191
    // js env has been destrcted, clear saved env info, and check befor use it
1
18392170496 已提交
192 193
    holder->CleanJsEnv();
}
194

L
liangshenglin1 已提交
195 196 197
napi_value RemoteObject_JS_Constructor(napi_env env, napi_callback_info info)
{
    // new napi remote object
198
    size_t argc = 2;
L
liangshenglin1 已提交
199
    size_t expectedArgc = 1;
200
    napi_value argv[2] = { 0 };
L
liangshenglin1 已提交
201 202
    napi_value thisVar = nullptr;
    napi_get_cb_info(env, info, &argc, argv, &thisVar, nullptr);
203
    NAPI_ASSERT(env, argc >= expectedArgc, "requires at least 1 parameters");
204
    napi_valuetype valueType = napi_null;
L
liangshenglin1 已提交
205 206
    napi_typeof(env, argv[0], &valueType);
    NAPI_ASSERT(env, valueType == napi_string, "type mismatch for parameter 1");
L
liangshenglin1 已提交
207 208 209 210 211
    size_t bufferSize = 0;
    size_t maxLen = 40960;
    napi_get_value_string_utf8(env, argv[0], nullptr, 0, &bufferSize);
    NAPI_ASSERT(env, bufferSize < maxLen, "string length too large");
    char stringValue[bufferSize + 1];
L
liangshenglin1 已提交
212
    size_t jsStringLength = 0;
L
liangshenglin1 已提交
213 214
    napi_get_value_string_utf8(env, argv[0], stringValue, bufferSize + 1, &jsStringLength);
    NAPI_ASSERT(env, jsStringLength == bufferSize, "string length wrong");
L
liangshenglin1 已提交
215
    std::string descriptor = stringValue;
1
18392170496 已提交
216
    auto holder = new NAPIRemoteObjectHolder(env, Str8ToStr16(descriptor), thisVar);
马根堂 已提交
217
    auto nativeObj = ConvertNativeValueTo<NativeObject>(reinterpret_cast<NativeValue *>(thisVar));
218 219 220 221 222
    if (nativeObj == nullptr) {
        ZLOGE(LOG_LABEL, "Failed to get RemoteObject native object");
        delete holder;
        return nullptr;
    }
马根堂 已提交
223
    nativeObj->ConvertToNativeBindingObject(env, RemoteObjectDetachCb, RemoteObjectAttachCb, holder, nullptr);
L
liangshenglin1 已提交
224
    // connect native object to js thisVar
马根堂 已提交
225
    napi_status status = napi_wrap(env, thisVar, holder, RemoteObjectHolderFinalizeCb, nullptr, nullptr);
L
liangshenglin1 已提交
226
    NAPI_ASSERT(env, status == napi_ok, "wrap js RemoteObject and native holder failed");
1
18392170496 已提交
227
    // register listener for env destruction
1
18392170496 已提交
228 229
    status = napi_add_env_cleanup_hook(env, OnEnvCleanUp, holder);
    NAPI_ASSERT(env, status == napi_ok, "add cleanup hook failed");
L
liangshenglin1 已提交
230 231 232
    return thisVar;
}

1
18392170496 已提交
233 234
NAPIRemoteObject::NAPIRemoteObject(std::thread::id jsThreadId, napi_env env, napi_ref jsObjectRef,
    const std::u16string &descriptor)
L
liangshenglin1 已提交
235 236 237
    : IPCObjectStub(descriptor)
{
    env_ = env;
1
18392170496 已提交
238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266
    jsThreadId_ = jsThreadId;
    thisVarRef_ = jsObjectRef;

    if (jsThreadId_ == std::this_thread::get_id()) {
        IncreaseJsObjectRef(env, jsObjectRef);
    } else {
        uv_loop_s *loop = nullptr;
        napi_get_uv_event_loop(env_, &loop);
        uv_work_t *work = new(std::nothrow) uv_work_t;
        NAPI_ASSERT_RETURN_VOID(env_, work != nullptr, "create NAPIRemoteObject, new work failed");
        std::shared_ptr<struct ThreadLockInfo> lockInfo = std::make_shared<struct ThreadLockInfo>();
        OperateJsRefParam *param = new OperateJsRefParam {
            .env = env_,
            .thisVarRef = jsObjectRef,
            .lockInfo = lockInfo.get()
        };

        work->data = reinterpret_cast<void *>(param);
        uv_queue_work(loop, work, [](uv_work_t *work) {}, [](uv_work_t *work, int status) {
            OperateJsRefParam *param = reinterpret_cast<OperateJsRefParam *>(work->data);
            napi_handle_scope scope = nullptr;
            napi_open_handle_scope(param->env, &scope);
            IncreaseJsObjectRef(param->env, param->thisVarRef);
            std::unique_lock<std::mutex> lock(param->lockInfo->mutex);
            param->lockInfo->ready = true;
            param->lockInfo->condition.notify_all();
            napi_close_handle_scope(param->env, scope);
        });
        std::unique_lock<std::mutex> lock(param->lockInfo->mutex);
1
18392170496 已提交
267
        param->lockInfo->condition.wait(lock, [&param] { return param->lockInfo->ready; });
1
18392170496 已提交
268 269 270
        delete param;
        delete work;
    }
L
liangshenglin1 已提交
271 272 273 274
}

NAPIRemoteObject::~NAPIRemoteObject()
{
1
18392170496 已提交
275
    ZLOGI(LOG_LABEL, "NAPIRemoteObject Destructor");
1
18392170496 已提交
276
    if (thisVarRef_ != nullptr && env_ != nullptr) {
1
18392170496 已提交
277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298
        if (jsThreadId_ == std::this_thread::get_id()) {
            DecreaseJsObjectRef(env_, thisVarRef_);
        } else {
            uv_loop_s *loop = nullptr;
            napi_get_uv_event_loop(env_, &loop);
            uv_work_t *work = new(std::nothrow) uv_work_t;
            NAPI_ASSERT_RETURN_VOID(env_, work != nullptr, "release NAPIRemoteObject, new work failed");
            OperateJsRefParam *param = new OperateJsRefParam {
                .env = env_,
                .thisVarRef = thisVarRef_
            };
            work->data = reinterpret_cast<void *>(param);
            uv_queue_work(loop, work, [](uv_work_t *work) {}, [](uv_work_t *work, int status) {
                OperateJsRefParam *param = reinterpret_cast<OperateJsRefParam *>(work->data);
                napi_handle_scope scope = nullptr;
                napi_open_handle_scope(param->env, &scope);
                DecreaseJsObjectRef(param->env, param->thisVarRef);
                napi_close_handle_scope(param->env, scope);
                delete param;
                delete work;
            });
        }
L
liangshenglin1 已提交
299 300 301 302 303 304 305 306 307
        thisVarRef_ = nullptr;
    }
}

bool NAPIRemoteObject::CheckObjectLegality() const
{
    return true;
}

308 309 310 311 312
int NAPIRemoteObject::GetObjectType() const
{
    return OBJECT_TYPE_JAVASCRIPT;
}

马根堂 已提交
313 314 315 316
napi_ref NAPIRemoteObject::GetJsObjectRef() const
{
    return thisVarRef_;
}
L
liangshenglin1 已提交
317

1
18392170496 已提交
318 319 320 321 322 323
void NAPIRemoteObject::ResetJsEnv()
{
    env_ = nullptr;
    thisVarRef_ = nullptr;
}

C
chenyuyan 已提交
324 325 326 327 328 329 330 331 332 333 334
void NAPI_RemoteObject_getCallingInfo(CallingInfo &newCallingInfoParam)
{
    newCallingInfoParam.callingPid = IPCSkeleton::GetCallingPid();
    newCallingInfoParam.callingUid = IPCSkeleton::GetCallingUid();
    newCallingInfoParam.callingTokenId = IPCSkeleton::GetCallingTokenID();
    newCallingInfoParam.callingDeviceID = IPCSkeleton::GetCallingDeviceID();
    newCallingInfoParam.localDeviceID = IPCSkeleton::GetLocalDeviceID();
    newCallingInfoParam.isLocalCalling = IPCSkeleton::IsLocalCalling();
    newCallingInfoParam.activeStatus = IRemoteInvoker::ACTIVE_INVOKER;
};

L
liangshenglin1 已提交
335 336
int NAPIRemoteObject::OnRemoteRequest(uint32_t code, MessageParcel &data, MessageParcel &reply, MessageOption &option)
{
W
wanghaoxu 已提交
337
    ZLOGI(LOG_LABEL, "enter OnRemoteRequest");
L
liangshenglin1 已提交
338
    if (code == DUMP_TRANSACTION) {
W
wanghaoxu 已提交
339
        ZLOGE(LOG_LABEL, "DUMP_TRANSACTION data size:%zu", data.GetReadableBytes());
L
liangshenglin1 已提交
340 341 342 343 344 345 346 347 348
    }
    std::shared_ptr<struct ThreadLockInfo> lockInfo = std::make_shared<struct ThreadLockInfo>();
    CallbackParam *param = new CallbackParam {
        .env = env_,
        .thisVarRef = thisVarRef_,
        .code = code,
        .data = &data,
        .reply = &reply,
        .option = &option,
349
        .lockInfo = lockInfo.get(),
L
liangshenglin1 已提交
350 351
        .result = 0
    };
C
chenyuyan 已提交
352 353

    NAPI_RemoteObject_getCallingInfo(param->callingInfo);
354 355 356 357 358
    ZLOGI(LOG_LABEL, "callingPid:%{public}u, callingUid:%{public}u,"
        "callingDeviceID:%{public}s, localDeviceId:%{public}s, localCalling:%{public}d",
        param->callingInfo.callingPid, param->callingInfo.callingUid,
        param->callingInfo.callingDeviceID.c_str(), param->callingInfo.localDeviceID.c_str(),
        param->callingInfo.isLocalCalling);
359
    int ret = OnJsRemoteRequest(param);
W
wanghaoxu 已提交
360
    ZLOGI(LOG_LABEL, "OnJsRemoteRequest done, ret:%{public}d", ret);
L
liangshenglin1 已提交
361 362 363
    return ret;
}

C
chenyuyan 已提交
364
napi_value NAPIRemoteObject::ThenCallback(napi_env env, napi_callback_info info)
C
chenyuyan 已提交
365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387
{
    ZLOGI(LOG_LABEL, "call js onRemoteRequest done");
    size_t argc = 1;
    napi_value argv[1] = {nullptr};
    void* data = nullptr;
    napi_get_cb_info(env, info, &argc, argv, nullptr, &data);
    CallbackParam *param = static_cast<CallbackParam *>(data);
    bool result = false;
    napi_get_value_bool(param->env, argv[0], &result);
    if (!result) {
        ZLOGE(LOG_LABEL, "OnRemoteRequest res:%{public}s", result ? "true" : "false");
        param->result = ERR_UNKNOWN_TRANSACTION;
    } else {
        param->result = ERR_NONE;
    }
    std::unique_lock<std::mutex> lock(param->lockInfo->mutex);
    param->lockInfo->ready = true;
    param->lockInfo->condition.notify_all();
    napi_value res;
    napi_get_undefined(env, &res);
    return res;
}

C
chenyuyan 已提交
388
napi_value NAPIRemoteObject::CatchCallback(napi_env env, napi_callback_info info)
C
chenyuyan 已提交
389
{
“zhangboyuan” 已提交
390
    ZLOGI(LOG_LABEL, "Async onReomteReuqest's returnVal is rejected");
C
chenyuyan 已提交
391 392 393 394 395 396 397 398 399 400 401 402 403 404
    size_t argc = 1;
    napi_value argv[1] = {nullptr};
    void* data = nullptr;
    napi_get_cb_info(env, info, &argc, argv, nullptr, &data);
    CallbackParam *param = static_cast<CallbackParam *>(data);
    param->result = ERR_UNKNOWN_TRANSACTION;
    std::unique_lock<std::mutex> lock(param->lockInfo->mutex);
    param->lockInfo->ready = true;
    param->lockInfo->condition.notify_all();
    napi_value res;
    napi_get_undefined(env, &res);
    return res;
}

C
chenyuyan 已提交
405
void NAPI_RemoteObject_saveOldCallingInfo(napi_env env, NAPI_CallingInfo &oldCallingInfo)
C
chenyuyan 已提交
406 407 408 409 410 411 412 413 414 415 416 417 418
{
    napi_value global = nullptr;
    napi_get_global(env, &global);
    napi_get_named_property(env, global, "callingPid_", &oldCallingInfo.callingPid);
    napi_get_named_property(env, global, "callingUid_", &oldCallingInfo.callingUid);
    napi_get_named_property(env, global, "callingTokenId_", &oldCallingInfo.callingTokenId);
    napi_get_named_property(env, global, "callingDeviceID_", &oldCallingInfo.callingDeviceID);
    napi_get_named_property(env, global, "localDeviceID_", &oldCallingInfo.localDeviceID);
    napi_get_named_property(env, global, "isLocalCalling_", &oldCallingInfo.isLocalCalling);
    napi_get_named_property(env, global, "isLocalCalling_", &oldCallingInfo.isLocalCalling);
    napi_get_named_property(env, global, "activeStatus_", &oldCallingInfo.activeStatus);
}

C
chenyuyan 已提交
419
void NAPI_RemoteObject_setNewCallingInfo(napi_env env, const CallingInfo &newCallingInfoParam)
C
chenyuyan 已提交
420 421 422 423
{
    napi_value global = nullptr;
    napi_get_global(env, &global);
    napi_value newPid;
C
chenyuyan 已提交
424
    napi_create_int32(env, static_cast<int32_t>(newCallingInfoParam.callingPid), &newPid);
C
chenyuyan 已提交
425 426
    napi_set_named_property(env, global, "callingPid_", newPid);
    napi_value newUid;
C
chenyuyan 已提交
427
    napi_create_int32(env, static_cast<int32_t>(newCallingInfoParam.callingUid), &newUid);
C
chenyuyan 已提交
428 429
    napi_set_named_property(env, global, "callingUid_", newUid);
    napi_value newCallingTokenId;
C
chenyuyan 已提交
430
    napi_create_uint32(env, newCallingInfoParam.callingTokenId, &newCallingTokenId);
C
chenyuyan 已提交
431 432
    napi_set_named_property(env, global, "callingTokenId_", newCallingTokenId);
    napi_value newDeviceID;
C
chenyuyan 已提交
433
    napi_create_string_utf8(env, newCallingInfoParam.callingDeviceID.c_str(), NAPI_AUTO_LENGTH, &newDeviceID);
C
chenyuyan 已提交
434 435
    napi_set_named_property(env, global, "callingDeviceID_", newDeviceID);
    napi_value newLocalDeviceID;
C
chenyuyan 已提交
436
    napi_create_string_utf8(env, newCallingInfoParam.localDeviceID.c_str(), NAPI_AUTO_LENGTH, &newLocalDeviceID);
C
chenyuyan 已提交
437 438
    napi_set_named_property(env, global, "localDeviceID_", newLocalDeviceID);
    napi_value newIsLocalCalling;
C
chenyuyan 已提交
439
    napi_get_boolean(env, newCallingInfoParam.isLocalCalling, &newIsLocalCalling);
C
chenyuyan 已提交
440 441
    napi_set_named_property(env, global, "isLocalCalling_", newIsLocalCalling);
    napi_value newActiveStatus;
C
chenyuyan 已提交
442
    napi_create_int32(env, newCallingInfoParam.activeStatus, &newActiveStatus);
C
chenyuyan 已提交
443 444 445
    napi_set_named_property(env, global, "activeStatus_", newActiveStatus);
}

C
chenyuyan 已提交
446
void NAPI_RemoteObject_resetOldCallingInfo(napi_env env, NAPI_CallingInfo &oldCallingInfo)
447
{
C
chenyuyan 已提交
448 449 450 451 452 453 454 455 456 457 458
    napi_value global = nullptr;
    napi_get_global(env, &global);
    napi_set_named_property(env, global, "callingPid_", oldCallingInfo.callingPid);
    napi_set_named_property(env, global, "callingUid_", oldCallingInfo.callingUid);
    napi_set_named_property(env, global, "callingTokenId_", oldCallingInfo.callingTokenId);
    napi_set_named_property(env, global, "callingDeviceID_", oldCallingInfo.callingDeviceID);
    napi_set_named_property(env, global, "localDeviceID_", oldCallingInfo.localDeviceID);
    napi_set_named_property(env, global, "isLocalCalling_", oldCallingInfo.isLocalCalling);
    napi_set_named_property(env, global, "activeStatus_", oldCallingInfo.activeStatus);
}

459
int NAPIRemoteObject::OnJsRemoteRequest(CallbackParam *jsParam)
L
liangshenglin1 已提交
460
{
1
18392170496 已提交
461 462 463 464
    if (thisVarRef_ == nullptr || env_ == nullptr) {
        ZLOGE(LOG_LABEL, "Js env has been destructed");
        return ERR_UNKNOWN_REASON;
    }
L
liangshenglin1 已提交
465 466 467 468 469
    uv_loop_s *loop = nullptr;
    napi_get_uv_event_loop(env_, &loop);

    uv_work_t *work = new(std::nothrow) uv_work_t;
    if (work == nullptr) {
W
wanghaoxu 已提交
470
        ZLOGE(LOG_LABEL, "failed to new uv_work_t");
471 472
        delete jsParam;
        return -1;
L
liangshenglin1 已提交
473 474
    }
    work->data = reinterpret_cast<void *>(jsParam);
W
wanghaoxu 已提交
475
    ZLOGI(LOG_LABEL, "start nv queue work loop");
L
liangshenglin1 已提交
476
    uv_queue_work(loop, work, [](uv_work_t *work) {}, [](uv_work_t *work, int status) {
W
wanghaoxu 已提交
477
        ZLOGI(LOG_LABEL, "enter thread pool");
L
liangshenglin1 已提交
478
        CallbackParam *param = reinterpret_cast<CallbackParam *>(work->data);
S
shufewhx 已提交
479 480
        napi_handle_scope scope = nullptr;
        napi_open_handle_scope(param->env, &scope);
L
liangshenglin1 已提交
481 482 483 484
        napi_value onRemoteRequest = nullptr;
        napi_value thisVar = nullptr;
        napi_get_reference_value(param->env, param->thisVarRef, &thisVar);
        if (thisVar == nullptr) {
W
wanghaoxu 已提交
485
            ZLOGE(LOG_LABEL, "thisVar is null");
L
liangshenglin1 已提交
486 487 488 489
            param->result = -1;
            std::unique_lock<std::mutex> lock(param->lockInfo->mutex);
            param->lockInfo->ready = true;
            param->lockInfo->condition.notify_all();
S
shufewhx 已提交
490
            napi_close_handle_scope(param->env, scope);
L
liangshenglin1 已提交
491 492
            return;
        }
493
        napi_get_named_property(param->env, thisVar, "onRemoteMessageRequest", &onRemoteRequest);
L
liangshenglin1 已提交
494
        if (onRemoteRequest == nullptr) {
W
wanghaoxu 已提交
495
            ZLOGE(LOG_LABEL, "get founction onRemoteRequest failed");
L
liangshenglin1 已提交
496 497 498 499
            param->result = -1;
            std::unique_lock<std::mutex> lock(param->lockInfo->mutex);
            param->lockInfo->ready = true;
            param->lockInfo->condition.notify_all();
S
shufewhx 已提交
500
            napi_close_handle_scope(param->env, scope);
L
liangshenglin1 已提交
501 502
            return;
        }
503 504
        napi_valuetype type = napi_undefined;
        napi_typeof(param->env, onRemoteRequest, &type);
505
        bool isOnRemoteMessageRequest = true;
506 507 508 509 510 511 512 513
        if (type != napi_function) {
            napi_get_named_property(param->env, thisVar, "onRemoteRequest", &onRemoteRequest);
            if (onRemoteRequest == nullptr) {
                ZLOGE(LOG_LABEL, "get founction onRemoteRequest failed");
                param->result = -1;
                std::unique_lock<std::mutex> lock(param->lockInfo->mutex);
                param->lockInfo->ready = true;
                param->lockInfo->condition.notify_all();
S
shufewhx 已提交
514
                napi_close_handle_scope(param->env, scope);
515 516
                return;
            }
517
            isOnRemoteMessageRequest = false;
518
        }
L
liangshenglin1 已提交
519 520 521
        napi_value jsCode;
        napi_create_uint32(param->env, param->code, &jsCode);

522 523 524
        napi_value global = nullptr;
        napi_get_global(param->env, &global);
        if (global == nullptr) {
W
wanghaoxu 已提交
525
            ZLOGE(LOG_LABEL, "get napi global failed");
526 527 528 529
            param->result = -1;
            std::unique_lock<std::mutex> lock(param->lockInfo->mutex);
            param->lockInfo->ready = true;
            param->lockInfo->condition.notify_all();
S
shufewhx 已提交
530
            napi_close_handle_scope(param->env, scope);
531 532
            return;
        }
L
liangshenglin1 已提交
533
        napi_value jsOptionConstructor = nullptr;
534
        napi_get_named_property(param->env, global, "IPCOptionConstructor_", &jsOptionConstructor);
L
liangshenglin1 已提交
535
        if (jsOptionConstructor == nullptr) {
W
wanghaoxu 已提交
536
            ZLOGE(LOG_LABEL, "jsOption constructor is null");
L
liangshenglin1 已提交
537 538 539 540
            param->result = -1;
            std::unique_lock<std::mutex> lock(param->lockInfo->mutex);
            param->lockInfo->ready = true;
            param->lockInfo->condition.notify_all();
S
shufewhx 已提交
541
            napi_close_handle_scope(param->env, scope);
L
liangshenglin1 已提交
542 543 544 545 546 547 548 549 550 551 552
            return;
        }
        napi_value jsOption;
        size_t argc = 2;
        napi_value flags = nullptr;
        napi_create_int32(param->env, param->option->GetFlags(), &flags);
        napi_value waittime = nullptr;
        napi_create_int32(param->env, param->option->GetWaitTime(), &waittime);
        napi_value argv[2] = { flags, waittime };
        napi_new_instance(param->env, jsOptionConstructor, argc, argv, &jsOption);
        if (jsOption == nullptr) {
W
wanghaoxu 已提交
553
            ZLOGE(LOG_LABEL, "new jsOption failed");
L
liangshenglin1 已提交
554 555 556 557
            param->result = -1;
            std::unique_lock<std::mutex> lock(param->lockInfo->mutex);
            param->lockInfo->ready = true;
            param->lockInfo->condition.notify_all();
S
shufewhx 已提交
558
            napi_close_handle_scope(param->env, scope);
L
liangshenglin1 已提交
559 560 561
            return;
        }
        napi_value jsParcelConstructor = nullptr;
562
        if (isOnRemoteMessageRequest) {
563
            napi_get_named_property(param->env, global, "IPCSequenceConstructor_", &jsParcelConstructor);
564 565 566
        } else {
            napi_get_named_property(param->env, global, "IPCParcelConstructor_", &jsParcelConstructor);
        }
L
liangshenglin1 已提交
567
        if (jsParcelConstructor == nullptr) {
W
wanghaoxu 已提交
568
            ZLOGE(LOG_LABEL, "jsParcel constructor is null");
L
liangshenglin1 已提交
569 570 571 572
            param->result = -1;
            std::unique_lock<std::mutex> lock(param->lockInfo->mutex);
            param->lockInfo->ready = true;
            param->lockInfo->condition.notify_all();
S
shufewhx 已提交
573
            napi_close_handle_scope(param->env, scope);
L
liangshenglin1 已提交
574 575 576 577
            return;
        }
        napi_value jsData;
        napi_value dataParcel;
578 579 580
        napi_create_object(param->env, &dataParcel);
        napi_wrap(param->env, dataParcel, param->data,
            [](napi_env env, void *data, void *hint) {}, nullptr, nullptr);
L
liangshenglin1 已提交
581
        if (dataParcel == nullptr) {
W
wanghaoxu 已提交
582
            ZLOGE(LOG_LABEL, "create js object for data parcel address failed");
L
liangshenglin1 已提交
583 584 585 586
            param->result = -1;
            std::unique_lock<std::mutex> lock(param->lockInfo->mutex);
            param->lockInfo->ready = true;
            param->lockInfo->condition.notify_all();
S
shufewhx 已提交
587
            napi_close_handle_scope(param->env, scope);
L
liangshenglin1 已提交
588 589 590 591 592 593
            return;
        }
        size_t argc3 = 1;
        napi_value argv3[1] = { dataParcel };
        napi_new_instance(param->env, jsParcelConstructor, argc3, argv3, &jsData);
        if (jsData == nullptr) {
W
wanghaoxu 已提交
594
            ZLOGE(LOG_LABEL, "create js data parcel failed");
L
liangshenglin1 已提交
595 596 597 598
            param->result = -1;
            std::unique_lock<std::mutex> lock(param->lockInfo->mutex);
            param->lockInfo->ready = true;
            param->lockInfo->condition.notify_all();
S
shufewhx 已提交
599
            napi_close_handle_scope(param->env, scope);
L
liangshenglin1 已提交
600 601 602 603
            return;
        }
        napi_value jsReply;
        napi_value replyParcel;
604 605 606
        napi_create_object(param->env, &replyParcel);
        napi_wrap(param->env, replyParcel, param->reply,
            [](napi_env env, void *data, void *hint) {}, nullptr, nullptr);
L
liangshenglin1 已提交
607
        if (replyParcel == nullptr) {
W
wanghaoxu 已提交
608
            ZLOGE(LOG_LABEL, "create js object for reply parcel address failed");
L
liangshenglin1 已提交
609 610 611 612
            param->result = -1;
            std::unique_lock<std::mutex> lock(param->lockInfo->mutex);
            param->lockInfo->ready = true;
            param->lockInfo->condition.notify_all();
S
shufewhx 已提交
613
            napi_close_handle_scope(param->env, scope);
L
liangshenglin1 已提交
614 615 616 617 618 619
            return;
        }
        size_t argc4 = 1;
        napi_value argv4[1] = { replyParcel };
        napi_new_instance(param->env, jsParcelConstructor, argc4, argv4, &jsReply);
        if (jsReply == nullptr) {
W
wanghaoxu 已提交
620
            ZLOGE(LOG_LABEL, "create js reply parcel failed");
L
liangshenglin1 已提交
621 622 623 624
            param->result = -1;
            std::unique_lock<std::mutex> lock(param->lockInfo->mutex);
            param->lockInfo->ready = true;
            param->lockInfo->condition.notify_all();
S
shufewhx 已提交
625
            napi_close_handle_scope(param->env, scope);
L
liangshenglin1 已提交
626 627
            return;
        }
C
chenyuyan 已提交
628
        NAPI_CallingInfo oldCallingInfo;
C
chenyuyan 已提交
629
        NAPI_RemoteObject_saveOldCallingInfo(param->env, oldCallingInfo);
C
chenyuyan 已提交
630
        NAPI_RemoteObject_setNewCallingInfo(param->env, param->callingInfo);
L
liangshenglin1 已提交
631 632 633
        // start to call onRemoteRequest
        size_t argc2 = 4;
        napi_value argv2[] = { jsCode, jsData, jsReply, jsOption };
“zhangboyuan” 已提交
634 635
        napi_value returnVal;
        napi_status ret = napi_call_function(param->env, thisVar, onRemoteRequest, argc2, argv2, &returnVal);
C
chenyuyan 已提交
636 637 638 639 640 641
        // Reset old calling pid, uid, device id
        NAPI_RemoteObject_resetOldCallingInfo(param->env, oldCallingInfo);

        do {
            if (ret != napi_ok) {
                ZLOGE(LOG_LABEL, "OnRemoteRequest got exception");
L
liangshenglin1 已提交
642
                param->result = ERR_UNKNOWN_TRANSACTION;
C
chenyuyan 已提交
643
                break;
L
liangshenglin1 已提交
644 645
            }

C
chenyuyan 已提交
646
            ZLOGD(LOG_LABEL, "call js onRemoteRequest done");
C
chenyuyan 已提交
647
            // Check whether return_val is Promise
648
            bool returnIsPromise = false;
“zhangboyuan” 已提交
649
            napi_is_promise(param->env, returnVal, &returnIsPromise);
C
chenyuyan 已提交
650
            if (!returnIsPromise) {
C
chenyuyan 已提交
651
                ZLOGD(LOG_LABEL, "onRemoteRequest is synchronous");
C
chenyuyan 已提交
652
                bool result = false;
“zhangboyuan” 已提交
653
                napi_get_value_bool(param->env, returnVal, &result);
C
chenyuyan 已提交
654 655 656 657 658 659 660 661 662
                if (!result) {
                    ZLOGE(LOG_LABEL, "OnRemoteRequest res:%{public}s", result ? "true" : "false");
                    param->result = ERR_UNKNOWN_TRANSACTION;
                } else {
                    param->result = ERR_NONE;
                }
                break;
            }

C
chenyuyan 已提交
663
            ZLOGD(LOG_LABEL, "onRemoteRequest is asynchronous");
C
chenyuyan 已提交
664 665
            // Create promiseThen
            napi_value promiseThen = nullptr;
“zhangboyuan” 已提交
666
            napi_get_named_property(param->env, returnVal, "then", &promiseThen);
C
chenyuyan 已提交
667 668 669 670 671
            if (promiseThen == nullptr) {
                ZLOGE(LOG_LABEL, "get promiseThen failed");
                param->result = -1;
                break;
            }
“zhangboyuan” 已提交
672 673
            napi_value thenValue;
            ret = napi_create_function(param->env, "thenCallback", NAPI_AUTO_LENGTH, ThenCallback, param, &thenValue);
C
chenyuyan 已提交
674
            if (ret != napi_ok) {
C
chenyuyan 已提交
675
                ZLOGE(LOG_LABEL, "thenCallback got exception");
C
chenyuyan 已提交
676 677 678
                param->result = ERR_UNKNOWN_TRANSACTION;
                break;
            }
“zhangboyuan” 已提交
679
            napi_value catchValue;
680
            ret = napi_create_function(param->env, "catchCallback",
“zhangboyuan” 已提交
681
                NAPI_AUTO_LENGTH, CatchCallback, param, &catchValue);
C
chenyuyan 已提交
682
            if (ret != napi_ok) {
C
chenyuyan 已提交
683
                ZLOGE(LOG_LABEL, "catchCallback got exception");
C
chenyuyan 已提交
684 685 686
                param->result = ERR_UNKNOWN_TRANSACTION;
                break;
            }
687 688 689 690 691 692
            // Start to call promiseThen
            napi_env env = param->env;
            napi_value thenReturnValue;
            constexpr uint32_t THEN_ARGC = 2;
            napi_value thenArgv[THEN_ARGC] = {thenValue, catchValue};
            ret = napi_call_function(env, returnVal, promiseThen, THEN_ARGC, thenArgv, &thenReturnValue);
C
chenyuyan 已提交
693
            if (ret != napi_ok) {
694
                ZLOGE(LOG_LABEL, "PromiseThen got exception");
C
chenyuyan 已提交
695 696 697
                param->result = ERR_UNKNOWN_TRANSACTION;
                break;
            }
698
            napi_close_handle_scope(env, scope);
C
chenyuyan 已提交
699
            return;
700
        } while (0);
C
chenyuyan 已提交
701

L
liangshenglin1 已提交
702 703 704
        std::unique_lock<std::mutex> lock(param->lockInfo->mutex);
        param->lockInfo->ready = true;
        param->lockInfo->condition.notify_all();
S
shufewhx 已提交
705
        napi_close_handle_scope(param->env, scope);
L
liangshenglin1 已提交
706 707 708
    });
    std::unique_lock<std::mutex> lock(jsParam->lockInfo->mutex);
    jsParam->lockInfo->condition.wait(lock, [&jsParam] { return jsParam->lockInfo->ready; });
709 710 711 712
    int ret = jsParam->result;
    delete jsParam;
    delete work;
    return ret;
L
liangshenglin1 已提交
713 714 715 716 717
}

napi_value NAPI_ohos_rpc_CreateJsRemoteObject(napi_env env, const sptr<IRemoteObject> target)
{
    if (target == nullptr) {
W
wanghaoxu 已提交
718
        ZLOGE(LOG_LABEL, "RemoteObject is null");
L
liangshenglin1 已提交
719 720 721
        return nullptr;
    }

1
18392170496 已提交
722
    if (!target->IsProxyObject()) {
723
        IPCObjectStub *tmp = static_cast<IPCObjectStub *>(target.GetRefPtr());
马根堂 已提交
724
        uint32_t objectType = tmp->GetObjectType();
1
18392170496 已提交
725
        ZLOGI(LOG_LABEL, "create js object, type:%{public}d", objectType);
马根堂 已提交
726
        if (objectType == IPCObjectStub::OBJECT_TYPE_JAVASCRIPT || objectType == IPCObjectStub::OBJECT_TYPE_NATIVE) {
727
            // retrieve js remote object constructor
马根堂 已提交
728
            napi_value global = nullptr;
729 730 731 732 733 734 735
            napi_status status = napi_get_global(env, &global);
            NAPI_ASSERT(env, status == napi_ok, "get napi global failed");
            napi_value constructor = nullptr;
            status = napi_get_named_property(env, global, "IPCStubConstructor_", &constructor);
            NAPI_ASSERT(env, status == napi_ok, "set stub constructor failed");
            NAPI_ASSERT(env, constructor != nullptr, "failed to get js RemoteObject constructor");
            // retrieve descriptor and it's length
1
18392170496 已提交
736
            std::u16string descriptor = target->GetObjectDescriptor();
737 738 739 740
            std::string desc = Str16ToStr8(descriptor);
            napi_value jsDesc = nullptr;
            napi_create_string_utf8(env, desc.c_str(), desc.length(), &jsDesc);
            // create a new js remote object
741 742
            size_t argc = 1;
            napi_value argv[1] = { jsDesc };
L
liangshenglin1 已提交
743
            napi_value jsRemoteObject = nullptr;
744 745 746 747 748 749
            status = napi_new_instance(env, constructor, argc, argv, &jsRemoteObject);
            NAPI_ASSERT(env, status == napi_ok, "failed to  construct js RemoteObject");
            // retrieve holder and set object
            NAPIRemoteObjectHolder *holder = nullptr;
            napi_unwrap(env, jsRemoteObject, (void **)&holder);
            NAPI_ASSERT(env, holder != nullptr, "failed to get napi remote object holder");
1
18392170496 已提交
750
            holder->Set(target);
马根堂 已提交
751
            return jsRemoteObject;
752
        }
L
liangshenglin1 已提交
753 754
    }

755 756 757
    napi_value global = nullptr;
    napi_status status = napi_get_global(env, &global);
    NAPI_ASSERT(env, status == napi_ok, "get napi global failed");
L
liangshenglin1 已提交
758
    napi_value constructor = nullptr;
759 760
    status = napi_get_named_property(env, global, "IPCProxyConstructor_", &constructor);
    NAPI_ASSERT(env, status == napi_ok, "get proxy constructor failed");
L
liangshenglin1 已提交
761 762 763 764 765 766 767 768 769 770 771 772 773
    napi_value jsRemoteProxy;
    status = napi_new_instance(env, constructor, 0, nullptr, &jsRemoteProxy);
    NAPI_ASSERT(env, status == napi_ok, "failed to  construct js RemoteProxy");
    NAPIRemoteProxyHolder *proxyHolder = NAPI_ohos_rpc_getRemoteProxyHolder(env, jsRemoteProxy);
    proxyHolder->object_ = target;
    proxyHolder->list_ = new NAPIDeathRecipientList();

    return jsRemoteProxy;
}

sptr<IRemoteObject> NAPI_ohos_rpc_getNativeRemoteObject(napi_env env, napi_value object)
{
    if (object != nullptr) {
774 775 776 777 778 779
        napi_value global = nullptr;
        napi_status status = napi_get_global(env, &global);
        NAPI_ASSERT(env, status == napi_ok, "get napi global failed");
        napi_value stubConstructor = nullptr;
        status = napi_get_named_property(env, global, "IPCStubConstructor_", &stubConstructor);
        NAPI_ASSERT(env, status == napi_ok, "get stub constructor failed");
L
liangshenglin1 已提交
780
        bool instanceOfStub = false;
781
        status = napi_instanceof(env, object, stubConstructor, &instanceOfStub);
L
liangshenglin1 已提交
782 783 784 785 786
        NAPI_ASSERT(env, status == napi_ok, "failed to check js object type");
        if (instanceOfStub) {
            NAPIRemoteObjectHolder *holder = nullptr;
            napi_unwrap(env, object, (void **)&holder);
            NAPI_ASSERT(env, holder != nullptr, "failed to get napi remote object holder");
1
18392170496 已提交
787
            return holder != nullptr ? holder->Get() : nullptr;
L
liangshenglin1 已提交
788 789
        }

790 791 792
        napi_value proxyConstructor = nullptr;
        status = napi_get_named_property(env, global, "IPCProxyConstructor_", &proxyConstructor);
        NAPI_ASSERT(env, status == napi_ok, "get proxy constructor failed");
L
liangshenglin1 已提交
793
        bool instanceOfProxy = false;
794
        status = napi_instanceof(env, object, proxyConstructor, &instanceOfProxy);
L
liangshenglin1 已提交
795 796 797 798 799 800 801 802 803
        NAPI_ASSERT(env, status == napi_ok, "failed to check js object type");
        if (instanceOfProxy) {
            NAPIRemoteProxyHolder *holder = NAPI_ohos_rpc_getRemoteProxyHolder(env, object);
            return holder != nullptr ? holder->object_ : nullptr;
        }
    }
    return nullptr;
}

S
shufewhx 已提交
804
static napi_value NAPI_RemoteObject_queryLocalInterface(napi_env env, napi_callback_info info)
L
liangshenglin1 已提交
805 806 807 808 809 810 811
{
    size_t argc = 1;
    size_t expectedArgc = 1;
    napi_value argv[1] = { 0 };
    napi_value thisVar = nullptr;
    napi_get_cb_info(env, info, &argc, argv, &thisVar, nullptr);
    NAPI_ASSERT(env, argc == expectedArgc, "requires 1 parameters");
812
    napi_valuetype valueType = napi_null;
L
liangshenglin1 已提交
813 814 815 816 817 818 819 820 821 822 823 824 825 826 827 828 829 830
    napi_typeof(env, argv[0], &valueType);
    NAPI_ASSERT(env, valueType == napi_string, "type mismatch for parameter 1");
    size_t bufferSize = 0;
    size_t maxLen = 40960;
    napi_get_value_string_utf8(env, argv[0], nullptr, 0, &bufferSize);
    NAPI_ASSERT(env, bufferSize < maxLen, "string length too large");
    char stringValue[bufferSize + 1];
    size_t jsStringLength = 0;
    napi_get_value_string_utf8(env, argv[0], stringValue, bufferSize + 1, &jsStringLength);
    NAPI_ASSERT(env, jsStringLength == bufferSize, "string length wrong");
    std::string descriptor = stringValue;
    NAPIRemoteObjectHolder *holder = nullptr;
    napi_unwrap(env, thisVar, (void **)&holder);
    NAPI_ASSERT(env, holder != nullptr, "failed to get napi remote object holder");
    napi_value ret = holder->queryLocalInterface(descriptor);
    return ret;
}

S
shufewhx 已提交
831
static napi_value NAPI_RemoteObject_getLocalInterface(napi_env env, napi_callback_info info)
832 833 834 835 836 837 838 839
{
    size_t argc = 1;
    size_t expectedArgc = 1;
    napi_value argv[1] = { 0 };
    napi_value thisVar = nullptr;
    napi_get_cb_info(env, info, &argc, argv, &thisVar, nullptr);
    if (argc != expectedArgc) {
        ZLOGE(LOG_LABEL, "requires 1 parameters");
840
        return napiErr.ThrowError(env, errorDesc::CHECK_PARAM_ERROR);
841 842 843 844 845
    }
    napi_valuetype valueType = napi_null;
    napi_typeof(env, argv[0], &valueType);
    if (valueType != napi_string) {
        ZLOGE(LOG_LABEL, "type mismatch for parameter 1");
846
        return napiErr.ThrowError(env, errorDesc::CHECK_PARAM_ERROR);
847 848 849 850 851 852
    }
    size_t bufferSize = 0;
    size_t maxLen = 40960;
    napi_get_value_string_utf8(env, argv[0], nullptr, 0, &bufferSize);
    if (bufferSize >= maxLen) {
        ZLOGE(LOG_LABEL, "string length too large");
853
        return napiErr.ThrowError(env, errorDesc::CHECK_PARAM_ERROR);
854 855 856 857 858 859
    }
    char stringValue[bufferSize + 1];
    size_t jsStringLength = 0;
    napi_get_value_string_utf8(env, argv[0], stringValue, bufferSize + 1, &jsStringLength);
    if (jsStringLength != bufferSize) {
        ZLOGE(LOG_LABEL, "string length wrong");
860
        return napiErr.ThrowError(env, errorDesc::CHECK_PARAM_ERROR);
861 862 863 864 865 866 867 868 869 870 871 872
    }
    std::string descriptor = stringValue;
    NAPIRemoteObjectHolder *holder = nullptr;
    napi_unwrap(env, thisVar, (void **)&holder);
    if (holder == nullptr) {
        ZLOGE(LOG_LABEL, "failed to get napi remote object holder");
        return nullptr;
    }
    napi_value ret = holder->queryLocalInterface(descriptor);
    return ret;
}

S
shufewhx 已提交
873
static napi_value NAPI_RemoteObject_getInterfaceDescriptor(napi_env env, napi_callback_info info)
L
liangshenglin1 已提交
874 875 876
{
    napi_value result = nullptr;
    napi_value thisVar = nullptr;
“zhangboyuan” 已提交
877
    napi_get_cb_info(env, info, nullptr, nullptr, &thisVar, nullptr);
L
liangshenglin1 已提交
878 879 880 881
    sptr<IRemoteObject> nativeObject = NAPI_ohos_rpc_getNativeRemoteObject(env, thisVar);
    std::u16string descriptor = nativeObject->GetObjectDescriptor();
    napi_create_string_utf8(env, Str16ToStr8(descriptor).c_str(), NAPI_AUTO_LENGTH, &result);
    return result;
L
liangshenglin1 已提交
882 883
}

S
shufewhx 已提交
884
static napi_value NAPI_RemoteObject_getDescriptor(napi_env env, napi_callback_info info)
885 886 887
{
    napi_value result = nullptr;
    napi_value thisVar = nullptr;
“zhangboyuan” 已提交
888
    napi_get_cb_info(env, info, nullptr, nullptr, &thisVar, nullptr);
889 890 891 892 893 894 895 896 897 898
    sptr<IRemoteObject> nativeObject = NAPI_ohos_rpc_getNativeRemoteObject(env, thisVar);
    if (nativeObject == nullptr) {
        ZLOGE(LOG_LABEL, "native stub object is nullptr");
        return napiErr.ThrowError(env, errorDesc::PROXY_OR_REMOTE_OBJECT_INVALID_ERROR);
    }
    std::u16string descriptor = nativeObject->GetObjectDescriptor();
    napi_create_string_utf8(env, Str16ToStr8(descriptor).c_str(), NAPI_AUTO_LENGTH, &result);
    return result;
}

S
shufewhx 已提交
899
static napi_value NAPI_RemoteObject_getCallingPid(napi_env env, napi_callback_info info)
L
liangshenglin1 已提交
900
{
S
shufewhx 已提交
901
    return NAPI_getCallingPid(env, info);
L
liangshenglin1 已提交
902 903
}

S
shufewhx 已提交
904
static napi_value NAPI_RemoteObject_getCallingUid(napi_env env, napi_callback_info info)
L
liangshenglin1 已提交
905
{
S
shufewhx 已提交
906
    return NAPI_getCallingUid(env, info);
907 908 909 910 911 912 913 914 915 916 917 918
}

napi_value MakeSendRequestResult(SendRequestParam *param)
{
    napi_value errCode = nullptr;
    napi_create_int32(param->env, param->errCode, &errCode);
    napi_value code = nullptr;
    napi_get_reference_value(param->env, param->jsCodeRef, &code);
    napi_value data = nullptr;
    napi_get_reference_value(param->env, param->jsDataRef, &data);
    napi_value reply = nullptr;
    napi_get_reference_value(param->env, param->jsReplyRef, &reply);
L
liangshenglin1 已提交
919
    napi_value result = nullptr;
920 921 922 923 924
    napi_create_object(param->env, &result);
    napi_set_named_property(param->env, result, "errCode", errCode);
    napi_set_named_property(param->env, result, "code", code);
    napi_set_named_property(param->env, result, "data", data);
    napi_set_named_property(param->env, result, "reply", reply);
L
liangshenglin1 已提交
925 926 927
    return result;
}

928
void StubExecuteSendRequest(napi_env env, SendRequestParam *param)
929 930 931
{
    param->errCode = param->target->SendRequest(param->code,
        *(param->data.get()), *(param->reply.get()), param->option);
W
wanghaoxu 已提交
932
    ZLOGI(LOG_LABEL, "sendRequest done, errCode:%{public}d", param->errCode);
Z
zhou-liting125 已提交
933
    if (param->traceId != 0) {
1
18392170496 已提交
934
        FinishAsyncTrace(HITRACE_TAG_RPC, (param->traceValue).c_str(), param->traceId);
Z
zhou-liting125 已提交
935
    }
936 937 938 939
    uv_loop_s *loop = nullptr;
    napi_get_uv_event_loop(env, &loop);
    uv_work_t *work = new uv_work_t;
    work->data = reinterpret_cast<void *>(param);
940 941 942
    uv_after_work_cb afterWorkCb = nullptr;
    if (param->callback != nullptr) {
        afterWorkCb = [](uv_work_t *work, int status) {
W
wanghaoxu 已提交
943
            ZLOGI(LOG_LABEL, "callback started");
944
            SendRequestParam *param = reinterpret_cast<SendRequestParam *>(work->data);
S
shufewhx 已提交
945 946
            napi_handle_scope scope = nullptr;
            napi_open_handle_scope(param->env, &scope);
947 948 949 950 951 952 953 954 955
            napi_value result = MakeSendRequestResult(param);
            napi_value callback = nullptr;
            napi_get_reference_value(param->env, param->callback, &callback);
            napi_value cbResult = nullptr;
            napi_call_function(param->env, nullptr, callback, 1, &result, &cbResult);
            napi_delete_reference(param->env, param->jsCodeRef);
            napi_delete_reference(param->env, param->jsDataRef);
            napi_delete_reference(param->env, param->jsReplyRef);
            napi_delete_reference(param->env, param->callback);
S
shufewhx 已提交
956
            napi_close_handle_scope(param->env, scope);
957 958 959 960 961
            delete param;
            delete work;
        };
    } else {
        afterWorkCb = [](uv_work_t *work, int status) {
W
wanghaoxu 已提交
962
            ZLOGI(LOG_LABEL, "promise fullfilled");
963
            SendRequestParam *param = reinterpret_cast<SendRequestParam *>(work->data);
S
shufewhx 已提交
964 965
            napi_handle_scope scope = nullptr;
            napi_open_handle_scope(param->env, &scope);
966 967 968 969 970 971 972 973 974
            napi_value result = MakeSendRequestResult(param);
            if (param->errCode == 0) {
                napi_resolve_deferred(param->env, param->deferred, result);
            } else {
                napi_reject_deferred(param->env, param->deferred, result);
            }
            napi_delete_reference(param->env, param->jsCodeRef);
            napi_delete_reference(param->env, param->jsDataRef);
            napi_delete_reference(param->env, param->jsReplyRef);
S
shufewhx 已提交
975
            napi_close_handle_scope(param->env, scope);
976 977 978 979 980 981 982 983 984 985 986 987 988 989 990 991 992 993 994 995 996 997 998 999 1000
            delete param;
            delete work;
        };
    }
    uv_queue_work(loop, work, [](uv_work_t *work) {}, afterWorkCb);
}

napi_value StubSendRequestAsync(napi_env env, sptr<IRemoteObject> target, uint32_t code,
    std::shared_ptr<MessageParcel> data, std::shared_ptr<MessageParcel> reply,
    MessageOption &option, napi_value *argv)
{
    SendRequestParam *sendRequestParam = new SendRequestParam {
        .target = target,
        .code = code,
        .data = data,
        .reply = reply,
        .option = option,
        .asyncWork = nullptr,
        .deferred = nullptr,
        .errCode = -1,
        .jsCodeRef = nullptr,
        .jsDataRef = nullptr,
        .jsReplyRef = nullptr,
        .callback = nullptr,
        .env = env,
Z
zhou-liting125 已提交
1001
        .traceId = 0,
1002
    };
Z
zhou-liting125 已提交
1003 1004 1005 1006 1007
    if (target != nullptr) {
        std::string remoteDescriptor = Str16ToStr8(target->GetObjectDescriptor());
        if (!remoteDescriptor.empty()) {
            sendRequestParam->traceValue = remoteDescriptor + std::to_string(code);
            sendRequestParam->traceId = bytraceId.fetch_add(1, std::memory_order_seq_cst);
1
18392170496 已提交
1008
            StartAsyncTrace(HITRACE_TAG_RPC, (sendRequestParam->traceValue).c_str(), sendRequestParam->traceId);
Z
zhou-liting125 已提交
1009 1010
        }
    }
1011 1012 1013 1014 1015 1016 1017 1018 1019
    napi_create_reference(env, argv[0], 1, &sendRequestParam->jsCodeRef);
    napi_create_reference(env, argv[1], 1, &sendRequestParam->jsDataRef);
    napi_create_reference(env, argv[2], 1, &sendRequestParam->jsReplyRef);
    napi_create_reference(env, argv[4], 1, &sendRequestParam->callback);
    std::thread t(StubExecuteSendRequest, env, sendRequestParam);
    t.detach();
    napi_value result = nullptr;
    napi_get_undefined(env, &result);
    return result;
1020 1021 1022
}

napi_value StubSendRequestPromise(napi_env env, sptr<IRemoteObject> target, uint32_t code,
1023 1024
    std::shared_ptr<MessageParcel> data, std::shared_ptr<MessageParcel> reply,
    MessageOption &option, napi_value *argv)
1025 1026 1027 1028 1029 1030 1031 1032 1033 1034 1035 1036 1037
{
    napi_deferred deferred = nullptr;
    napi_value promise = nullptr;
    NAPI_CALL(env, napi_create_promise(env, &deferred, &promise));
    SendRequestParam *sendRequestParam = new SendRequestParam {
        .target = target,
        .code = code,
        .data = data,
        .reply = reply,
        .option = option,
        .asyncWork = nullptr,
        .deferred = deferred,
        .errCode = -1,
1038 1039 1040 1041 1042
        .jsCodeRef = nullptr,
        .jsDataRef = nullptr,
        .jsReplyRef = nullptr,
        .callback = nullptr,
        .env = env,
Z
zhou-liting125 已提交
1043
        .traceId = 0,
1044
    };
Z
zhou-liting125 已提交
1045 1046 1047 1048 1049
    if (target != nullptr) {
        std::string remoteDescriptor = Str16ToStr8(target->GetObjectDescriptor());
        if (!remoteDescriptor.empty()) {
            sendRequestParam->traceValue = remoteDescriptor + std::to_string(code);
            sendRequestParam->traceId = bytraceId.fetch_add(1, std::memory_order_seq_cst);
1
18392170496 已提交
1050
            StartAsyncTrace(HITRACE_TAG_RPC, (sendRequestParam->traceValue).c_str(), sendRequestParam->traceId);
Z
zhou-liting125 已提交
1051 1052
        }
    }
1053 1054 1055 1056
    napi_create_reference(env, argv[0], 1, &sendRequestParam->jsCodeRef);
    napi_create_reference(env, argv[1], 1, &sendRequestParam->jsDataRef);
    napi_create_reference(env, argv[2], 1, &sendRequestParam->jsReplyRef);
    std::thread t(StubExecuteSendRequest, env, sendRequestParam);
1057 1058 1059 1060
    t.detach();
    return promise;
}

S
shufewhx 已提交
1061
static napi_value NAPI_RemoteObject_sendRequest(napi_env env, napi_callback_info info)
1062 1063
{
    size_t argc = 4;
1064
    size_t argcCallback = 5;
L
liangshenglin1 已提交
1065
    size_t argcPromise = 4;
1066
    napi_value argv[5] = { 0 };
1067 1068
    napi_value thisVar = nullptr;
    napi_get_cb_info(env, info, &argc, argv, &thisVar, nullptr);
1069
    NAPI_ASSERT(env, argc == argcPromise || argc == argcCallback, "requires 4 or 5 parameters");
L
liangshenglin1 已提交
1070
    napi_valuetype valueType = napi_null;
1071 1072 1073 1074 1075 1076 1077 1078 1079 1080 1081 1082 1083 1084 1085 1086 1087
    napi_typeof(env, argv[0], &valueType);
    NAPI_ASSERT(env, valueType == napi_number, "type mismatch for parameter 1");
    napi_typeof(env, argv[1], &valueType);
    NAPI_ASSERT(env, valueType == napi_object, "type mismatch for parameter 2");
    napi_typeof(env, argv[2], &valueType);
    NAPI_ASSERT(env, valueType == napi_object, "type mismatch for parameter 3");
    napi_typeof(env, argv[3], &valueType);
    NAPI_ASSERT(env, valueType == napi_object, "type mismatch for parameter 4");

    NAPI_MessageParcel *data = nullptr;
    napi_status status = napi_unwrap(env, argv[1], (void **)&data);
    NAPI_ASSERT(env, status == napi_ok, "failed to get data message parcel");
    NAPI_MessageParcel *reply = nullptr;
    status = napi_unwrap(env, argv[2], (void **)&reply);
    NAPI_ASSERT(env, status == napi_ok, "failed to get reply message parcel");
    MessageOption *option = nullptr;
    status = napi_unwrap(env, argv[3], (void **)&option);
1088
    NAPI_ASSERT(env, status == napi_ok, "failed to get message option");
1089 1090 1091 1092
    int32_t code = 0;
    napi_get_value_int32(env, argv[0], &code);

    sptr<IRemoteObject> target = NAPI_ohos_rpc_getNativeRemoteObject(env, thisVar);
1093 1094 1095 1096 1097 1098 1099 1100 1101 1102 1103
    if (argc == argcCallback) {
        napi_get_cb_info(env, info, &argc, argv, &thisVar, nullptr);
        napi_valuetype valuetype = napi_undefined;
        napi_typeof(env, argv[argcPromise], &valuetype);
        if (valuetype == napi_function) {
            return StubSendRequestAsync(env, target, code, data->GetMessageParcel(),
                reply->GetMessageParcel(), *option, argv);
        }
    }
    return StubSendRequestPromise(env, target, code, data->GetMessageParcel(),
        reply->GetMessageParcel(), *option, argv);
1104 1105
}

1106 1107 1108 1109 1110
napi_value NAPI_RemoteObject_checkSendMessageRequestArgs(napi_env env,
                                                         size_t argc,
                                                         size_t argcCallback,
                                                         size_t argcPromise,
                                                         napi_value* argv)
L
liangshenglin1 已提交
1111
{
1112 1113
    if (argc != argcPromise && argc != argcCallback) {
        ZLOGE(LOG_LABEL, "requires 4 or 5 parameters");
1114
        return napiErr.ThrowError(env, errorDesc::CHECK_PARAM_ERROR);
1115
    }
1116
    napi_valuetype valueType = napi_null;
1117 1118 1119
    napi_typeof(env, argv[ARGV_INDEX_0], &valueType);
    if (valueType != napi_number) {
        ZLOGE(LOG_LABEL, "type mismatch for parameter 1");
1120
        return napiErr.ThrowError(env, errorDesc::CHECK_PARAM_ERROR);
Z
zhou-liting125 已提交
1121
    }
1122 1123 1124
    napi_typeof(env, argv[ARGV_INDEX_1], &valueType);
    if (valueType != napi_object) {
        ZLOGE(LOG_LABEL, "type mismatch for parameter 2");
1125
        return napiErr.ThrowError(env, errorDesc::CHECK_PARAM_ERROR);
L
liangshenglin1 已提交
1126
    }
1127 1128 1129
    napi_typeof(env, argv[ARGV_INDEX_2], &valueType);
    if (valueType != napi_object) {
        ZLOGE(LOG_LABEL, "type mismatch for parameter 3");
1130
        return napiErr.ThrowError(env, errorDesc::CHECK_PARAM_ERROR);
Z
zhou-liting125 已提交
1131
    }
1132 1133 1134
    napi_typeof(env, argv[ARGV_INDEX_3], &valueType);
    if (valueType != napi_object) {
        ZLOGE(LOG_LABEL, "type mismatch for parameter 4");
1135
        return napiErr.ThrowError(env, errorDesc::CHECK_PARAM_ERROR);
1136 1137
    }
    napi_value result = nullptr;
1138 1139 1140 1141
    napi_get_undefined(env, &result);
    return result;
}

S
shufewhx 已提交
1142
static napi_value NAPI_RemoteObject_sendMessageRequest(napi_env env, napi_callback_info info)
L
liangshenglin1 已提交
1143 1144
{
    size_t argc = 4;
1145
    size_t argcCallback = 5;
L
liangshenglin1 已提交
1146
    size_t argcPromise = 4;
1147
    napi_value argv[5] = { 0 };
L
liangshenglin1 已提交
1148 1149
    napi_value thisVar = nullptr;
    napi_get_cb_info(env, info, &argc, argv, &thisVar, nullptr);
1150 1151 1152 1153 1154
    napi_value checkArgsResult = NAPI_RemoteObject_checkSendMessageRequestArgs(env, argc, argcCallback, argcPromise,
                                                                               argv);
    if (checkArgsResult == nullptr) {
        return checkArgsResult;
    }
1155
    NAPI_MessageSequence *data = nullptr;
L
liangshenglin1 已提交
1156
    napi_status status = napi_unwrap(env, argv[1], (void **)&data);
1157 1158
    if (status != napi_ok) {
        ZLOGE(LOG_LABEL, "failed to get data message sequence");
1159
        return napiErr.ThrowError(env, errorDesc::CHECK_PARAM_ERROR);
1160
    }
1161
    NAPI_MessageSequence *reply = nullptr;
L
liangshenglin1 已提交
1162
    status = napi_unwrap(env, argv[2], (void **)&reply);
1163 1164
    if (status != napi_ok) {
        ZLOGE(LOG_LABEL, "failed to get data message sequence");
1165
        return napiErr.ThrowError(env, errorDesc::CHECK_PARAM_ERROR);
1166
    }
L
liangshenglin1 已提交
1167 1168
    MessageOption *option = nullptr;
    status = napi_unwrap(env, argv[3], (void **)&option);
1169 1170
    if (status != napi_ok) {
        ZLOGE(LOG_LABEL, "failed to get message option");
1171
        return napiErr.ThrowError(env, errorDesc::CHECK_PARAM_ERROR);
1172
    }
L
liangshenglin1 已提交
1173 1174 1175
    int32_t code = 0;
    napi_get_value_int32(env, argv[0], &code);

1176
    sptr<IRemoteObject> target = NAPI_ohos_rpc_getNativeRemoteObject(env, thisVar);
1177 1178 1179 1180 1181
    if (argc == argcCallback) {
        napi_get_cb_info(env, info, &argc, argv, &thisVar, nullptr);
        napi_valuetype valuetype = napi_undefined;
        napi_typeof(env, argv[argcPromise], &valuetype);
        if (valuetype == napi_function) {
1182
            return StubSendRequestAsync(env, target, code, data->GetMessageParcel(),
1183 1184
                reply->GetMessageParcel(), *option, argv);
        }
L
liangshenglin1 已提交
1185
    }
1186
    return StubSendRequestPromise(env, target, code, data->GetMessageParcel(),
1187
        reply->GetMessageParcel(), *option, argv);
L
liangshenglin1 已提交
1188 1189
}

S
shufewhx 已提交
1190
static napi_value NAPI_RemoteObject_attachLocalInterface(napi_env env, napi_callback_info info)
L
liangshenglin1 已提交
1191 1192 1193 1194 1195
{
    size_t argc = 2;
    size_t expectedArgc = 2;
    napi_value argv[2] = { 0 };
    napi_value thisVar = nullptr;
1196 1197
    napi_get_cb_info(env, info, &argc, argv, &thisVar, nullptr);
    NAPI_ASSERT(env, argc == expectedArgc, "requires 2 parameters");
L
liangshenglin1 已提交
1198
    napi_valuetype valueType = napi_null;
L
liangshenglin1 已提交
1199 1200 1201
    napi_typeof(env, argv[0], &valueType);
    NAPI_ASSERT(env, valueType == napi_object, "type mismatch for parameter 1");
    napi_typeof(env, argv[1], &valueType);
1202 1203 1204 1205 1206 1207 1208 1209 1210 1211
    NAPI_ASSERT(env, valueType == napi_string, "type mismatch for parameter 2");
    size_t bufferSize = 0;
    size_t maxLen = 40960;
    napi_get_value_string_utf8(env, argv[1], nullptr, 0, &bufferSize);
    NAPI_ASSERT(env, bufferSize < maxLen, "string length too large");
    char stringValue[bufferSize + 1];
    size_t jsStringLength = 0;
    napi_get_value_string_utf8(env, argv[1], stringValue, bufferSize + 1, &jsStringLength);
    NAPI_ASSERT(env, jsStringLength == bufferSize, "string length wrong");
    std::string descriptor = stringValue;
L
liangshenglin1 已提交
1212

1213 1214 1215 1216
    NAPIRemoteObjectHolder *holder = nullptr;
    napi_unwrap(env, thisVar, (void* *)&holder);
    NAPI_ASSERT(env, holder != nullptr, "failed to get napi remote object holder");
    holder->attachLocalInterface(argv[0], descriptor);
L
liangshenglin1 已提交
1217

1218 1219 1220 1221 1222 1223 1224 1225 1226 1227 1228
    napi_value result = nullptr;
    napi_get_undefined(env, &result);
    return result;
}

napi_value NAPI_RemoteObject_checkModifyLocalInterfaceArgs(napi_env env, size_t argc, napi_value* argv)
{
    size_t expectedArgc = 2;

    if (argc != expectedArgc) {
        ZLOGE(LOG_LABEL, "requires 2 parameters");
1229
        return napiErr.ThrowError(env, errorDesc::CHECK_PARAM_ERROR);
L
liangshenglin1 已提交
1230
    }
1231 1232 1233 1234
    napi_valuetype valueType = napi_null;
    napi_typeof(env, argv[ARGV_INDEX_0], &valueType);
    if (valueType != napi_object) {
        ZLOGE(LOG_LABEL, "type mismatch for parameter 1");
1235
        return napiErr.ThrowError(env, errorDesc::CHECK_PARAM_ERROR);
L
liangshenglin1 已提交
1236
    }
1237 1238 1239
    napi_typeof(env, argv[ARGV_INDEX_1], &valueType);
    if (valueType != napi_string) {
        ZLOGE(LOG_LABEL, "type mismatch for parameter 2");
1240
        return napiErr.ThrowError(env, errorDesc::CHECK_PARAM_ERROR);
L
liangshenglin1 已提交
1241
    }
1242 1243
    napi_value result = nullptr;
    napi_get_undefined(env, &result);
L
liangshenglin1 已提交
1244 1245 1246
    return result;
}

S
shufewhx 已提交
1247
static napi_value NAPI_RemoteObject_modifyLocalInterface(napi_env env, napi_callback_info info)
L
liangshenglin1 已提交
1248 1249 1250 1251
{
    size_t argc = 2;
    napi_value argv[2] = { 0 };
    napi_value thisVar = nullptr;
1252 1253 1254 1255
    napi_get_cb_info(env, info, &argc, argv, &thisVar, nullptr);
    napi_value checkArgsResult = NAPI_RemoteObject_checkModifyLocalInterfaceArgs(env, argc, argv);
    if (checkArgsResult == nullptr) {
        return checkArgsResult;
L
liangshenglin1 已提交
1256
    }
1257 1258 1259 1260 1261
    size_t bufferSize = 0;
    size_t maxLen = 40960;
    napi_get_value_string_utf8(env, argv[1], nullptr, 0, &bufferSize);
    if (bufferSize >= maxLen) {
        ZLOGE(LOG_LABEL, "string length too large");
1262
        return napiErr.ThrowError(env, errorDesc::CHECK_PARAM_ERROR);
L
liangshenglin1 已提交
1263
    }
1264 1265 1266 1267 1268
    char stringValue[bufferSize + 1];
    size_t jsStringLength = 0;
    napi_get_value_string_utf8(env, argv[1], stringValue, bufferSize + 1, &jsStringLength);
    if (jsStringLength != bufferSize) {
        ZLOGE(LOG_LABEL, "string length wrong");
1269
        return napiErr.ThrowError(env, errorDesc::CHECK_PARAM_ERROR);
L
liangshenglin1 已提交
1270
    }
1271 1272 1273 1274 1275 1276 1277
    std::string descriptor = stringValue;

    NAPIRemoteObjectHolder *holder = nullptr;
    napi_unwrap(env, thisVar, (void* *)&holder);
    if (holder == nullptr) {
        ZLOGE(LOG_LABEL, "failed to get napi remote object holder");
        return nullptr;
L
liangshenglin1 已提交
1278
    }
1279 1280 1281 1282 1283
    holder->attachLocalInterface(argv[0], descriptor);

    napi_value result = nullptr;
    napi_get_undefined(env, &result);
    return result;
L
liangshenglin1 已提交
1284 1285
}

S
shufewhx 已提交
1286
static napi_value NAPI_RemoteObject_addDeathRecipient(napi_env env, napi_callback_info info)
L
liangshenglin1 已提交
1287
{
1288 1289
    napi_value result = nullptr;
    napi_get_boolean(env, false, &result);
L
liangshenglin1 已提交
1290 1291 1292
    return result;
}

S
shufewhx 已提交
1293
static napi_value NAPI_RemoteObject_registerDeathRecipient(napi_env env, napi_callback_info info)
1294 1295 1296 1297 1298
{
    ZLOGE(LOG_LABEL, "only proxy object permitted");
    return napiErr.ThrowError(env, errorDesc::ONLY_PROXY_OBJECT_PERMITTED_ERROR);
}

S
shufewhx 已提交
1299
static napi_value NAPI_RemoteObject_removeDeathRecipient(napi_env env, napi_callback_info info)
L
liangshenglin1 已提交
1300
{
1301 1302 1303 1304
    napi_value result = nullptr;
    napi_get_boolean(env, false, &result);
    return result;
}
L
liangshenglin1 已提交
1305

S
shufewhx 已提交
1306
static napi_value NAPI_RemoteObject_unregisterDeathRecipient(napi_env env, napi_callback_info info)
1307 1308 1309 1310 1311
{
    ZLOGE(LOG_LABEL, "only proxy object permitted");
    return napiErr.ThrowError(env, errorDesc::ONLY_PROXY_OBJECT_PERMITTED_ERROR);
}

S
shufewhx 已提交
1312
static napi_value NAPI_RemoteObject_isObjectDead(napi_env env, napi_callback_info info)
1313 1314 1315 1316
{
    napi_value result = nullptr;
    napi_get_boolean(env, false, &result);
    return result;
L
liangshenglin1 已提交
1317 1318 1319 1320 1321 1322
}

EXTERN_C_START
/*
 * function for module exports
 */
S
shufewhx 已提交
1323
napi_value NAPIRemoteObjectExport(napi_env env, napi_value exports)
L
liangshenglin1 已提交
1324
{
S
shufewhx 已提交
1325
    const std::string className = "RemoteObject";
L
liangshenglin1 已提交
1326
    napi_property_descriptor properties[] = {
S
shufewhx 已提交
1327 1328 1329 1330 1331 1332 1333 1334 1335 1336 1337 1338 1339 1340 1341
        DECLARE_NAPI_FUNCTION("sendRequest", NAPI_RemoteObject_sendRequest),
        DECLARE_NAPI_FUNCTION("sendMessageRequest", NAPI_RemoteObject_sendMessageRequest),
        DECLARE_NAPI_FUNCTION("getCallingPid", NAPI_RemoteObject_getCallingPid),
        DECLARE_NAPI_FUNCTION("getCallingUid", NAPI_RemoteObject_getCallingUid),
        DECLARE_NAPI_FUNCTION("getInterfaceDescriptor", NAPI_RemoteObject_getInterfaceDescriptor),
        DECLARE_NAPI_FUNCTION("getDescriptor", NAPI_RemoteObject_getDescriptor),
        DECLARE_NAPI_FUNCTION("attachLocalInterface", NAPI_RemoteObject_attachLocalInterface),
        DECLARE_NAPI_FUNCTION("modifyLocalInterface", NAPI_RemoteObject_modifyLocalInterface),
        DECLARE_NAPI_FUNCTION("queryLocalInterface", NAPI_RemoteObject_queryLocalInterface),
        DECLARE_NAPI_FUNCTION("getLocalInterface", NAPI_RemoteObject_getLocalInterface),
        DECLARE_NAPI_FUNCTION("addDeathRecipient", NAPI_RemoteObject_addDeathRecipient),
        DECLARE_NAPI_FUNCTION("registerDeathRecipient", NAPI_RemoteObject_registerDeathRecipient),
        DECLARE_NAPI_FUNCTION("removeDeathRecipient", NAPI_RemoteObject_removeDeathRecipient),
        DECLARE_NAPI_FUNCTION("unregisterDeathRecipient", NAPI_RemoteObject_unregisterDeathRecipient),
        DECLARE_NAPI_FUNCTION("isObjectDead", NAPI_RemoteObject_isObjectDead),
L
liangshenglin1 已提交
1342
    };
1343
    napi_value constructor = nullptr;
S
shufewhx 已提交
1344
    napi_define_class(env, className.c_str(), className.length(), RemoteObject_JS_Constructor, nullptr,
1345
        sizeof(properties) / sizeof(properties[0]), properties, &constructor);
S
shufewhx 已提交
1346 1347 1348
    NAPI_ASSERT(env, constructor != nullptr, "define js class RemoteObject failed");
    napi_status status = napi_set_named_property(env, exports, "RemoteObject", constructor);
    NAPI_ASSERT(env, status == napi_ok, "set property RemoteObject to exports failed");
1349 1350 1351
    napi_value global = nullptr;
    status = napi_get_global(env, &global);
    NAPI_ASSERT(env, status == napi_ok, "get napi global failed");
S
shufewhx 已提交
1352 1353
    status = napi_set_named_property(env, global, "IPCStubConstructor_", constructor);
    NAPI_ASSERT(env, status == napi_ok, "set stub constructor failed");
L
liangshenglin1 已提交
1354 1355 1356
    return exports;
}
EXTERN_C_END
W
wanderer-dl122 已提交
1357
} // namespace OHOS