Files
windowmanager/interfaces/kits/napi/display_runtime/js_display_manager.cpp
T
zengqingyu 8d14ce45ad fix screen js enum usages
Signed-off-by: zengqingyu <zengqingyu3@huawei.com>
Change-Id: I6f62aeb489e3fd53e19cc38e791596e098aacb35
2022-06-24 15:23:44 +08:00

389 lines
16 KiB
C++

/*
* Copyright (c) 2022 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 <vector>
#include <new>
#include "js_runtime_utils.h"
#include "native_engine/native_reference.h"
#include "display_manager.h"
#include "window_manager_hilog.h"
#include "singleton_container.h"
#include "js_display_listener.h"
#include "js_display.h"
#include "js_display_manager.h"
namespace OHOS {
namespace Rosen {
using namespace AbilityRuntime;
constexpr size_t ARGC_ONE = 1;
constexpr size_t ARGC_TWO = 2;
constexpr int32_t INDEX_ONE = 1;
namespace {
constexpr HiviewDFX::HiLogLabel LABEL = {LOG_CORE, 0, "JsDisplayManager"};
}
class JsDisplayManager {
public:
explicit JsDisplayManager(NativeEngine* engine) {
}
~JsDisplayManager() = default;
static void Finalizer(NativeEngine* engine, void* data, void* hint)
{
WLOGFI("JsDisplayManager::Finalizer is called");
std::unique_ptr<JsDisplayManager>(static_cast<JsDisplayManager*>(data));
}
static NativeValue* GetDefaultDisplay(NativeEngine* engine, NativeCallbackInfo* info)
{
JsDisplayManager* me = CheckParamsAndGetThis<JsDisplayManager>(engine, info);
return (me != nullptr) ? me->OnGetDefaultDisplay(*engine, *info) : nullptr;
}
static NativeValue* GetDefaultDisplaySync(NativeEngine* engine, NativeCallbackInfo* info)
{
JsDisplayManager* me = CheckParamsAndGetThis<JsDisplayManager>(engine, info);
return (me != nullptr) ? me->OnGetDefaultDisplaySync(*engine, *info) : nullptr;
}
static NativeValue* GetAllDisplay(NativeEngine* engine, NativeCallbackInfo* info)
{
JsDisplayManager* me = CheckParamsAndGetThis<JsDisplayManager>(engine, info);
return (me != nullptr) ? me->OnGetAllDisplay(*engine, *info) : nullptr;
}
static NativeValue* RegisterDisplayManagerCallback(NativeEngine* engine, NativeCallbackInfo* info)
{
JsDisplayManager* me = CheckParamsAndGetThis<JsDisplayManager>(engine, info);
return (me != nullptr) ? me->OnRegisterDisplayManagerCallback(*engine, *info) : nullptr;
}
static NativeValue* UnregisterDisplayManagerCallback(NativeEngine* engine, NativeCallbackInfo* info)
{
JsDisplayManager* me = CheckParamsAndGetThis<JsDisplayManager>(engine, info);
return (me != nullptr) ? me->OnUnregisterDisplayManagerCallback(*engine, *info) : nullptr;
}
private:
std::map<std::string, std::map<std::unique_ptr<NativeReference>, sptr<JsDisplayListener>>> jsCbMap_;
std::mutex mtx_;
NativeValue* OnGetDefaultDisplay(NativeEngine& engine, NativeCallbackInfo& info)
{
WLOGFI("JsDisplayManager::OnGetDefaultDisplay is called");
DMError errCode = DMError::DM_OK;
if (info.argc != 0 && info.argc != ARGC_ONE) {
WLOGFE("JsDisplayManager::OnGetDefaultDisplay params not match");
errCode = DMError::DM_ERROR_INVALID_PARAM;
}
AsyncTask::CompleteCallback complete =
[=](NativeEngine& engine, AsyncTask& task, int32_t status) {
if (errCode != DMError::DM_OK) {
task.Reject(engine, CreateJsError(engine,
static_cast<int32_t>(errCode), "JsDisplayManager::OnGetDefaultDisplay failed."));
}
sptr<Display> display = SingletonContainer::Get<DisplayManager>().GetDefaultDisplay();
if (display != nullptr) {
task.Resolve(engine, CreateJsDisplayObject(engine, display));
WLOGFI("JsDisplayManager::OnGetDefaultDisplay success");
} else {
task.Reject(engine, CreateJsError(engine,
static_cast<int32_t>(DMError::DM_ERROR_NULLPTR), "JsDisplayManager::OnGetDefaultDisplay failed."));
}
};
NativeValue* lastParam = nullptr;
if (info.argc == ARGC_ONE && info.argv[0]->TypeOf() == NATIVE_FUNCTION) {
lastParam = info.argv[0];
}
NativeValue* result = nullptr;
AsyncTask::Schedule("JsDisplayManager::OnGetDefaultDisplay",
engine, CreateAsyncTaskWithLastParam(engine, lastParam, nullptr, std::move(complete), &result));
return result;
}
NativeValue* OnGetDefaultDisplaySync(NativeEngine& engine, NativeCallbackInfo& info)
{
WLOGFI("JsDisplayManager::OnGetDefaultDisplaySync is called");
if (info.argc != 0) {
WLOGFE("JsDisplayManager::OnGetDefaultDisplaySync params not match");
return engine.CreateUndefined();
}
sptr<Display> display = SingletonContainer::Get<DisplayManager>().GetDefaultDisplay();
if (display == nullptr) {
WLOGFE("JsDisplayManager::OnGetDefaultDisplaySync, display is nullptr.");
return engine.CreateUndefined();
}
return CreateJsDisplayObject(engine, display);
}
NativeValue* OnGetAllDisplay(NativeEngine& engine, NativeCallbackInfo& info)
{
WLOGFI("JsDisplayManager::OnGetAllDisplay is called");
DMError errCode = DMError::DM_OK;
if (info.argc != 0 && info.argc != ARGC_ONE) {
WLOGFE("JsDisplayManager::OnGetAllDisplay params not match");
errCode = DMError::DM_ERROR_INVALID_PARAM;
}
AsyncTask::CompleteCallback complete =
[=](NativeEngine& engine, AsyncTask& task, int32_t status) {
if (errCode != DMError::DM_OK) {
task.Reject(engine, CreateJsError(engine,
static_cast<int32_t>(errCode), "JsDisplayManager::OnGetAllDisplay failed."));
}
std::vector<sptr<Display>> displays = SingletonContainer::Get<DisplayManager>().GetAllDisplays();
if (!displays.empty()) {
task.Resolve(engine, CreateJsDisplayArrayObject(engine, displays));
WLOGFI("JsDisplayManager::GetAllDisplays success");
} else {
task.Reject(engine, CreateJsError(engine,
static_cast<int32_t>(DMError::DM_ERROR_NULLPTR), "JsDisplayManager::OnGetAllDisplay failed."));
}
};
NativeValue* lastParam = nullptr;
if (info.argc == ARGC_ONE && info.argv[0]->TypeOf() == NATIVE_FUNCTION) {
lastParam = info.argv[0];
}
NativeValue* result = nullptr;
AsyncTask::Schedule("JsDisplayManager::OnGetAllDisplay",
engine, CreateAsyncTaskWithLastParam(engine, lastParam, nullptr, std::move(complete), &result));
return result;
}
void RegisterDisplayListenerWithType(NativeEngine& engine, const std::string& type, NativeValue* value)
{
if (IfCallbackRegistered(type, value)) {
WLOGFE("JsDisplayManager::RegisterDisplayListenerWithType callback already registered!");
return;
}
std::unique_ptr<NativeReference> callbackRef;
callbackRef.reset(engine.CreateReference(value, 1));
sptr<JsDisplayListener> displayListener = new(std::nothrow) JsDisplayListener(&engine);
if (displayListener == nullptr) {
WLOGFE("displayListener is nullptr");
return;
}
if (type == EVENT_ADD || type == EVENT_REMOVE || type == EVENT_CHANGE) {
SingletonContainer::Get<DisplayManager>().RegisterDisplayListener(displayListener);
WLOGFI("JsDisplayManager::RegisterDisplayListenerWithType success");
} else {
WLOGFE("JsDisplayManager::RegisterDisplayListenerWithType failed method: %{public}s not support!",
type.c_str());
return;
}
displayListener->AddCallback(type, value);
jsCbMap_[type][std::move(callbackRef)] = displayListener;
}
bool IfCallbackRegistered(const std::string& type, NativeValue* jsListenerObject)
{
if (jsCbMap_.empty() || jsCbMap_.find(type) == jsCbMap_.end()) {
WLOGFI("JsDisplayManager::IfCallbackRegistered methodName %{public}s not registered!", type.c_str());
return false;
}
for (auto& iter : jsCbMap_[type]) {
if (jsListenerObject->StrictEquals(iter.first->Get())) {
WLOGFE("JsDisplayManager::IfCallbackRegistered callback already registered!");
return true;
}
}
return false;
}
void UnregisterAllDisplayListenerWithType(const std::string& type)
{
if (jsCbMap_.empty() || jsCbMap_.find(type) == jsCbMap_.end()) {
WLOGFI("JsDisplayManager::UnregisterAllDisplayListenerWithType methodName %{public}s not registered!",
type.c_str());
return;
}
for (auto it = jsCbMap_[type].begin(); it != jsCbMap_[type].end();) {
it->second->RemoveAllCallback();
if (type == EVENT_ADD || type == EVENT_REMOVE || type == EVENT_CHANGE) {
sptr<DisplayManager::IDisplayListener> thisListener(it->second);
SingletonContainer::Get<DisplayManager>().UnregisterDisplayListener(thisListener);
WLOGFI("JsDisplayManager::UnregisterAllDisplayListenerWithType success");
}
jsCbMap_[type].erase(it++);
}
jsCbMap_.erase(type);
}
void UnRegisterDisplayListenerWithType(const std::string& type, NativeValue* value)
{
if (jsCbMap_.empty() || jsCbMap_.find(type) == jsCbMap_.end()) {
WLOGFI("JsDisplayManager::UnRegisterDisplayListenerWithType methodName %{public}s not registered!",
type.c_str());
return;
}
for (auto it = jsCbMap_[type].begin(); it != jsCbMap_[type].end();) {
if (value->StrictEquals(it->first->Get())) {
it->second->RemoveCallback(type, value);
if (type == EVENT_ADD || type == EVENT_REMOVE || type == EVENT_CHANGE) {
sptr<DisplayManager::IDisplayListener> thisListener(it->second);
SingletonContainer::Get<DisplayManager>().UnregisterDisplayListener(thisListener);
WLOGFI("JsDisplayManager::UnRegisterDisplayListenerWithType success");
}
jsCbMap_[type].erase(it++);
break;
} else {
it++;
}
}
if (jsCbMap_[type].empty()) {
jsCbMap_.erase(type);
}
}
NativeValue* OnRegisterDisplayManagerCallback(NativeEngine& engine, NativeCallbackInfo& info)
{
WLOGFI("JsDisplayManager::OnRegisterDisplayManagerCallback is called");
if (info.argc != ARGC_TWO) {
WLOGFE("JsDisplayManager Params not match: %{public}zu", info.argc);
return engine.CreateUndefined();
}
std::string cbType;
if (!ConvertFromJsValue(engine, info.argv[0], cbType)) {
WLOGFE("Failed to convert parameter to callbackType");
return engine.CreateUndefined();
}
NativeValue* value = info.argv[INDEX_ONE];
if (value == nullptr) {
WLOGFI("JsDisplayManager::OnRegisterDisplayManagerCallback info->argv[1] is nullptr");
return engine.CreateUndefined();
}
if (!value->IsCallable()) {
WLOGFI("JsDisplayManager::OnRegisterDisplayManagerCallback info->argv[1] is not callable");
return engine.CreateUndefined();
}
std::lock_guard<std::mutex> lock(mtx_);
RegisterDisplayListenerWithType(engine, cbType, value);
return engine.CreateUndefined();
}
NativeValue* OnUnregisterDisplayManagerCallback(NativeEngine& engine, NativeCallbackInfo& info)
{
WLOGFI("JsDisplayManager::OnUnregisterDisplayCallback is called");
if (info.argc == 0) {
WLOGFE("JsDisplayManager Params not match %{public}zu", info.argc);
return engine.CreateUndefined();
}
std::string cbType;
if (!ConvertFromJsValue(engine, info.argv[0], cbType)) {
WLOGFE("Failed to convert parameter to callbackType");
return engine.CreateUndefined();
}
std::lock_guard<std::mutex> lock(mtx_);
if (info.argc == ARGC_ONE) {
UnregisterAllDisplayListenerWithType(cbType);
} else {
NativeValue* value = info.argv[INDEX_ONE];
if (value == nullptr) {
WLOGFI("JsDisplayManager::OnUnregisterDisplayManagerCallback info->argv[1] is nullptr");
return engine.CreateUndefined();
}
if (!value->IsCallable()) {
WLOGFI("JsDisplayManager::OnUnregisterDisplayManagerCallback info->argv[1] is not callable");
return engine.CreateUndefined();
}
UnRegisterDisplayListenerWithType(cbType, value);
}
return engine.CreateUndefined();
}
NativeValue* CreateJsDisplayArrayObject(NativeEngine& engine, std::vector<sptr<Display>>& displays)
{
WLOGFI("JsDisplayManager::CreateJsDisplayArrayObject is called");
NativeValue* arrayValue = engine.CreateArray(displays.size());
NativeArray* array = ConvertNativeValueTo<NativeArray>(arrayValue);
if (array == nullptr) {
WLOGFE("Failed to create display array");
return engine.CreateUndefined();
}
int32_t i = 0;
for (auto& display : displays) {
if (display == nullptr) {
continue;
}
array->SetElement(i++, CreateJsDisplayObject(engine, display));
}
return arrayValue;
}
};
NativeValue* InitDisplayState(NativeEngine* engine)
{
WLOGFI("JsDisplayManager::InitDisplayState called");
if (engine == nullptr) {
WLOGFE("engine is nullptr");
return nullptr;
}
NativeValue *objValue = engine->CreateObject();
NativeObject *object = ConvertNativeValueTo<NativeObject>(objValue);
if (object == nullptr) {
WLOGFE("Failed to get object");
return nullptr;
}
object->SetProperty("STATE_UNKNOWN", CreateJsValue(*engine, static_cast<int32_t>(DisplayStateMode::STATE_UNKNOWN)));
object->SetProperty("STATE_OFF", CreateJsValue(*engine, static_cast<int32_t>(DisplayStateMode::STATE_OFF)));
object->SetProperty("STATE_ON", CreateJsValue(*engine, static_cast<int32_t>(DisplayStateMode::STATE_ON)));
object->SetProperty("STATE_DOZE",
CreateJsValue(*engine, static_cast<int32_t>(DisplayStateMode::STATE_DOZE)));
object->SetProperty("STATE_DOZE_SUSPEND",
CreateJsValue(*engine, static_cast<int32_t>(DisplayStateMode::STATE_DOZE_SUSPEND)));
object->SetProperty("STATE_VR",
CreateJsValue(*engine, static_cast<int32_t>(DisplayStateMode::STATE_VR)));
object->SetProperty("STATE_ON_SUSPEND",
CreateJsValue(*engine, static_cast<int32_t>(DisplayStateMode::STATE_ON_SUSPEND)));
return objValue;
}
NativeValue* JsDisplayManagerInit(NativeEngine* engine, NativeValue* exportObj)
{
WLOGFI("JsDisplayManagerInit is called");
if (engine == nullptr || exportObj == nullptr) {
WLOGFE("JsDisplayManagerInit engine or exportObj is nullptr");
return nullptr;
}
NativeObject* object = ConvertNativeValueTo<NativeObject>(exportObj);
if (object == nullptr) {
WLOGFE("JsDisplayManagerInit object is nullptr");
return nullptr;
}
std::unique_ptr<JsDisplayManager> jsDisplayManager = std::make_unique<JsDisplayManager>(engine);
object->SetNativePointer(jsDisplayManager.release(), JsDisplayManager::Finalizer, nullptr);
object->SetProperty("DisplayState", InitDisplayState(engine));
BindNativeFunction(*engine, *object, "getDefaultDisplay", JsDisplayManager::GetDefaultDisplay);
BindNativeFunction(*engine, *object, "getDefaultDisplaySync", JsDisplayManager::GetDefaultDisplaySync);
BindNativeFunction(*engine, *object, "getAllDisplay", JsDisplayManager::GetAllDisplay);
BindNativeFunction(*engine, *object, "on", JsDisplayManager::RegisterDisplayManagerCallback);
BindNativeFunction(*engine, *object, "off", JsDisplayManager::UnregisterDisplayManagerCallback);
return engine->CreateUndefined();
}
} // namespace Rosen
} // namespace OHOS