!2520 [NAPI] root scene session

Merge pull request !2520 from qpzeng/root
This commit is contained in:
openharmony_ci 2023-05-07 07:03:47 +00:00 committed by Gitee
commit f36894be32
No known key found for this signature in database
GPG Key ID: 173E9B9CA92EEF8F
6 changed files with 303 additions and 1 deletions

View File

@ -14,5 +14,8 @@
import("//build/ohos.gni")
group("window_scene_napi_packages") {
public_deps = [ "screen_session_manager:screensessionmanager_napi" ]
public_deps = [
"scene_session_manager:scenesessionmanager_napi",
"screen_session_manager:screensessionmanager_napi",
]
}

View File

@ -21,6 +21,7 @@ config("scene_session_manager_napi_public_config") {
ohos_shared_library("scenesessionmanager_napi") {
sources = [
"js_root_scene_session.cpp",
"js_scene_session.cpp",
"js_scene_session_manager.cpp",
"js_scene_utils.cpp",

View File

@ -0,0 +1,220 @@
/*
* 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_root_scene_session.h"
#include "context.h"
#include <js_runtime_utils.h>
#include "window_manager_hilog.h"
#include "js_scene_utils.h"
namespace OHOS::Rosen {
using namespace AbilityRuntime;
namespace {
constexpr HiviewDFX::HiLogLabel LABEL = { LOG_CORE, HILOG_DOMAIN_WINDOW, "JsRootSceneSession" };
const std::string PENDING_SCENE_CB = "pendingSceneSessionActivation";
} // namespace
JsRootSceneSession::JsRootSceneSession(NativeEngine& engine, const sptr<RootSceneSession>& rootSceneSession)
: engine_(engine), rootSceneSession_(rootSceneSession)
{}
NativeValue* JsRootSceneSession::Create(NativeEngine& engine, const sptr<RootSceneSession>& rootSceneSession)
{
NativeValue* objValue = engine.CreateObject();
NativeObject* object = ConvertNativeValueTo<NativeObject>(objValue);
if (object == nullptr) {
WLOGFE("[NAPI]Object is null!");
return engine.CreateUndefined();
}
auto jsRootSceneSession = std::make_unique<JsRootSceneSession>(engine, rootSceneSession);
object->SetNativePointer(jsRootSceneSession.release(), JsRootSceneSession::Finalizer, nullptr);
const char* moduleName = "JsRootSceneSession";
BindNativeFunction(engine, *object, "loadContent", moduleName, JsRootSceneSession::LoadContent);
BindNativeFunction(engine, *object, "on", moduleName, JsRootSceneSession::RegisterCallback);
return objValue;
}
void JsRootSceneSession::Finalizer(NativeEngine* engine, void* data, void* hint)
{
WLOGD("Finalizer.");
std::unique_ptr<JsRootSceneSession>(static_cast<JsRootSceneSession*>(data));
}
NativeValue* JsRootSceneSession::RegisterCallback(NativeEngine* engine, NativeCallbackInfo* info)
{
WLOGD("RegisterCallback.");
JsRootSceneSession* me = CheckParamsAndGetThis<JsRootSceneSession>(engine, info);
return (me != nullptr) ? me->OnRegisterCallback(*engine, *info) : nullptr;
}
NativeValue* JsRootSceneSession::LoadContent(NativeEngine* engine, NativeCallbackInfo* info)
{
WLOGD("LoadContent.");
JsRootSceneSession* me = CheckParamsAndGetThis<JsRootSceneSession>(engine, info);
return (me != nullptr) ? me->OnLoadContent(*engine, *info) : nullptr;
}
NativeValue* JsRootSceneSession::OnRegisterCallback(NativeEngine& engine, NativeCallbackInfo& info)
{
if (info.argc < 2) { // 2: params num
WLOGFE("[NAPI]Argc is invalid: %{public}zu", info.argc);
engine.Throw(CreateJsError(engine, static_cast<int32_t>(WSErrorCode::WS_ERROR_INVALID_PARAM),
"Input parameter is missing or invalid"));
return engine.CreateUndefined();
}
std::string cbType;
if (!ConvertFromJsValue(engine, info.argv[0], cbType)) {
WLOGFE("[NAPI]Failed to convert parameter to callbackType");
engine.Throw(CreateJsError(engine, static_cast<int32_t>(WSErrorCode::WS_ERROR_INVALID_PARAM),
"Input parameter is missing or invalid"));
return engine.CreateUndefined();
}
NativeValue* value = info.argv[1];
if (value == nullptr || !value->IsCallable()) {
WLOGFE("[NAPI]Invalid argument");
engine.Throw(CreateJsError(engine, static_cast<int32_t>(WSErrorCode::WS_ERROR_INVALID_PARAM),
"Input parameter is missing or invalid"));
return engine.CreateUndefined();
}
if (IsCallbackRegistered(cbType, value)) {
return engine.CreateUndefined();
}
if (rootSceneSession_ == nullptr) {
WLOGFE("[NAPI]root session is nullptr");
engine.Throw(CreateJsError(
engine, static_cast<int32_t>(WSErrorCode::WS_ERROR_INVALID_PARAM), "Root scene session is null!"));
return engine.CreateUndefined();
}
wptr<JsRootSceneSession> rootSessionWptr(this);
NotifyPendingSessionActivationFunc func = [rootSessionWptr](const SessionInfo& info) {
auto jsRootSceneSession = rootSessionWptr.promote();
if (jsRootSceneSession == nullptr) {
WLOGFE("[NAPI]this scene session");
return;
}
jsRootSceneSession->PendingSessionActivation(info);
};
rootSceneSession_->SetPendingSessionActivationEventListener(func);
std::shared_ptr<NativeReference> callbackRef;
callbackRef.reset(engine.CreateReference(value, 1));
jsCbMap_[cbType] = callbackRef;
WLOGFI("[NAPI]Register end, type = %{public}s, callback = %{public}p", cbType.c_str(), value);
return engine.CreateUndefined();
}
NativeValue* JsRootSceneSession::OnLoadContent(NativeEngine& engine, NativeCallbackInfo& info)
{
WLOGD("[NAPI]OnLoadContent");
if (info.argc < 2) { // 2: params num
WLOGFE("[NAPI]Argc is invalid: %{public}zu", info.argc);
engine.Throw(CreateJsError(engine, static_cast<int32_t>(WSErrorCode::WS_ERROR_INVALID_PARAM),
"Input parameter is missing or invalid"));
return engine.CreateUndefined();
}
std::string contentUrl;
NativeValue* context = info.argv[1];
NativeValue* storage = info.argc < 3 ? nullptr : info.argv[2];
if (!ConvertFromJsValue(engine, info.argv[0], contentUrl)) {
WLOGFE("[NAPI]Failed to convert parameter to content url");
engine.Throw(CreateJsError(engine, static_cast<int32_t>(WSErrorCode::WS_ERROR_INVALID_PARAM),
"Input parameter is missing or invalid"));
return engine.CreateUndefined();
}
auto contextObj = ConvertNativeValueTo<NativeObject>(context);
if (contextObj == nullptr) {
WLOGFE("[NAPI]Failed to get context object");
engine.Throw(CreateJsError(engine, static_cast<int32_t>(WSErrorCode::WS_ERROR_STATE_ABNORMALLY)));
return engine.CreateUndefined();
}
auto contextNativePointer = static_cast<std::weak_ptr<Context>*>(contextObj->GetNativePointer());
if (contextNativePointer == nullptr) {
WLOGFE("[NAPI]Failed to get context pointer from js object");
engine.Throw(CreateJsError(engine, static_cast<int32_t>(WSErrorCode::WS_ERROR_STATE_ABNORMALLY)));
return engine.CreateUndefined();
}
auto contextWeakPtr = *contextNativePointer;
std::shared_ptr<NativeReference> contentStorage =
(storage == nullptr) ? nullptr : std::shared_ptr<NativeReference>(engine.CreateReference(storage, 1));
NativeValue* nativeStorage = contentStorage ? contentStorage->Get() : nullptr;
AsyncTask::CompleteCallback complete = [rootSceneSession = rootSceneSession_, contentUrl, contextWeakPtr,
nativeStorage](NativeEngine& engine, AsyncTask& task, int32_t status) {
if (rootSceneSession == nullptr) {
WLOGFE("[NAPI]rootSceneSession is nullptr");
task.Reject(engine, CreateJsError(engine, static_cast<int32_t>(WSErrorCode::WS_ERROR_STATE_ABNORMALLY)));
return;
}
rootSceneSession->LoadContent(contentUrl, &engine, nativeStorage, contextWeakPtr.lock().get());
};
NativeValue* lastParam = nullptr;
NativeValue* result = nullptr;
AsyncTask::Schedule("JsRootSceneSession::OnLoadContent", engine,
CreateAsyncTaskWithLastParam(engine, lastParam, nullptr, std::move(complete), &result));
return result;
}
bool JsRootSceneSession::IsCallbackRegistered(std::string type, NativeValue* jsListenerObject)
{
if (jsCbMap_.empty() || jsCbMap_.find(type) == jsCbMap_.end()) {
WLOGFI("[NAPI]Method %{public}s has not been registered", type.c_str());
return false;
}
for (auto iter = jsCbMap_.begin(); iter != jsCbMap_.end(); ++iter) {
if (jsListenerObject->StrictEquals(iter->second->Get())) {
WLOGFE("[NAPI]Method %{public}s has already been registered", type.c_str());
return true;
}
}
return false;
}
void JsRootSceneSession::PendingSessionActivation(const SessionInfo& info)
{
WLOGI("[NAPI]pending session activation: bundleName = %{public}s, id = %{public}s", info.bundleName_.c_str(),
info.abilityName_.c_str());
auto iter = jsCbMap_.find(PENDING_SCENE_CB);
if (iter == jsCbMap_.end()) {
return;
}
wptr<JsRootSceneSession> rootSessionWptr(this);
auto jsCallBack = iter->second;
auto complete = std::make_unique<AsyncTask::CompleteCallback>(
[rootSessionWptr, info, jsCallBack](NativeEngine& engine, AsyncTask& task, int32_t status) {
auto jsRootSceneSession = rootSessionWptr.promote();
if (jsRootSceneSession == nullptr) {
WLOGFE("[NAPI]root session or target session or engine is nullptr");
return;
}
NativeValue* jsSessionInfo = CreateJsSessionInfo(engine, info);
if (jsSessionInfo == nullptr) {
WLOGFE("[NAPI]this target session info is nullptr");
}
NativeValue* argv[] = { jsSessionInfo };
engine.CallFunction(engine.CreateUndefined(), jsCallBack->Get(), argv, ArraySize(argv));
});
NativeReference* callback = nullptr;
std::unique_ptr<AsyncTask::ExecuteCallback> execute = nullptr;
AsyncTask::Schedule("JsSceneSession::PendingSessionActivation", engine_,
std::make_unique<AsyncTask>(callback, std::move(execute), std::move(complete)));
}
} // namespace OHOS::Rosen

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.
*/
#ifndef OHOS_WINDOW_SCENE_JS_ROOT_SCENE_SESSION_H
#define OHOS_WINDOW_SCENE_JS_ROOT_SCENE_SESSION_H
#include <native_engine/native_engine.h>
#include <native_engine/native_value.h>
#include <refbase.h>
#include "session/host/include/root_scene_session.h"
namespace OHOS::Rosen {
class JsRootSceneSession : public RefBase {
public:
JsRootSceneSession(NativeEngine& engine, const sptr<RootSceneSession>& rootSceneSession);
~JsRootSceneSession() = default;
static NativeValue* Create(NativeEngine& engine, const sptr<RootSceneSession>& rootSceneSession);
static void Finalizer(NativeEngine* engine, void* data, void* hint);
static NativeValue* RegisterCallback(NativeEngine* engine, NativeCallbackInfo* info);
static NativeValue* LoadContent(NativeEngine* engine, NativeCallbackInfo* info);
private:
NativeValue* OnRegisterCallback(NativeEngine& engine, NativeCallbackInfo& info);
NativeValue* OnLoadContent(NativeEngine& engine, NativeCallbackInfo& info);
bool IsCallbackRegistered(std::string type, NativeValue* jsListenerObject);
void PendingSessionActivation(const SessionInfo& info);
NativeEngine& engine_;
std::map<std::string, std::shared_ptr<NativeReference>> jsCbMap_;
sptr<RootSceneSession> rootSceneSession_;
};
} // namespace OHOS::Rosen
#endif // OHOS_WINDOW_SCENE_JS_ROOT_SCENE_SESSION_H

View File

@ -20,6 +20,7 @@
#include "session_manager/include/scene_session_manager.h"
#include "window_manager_hilog.h"
#include "js_root_scene_session.h"
#include "js_scene_session.h"
#include "js_scene_utils.h"
@ -47,6 +48,7 @@ NativeValue* JsSceneSessionManager::Init(NativeEngine* engine, NativeValue* expo
object->SetNativePointer(jsSceneSessionManager.release(), JsSceneSessionManager::Finalizer, nullptr);
const char* moduleName = "JsSceneSessionManager";
BindNativeFunction(*engine, *object, "getRootSceneSession", moduleName, JsSceneSessionManager::GetRootSceneSession);
BindNativeFunction(*engine, *object, "requestSceneSession", moduleName, JsSceneSessionManager::RequestSceneSession);
BindNativeFunction(*engine, *object, "requestSceneSessionActivation", moduleName,
JsSceneSessionManager::RequestSceneSessionActivation);
@ -63,6 +65,13 @@ void JsSceneSessionManager::Finalizer(NativeEngine* engine, void* data, void* hi
std::unique_ptr<JsSceneSessionManager>(static_cast<JsSceneSessionManager*>(data));
}
NativeValue* JsSceneSessionManager::GetRootSceneSession(NativeEngine* engine, NativeCallbackInfo* info)
{
WLOGI("[NAPI]GetRootSceneSession");
JsSceneSessionManager* me = CheckParamsAndGetThis<JsSceneSessionManager>(engine, info);
return (me != nullptr) ? me->OnGetRootSceneSession(*engine, *info) : nullptr;
}
NativeValue* JsSceneSessionManager::RequestSceneSession(NativeEngine* engine, NativeCallbackInfo* info)
{
WLOGI("[NAPI]RequestSceneSession");
@ -91,6 +100,25 @@ NativeValue* JsSceneSessionManager::RequestSceneSessionDestruction(NativeEngine*
return (me != nullptr) ? me->OnRequestSceneSessionDestruction(*engine, *info) : nullptr;
}
NativeValue* JsSceneSessionManager::OnGetRootSceneSession(NativeEngine& engine, NativeCallbackInfo& info)
{
WLOGFI("[NAPI]OnGetRootSceneSession");
sptr<RootSceneSession> rootSceneSession = SceneSessionManager::GetInstance().GetRootSceneSession();
if (rootSceneSession == nullptr) {
engine.Throw(
CreateJsError(engine, static_cast<int32_t>(WSErrorCode::WS_ERROR_STATE_ABNORMALLY), "System is abnormal"));
return engine.CreateUndefined();
} else {
NativeValue* jsRootSceneSessionObj = JsRootSceneSession::Create(engine, rootSceneSession);
if (jsRootSceneSessionObj == nullptr) {
WLOGFE("[NAPI]jsRootSceneSessionObj is nullptr");
engine.Throw(CreateJsError(
engine, static_cast<int32_t>(WSErrorCode::WS_ERROR_STATE_ABNORMALLY), "System is abnormal"));
}
return jsRootSceneSessionObj;
}
}
NativeValue* JsSceneSessionManager::OnRequestSceneSession(NativeEngine& engine, NativeCallbackInfo& info)
{
WLOGI("[NAPI]OnRequestSceneSession");

View File

@ -28,12 +28,14 @@ public:
static NativeValue* Init(NativeEngine* engine, NativeValue* exportObj);
static void Finalizer(NativeEngine* engine, void* data, void* hint);
static NativeValue* GetRootSceneSession(NativeEngine* engine, NativeCallbackInfo* info);
static NativeValue* RequestSceneSession(NativeEngine* engine, NativeCallbackInfo* info);
static NativeValue* RequestSceneSessionActivation(NativeEngine* engine, NativeCallbackInfo* info);
static NativeValue* RequestSceneSessionBackground(NativeEngine* engine, NativeCallbackInfo* info);
static NativeValue* RequestSceneSessionDestruction(NativeEngine* engine, NativeCallbackInfo* info);
private:
NativeValue* OnGetRootSceneSession(NativeEngine& engine, NativeCallbackInfo& info);
NativeValue* OnRequestSceneSession(NativeEngine& engine, NativeCallbackInfo& info);
NativeValue* OnRequestSceneSessionActivation(NativeEngine& engine, NativeCallbackInfo& info);
NativeValue* OnRequestSceneSessionBackground(NativeEngine& engine, NativeCallbackInfo& info);