js callback 重构

Signed-off-by: chyyy0213 <chenhaiying3@huawei.com>
Change-Id: I2d2b734fff3a4081517606535513ba767d96c5ce
This commit is contained in:
chyyy0213
2022-03-03 19:00:01 +08:00
parent 4590478858
commit d7416f7d4f
12 changed files with 322 additions and 257 deletions
+1 -1
View File
@@ -121,7 +121,7 @@ public:
virtual void UnregisterLifeCycleListener(sptr<IWindowLifeCycle>& listener) = 0;
virtual void UnregisterWindowChangeListener(sptr<IWindowChangeListener>& listener) = 0;
virtual void RegisterAvoidAreaChangeListener(sptr<IAvoidAreaChangedListener>& listener) = 0;
virtual void UnregisterAvoidAreaChangeListener() = 0;
virtual void UnregisterAvoidAreaChangeListener(sptr<IAvoidAreaChangedListener>& listener) = 0;
virtual void RegisterDragListener(sptr<IWindowDragListener>& listener) = 0;
virtual void UnregisterDragListener(sptr<IWindowDragListener>& listener) = 0;
virtual void RegisterDisplayMoveListener(sptr<IDisplayMoveListener>& listener) = 0;
@@ -20,7 +20,7 @@
namespace OHOS {
namespace Rosen {
class IWindowLifeCycle : public RefBase {
class IWindowLifeCycle : virtual public RefBase {
public:
virtual void AfterForeground() = 0;
virtual void AfterBackground() = 0;
@@ -118,7 +118,6 @@ static void GetNativeContext(NativeValue* nativeContext, void*& contextPtr, WMEr
}
contextPtr = objContext->GetNativePointer();
}
return;
}
static bool GetWindowTypeAndParentName(NativeEngine& engine, std::string& parentName, WindowType& winType,
@@ -204,7 +203,6 @@ static void CreateSystemWindowTask(void* contextPtr, std::string windowName, Win
task.Reject(engine, CreateJsError(engine,
static_cast<int32_t>(WMError::WM_ERROR_NULLPTR), "JsWindowManager::OnCreateWindow failed."));
}
return;
}
static void CreateSubWindowTask(std::string parentWinName, std::string windowName, WindowType winType,
@@ -229,7 +227,6 @@ static void CreateSubWindowTask(std::string parentWinName, std::string windowNam
task.Reject(engine, CreateJsError(engine,
static_cast<int32_t>(WMError::WM_ERROR_NULLPTR), "JsWindowManager::OnCreateWindow failed."));
}
return;
}
NativeValue* JsWindowManager::OnCreateWindow(NativeEngine& engine, NativeCallbackInfo& info)
@@ -378,10 +375,9 @@ void JsWindowManager::RegisterWmListenerWithType(NativeEngine& engine, std::stri
WLOGFE("JsWindowManager::RegisterWmListenerWithType callback already registered!");
return;
}
std::unique_ptr<NativeReference> callbackRef;
std::shared_ptr<NativeReference> callbackRef;
callbackRef.reset(engine.CreateReference(value, 1));
sptr<JsWindowListener> windowManagerListener = new(std::nothrow) JsWindowListener(&engine);
sptr<JsWindowListener> windowManagerListener = new(std::nothrow) JsWindowListener(&engine, callbackRef);
if (windowManagerListener == nullptr) {
WLOGFE("JsWindowManager::RegisterWmListenerWithType windowManagerListener malloc failed");
return;
@@ -395,9 +391,7 @@ void JsWindowManager::RegisterWmListenerWithType(NativeEngine& engine, std::stri
type.c_str());
return;
}
windowManagerListener->AddCallback(value);
jsCbMap_[type][std::move(callbackRef)] = windowManagerListener;
return;
jsCbMap_[type][callbackRef] = windowManagerListener;
}
void JsWindowManager::UnregisterAllWmListenerWithType(std::string type)
@@ -408,16 +402,16 @@ void JsWindowManager::UnregisterAllWmListenerWithType(std::string type)
return;
}
for (auto it = jsCbMap_[type].begin(); it != jsCbMap_[type].end();) {
it->second->RemoveAllCallback();
if (type.compare(SYSTEM_BAR_TINT_CHANGE_CB) == 0) {
// it->second.jsCallBack_ = nullptr
sptr<ISystemBarChangedListener> thisListener(it->second);
SingletonContainer::Get<WindowManager>().UnregisterSystemBarChangedListener(thisListener);
WLOGFI("JsWindowManager::UnregisterAllWmListenerWithType systemBarTintChange success");
}
jsCbMap_[type].erase(it++);
}
WLOGFI("JsWindow::UnregisterWindowListenerWithType callback map size: %{public}u success", jsCbMap_[type].size());
jsCbMap_.erase(type);
return;
}
void JsWindowManager::UnregisterWmListenerWithType(std::string type, NativeValue* value)
@@ -427,11 +421,8 @@ void JsWindowManager::UnregisterWmListenerWithType(std::string type, NativeValue
type.c_str());
return;
}
bool findFlag = false;
for (auto it = jsCbMap_[type].begin(); it != jsCbMap_[type].end();) {
for (auto it = jsCbMap_[type].begin(); it != jsCbMap_[type].end();it++) {
if (value->StrictEquals(it->first->Get())) {
findFlag = true;
it->second->RemoveCallback(value);
if (type.compare(SYSTEM_BAR_TINT_CHANGE_CB) == 0) {
sptr<ISystemBarChangedListener> thisListener(it->second);
SingletonContainer::Get<WindowManager>().UnregisterSystemBarChangedListener(thisListener);
@@ -439,25 +430,19 @@ void JsWindowManager::UnregisterWmListenerWithType(std::string type, NativeValue
}
jsCbMap_[type].erase(it++);
break;
} else {
it++;
}
}
if (!findFlag) {
WLOGFE("JsWindowManager::UnregisterWmListenerWithType can't find callback!");
return;
}
WLOGFI("JsWindow::UnregisterWindowListenerWithType callback map size: %{public}u success", jsCbMap_[type].size());
// one type with multi jscallback, erase type when there is no callback in one type
if (jsCbMap_[type].empty()) {
jsCbMap_.erase(type);
}
return;
}
NativeValue* JsWindowManager::OnRegisterWindowMangerCallback(NativeEngine& engine, NativeCallbackInfo& info)
{
WLOGFI("JsWindowManager::OnRegisterWindowMangerCallback is called");
if (info.argc != ARGC_TWO) {
if (info.argc != 2) { // 2 is num of argc
WLOGFE("Params not match");
return engine.CreateUndefined();
}
@@ -52,7 +52,7 @@ private:
NativeValue* OnGetTopWindow(NativeEngine& engine, NativeCallbackInfo& info);
NativeValue* OnSetWindowLayoutMode(NativeEngine& engine, NativeCallbackInfo& info);
std::weak_ptr<AbilityRuntime::Context> context_;
std::map<std::string, std::map<std::unique_ptr<NativeReference>, sptr<JsWindowListener>>> jsCbMap_;
std::map<std::string, std::map<std::shared_ptr<NativeReference>, sptr<JsWindowListener>>> jsCbMap_;
std::mutex mtx_;
};
} // namespace Rosen
@@ -28,6 +28,14 @@ namespace {
static std::map<std::string, std::shared_ptr<NativeReference>> g_jsWindowMap;
std::recursive_mutex g_mutex;
// std::map<string, function<void(sptr<JsWindowListener>, sptr<Window>)>> JsWindow::g_registerMap =
// {
// {WINDOW_SIZE_CHANGE_CB, add},
// {SYSTEM_BAR_TINT_CHANGE_CB, std::minus<int>()},//标准库的函数,参数为两个整数,可以参考前一篇博客
// {SYSTEM_AVOID_AREA_CHANGE_CB, divide()},//类成员函数
// {LIFECYCLE_EVENT_CB, [](sptr<JsWindowListener> listener, sptr<Window> window){sptr<IAvoidAreaChangedListener> thisListener(listener);
// window->UnregisterAvoidAreaChangeListener(thisListener);}},//lambda表达式
// };
JsWindow::JsWindow(const sptr<Window>& window) : windowToken_(window)
{
}
@@ -162,7 +170,7 @@ NativeValue* JsWindow::SetSystemBarEnable(NativeEngine* engine, NativeCallbackIn
NativeValue* JsWindow::SetSystemBarProperties(NativeEngine* engine, NativeCallbackInfo* info)
{
WLOGFI("JsWindow::SetBarProperties is called");
WLOGFI("JsWindow::SetSystemBarProperties is called");
JsWindow* me = CheckParamsAndGetThis<JsWindow>(engine, info);
return (me != nullptr) ? me->OnSetSystemBarProperties(*engine, *info) : nullptr;
}
@@ -514,13 +522,13 @@ NativeValue* JsWindow::OnGetProperties(NativeEngine& engine, NativeCallbackInfo&
bool JsWindow::IsCallbackRegistered(std::string type, NativeValue* jsListenerObject)
{
if (jsCallbackMap_.empty() || jsCallbackMap_.find(type) == jsCallbackMap_.end()) {
if (jsCbMap_.empty() || jsCbMap_.find(type) == jsCbMap_.end()) {
WLOGFI("JsWindow::IsCallbackRegistered methodName %{public}s not registertd!", type.c_str());
return false;
}
for (auto iter = jsCallbackMap_[type].begin(); iter != jsCallbackMap_[type].end(); iter++) {
if (jsListenerObject->StrictEquals((*iter)->Get())) {
for (auto iter = jsCbMap_[type].begin(); iter != jsCbMap_[type].end(); iter++) {
if (jsListenerObject->StrictEquals(iter->first->Get())) {
WLOGFE("JsWindow::IsCallbackRegistered callback already registered!");
return true;
}
@@ -528,95 +536,142 @@ bool JsWindow::IsCallbackRegistered(std::string type, NativeValue* jsListenerObj
return false;
}
// void JsWindow::ListenerProcess(std::string type, sptr<JsWindowListener> listener, bool isRegister)
// {
// switch (type)
// {
// case WINDOW_SIZE_CHANGE_CB: {
// sptr<IWindowChangeListener> thisListener(listener);
// if (isRegister) {
// windowToken_->RegisterWindowChangeListener(thisListener);
// } else {
// windowToken_->UnregisterWindowChangeListener(thisListener);
// }
// break;
// }
// case SYSTEM_AVOID_AREA_CHANGE_CB: {
// sptr<IAvoidAreaChangedListener> thisListener(listener);
// if (isRegister) {
// windowToken_->RegisterAvoidAreaChangeListener(thisListener);
// } else {
// windowToken_->UnregisterAvoidAreaChangeListener(thisListener);
// }
// break;
// }
// case LIFECYCLE_EVENT_CB: {
// sptr<IAvoidAreaChangedListener> thisListener(listener);
// if (isRegister) {
// windowToken_->RegisterAvoidAreaChangeListener(thisListener);
// } else {
// windowToken_->RegisterLifeCycleListener(thisListener);
// }
// break;
// }
// default: {
// WLOGFE("JsWindow::RegisterWindowListenerWithType failed method: %{public}s not support!",
// type.c_str());
// break;
// }
// }
// }
void JsWindow::RegisterWindowListenerWithType(NativeEngine& engine, std::string type, NativeValue* value)
{
if (IsCallbackRegistered(type, value)) {
WLOGFE("JsWindow::RegisterWindowListenerWithType callback already registered!");
return;
}
std::unique_ptr<NativeReference> callbackRef;
std::shared_ptr<NativeReference> callbackRef;
callbackRef.reset(engine.CreateReference(value, 1));
if (jsListenerMap_.find(type) == jsListenerMap_.end()) {
sptr<JsWindowListener> windowListener = new(std::nothrow) JsWindowListener(&engine);
if (windowListener == nullptr) {
WLOGFE("JsWindow::RegisterWindowListenerWithType windowListener malloc failed");
return;
}
if (type.compare(WINDOW_SIZE_CHANGE_CB) == 0) {
sptr<IWindowChangeListener> thisListener(windowListener);
windowToken_->RegisterWindowChangeListener(thisListener);
WLOGFI("JsWindow::RegisterWindowListenerWithType windowSizeChange success");
} else if (type.compare(SYSTEM_AVOID_AREA_CHANGE_CB) == 0) {
sptr<IAvoidAreaChangedListener> thisListener(windowListener);
windowToken_->RegisterAvoidAreaChangeListener(thisListener);
WLOGFI("JsWindow::RegisterWindowListenerWithType systemAvoidAreaChange success");
} else {
WLOGFE("JsWindow::RegisterWindowListenerWithType failed method: %{public}s not support!",
type.c_str());
return;
}
windowListener->AddCallback(value);
jsListenerMap_[type] = windowListener;
} else {
jsListenerMap_[type]->AddCallback(value);
sptr<JsWindowListener> windowListener = new(std::nothrow) JsWindowListener(&engine, callbackRef);
if (windowListener == nullptr) {
WLOGFE("JsWindow::RegisterWindowListenerWithType windowListener malloc failed");
return;
}
jsCallbackMap_[type].push_back(std::move(callbackRef));
return;
if (type.compare(WINDOW_SIZE_CHANGE_CB) == 0) {
sptr<IWindowChangeListener> thisListener(windowListener);
windowToken_->RegisterWindowChangeListener(thisListener);
} else if (type.compare(SYSTEM_AVOID_AREA_CHANGE_CB) == 0) {
sptr<IAvoidAreaChangedListener> thisListener(windowListener);
windowToken_->RegisterAvoidAreaChangeListener(thisListener);
} else if (type.compare(LIFECYCLE_EVENT_CB) == 0) {
sptr<IWindowLifeCycle> thisListener(windowListener);
windowToken_->RegisterLifeCycleListener(thisListener);
} else {
WLOGFE("JsWindow::RegisterWindowListenerWithType failed method: %{public}s not support!",
type.c_str());
return;
}
jsCbMap_[type][callbackRef] = windowListener;
WLOGFI("JsWindow::RegisterWindowListenerWithType %{public}s success! callback map size: %{public}u ",
type.c_str(), jsCbMap_[type].size());
}
void JsWindow::UnregisterAllWindowListenerWithType(std::string type)
{
if (jsListenerMap_.empty() || jsListenerMap_.find(type) == jsListenerMap_.end()) {
if (jsCbMap_.empty() || jsCbMap_.find(type) == jsCbMap_.end()) {
WLOGFI("JsWindow::UnregisterAllWindowListenerWithType methodName %{public}s not registerted!",
type.c_str());
return;
}
jsListenerMap_[type]->RemoveAllCallback();
if (type.compare(WINDOW_SIZE_CHANGE_CB) == 0) {
sptr<IWindowChangeListener> thisListener(jsListenerMap_[type]);
windowToken_->UnregisterWindowChangeListener(thisListener);
WLOGFI("JsWindow::UnregisterAllWindowListenerWithType windowSizeChange success");
for (auto it = jsCbMap_[type].begin(); it != jsCbMap_[type].end();) {
if (type.compare(WINDOW_SIZE_CHANGE_CB) == 0) {
sptr<IWindowChangeListener> thisListener(it->second);
windowToken_->UnregisterWindowChangeListener(thisListener);
} else if (type.compare(SYSTEM_AVOID_AREA_CHANGE_CB) == 0) {
sptr<IAvoidAreaChangedListener> thisListener(it->second);
windowToken_->UnregisterAvoidAreaChangeListener(thisListener);
} else if (type.compare(LIFECYCLE_EVENT_CB) == 0) {
sptr<IWindowLifeCycle> thisListener(it->second);
windowToken_->UnregisterLifeCycleListener(thisListener);
} else {
WLOGFE("JsWindow::UnregisterWindowListenerWithType failed method: %{public}s not support!",
type.c_str());
return;
}
jsCbMap_[type].erase(it++);
}
if (type.compare(SYSTEM_AVOID_AREA_CHANGE_CB) == 0) {
windowToken_->UnregisterAvoidAreaChangeListener();
WLOGFI("JsWindow::UnregisterAllWindowListenerWithType systemAvoidAreaChange success");
}
jsListenerMap_.erase(type);
jsCallbackMap_.erase(type);
return;
WLOGFI("JsWindow::UnregisterWindowListenerWithType %{public}s success! callback map size: %{public}u",
type.c_str(), jsCbMap_[type].size());
jsCbMap_.erase(type);
}
void JsWindow::UnregisterWindowListenerWithType(std::string type, NativeValue* value)
{
if (jsListenerMap_.empty() || jsListenerMap_.find(type) == jsListenerMap_.end()) {
if (jsCbMap_.empty() || jsCbMap_.find(type) == jsCbMap_.end()) {
WLOGFI("JsWindow::UnregisterWindowListenerWithType methodName %{public}s not registerted!",
type.c_str());
return;
}
for (auto it = jsCallbackMap_[type].begin(); it != jsCallbackMap_[type].end();) {
if (value->StrictEquals((*it)->Get())) {
jsListenerMap_[type]->RemoveCallback(value);
jsCallbackMap_[type].erase(it++);
for (auto it = jsCbMap_[type].begin(); it != jsCbMap_[type].end();it++) {
if (value->StrictEquals(it->first->Get())) {
if (type.compare(WINDOW_SIZE_CHANGE_CB) == 0) {
sptr<IWindowChangeListener> thisListener(it->second);
windowToken_->UnregisterWindowChangeListener (thisListener);
WLOGFI("JsWindow::UnregisterWindowListenerWithType windowSizeChange success");
} else if (type.compare(SYSTEM_AVOID_AREA_CHANGE_CB) == 0) {
sptr<IAvoidAreaChangedListener> thisListener(it->second);
windowToken_->UnregisterAvoidAreaChangeListener(thisListener);
WLOGFI("JsWindow::UnregisterWindowListenerWithType systemAvoidAreaChange success");
} else if (type.compare(LIFECYCLE_EVENT_CB) == 0) {
sptr<IWindowLifeCycle> thisListener(it->second);
windowToken_->UnregisterLifeCycleListener(thisListener);
} else {
WLOGFE("JsWindow::UnregisterWindowListenerWithType failed method: %{public}s not support!",
type.c_str());
return;
}
jsCbMap_[type].erase(it++);
break;
} else {
it++;
}
}
// one type with multi jscallback, erase type when there is no callback in one type
if (jsCallbackMap_[type].empty()) {
if (type.compare(WINDOW_SIZE_CHANGE_CB) == 0) {
sptr<IWindowChangeListener> thisListener(jsListenerMap_[type]);
windowToken_->UnregisterWindowChangeListener (thisListener);
WLOGFI("JsWindow::UnregisterWindowListenerWithType windowSizeChange success");
}
if (type.compare(SYSTEM_AVOID_AREA_CHANGE_CB) == 0) {
windowToken_->UnregisterAvoidAreaChangeListener();
WLOGFI("JsWindow::UnregisterWindowListenerWithType systemAvoidAreaChange success");
}
jsCallbackMap_.erase(type);
jsListenerMap_.erase(type);
WLOGFI("JsWindow::UnregisterWindowListenerWithType callback map size: %{public}u success", jsCbMap_[type].size());
if (jsCbMap_[type].empty()) {
jsCbMap_.erase(type);
}
return;
}
NativeValue* JsWindow::OnRegisterWindowCallback(NativeEngine& engine, NativeCallbackInfo& info)
@@ -649,12 +704,8 @@ NativeValue* JsWindow::OnRegisterWindowCallback(NativeEngine& engine, NativeCall
NativeValue* JsWindow::OnUnregisterWindowCallback(NativeEngine& engine, NativeCallbackInfo& info)
{
WLOGFI("JsWindow::OnUnregisterWindowCallback is called");
if (windowToken_ == nullptr) {
WLOGFE("JsWindow windowToken_ is nullptr");
return engine.CreateUndefined();
}
if (info.argc == 0) {
WLOGFE("Params not match");
if (windowToken_ == nullptr || info.argc < 1 || info.argc > 2) {
WLOGFE("JsWindow windowToken_ is nullptr or params not match");
return engine.CreateUndefined();
}
std::string cbType;
@@ -900,9 +951,9 @@ NativeValue* JsWindow::OnSetSystemBarProperties(NativeEngine& engine, NativeCall
NativeValue* JsWindow::OnGetAvoidArea(NativeEngine& engine, NativeCallbackInfo& info)
{
WLOGFI("JsWindow::OnGetAvoidArea is called");
WLOGFI("JsWindow::OnGetAvoidArea is called info.argc: %{public}d", info.argc);
WMError errCode = WMError::WM_OK;
if (windowToken_ == nullptr || info.argc < ARGC_ONE) {
if (windowToken_ == nullptr || info.argc < 1 || info.argc > 2) { // 2 is max num of argv
WLOGFE("JsWindow windowToken_ is nullptr or param is too small!");
errCode = WMError::WM_ERROR_INVALID_PARAM;
}
@@ -1117,4 +1168,4 @@ NativeValue* CreateJsWindowObject(NativeEngine& engine, sptr<Window>& window)
return objValue;
}
} // namespace Rosen
} // namespace OHOS
} // namespace OHOS
@@ -85,8 +85,7 @@ private:
NativeValue* OnGetColorSpace(NativeEngine& engine, NativeCallbackInfo& info);
sptr<Window> windowToken_ = nullptr;
std::map<std::string, std::vector<std::unique_ptr<NativeReference>>> jsCallbackMap_;
std::map<std::string, sptr<JsWindowListener>> jsListenerMap_;
std::map<std::string, std::map<std::shared_ptr<NativeReference>, sptr<JsWindowListener>>> jsCbMap_;
std::mutex mtx_;
};
} // namespace Rosen
@@ -25,53 +25,19 @@ namespace {
constexpr uint32_t AVOID_AREA_NUM = 4;
void JsWindowListener::AddCallback(NativeValue* jsListenerObject)
{
WLOGFI("JsWindowListener::AddCallback is called");
std::lock_guard<std::mutex> lock(mtx_);
std::unique_ptr<NativeReference> callbackRef;
callbackRef.reset(engine_->CreateReference(jsListenerObject, 1));
jsCallBack_.push_back(std::move(callbackRef));
WLOGFI("JsWindowListener::AddCallback success jsCallBack_ size: %{public}d!",
static_cast<uint32_t>(jsCallBack_.size()));
return;
}
void JsWindowListener::RemoveAllCallback()
{
std::lock_guard<std::mutex> lock(mtx_);
jsCallBack_.clear();
}
void JsWindowListener::RemoveCallback(NativeValue* jsListenerObject)
{
std::lock_guard<std::mutex> lock(mtx_);
for (auto iter = jsCallBack_.begin(); iter != jsCallBack_.end(); ++iter) {
if (jsListenerObject->StrictEquals((*iter)->Get())) {
iter = jsCallBack_.erase(iter);
break;
}
}
WLOGFI("JsWindowListener::RemoveCallback success jsCallBack_ size: %{public}d!",
static_cast<uint32_t>(jsCallBack_.size()));
return;
}
void JsWindowListener::CallJsMethod(const char* methodName, NativeValue* const* argv, size_t argc)
{
WLOGFI("CallJsMethod methodName = %{public}s", methodName);
if (engine_ == nullptr || jsCallBack_.empty()) {
WLOGFE("engine_ nullptr or jsCallBack_ is empty");
if (engine_ == nullptr || jsCallBack_ == nullptr) {
WLOGFE("engine_ nullptr or jsCallBack_ is nullptr");
return;
}
for (auto &item : jsCallBack_) {
NativeValue* method = item->Get();
if (method == nullptr) {
WLOGFE("Failed to get method callback from object");
continue;
}
engine_->CallFunction(engine_->CreateUndefined(), method, argv, argc);
NativeValue* method = jsCallBack_->Get();
if (method == nullptr) {
WLOGFE("Failed to get method callback from object");
return;
}
engine_->CallFunction(engine_->CreateUndefined(), method, argv, argc);
}
void JsWindowListener::OnSizeChange(Rect rect, WindowSizeChangeReason reason)
@@ -159,5 +125,61 @@ void JsWindowListener::OnAvoidAreaChanged(const std::vector<Rect> avoidAreas)
std::unique_ptr<AsyncTask::ExecuteCallback> execute = nullptr;
AsyncTask::Schedule(*engine_, std::make_unique<AsyncTask>(callback, std::move(execute), std::move(complete)));
}
void JsWindowListener::AfterForeground()
{
WLOGFI("JsWindowListener::AfterForeground is called");
std::unique_ptr<AsyncTask::CompleteCallback> complete = std::make_unique<AsyncTask::CompleteCallback>(
[=] (NativeEngine &engine, AsyncTask &task, int32_t status) {
NativeValue* argv[] = {CreateJsValue(*engine_, static_cast<uint32_t>(LifeCycleEventType::FOREGROUND))};
CallJsMethod(LIFECYCLE_EVENT_CB.c_str(), argv, ArraySize(argv));
}
);
NativeReference* callback = nullptr;
std::unique_ptr<AsyncTask::ExecuteCallback> execute = nullptr;
AsyncTask::Schedule(*engine_, std::make_unique<AsyncTask>(callback, std::move(execute), std::move(complete)));
}
void JsWindowListener::AfterBackground()
{
WLOGFI("JsWindowListener::AfterBackground is called");
std::unique_ptr<AsyncTask::CompleteCallback> complete = std::make_unique<AsyncTask::CompleteCallback>(
[=] (NativeEngine &engine, AsyncTask &task, int32_t status) {
NativeValue* argv[] = {CreateJsValue(*engine_, static_cast<uint32_t>(LifeCycleEventType::BACKGROUND))};
CallJsMethod(LIFECYCLE_EVENT_CB.c_str(), argv, ArraySize(argv));
}
);
NativeReference* callback = nullptr;
std::unique_ptr<AsyncTask::ExecuteCallback> execute = nullptr;
AsyncTask::Schedule(*engine_, std::make_unique<AsyncTask>(callback, std::move(execute), std::move(complete)));
}
void JsWindowListener::AfterFocused()
{
WLOGFI("JsWindowListener::AfterFocused is called");
std::unique_ptr<AsyncTask::CompleteCallback> complete = std::make_unique<AsyncTask::CompleteCallback>(
[=] (NativeEngine &engine, AsyncTask &task, int32_t status) {
NativeValue* argv[] = {CreateJsValue(*engine_, static_cast<uint32_t>(LifeCycleEventType::ACTIVE))};
CallJsMethod(LIFECYCLE_EVENT_CB.c_str(), argv, ArraySize(argv));
}
);
NativeReference* callback = nullptr;
std::unique_ptr<AsyncTask::ExecuteCallback> execute = nullptr;
AsyncTask::Schedule(*engine_, std::make_unique<AsyncTask>(callback, std::move(execute), std::move(complete)));
}
void JsWindowListener::AfterUnfocused()
{
WLOGFI("JsWindowListener::AfterUnfocused is called");
std::unique_ptr<AsyncTask::CompleteCallback> complete = std::make_unique<AsyncTask::CompleteCallback>(
[=] (NativeEngine &engine, AsyncTask &task, int32_t status) {
NativeValue* argv[] = {CreateJsValue(*engine_, static_cast<uint32_t>(LifeCycleEventType::INACTIVE))};
CallJsMethod(LIFECYCLE_EVENT_CB.c_str(), argv, ArraySize(argv));
}
);
NativeReference* callback = nullptr;
std::unique_ptr<AsyncTask::ExecuteCallback> execute = nullptr;
AsyncTask::Schedule(*engine_, std::make_unique<AsyncTask>(callback, std::move(execute), std::move(complete)));
}
} // namespace Rosen
} // namespace OHOS
@@ -18,7 +18,6 @@
#include <map>
#include <mutex>
#include <unordered_set>
#include "native_engine/native_engine.h"
#include "native_engine/native_value.h"
#include "refbase.h"
@@ -31,26 +30,33 @@ namespace Rosen {
const std::string WINDOW_SIZE_CHANGE_CB = "windowSizeChange";
const std::string SYSTEM_BAR_TINT_CHANGE_CB = "systemBarTintChange";
const std::string SYSTEM_AVOID_AREA_CHANGE_CB = "systemAvoidAreaChange";
const std::string LIFECYCLE_EVENT_CB = "lifeCycleEvent";
class JsWindowListener : public IWindowChangeListener,
public ISystemBarChangedListener,
public IAvoidAreaChangedListener {
public IAvoidAreaChangedListener,
public IWindowLifeCycle {
public:
explicit JsWindowListener(NativeEngine* engine) : engine_(engine) {}
JsWindowListener(NativeEngine* engine, std::shared_ptr<NativeReference> callback)
: engine_(engine), jsCallBack_(callback) {}
virtual ~JsWindowListener() = default;
void AddCallback(NativeValue* jsListenerObject);
void RemoveAllCallback();
void RemoveCallback(NativeValue* jsListenerObject);
void OnSystemBarPropertyChange(DisplayId displayId, const SystemBarRegionTints& tints) override;
void OnSizeChange(Rect rect, WindowSizeChangeReason reason) override;
void OnModeChange(WindowMode mode) override;
void OnAvoidAreaChanged(std::vector<Rect> avoidAreas) override;
void AfterForeground() override;
void AfterBackground() override;
void AfterFocused() override;
void AfterUnfocused() override;
private:
enum class LifeCycleEventType : uint32_t {
FOREGROUND = 1,
ACTIVE,
INACTIVE,
BACKGROUND,
};
void CallJsMethod(const char* methodName, NativeValue* const* argv = nullptr, size_t argc = 0);
NativeEngine* engine_ = nullptr;
std::mutex mtx_;
std::vector<std::unique_ptr<NativeReference>> jsCallBack_;
std::shared_ptr<NativeReference> jsCallBack_ = nullptr;
};
} // namespace Rosen
} // namespace OHOS
@@ -17,6 +17,7 @@
#include <string>
#include "js_runtime_utils.h"
#include "js_window.h"
#include "js_window_listener.h"
#include "js_window_utils.h"
#include "window_manager_hilog.h"
namespace OHOS {
@@ -27,6 +28,7 @@ const int CONTENT_STORAGE_ARG = 2;
constexpr HiviewDFX::HiLogLabel LABEL = {LOG_CORE, HILOG_DOMAIN_WINDOW, "JsWindowStage"};
} // namespace
static std::map<std::shared_ptr<NativeReference>, sptr<JsWindowListener>> g_jsCbMap;
void JsWindowStage::Finalizer(NativeEngine* engine, void* data, void* hint)
{
WLOGFI("JsWindowStage::Finalizer is called");
@@ -89,47 +91,6 @@ NativeValue* JsWindowStage::GetSubWindow(NativeEngine* engine, NativeCallbackInf
return (me != nullptr) ? me->OnGetSubWindow(*engine, *info) : nullptr;
}
void JsWindowStage::AfterForeground()
{
LifeCycleCallBack(WindowStageEventType::FOREGROUND);
}
void JsWindowStage::AfterBackground()
{
LifeCycleCallBack(WindowStageEventType::BACKGROUND);
}
void JsWindowStage::AfterFocused()
{
LifeCycleCallBack(WindowStageEventType::ACTIVE);
}
void JsWindowStage::AfterUnfocused()
{
LifeCycleCallBack(WindowStageEventType::INACTIVE);
}
void JsWindowStage::LifeCycleCallBack(WindowStageEventType type)
{
WLOGFI("JsWindowStage::LifeCycleCallBack is called, type: %{public}d", type);
std::unique_ptr<AsyncTask::CompleteCallback> complete = std::make_unique<AsyncTask::CompleteCallback>(
[=] (NativeEngine &engine, AsyncTask &task, int32_t status) {
NativeValue* argv[] = {CreateJsValue(*engine_, static_cast<uint32_t>(type))};
for (auto &iter : eventCallbackMap_) {
NativeValue* method = (iter.first)->Get();
if (method == nullptr) {
WLOGFE("callback is null");
return;
}
engine_->CallFunction(engine_->CreateUndefined(), method, argv, ArraySize(argv));
}
}
);
NativeReference* callback = nullptr;
std::unique_ptr<AsyncTask::ExecuteCallback> execute = nullptr;
AsyncTask::Schedule(*engine_, std::make_unique<AsyncTask>(callback, std::move(execute), std::move(complete)));
}
NativeValue* JsWindowStage::OnSetUIContent(NativeEngine& engine, NativeCallbackInfo& info)
{
WLOGFI("JsWindowStage::OnSetUIContent is called");
@@ -194,19 +155,29 @@ NativeValue* JsWindowStage::OnGetMainWindow(NativeEngine& engine, NativeCallback
return result;
}
bool JsWindowStage::IsCallbackRegistered(std::string type, NativeValue* jsListenerObject)
{
if (g_jsCbMap.empty()) {
WLOGFI("JsWindowStage::JsWindowStage methodName %{public}s not registerted!", type.c_str());
return false;
}
for (auto iter = g_jsCbMap.begin(); iter != g_jsCbMap.end(); iter++) {
if (jsListenerObject->StrictEquals(iter->first->Get())) {
WLOGFE("JsWindowStage::IsCallbackRegistered callback already registered!");
return true;
}
}
return false;
}
NativeValue* JsWindowStage::OnEvent(NativeEngine& engine, NativeCallbackInfo& info)
{
WLOGFI("JsWindowStage::OnEvent is called");
if (windowScene_ == nullptr) {
WLOGFE("JsWindowStage::OnEvent windowScene_ is nullptr");
if (windowScene_ == nullptr || info.argc < 2) { // 2: minimum param nums
WLOGFE("JsWindowStage::OnEvent windowScene_ is nullptr or params not match");
return engine.CreateUndefined();
}
if (info.argc < 2) { // 2: minimum param nums
WLOGFE("JsWindowStage::OnEvent wrong input params");
return engine.CreateUndefined();
}
// Parse info->argv[0] as string
std::string eventString;
if (!ConvertFromJsValue(engine, info.argv[0], eventString)) {
@@ -218,33 +189,78 @@ NativeValue* JsWindowStage::OnEvent(NativeEngine& engine, NativeCallbackInfo& in
eventString.c_str());
return engine.CreateUndefined();
}
NativeValue* value = info.argv[1];
if (!value->IsCallable()) {
WLOGFE("JsWindowStage::OnEvent info->argv[1] is not callable");
return engine.CreateUndefined();
}
std::lock_guard<std::mutex> lock(mtx_);
if (IsCallbackRegistered(eventString, value)) {
WLOGFE("JsWindowStage::OnEvent callback already registered!");
return engine.CreateUndefined();
}
std::shared_ptr<NativeReference> reference = nullptr;
reference.reset(engine.CreateReference(value, 1));
eventCallbackMap_[reference] = 1;
engine_ = &engine;
WLOGFI("JsWindowStage::OnEvent eventCallbackMap_ size: %{public}d",
static_cast<uint32_t>(eventCallbackMap_.size()));
if (!regLifeCycleListenerFlag_) {
auto window = windowScene_->GetMainWindow();
if (window != nullptr) {
sptr<IWindowLifeCycle> listener = this;
window->RegisterLifeCycleListener(listener);
regLifeCycleListenerFlag_ = true;
WLOGFI("JsWindowStage::OnEvent regist lifecycle success");
}
} else {
WLOGFI("JsWindowStage::OnEvent already regist lifecycle");
sptr<JsWindowListener> windowListener = new(std::nothrow) JsWindowListener(&engine, reference);
if (windowListener == nullptr) {
WLOGFE("JsWindowStage::OnEvent windowListener malloc failed");
return engine.CreateUndefined();
}
auto window = windowScene_->GetMainWindow();
if (window != nullptr) {
sptr<IWindowLifeCycle> thisListener(windowListener);
window->RegisterLifeCycleListener(thisListener);
}
g_jsCbMap[reference] = windowListener;
WLOGFI("JsWindowStage::OnEvent callback map size: %{public}u success", g_jsCbMap.size());
return engine.CreateUndefined();
}
void JsWindowStage::UnregisterAllWindowListenerWithType(std::string type)
{
if (g_jsCbMap.empty()) {
WLOGFE("JsWindowStage::UnregisterAllWindowListenerWithType methodName %{public}s not registerted!",
type.c_str());
return;
}
auto window = windowScene_->GetMainWindow();
if (window == nullptr) {
WLOGFE("JsWindowStage::UnregisterAllWindowListenerWithType mainWindow is null!");
return;
}
for (auto it = g_jsCbMap.begin(); it != g_jsCbMap.end();) {
sptr<IWindowLifeCycle> thisListener(it->second);
window->UnregisterLifeCycleListener(thisListener);
g_jsCbMap.erase(it++);
}
WLOGFI("JsWindowStage::UnregisterWindowListenerWithType callback map size: %{public}u success",
g_jsCbMap.size());
}
void JsWindowStage::UnregisterWindowListenerWithType(std::string type, NativeValue* value)
{
if (g_jsCbMap.empty()) {
WLOGFE("JsWindowStage::UnregisterWindowListenerWithType methodName %{public}s not registerted!",
type.c_str());
return;
}
for (auto it = g_jsCbMap.begin(); it != g_jsCbMap.end();it++) {
if (value->StrictEquals(it->first->Get())) {
auto window = windowScene_->GetMainWindow();
if (window != nullptr) {
sptr<IWindowLifeCycle> thisListener(it->second);
window->UnregisterLifeCycleListener(thisListener);
}
g_jsCbMap.erase(it++);
break;
}
}
// one type with multi jscallback, erase type when there is no callback in one type
WLOGFI("JsWindowStage::UnregisterWindowListenerWithType callback map size: %{public}u success",
g_jsCbMap.size());
}
NativeValue* JsWindowStage::OffEvent(NativeEngine& engine, NativeCallbackInfo& info)
{
WLOGFI("JsWindowStage::OffEvent is called");
@@ -269,19 +285,13 @@ NativeValue* JsWindowStage::OffEvent(NativeEngine& engine, NativeCallbackInfo& i
}
NativeValue* value = info.argv[1];
if (value->IsCallable()) {
std::lock_guard<std::mutex> lock(mtx_);
if (value->TypeOf() == NATIVE_FUNCTION) {
WLOGFI("JsWindowStage::OffEvent info->argv[1] is callable type");
for (auto iter = eventCallbackMap_.begin(); iter != eventCallbackMap_.end(); iter++) {
std::shared_ptr<NativeReference> callback = iter->first;
if (value->StrictEquals(callback->Get())) {
eventCallbackMap_.erase(iter);
break;
}
}
return engine.CreateUndefined();
UnregisterWindowListenerWithType(eventString, value);
} else if (value->TypeOf() == NativeValueType::NATIVE_UNDEFINED) {
WLOGFI("JsWindowStage::OffEvent info->argv[1] is native undefined type");
eventCallbackMap_.clear();
UnregisterAllWindowListenerWithType(eventString);
} else {
WLOGFE("JsWindowStage::OffEvent info->argv[1] is InValid param");
}
@@ -24,8 +24,7 @@
namespace OHOS {
namespace Rosen {
NativeValue* CreateJsWindowStage(NativeEngine& engine, std::shared_ptr<Rosen::WindowScene> windowScene);
class JsWindowStage : Rosen::IWindowLifeCycle {
class JsWindowStage {
public:
explicit JsWindowStage(const std::shared_ptr<Rosen::WindowScene>& windowScene)
: windowScene_(windowScene) {}
@@ -39,12 +38,11 @@ public:
static NativeValue* GetWindowMode(NativeEngine* engine, NativeCallbackInfo* info);
static NativeValue* CreateSubWindow(NativeEngine* engine, NativeCallbackInfo* info);
static NativeValue* GetSubWindow(NativeEngine* engine, NativeCallbackInfo* info);
virtual void AfterForeground() override;
virtual void AfterBackground() override;
virtual void AfterFocused() override;
virtual void AfterUnfocused() override;
private:
bool IsCallbackRegistered(std::string type, NativeValue* jsListenerObject);
void UnregisterAllWindowListenerWithType(std::string type);
void UnregisterWindowListenerWithType(std::string type, NativeValue* value);
NativeValue* CreateJsSubWindowArrayObject(NativeEngine& engine, std::vector<sptr<Window>> subWinVec);
NativeValue* OnSetUIContent(NativeEngine& engine, NativeCallbackInfo& info);
NativeValue* OnGetMainWindow(NativeEngine& engine, NativeCallbackInfo& info);
@@ -54,19 +52,9 @@ private:
NativeValue* OnGetWindowMode(NativeEngine& engine, NativeCallbackInfo& info);
NativeValue* OnCreateSubWindow(NativeEngine& engine, NativeCallbackInfo& info);
NativeValue* OnGetSubWindow(NativeEngine& engine, NativeCallbackInfo& info);
enum class WindowStageEventType : uint32_t {
FOREGROUND = 1,
ACTIVE,
INACTIVE,
BACKGROUND,
};
void LifeCycleCallBack(WindowStageEventType type);
std::shared_ptr<Rosen::WindowScene> windowScene_;
NativeEngine* engine_ = nullptr;
sptr<IWindowLifeCycle> lifecycleListener_ = nullptr;
std::map<std::shared_ptr<NativeReference>, int> eventCallbackMap_;
bool regLifeCycleListenerFlag_ = false;
std::mutex mtx_;
};
} // namespace Rosen
} // namespace OHOS
+2 -2
View File
@@ -105,7 +105,7 @@ public:
virtual void UnregisterLifeCycleListener(sptr<IWindowLifeCycle>& listener) override;
virtual void UnregisterWindowChangeListener(sptr<IWindowChangeListener>& listener) override;
virtual void RegisterAvoidAreaChangeListener(sptr<IAvoidAreaChangedListener>& listener) override;
virtual void UnregisterAvoidAreaChangeListener() override;
virtual void UnregisterAvoidAreaChangeListener(sptr<IAvoidAreaChangedListener>& listener) override;
virtual void RegisterDragListener(sptr<IWindowDragListener>& listener) override;
virtual void UnregisterDragListener(sptr<IWindowDragListener>& listener) override;
virtual void RegisterDisplayMoveListener(sptr<IDisplayMoveListener>& listener) override;
@@ -197,7 +197,7 @@ private:
WindowState state_ { WindowState::STATE_INITIAL };
std::vector<sptr<IWindowLifeCycle>> lifecycleListeners_;
std::vector<sptr<IWindowChangeListener>> windowChangeListeners_;
sptr<IAvoidAreaChangedListener> avoidAreaChangeListener_;
std::vector<sptr<IAvoidAreaChangedListener>> avoidAreaChangeListeners_;
std::vector<sptr<IWindowDragListener>> windowDragListeners_;
std::vector<sptr<IDisplayMoveListener>> displayMoveListeners_;
std::shared_ptr<RSSurfaceNode> surfaceNode_;
+16 -12
View File
@@ -852,20 +852,21 @@ void WindowImpl::UnregisterWindowChangeListener(sptr<IWindowChangeListener>& lis
void WindowImpl::RegisterAvoidAreaChangeListener(sptr<IAvoidAreaChangedListener>& listener)
{
if (avoidAreaChangeListener_ != nullptr) {
WLOGFE("RegisterAvoidAreaChangeListener failed. AvoidAreaChangeListene is not nullptr");
if (listener == nullptr) {
WLOGFE("RegisterAvoidAreaChangeListener failed. AvoidAreaChangeListener is nullptr");
return;
}
avoidAreaChangeListener_ = listener;
std::lock_guard<std::recursive_mutex> lock(mutex_);
avoidAreaChangeListeners_.emplace_back(listener);
}
void WindowImpl::UnregisterAvoidAreaChangeListener()
void WindowImpl::UnregisterAvoidAreaChangeListener(sptr<IAvoidAreaChangedListener>& listener)
{
if (avoidAreaChangeListener_ == nullptr) {
WLOGFE("UnregisterAvoidAreaChangeListener failed. AvoidAreaChangeListene is nullptr");
return;
}
avoidAreaChangeListener_ = nullptr;
std::lock_guard<std::recursive_mutex> lock(mutex_);
avoidAreaChangeListeners_.erase(std::remove_if(avoidAreaChangeListeners_.begin(), avoidAreaChangeListeners_.end(),
[listener](sptr<IAvoidAreaChangedListener> registeredListener) {
return registeredListener == listener;
}), avoidAreaChangeListeners_.end());
}
void WindowImpl::RegisterDragListener(sptr<IWindowDragListener>& listener)
@@ -920,6 +921,7 @@ void WindowImpl::UpdateRect(const struct Rect& rect, WindowSizeChangeReason reas
WLOGFI("winId:%{public}u, rect[%{public}d, %{public}d, %{public}u, %{public}u], vpr:%{public}f, reason:%{public}u",
GetWindowId(), rect.posX_, rect.posY_, rect.width_, rect.height_, virtualPixelRatio, reason);
property_->SetWindowRect(rect);
WLOGFI("sizeChange callback size: %{public}u", windowChangeListeners_.size());
for (auto& listener : windowChangeListeners_) {
if (listener != nullptr) {
listener->OnSizeChange(rect, reason);
@@ -1065,7 +1067,7 @@ void WindowImpl::ReadyToMoveOrDragWindow(int32_t globalX, int32_t globalY, int32
return;
}
float virtualPixelRatio = display->GetVirtualPixelRatio();
startRectExceptFrame_.posX_ = startPointRect_.posX_ +
static_cast<int32_t>(WINDOW_FRAME_WIDTH * virtualPixelRatio);
startRectExceptFrame_.posY_ = startPointRect_.posY_ +
@@ -1200,8 +1202,10 @@ void WindowImpl::UpdateConfiguration(const std::shared_ptr<AppExecFwk::Configura
void WindowImpl::UpdateAvoidArea(const std::vector<Rect>& avoidArea)
{
WLOGFI("Window Update AvoidArea, id: %{public}d", property_->GetWindowId());
if (avoidAreaChangeListener_ != nullptr) {
avoidAreaChangeListener_->OnAvoidAreaChanged(avoidArea);
for (auto& listener : avoidAreaChangeListeners_) {
if (listener != nullptr) {
listener->OnAvoidAreaChanged(avoidArea);
}
}
}