This commit is contained in:
2024-09-27 19:16:49 +08:00
commit 49d0cea04d
10000 changed files with 1616312 additions and 0 deletions

View File

@@ -0,0 +1,84 @@
# Copyright (c) 2023 Huawei Device Co., Ltd.
# 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.
import("//build/ohos.gni")
import("//foundation/ability/ability_runtime/ability_runtime.gni")
config("ability_config") {
visibility = [ ":*" ]
include_dirs = [
"${ability_runtime_path}/interfaces/kits/native/ability/native",
"${ability_runtime_services_path}/common/include",
]
cflags = []
if (target_cpu == "arm") {
cflags += [ "-DBINDER_IPC_32BIT" ]
}
}
ohos_shared_library("driver_extension") {
include_dirs = [ "include" ]
sources = [
"src/driver_extension.cpp",
"src/driver_extension_context.cpp",
"src/js_driver_extension.cpp",
"src/js_driver_extension_context.cpp",
]
external_deps = [
"ability_base:want",
"ability_runtime:ability_context_native",
"ability_runtime:ability_manager",
"ability_runtime:abilitykit_native",
"ability_runtime:app_context",
"ability_runtime:napi_common",
"ability_runtime:runtime",
"c_utils:utils",
"eventhandler:libeventhandler",
"hilog:libhilog",
"hitrace:hitrace_meter",
"ipc:ipc_core",
"ipc:ipc_napi_common",
"napi:ace_napi",
]
subsystem_name = "hdf"
part_name = "external_device_manager"
}
ohos_shared_library("driver_extension_module") {
include_dirs = [ "include" ]
sources = [ "src/driver_extension_module_loader.cpp" ]
configs = [ ":ability_config" ]
deps = [ ":driver_extension" ]
external_deps = [
"ability_base:configuration",
"ability_base:session_info",
"ace_engine:ace_uicontent",
"bundle_framework:appexecfwk_base",
"bundle_framework:appexecfwk_core",
"c_utils:utils",
"hilog:libhilog",
"ipc:ipc_core",
"napi:ace_napi",
]
relative_install_dir = "extensionability/"
subsystem_name = "hdf"
part_name = "external_device_manager"
}

View File

@@ -0,0 +1,84 @@
/*
* Copyright (c) 2023 Huawei Device Co., Ltd.
* 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.
*/
#ifndef OHOS_ABILITY_RUNTIME_DRIVER_EXTENSION_H
#define OHOS_ABILITY_RUNTIME_DRIVER_EXTENSION_H
#include "extension_base.h"
namespace OHOS {
namespace AbilityRuntime {
class DriverExtensionContext;
class Runtime;
class DriverExtension;
using CreatorDriverFunc = std::function<DriverExtension* (const std::unique_ptr<Runtime>& runtime)>;
/**
* @brief Basic driver components.
*/
class DriverExtension : public ExtensionBase<DriverExtensionContext>,
public std::enable_shared_from_this<DriverExtension> {
public:
DriverExtension() = default;
virtual ~DriverExtension() = default;
/**
* @brief Create and init context.
*
* @param record the extension record.
* @param application the application info.
* @param handler the extension handler.
* @param token the remote token.
* @return The created context.
*/
virtual std::shared_ptr<DriverExtensionContext> CreateAndInitContext(
const std::shared_ptr<AbilityLocalRecord> &record,
const std::shared_ptr<OHOSApplication> &application,
std::shared_ptr<AbilityHandler> &handler,
const sptr<IRemoteObject> &token) override;
/**DRIVER
* @brief Init the extension.
*
* @param record the extension record.
* @param application the application info.
* @param handler the extension handler.
* @param token the remote token.
*/
virtual void Init(const std::shared_ptr<AbilityLocalRecord> &record,
const std::shared_ptr<OHOSApplication> &application,
std::shared_ptr<AbilityHandler> &handler,
const sptr<IRemoteObject> &token) override;
/**
* @brief Create Extension.
*
* @param runtime The runtime.
* @return The DriverExtension instance.
*/
static DriverExtension* Create(const std::unique_ptr<Runtime>& runtime);
/**
* @brief Set a creator function.
*
* @param creator The function for create a driver-extension ability.
*/
static void SetCreator(const CreatorDriverFunc& creator);
private:
static CreatorDriverFunc creator_;
};
} // namespace AbilityRuntime
} // namespace OHOS
#endif // OHOS_ABILITY_RUNTIME_DRIVER_EXTENSION_H

View File

@@ -0,0 +1,64 @@
/*
* Copyright (c) 2023 Huawei Device Co., Ltd.
* 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.
*/
#ifndef OHOS_ABILITY_RUNTIME_DRIVER_EXTENSION_CONTEXT_H
#define OHOS_ABILITY_RUNTIME_DRIVER_EXTENSION_CONTEXT_H
#include "extension_context.h"
#include "ability_connect_callback.h"
#include "connection_manager.h"
#include "local_call_container.h"
#include "start_options.h"
#include "want.h"
namespace OHOS {
namespace AbilityRuntime {
/**
* @brief context supply for driver
*
*/
class DriverExtensionContext : public ExtensionContext {
public:
DriverExtensionContext() = default;
virtual ~DriverExtensionContext() = default;
/**
* @brief Update the state of driver.
*
* @return errCode ERR_OK on success, others on failure.
*/
ErrCode UpdateDriverState();
using SelfType = DriverExtensionContext;
static const size_t CONTEXT_TYPE_ID;
protected:
bool IsContext(size_t contextTypeId) override
{
return contextTypeId == CONTEXT_TYPE_ID || ExtensionContext::IsContext(contextTypeId);
}
private:
/**
* @brief Get Current Ability Type
*
* @return Current Ability Type
*/
OHOS::AppExecFwk::AbilityType GetAbilityInfoType() const;
};
} // namespace AbilityRuntime
} // namespace OHOS
#endif // OHOS_ABILITY_RUNTIME_DRIVER_EXTENSION_CONTEXT_H

View File

@@ -0,0 +1,37 @@
/*
* Copyright (c) 2023 Huawei Device Co., Ltd.
* 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.
*/
#ifndef OHOS_ABILITY_RUNTIME_DRIVER_EXTENSION_MODULE_LOADER_H
#define OHOS_ABILITY_RUNTIME_DRIVER_EXTENSION_MODULE_LOADER_H
#include "extension_module_loader.h"
namespace OHOS::AbilityRuntime {
class DriverExtensionModuleLoader : public ExtensionModuleLoader, public Singleton<DriverExtensionModuleLoader> {
DECLARE_SINGLETON(DriverExtensionModuleLoader);
public:
/**
* @brief Create Extension.
*
* @param runtime The runtime.
* @return The Extension instance.
*/
virtual Extension *Create(const std::unique_ptr<Runtime>& runtime) const override;
virtual std::map<std::string, std::string> GetParams() override;
};
}
#endif // OHOS_ABILITY_RUNTIME_DRIVER_EXTENSION_MODULE_LOADER_H

View File

@@ -0,0 +1,147 @@
/*
* Copyright (c) 2023 Huawei Device Co., Ltd.
* 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.
*/
#ifndef OHOS_ABILITY_RUNTIME_JS_DRIVER_EXTENSION_H
#define OHOS_ABILITY_RUNTIME_JS_DRIVER_EXTENSION_H
#include "configuration.h"
#include "driver_extension.h"
class NativeReference;
class NativeValue;
class NativeObject;
namespace OHOS {
namespace AbilityRuntime {
class DriverExtension;
class JsRuntime;
/**
* @brief Basic driver components.
*/
class JsDriverExtension : public DriverExtension,
public std::enable_shared_from_this<JsDriverExtension> {
public:
explicit JsDriverExtension(JsRuntime& jsRuntime);
virtual ~JsDriverExtension() override;
/**
* @brief Create JsDriverExtension.
*
* @param runtime The runtime.
* @return The JsDriverExtension instance.
*/
static JsDriverExtension* Create(const std::unique_ptr<Runtime>& runtime);
/**
* @brief Init the extension.
*
* @param record the extension record.
* @param application the application info.
* @param handler the extension handler.
* @param token the remote token.
*/
virtual void Init(const std::shared_ptr<AppExecFwk::AbilityLocalRecord> &record,
const std::shared_ptr<AppExecFwk::OHOSApplication> &application,
std::shared_ptr<AppExecFwk::AbilityHandler> &handler,
const sptr<IRemoteObject> &token) override;
/**
* @brief Called when this extension is started. You must override this function if you want to perform some
* initialization operations during extension startup.
*
* This function can be called only once in the entire lifecycle of an extension.
* @param Want Indicates the {@link Want} structure containing startup information about the extension.
*/
virtual void OnStart(const AAFwk::Want &want) override;
/**
* @brief Called when this Driver extension is connected for the first time.
*
* You can override this function to implement your own processing logic.
*
* @param want Indicates the {@link Want} structure containing connection information about the Driver extension.
* @return Returns a pointer to the <b>sid</b> of the connected Driver extension.
*/
virtual sptr<IRemoteObject> OnConnect(const AAFwk::Want &want) override;
/**
* @brief Called when this Driver extension is connected for the first time.
*
* You can override this function to implement your own processing logic.
*
* @param want Indicates the {@link Want} structure containing connection information about the Driver extension.
* @param callbackInfo Indicates the lifecycle transaction callback information
* @param isAsyncCallback Indicates whether it is an asynchronous lifecycle callback
* @return Returns a pointer to the <b>sid</b> of the connected Driver extension.
*/
virtual sptr<IRemoteObject> OnConnect(const AAFwk::Want &want,
AppExecFwk::AbilityTransactionCallbackInfo<sptr<IRemoteObject>> *callbackInfo, bool &isAsyncCallback) override;
/**
* @brief Called when all abilities connected to this Driver extension are disconnected.
*
* You can override this function to implement your own processing logic.
*
*/
virtual void OnDisconnect(const AAFwk::Want &want) override;
/**
* @brief Called when all abilities connected to this Driver extension are disconnected.
*
* You can override this function to implement your own processing logic.
* @param callbackInfo Indicates the lifecycle transaction callback information
* @param isAsyncCallback Indicates whether it is an asynchronous lifecycle callback
*/
void OnDisconnect(const AAFwk::Want &want, AppExecFwk::AbilityTransactionCallbackInfo<> *callbackInfo,
bool &isAsyncCallback) override;
/**
* @brief Called when this extension enters the <b>STATE_STOP</b> state.
*
* The extension in the <b>STATE_STOP</b> is being destroyed.
* You can override this function to implement your own processing logic.
*/
virtual void OnStop() override;
/**
* @brief Called when extension need dump info.
*
* @param params The params from driver.
* @param info The dump info to show.
*/
virtual void Dump(const std::vector<std::string> &params, std::vector<std::string> &info) override;
private:
NativeValue* CallObjectMethod(const char* name, NativeValue* const *argv = nullptr, size_t argc = 0);
void BindContext(NativeEngine& engine, NativeObject* obj);
void GetSrcPath(std::string &srcPath);
NativeValue *CallOnConnect(const AAFwk::Want &want);
NativeValue *CallOnDisconnect(const AAFwk::Want &want, bool withResult = false);
bool CheckPromise(NativeValue *result);
bool CallPromise(NativeValue *result, AppExecFwk::AbilityTransactionCallbackInfo<> *callbackInfo);
JsRuntime& jsRuntime_;
std::unique_ptr<NativeReference> jsObj_;
std::shared_ptr<NativeReference> shellContextRef_ = nullptr;
};
} // namespace AbilityRuntime
} // namespace OHOS
#endif // OHOS_ABILITY_RUNTIME_JS_DRIVER_EXTENSION_H

View File

@@ -0,0 +1,32 @@
/*
* Copyright (c) 2023 Huawei Device Co., Ltd.
* 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.
*/
#ifndef OHOS_ABILITY_RUNTIME_JS_DRIVER_EXTENSION_CONTEXT_H
#define OHOS_ABILITY_RUNTIME_JS_DRIVER_EXTENSION_CONTEXT_H
#include <memory>
#include "ability_connect_callback.h"
#include "driver_extension_context.h"
#include "event_handler.h"
#include "js_free_install_observer.h"
#include "native_engine/native_engine.h"
namespace OHOS {
namespace AbilityRuntime {
NativeValue* CreateJsDriverExtensionContext(NativeEngine& engine, std::shared_ptr<DriverExtensionContext> context);
} // namespace AbilityRuntime
} // namespace OHOS
#endif // OHOS_ABILITY_RUNTIME_JS_DRIVER_EXTENSION_CONTEXT_H

View File

@@ -0,0 +1,79 @@
/*
* Copyright (c) 2023 Huawei Device Co., Ltd.
* 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.
*/
#include "driver_extension.h"
#include "configuration_utils.h"
#include "connection_manager.h"
#include "hilog_wrapper.h"
#include "js_driver_extension.h"
#include "runtime.h"
#include "driver_extension_context.h"
namespace OHOS {
namespace AbilityRuntime {
using namespace OHOS::AppExecFwk;
CreatorDriverFunc DriverExtension::creator_ = nullptr;
void DriverExtension::SetCreator(const CreatorDriverFunc& creator)
{
creator_ = creator;
}
DriverExtension* DriverExtension::Create(const std::unique_ptr<Runtime>& runtime)
{
if (!runtime) {
return new DriverExtension();
}
if (creator_) {
return creator_(runtime);
}
HILOG_INFO("DriverExtension::Create runtime");
switch (runtime->GetLanguage()) {
case Runtime::Language::JS:
return JsDriverExtension::Create(runtime);
default:
return new DriverExtension();
}
}
void DriverExtension::Init(const std::shared_ptr<AbilityLocalRecord> &record,
const std::shared_ptr<OHOSApplication> &application,
std::shared_ptr<AbilityHandler> &handler,
const sptr<IRemoteObject> &token)
{
ExtensionBase<DriverExtensionContext>::Init(record, application, handler, token);
HILOG_INFO("DriverExtension begin init context");
}
std::shared_ptr<DriverExtensionContext> DriverExtension::CreateAndInitContext(
const std::shared_ptr<AbilityLocalRecord> &record,
const std::shared_ptr<OHOSApplication> &application,
std::shared_ptr<AbilityHandler> &handler,
const sptr<IRemoteObject> &token)
{
std::shared_ptr<DriverExtensionContext> context =
ExtensionBase<DriverExtensionContext>::CreateAndInitContext(record, application, handler, token);
if (context == nullptr) {
HILOG_ERROR("DriverExtension::CreateAndInitContext context is nullptr");
return context;
}
return context;
}
} // namespace AbilityRuntime
} // namespace OHOS

View File

@@ -0,0 +1,48 @@
/*
* Copyright (c) 2023 Huawei Device Co., Ltd.
* 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.
*/
#include "driver_extension_context.h"
#include "ability_connection.h"
#include "ability_manager_client.h"
#include "hilog_wrapper.h"
#include "hitrace_meter.h"
namespace OHOS {
namespace AbilityRuntime {
const size_t DriverExtensionContext::CONTEXT_TYPE_ID(std::hash<const char*> {} ("DriverExtensionContext"));
ErrCode DriverExtensionContext::UpdateDriverState()
{
HILOG_INFO("%{public}s begin.", __func__);
ErrCode err = ERR_OK;
if (err != ERR_OK) {
HILOG_ERROR("DriverContext::UpdateDriverState is failed %{public}d", err);
}
return err;
}
AppExecFwk::AbilityType DriverExtensionContext::GetAbilityInfoType() const
{
std::shared_ptr<AppExecFwk::AbilityInfo> info = GetAbilityInfo();
if (info == nullptr) {
HILOG_ERROR("DriverContext::GetAbilityInfoType info == nullptr");
return AppExecFwk::AbilityType::UNKNOWN;
}
return info->type;
}
} // namespace AbilityRuntime
} // namespace OHOS

View File

@@ -0,0 +1,42 @@
/*
* Copyright (c) 2023 Huawei Device Co., Ltd.
* 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.
*/
#include "driver_extension_module_loader.h"
#include "driver_extension.h"
namespace OHOS::AbilityRuntime {
DriverExtensionModuleLoader::DriverExtensionModuleLoader() = default;
DriverExtensionModuleLoader::~DriverExtensionModuleLoader() = default;
Extension *DriverExtensionModuleLoader::Create(const std::unique_ptr<Runtime>& runtime) const
{
return DriverExtension::Create(runtime);
}
std::map<std::string, std::string> DriverExtensionModuleLoader::GetParams()
{
std::map<std::string, std::string> params;
// type means extension type in ExtensionAbilityType of extension_ability_info.h, 18 means driver.
params.insert(std::pair<std::string, std::string>("type", "18"));
// extension name
params.insert(std::pair<std::string, std::string>("name", "DriverExtension"));
return params;
}
extern "C" __attribute__((visibility("default"))) void* OHOS_EXTENSION_GetExtensionModule()
{
return &DriverExtensionModuleLoader::GetInstance();
}
} // namespace OHOS::AbilityRuntime

View File

@@ -0,0 +1,494 @@
/*
* Copyright (c) 2023 Huawei Device Co., Ltd.
* 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.
*/
#include "js_driver_extension.h"
#include "ability_info.h"
#include "hitrace_meter.h"
#include "hilog_wrapper.h"
#include "js_extension_common.h"
#include "js_extension_context.h"
#include "js_runtime.h"
#include "js_runtime_utils.h"
#include "js_driver_extension_context.h"
#include "napi/native_api.h"
#include "napi/native_node_api.h"
#include "napi_common_configuration.h"
#include "napi_common_want.h"
#include "napi_remote_object.h"
namespace OHOS {
namespace AbilityRuntime {
namespace {
constexpr size_t ARGC_ONE = 1;
}
namespace {
NativeValue *PromiseCallback(NativeEngine *engine, NativeCallbackInfo *info)
{
if (info == nullptr || info->functionInfo == nullptr || info->functionInfo->data == nullptr) {
HILOG_ERROR("PromiseCallback, Invalid input info.");
return nullptr;
}
void *data = info->functionInfo->data;
auto *callbackInfo = static_cast<AppExecFwk::AbilityTransactionCallbackInfo<> *>(data);
callbackInfo->Call();
AppExecFwk::AbilityTransactionCallbackInfo<>::Destroy(callbackInfo);
info->functionInfo->data = nullptr;
return nullptr;
}
NativeValue *OnConnectPromiseCallback(NativeEngine *engine, NativeCallbackInfo *info)
{
if (info == nullptr || info->functionInfo == nullptr || info->functionInfo->data == nullptr) {
HILOG_ERROR("PromiseCallback, Invalid input info.");
return nullptr;
}
void *data = info->functionInfo->data;
auto *callbackInfo = static_cast<AppExecFwk::AbilityTransactionCallbackInfo<sptr<IRemoteObject>> *>(data);
sptr<IRemoteObject> service = nullptr;
if (info->argc > 0) {
service = NAPI_ohos_rpc_getNativeRemoteObject(reinterpret_cast<napi_env>(engine),
reinterpret_cast<napi_value>(info->argv[0]));
}
callbackInfo->Call(service);
AppExecFwk::AbilityTransactionCallbackInfo<sptr<IRemoteObject>>::Destroy(callbackInfo);
info->functionInfo->data = nullptr;
return nullptr;
}
}
using namespace OHOS::AppExecFwk;
NativeValue *AttachDriverExtensionContext(NativeEngine *engine, void *value, void *)
{
HILOG_INFO("AttachDriverExtensionContext");
if (value == nullptr) {
HILOG_WARN("invalid parameter.");
return nullptr;
}
auto ptr = reinterpret_cast<std::weak_ptr<DriverExtensionContext> *>(value)->lock();
if (ptr == nullptr) {
HILOG_WARN("invalid context.");
return nullptr;
}
NativeValue *object = CreateJsDriverExtensionContext(*engine, ptr);
auto contextObj = JsRuntime::LoadSystemModuleByEngine(engine,
"application.DriverExtensionContext", &object, 1)->Get();
NativeObject *nObject = ConvertNativeValueTo<NativeObject>(contextObj);
nObject->ConvertToNativeBindingObject(engine, DetachCallbackFunc, AttachDriverExtensionContext,
value, nullptr);
auto workContext = new (std::nothrow) std::weak_ptr<DriverExtensionContext>(ptr);
nObject->SetNativePointer(workContext,
[](NativeEngine *, void *data, void *) {
HILOG_INFO("Finalizer for weak_ptr driver extension context is called");
delete static_cast<std::weak_ptr<DriverExtensionContext> *>(data);
}, nullptr);
return contextObj;
}
JsDriverExtension* JsDriverExtension::Create(const std::unique_ptr<Runtime>& runtime)
{
return new JsDriverExtension(static_cast<JsRuntime&>(*runtime));
}
JsDriverExtension::JsDriverExtension(JsRuntime& jsRuntime) : jsRuntime_(jsRuntime) {}
JsDriverExtension::~JsDriverExtension() = default;
void JsDriverExtension::Init(const std::shared_ptr<AbilityLocalRecord> &record,
const std::shared_ptr<OHOSApplication> &application, std::shared_ptr<AbilityHandler> &handler,
const sptr<IRemoteObject> &token)
{
DriverExtension::Init(record, application, handler, token);
std::string srcPath = "";
GetSrcPath(srcPath);
if (srcPath.empty()) {
HILOG_ERROR("Failed to get srcPath");
return;
}
std::string moduleName(Extension::abilityInfo_->moduleName);
moduleName.append("::").append(abilityInfo_->name);
HILOG_DEBUG("JsStaticSubscriberExtension::Init moduleName:%{public}s,srcPath:%{public}s.",
moduleName.c_str(), srcPath.c_str());
HandleScope handleScope(jsRuntime_);
auto& engine = jsRuntime_.GetNativeEngine();
jsObj_ = jsRuntime_.LoadModule(
moduleName, srcPath, abilityInfo_->hapPath, abilityInfo_->compileMode == CompileMode::ES_MODULE);
if (jsObj_ == nullptr) {
HILOG_ERROR("Failed to get jsObj_");
return;
}
HILOG_INFO("JsDriverExtension::Init ConvertNativeValueTo.");
NativeObject* obj = ConvertNativeValueTo<NativeObject>(jsObj_->Get());
if (obj == nullptr) {
HILOG_ERROR("Failed to get JsDriverExtension object");
return;
}
BindContext(engine, obj);
SetExtensionCommon(JsExtensionCommon::Create(jsRuntime_, static_cast<NativeReference&>(*jsObj_), shellContextRef_));
}
void JsDriverExtension::BindContext(NativeEngine& engine, NativeObject* obj)
{
auto context = GetContext();
if (context == nullptr) {
HILOG_ERROR("Failed to get context");
return;
}
HILOG_INFO("JsDriverExtension::Init CreateJsDriverExtensionContext.");
NativeValue* contextObj = CreateJsDriverExtensionContext(engine, context);
shellContextRef_ = JsRuntime::LoadSystemModuleByEngine(&engine, "application.DriverExtensionContext",
&contextObj, ARGC_ONE);
contextObj = shellContextRef_->Get();
NativeObject *nativeObj = ConvertNativeValueTo<NativeObject>(contextObj);
if (nativeObj == nullptr) {
HILOG_ERROR("Failed to get context native object");
return;
}
auto workContext = new (std::nothrow) std::weak_ptr<DriverExtensionContext>(context);
nativeObj->ConvertToNativeBindingObject(&engine, DetachCallbackFunc, AttachDriverExtensionContext,
workContext, nullptr);
HILOG_INFO("JsDriverExtension::Init Bind.");
context->Bind(jsRuntime_, shellContextRef_.get());
HILOG_INFO("JsDriverExtension::SetProperty.");
obj->SetProperty("context", contextObj);
HILOG_INFO("Set driver extension context");
nativeObj->SetNativePointer(workContext,
[](NativeEngine*, void* data, void*) {
HILOG_INFO("Finalizer for weak_ptr driver extension context is called");
delete static_cast<std::weak_ptr<DriverExtensionContext>*>(data);
}, nullptr);
HILOG_INFO("JsDriverExtension::Init end.");
}
void JsDriverExtension::OnStart(const AAFwk::Want &want)
{
Extension::OnStart(want);
HILOG_INFO("JsDriverExtension OnStart begin..");
HandleScope handleScope(jsRuntime_);
NativeEngine* nativeEngine = &jsRuntime_.GetNativeEngine();
napi_value napiWant = OHOS::AppExecFwk::WrapWant(reinterpret_cast<napi_env>(nativeEngine), want);
NativeValue* nativeWant = reinterpret_cast<NativeValue*>(napiWant);
NativeValue* argv[] = {nativeWant};
CallObjectMethod("onInit", argv, ARGC_ONE);
HILOG_INFO("%{public}s end.", __func__);
}
void JsDriverExtension::OnStop()
{
DriverExtension::OnStop();
HILOG_INFO("JsDriverExtension OnStop begin.");
CallObjectMethod("onRelease");
bool ret = ConnectionManager::GetInstance().DisconnectCaller(GetContext()->GetToken());
if (ret) {
ConnectionManager::GetInstance().ReportConnectionLeakEvent(getpid(), gettid());
HILOG_INFO("The driver extension connection is not disconnected.");
}
HILOG_INFO("%{public}s end.", __func__);
}
sptr<IRemoteObject> JsDriverExtension::OnConnect(const AAFwk::Want &want)
{
HandleScope handleScope(jsRuntime_);
NativeValue *result = CallOnConnect(want);
NativeEngine* nativeEngine = &jsRuntime_.GetNativeEngine();
auto remoteObj = NAPI_ohos_rpc_getNativeRemoteObject(
reinterpret_cast<napi_env>(nativeEngine), reinterpret_cast<napi_value>(result));
if (remoteObj == nullptr) {
HILOG_ERROR("remoteObj nullptr.");
}
return remoteObj;
}
sptr<IRemoteObject> JsDriverExtension::OnConnect(const AAFwk::Want &want,
AppExecFwk::AbilityTransactionCallbackInfo<sptr<IRemoteObject>> *callbackInfo, bool &isAsyncCallback)
{
HandleScope handleScope(jsRuntime_);
NativeEngine *nativeEngine = &jsRuntime_.GetNativeEngine();
NativeValue *result = CallOnConnect(want);
bool isPromise = CheckPromise(result);
if (!isPromise) {
isAsyncCallback = false;
sptr<IRemoteObject> remoteObj = NAPI_ohos_rpc_getNativeRemoteObject(reinterpret_cast<napi_env>(nativeEngine),
reinterpret_cast<napi_value>(result));
if (remoteObj == nullptr) {
HILOG_ERROR("remoteObj nullptr.");
}
return remoteObj;
}
bool callResult = false;
do {
auto *retObj = ConvertNativeValueTo<NativeObject>(result);
if (retObj == nullptr) {
HILOG_ERROR("CallPromise, Failed to convert native value to NativeObject.");
break;
}
NativeValue *then = retObj->GetProperty("then");
if (then == nullptr) {
HILOG_ERROR("CallPromise, Failed to get property: then.");
break;
}
if (!then->IsCallable()) {
HILOG_ERROR("CallPromise, property then is not callable.");
break;
}
auto promiseCallback = nativeEngine->CreateFunction("promiseCallback", strlen("promiseCallback"),
OnConnectPromiseCallback, callbackInfo);
NativeValue *argv[1] = { promiseCallback };
nativeEngine->CallFunction(result, then, argv, 1);
callResult = true;
} while (false);
if (!callResult) {
HILOG_ERROR("Failed to call promise.");
isAsyncCallback = false;
} else {
isAsyncCallback = true;
}
return nullptr;
}
void JsDriverExtension::OnDisconnect(const AAFwk::Want &want)
{
HITRACE_METER_NAME(HITRACE_TAG_ABILITY_MANAGER, __PRETTY_FUNCTION__);
Extension::OnDisconnect(want);
HILOG_DEBUG("%{public}s begin.", __func__);
CallOnDisconnect(want, false);
HILOG_DEBUG("%{public}s end.", __func__);
}
void JsDriverExtension::OnDisconnect(const AAFwk::Want &want,
AppExecFwk::AbilityTransactionCallbackInfo<> *callbackInfo, bool &isAsyncCallback)
{
HITRACE_METER_NAME(HITRACE_TAG_ABILITY_MANAGER, __PRETTY_FUNCTION__);
Extension::OnDisconnect(want);
HILOG_DEBUG("%{public}s begin.", __func__);
NativeValue *result = CallOnDisconnect(want, true);
bool isPromise = CheckPromise(result);
if (!isPromise) {
isAsyncCallback = false;
return;
}
bool callResult = CallPromise(result, callbackInfo);
if (!callResult) {
HILOG_ERROR("Failed to call promise.");
isAsyncCallback = false;
} else {
isAsyncCallback = true;
}
HILOG_DEBUG("%{public}s end.", __func__);
}
NativeValue* JsDriverExtension::CallObjectMethod(const char* name, NativeValue* const *argv, size_t argc)
{
HILOG_INFO("JsDriverExtension::CallObjectMethod(%{public}s), begin", name);
if (!jsObj_) {
HILOG_WARN("Not found DriverExtension.js");
return nullptr;
}
HandleScope handleScope(jsRuntime_);
auto& nativeEngine = jsRuntime_.GetNativeEngine();
NativeValue* value = jsObj_->Get();
NativeObject* obj = ConvertNativeValueTo<NativeObject>(value);
if (obj == nullptr) {
HILOG_ERROR("Failed to get DriverExtension object");
return nullptr;
}
NativeValue* method = obj->GetProperty(name);
if (method == nullptr || method->TypeOf() != NATIVE_FUNCTION) {
HILOG_ERROR("Failed to get '%{public}s' from DriverExtension object", name);
return nullptr;
}
HILOG_INFO("JsDriverExtension::CallFunction(%{public}s), success", name);
return nativeEngine.CallFunction(value, method, argv, argc);
}
void JsDriverExtension::GetSrcPath(std::string &srcPath)
{
if (!Extension::abilityInfo_->isModuleJson) {
/* temporary compatibility api8 + config.json */
srcPath.append(Extension::abilityInfo_->package);
srcPath.append("/assets/js/");
if (!Extension::abilityInfo_->srcPath.empty()) {
srcPath.append(Extension::abilityInfo_->srcPath);
}
srcPath.append("/").append(Extension::abilityInfo_->name).append(".abc");
return;
}
if (!Extension::abilityInfo_->srcEntrance.empty()) {
srcPath.append(Extension::abilityInfo_->moduleName + "/");
srcPath.append(Extension::abilityInfo_->srcEntrance);
srcPath.erase(srcPath.rfind('.'));
srcPath.append(".abc");
}
}
NativeValue *JsDriverExtension::CallOnConnect(const AAFwk::Want &want)
{
HITRACE_METER_NAME(HITRACE_TAG_ABILITY_MANAGER, __PRETTY_FUNCTION__);
Extension::OnConnect(want);
HILOG_DEBUG("%{public}s begin.", __func__);
NativeEngine* nativeEngine = &jsRuntime_.GetNativeEngine();
napi_value napiWant = OHOS::AppExecFwk::WrapWant(reinterpret_cast<napi_env>(nativeEngine), want);
auto* nativeWant = reinterpret_cast<NativeValue*>(napiWant);
NativeValue* argv[] = {nativeWant};
if (!jsObj_) {
HILOG_WARN("Not found DriverExtension.js");
return nullptr;
}
NativeValue* value = jsObj_->Get();
auto* obj = ConvertNativeValueTo<NativeObject>(value);
if (obj == nullptr) {
HILOG_ERROR("Failed to get DriverExtension object");
return nullptr;
}
NativeValue* method = obj->GetProperty("onConnect");
if (method == nullptr) {
HILOG_ERROR("Failed to get onConnect from DriverExtension object");
return nullptr;
}
HILOG_INFO("JsDriverExtension::CallFunction onConnect, success");
NativeValue* remoteNative = nativeEngine->CallFunction(value, method, argv, ARGC_ONE);
if (remoteNative == nullptr) {
HILOG_ERROR("remoteNative nullptr.");
}
HILOG_DEBUG("%{public}s end.", __func__);
return remoteNative;
}
NativeValue *JsDriverExtension::CallOnDisconnect(const AAFwk::Want &want, bool withResult)
{
HandleEscape handleEscape(jsRuntime_);
NativeEngine *nativeEngine = &jsRuntime_.GetNativeEngine();
napi_value napiWant = OHOS::AppExecFwk::WrapWant(reinterpret_cast<napi_env>(nativeEngine), want);
NativeValue *nativeWant = reinterpret_cast<NativeValue *>(napiWant);
NativeValue *argv[] = { nativeWant };
if (!jsObj_) {
HILOG_WARN("Not found DriverExtension.js");
return nullptr;
}
NativeValue *value = jsObj_->Get();
NativeObject *obj = ConvertNativeValueTo<NativeObject>(value);
if (obj == nullptr) {
HILOG_ERROR("Failed to get DriverExtension object");
return nullptr;
}
NativeValue *method = obj->GetProperty("onDisconnect");
if (method == nullptr) {
HILOG_ERROR("Failed to get onDisconnect from DriverExtension object");
return nullptr;
}
if (withResult) {
return handleEscape.Escape(nativeEngine->CallFunction(value, method, argv, ARGC_ONE));
} else {
nativeEngine->CallFunction(value, method, argv, ARGC_ONE);
return nullptr;
}
}
bool JsDriverExtension::CheckPromise(NativeValue *result)
{
if (result == nullptr) {
HILOG_DEBUG("CheckPromise, result is null, no need to call promise.");
return false;
}
if (!result->IsPromise()) {
HILOG_DEBUG("CheckPromise, result is not promise, no need to call promise.");
return false;
}
return true;
}
bool JsDriverExtension::CallPromise(NativeValue *result, AppExecFwk::AbilityTransactionCallbackInfo<> *callbackInfo)
{
auto *retObj = ConvertNativeValueTo<NativeObject>(result);
if (retObj == nullptr) {
HILOG_ERROR("CallPromise, Failed to convert native value to NativeObject.");
return false;
}
NativeValue *then = retObj->GetProperty("then");
if (then == nullptr) {
HILOG_ERROR("CallPromise, Failed to get property: then.");
return false;
}
if (!then->IsCallable()) {
HILOG_ERROR("CallPromise, property then is not callable.");
return false;
}
HandleScope handleScope(jsRuntime_);
auto &nativeEngine = jsRuntime_.GetNativeEngine();
auto promiseCallback = nativeEngine.CreateFunction("promiseCallback", strlen("promiseCallback"), PromiseCallback,
callbackInfo);
NativeValue *argv[1] = { promiseCallback };
nativeEngine.CallFunction(result, then, argv, 1);
return true;
}
void JsDriverExtension::Dump(const std::vector<std::string> &params, std::vector<std::string> &info)
{
Extension::Dump(params, info);
HILOG_INFO("%{public}s called.", __func__);
HandleScope handleScope(jsRuntime_);
auto& nativeEngine = jsRuntime_.GetNativeEngine();
// create js array object of params
NativeValue* arrayValue = nativeEngine.CreateArray(params.size());
NativeArray* array = ConvertNativeValueTo<NativeArray>(arrayValue);
uint32_t index = 0;
for (const auto &param : params) {
array->SetElement(index++, CreateJsValue(nativeEngine, param));
}
NativeValue* argv[] = { arrayValue };
NativeValue* dumpInfo = CallObjectMethod("onDump", argv, ARGC_ONE);
if (dumpInfo == nullptr) {
HILOG_ERROR("dumpInfo nullptr.");
return;
}
NativeArray* dumpInfoNative = ConvertNativeValueTo<NativeArray>(dumpInfo);
if (dumpInfoNative == nullptr) {
HILOG_ERROR("dumpInfoNative nullptr.");
return;
}
for (uint32_t i = 0; i < dumpInfoNative->GetLength(); i++) {
std::string dumpInfoStr;
if (!ConvertFromJsValue(nativeEngine, dumpInfoNative->GetElement(i), dumpInfoStr)) {
HILOG_ERROR("Parse dumpInfoStr failed");
return;
}
info.push_back(dumpInfoStr);
}
HILOG_DEBUG("Dump info size: %{public}zu", info.size());
}
}
}

View File

@@ -0,0 +1,116 @@
/*
* Copyright (c) 2023 Huawei Device Co., Ltd.
* 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.
*/
#include "js_driver_extension_context.h"
#include <chrono>
#include <cstdint>
#include "ability_manager_client.h"
#include "ability_runtime/js_caller_complex.h"
#include "hilog_wrapper.h"
#include "js_extension_context.h"
#include "js_error_utils.h"
#include "js_data_struct_converter.h"
#include "js_runtime.h"
#include "js_runtime_utils.h"
#include "napi/native_api.h"
#include "napi_common_ability.h"
#include "napi_common_want.h"
#include "napi_common_util.h"
#include "napi_remote_object.h"
#include "napi_common_start_options.h"
#include "start_options.h"
#include "hitrace_meter.h"
namespace OHOS {
namespace AbilityRuntime {
namespace {
constexpr int32_t INDEX_ZERO = 0;
constexpr int32_t ERROR_CODE_ONE = 1;
constexpr size_t ARGC_ZERO = 0;
class JsDriverExtensionContext final {
public:
explicit JsDriverExtensionContext(const std::shared_ptr<DriverExtensionContext>& context) : context_(context) {}
~JsDriverExtensionContext() = default;
static void Finalizer(NativeEngine* engine, void* data, void* hint)
{
HILOG_INFO("JsAbilityContext::Finalizer is called");
std::unique_ptr<JsDriverExtensionContext>(static_cast<JsDriverExtensionContext*>(data));
}
static NativeValue* UpdateDriverState(NativeEngine* engine, NativeCallbackInfo* info)
{
JsDriverExtensionContext* me = CheckParamsAndGetThis<JsDriverExtensionContext>(engine, info);
return (me != nullptr) ? me->OnUpdateDriverState(*engine, *info) : nullptr;
}
private:
std::weak_ptr<DriverExtensionContext> context_;
sptr<JsFreeInstallObserver> freeInstallObserver_ = nullptr;
NativeValue* OnUpdateDriverState(NativeEngine& engine, NativeCallbackInfo& info)
{
HILOG_INFO("OnUpdateDriverState is called");
AsyncTask::CompleteCallback complete =
[weak = context_](NativeEngine& engine, AsyncTask& task, int32_t status) {
HILOG_INFO("UpdateDriverState begin");
auto context = weak.lock();
if (!context) {
HILOG_WARN("context is released");
task.Reject(engine, CreateJsError(engine, ERROR_CODE_ONE, "Context is released"));
return;
}
ErrCode innerErrorCode = context->UpdateDriverState();
if (innerErrorCode == 0) {
task.Resolve(engine, engine.CreateUndefined());
} else {
task.Reject(engine, CreateJsErrorByNativeErr(engine, innerErrorCode));
}
};
NativeValue* lastParam = (info.argc == ARGC_ZERO) ? nullptr : info.argv[INDEX_ZERO];
NativeValue* result = nullptr;
AsyncTask::Schedule("JSDriverExtensionContext::OnUpdateDriverState",
engine, CreateAsyncTaskWithLastParam(engine, lastParam, nullptr, std::move(complete), &result));
return result;
}
};
} // namespace
NativeValue* CreateJsDriverExtensionContext(NativeEngine& engine, std::shared_ptr<DriverExtensionContext> context)
{
HILOG_INFO("CreateJsDriverExtensionContext begin");
std::shared_ptr<OHOS::AppExecFwk::AbilityInfo> abilityInfo = nullptr;
if (context) {
abilityInfo = context->GetAbilityInfo();
}
NativeValue* objValue = CreateJsExtensionContext(engine, context, abilityInfo);
NativeObject* object = ConvertNativeValueTo<NativeObject>(objValue);
std::unique_ptr<JsDriverExtensionContext> jsContext = std::make_unique<JsDriverExtensionContext>(context);
object->SetNativePointer(jsContext.release(), JsDriverExtensionContext::Finalizer, nullptr);
const char *moduleName = "JsDriverExtensionContext";
BindNativeFunction(engine, *object, "updateDriverState", moduleName, JsDriverExtensionContext::UpdateDriverState);
return objValue;
}
} // namespace AbilityRuntime
} // namespace OHOS