!15 把napi接口调用放到ui线程中去,以及解决输入法偶尔白屏问题

Merge pull request !15 from demon/master
This commit is contained in:
openharmony_ci
2021-10-20 08:16:53 +00:00
committed by Gitee
5 changed files with 82 additions and 32 deletions
@@ -17,6 +17,7 @@
#define INPUT_METHOD_NAPI_EVENT_TARGET_H
#include "napi/native_api.h"
#include "napi/native_node_api.h"
#include "global.h"
#include "input_method_ability.h"
@@ -37,7 +38,7 @@ namespace MiscServices {
virtual void Once(const char *type, napi_value handler);
virtual void Off(const char *type, napi_value handler);
virtual void Off(const char *type);
virtual void Emit(const char *type, Event *event);
virtual void Emit(sptr<EventTarget> &eventTarget, const char *type, Event *event);
protected:
napi_env env_;
@@ -12,7 +12,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include <uv.h>
#include "event_target.h"
#include "securec.h"
@@ -29,6 +29,15 @@ namespace MiscServices {
EventListener *back = nullptr;
EventListener *next = nullptr;
};
struct EventTargetCB {
napi_env env;
napi_ref thisVarRef;
EventListener *first;
EventListener *last;
sptr<EventTarget> &eventTarget;
const char *type;
Event *event;
};
EventTarget::EventTarget(napi_env env, napi_value thisVar)
{
IMSA_HILOGI("EventTarget::EventTarget");
@@ -159,27 +168,63 @@ namespace MiscServices {
}
}
void EventTarget::Emit(const char *type, Event *event)
void EventTarget::Emit(sptr<EventTarget> &eventTarget, const char *type, Event *event)
{
IMSA_HILOGI("EventTarget::Emit");
napi_handle_scope scope = nullptr;
napi_open_handle_scope(env_, &scope);
napi_value thisVar = nullptr;
napi_get_reference_value(env_, thisVarRef_, &thisVar);
for (EventListener *eventListener = first_; eventListener != nullptr; eventListener = eventListener->next) {
if (strcmp(eventListener->type, type) == 0) {
napi_value jsEvent = event ? event->ToJsObject() : nullptr;
napi_value handler = nullptr;
napi_value result = nullptr;
napi_get_reference_value(env_, eventListener->handlerRef, &handler);
napi_call_function(env_, thisVar, handler, jsEvent ? 1 : 0, jsEvent ? &jsEvent : nullptr, &result);
if (eventListener->isOnce) {
Off(type, handler);
}
}
uv_loop_s *loop = nullptr;
napi_get_uv_event_loop(env_, &loop);
if (loop == nullptr) {
IMSA_HILOGI("EventTarget::Emit loop == nullptr");
return;
}
uv_work_t *work = new (std::nothrow) uv_work_t;
if (work == nullptr) {
IMSA_HILOGI("EventTarget::Emit No memory work == nullptr");
return;
}
EventTargetCB *eventTargetCB = new (std::nothrow) EventTargetCB {.env = env_, .thisVarRef = thisVarRef_,
.first = first_, .last = last_, .type = type, .event = event, .eventTarget = eventTarget};
work->data = (void *)eventTargetCB;
int ret = uv_queue_work(loop, work, [](uv_work_t *work) {}, [](uv_work_t *work, int status) {
//Js Thread
if (work == nullptr) {
IMSA_HILOGI("EventTarget::Emit work == nullptr");
return;
}
EventTargetCB *eventTargetCB = (EventTargetCB *)work->data;
do {
napi_handle_scope scope = nullptr;
napi_open_handle_scope(eventTargetCB->env, &scope);
napi_value thisVar = nullptr;
napi_get_reference_value(eventTargetCB->env, eventTargetCB->thisVarRef, &thisVar);
for (EventListener *eventListener = eventTargetCB->first; eventListener != nullptr; eventListener = eventListener->next) {
if (strcmp(eventListener->type, eventTargetCB->type) == 0) {
napi_value jsEvent = eventTargetCB->event ? eventTargetCB->event->ToJsObject() : nullptr;
napi_value handler = nullptr;
napi_value result = nullptr;
napi_get_reference_value(eventTargetCB->env, eventListener->handlerRef, &handler);
napi_call_function(eventTargetCB->env, thisVar, handler, jsEvent ? 1 : 0, jsEvent ? &jsEvent : nullptr, &result);
if (eventListener->isOnce) {
eventTargetCB->eventTarget->Off(eventTargetCB->type, handler);
}
}
}
napi_close_handle_scope(eventTargetCB->env, scope);
} while (0);
if (eventTargetCB) {
delete eventTargetCB;
}
delete work;
});
if (ret != 0) {
IMSA_HILOGI("EventTarget::Emit failed to execute libuv work queue");
delete work;
}
napi_close_handle_scope(env_, scope);
}
}
}
@@ -38,6 +38,8 @@ namespace MiscServices {
InputMethodAbility::~InputMethodAbility()
{
IMSA_HILOGI("InputMethodAbility::~InputMethodAbility");
instance_ = nullptr;
if (msgHandler != nullptr) {
delete msgHandler;
msgHandler = nullptr;
@@ -240,13 +242,13 @@ namespace MiscServices {
void InputMethodAbility::ShowInputWindow()
{
IMSA_HILOGI("InputMethodAbility::ShowInputWindow");
eventTarget_->Emit("keyboardShow", nullptr);
eventTarget_->Emit(eventTarget_, "keyboardShow", nullptr);
}
void InputMethodAbility::DissmissInputWindow()
{
IMSA_HILOGI("InputMethodAbility::DissmissInputWindow");
eventTarget_->Emit("keyboardHide", nullptr);
eventTarget_->Emit(eventTarget_, "keyboardHide", nullptr);
}
bool InputMethodAbility::InsertText(const std::string text)
+3 -3
View File
@@ -329,8 +329,8 @@ namespace MiscServices {
IMSA_HILOGI("PerUserSession::AddClient");
ClientInfo *clientInfo = GetClientInfo(inputClient);
if (clientInfo != nullptr) {
IMSA_HILOGE("PerUserSession::AddClient clientInfo is not nullptr");
return ErrorCode::ERROR_CLIENT_DUPLICATED;
IMSA_HILOGE("PerUserSession::AddClient clientInfo is exist, not need add.");
return ErrorCode::NO_ERROR;
}
sptr<IRemoteObject> obj = inputClient->AsObject();
@@ -1296,7 +1296,6 @@ namespace MiscServices {
}
if (imsCore[index] != nullptr) {
IMSA_HILOGI("PerUserSession::onSetInputMethodCore End... Input Method Service has already been started ! ");
return;
}
imsCore[index] = core;
int ret = StartInputMethod(index);
@@ -1314,6 +1313,7 @@ namespace MiscServices {
IMSA_HILOGI("PerUserSession::OnStartInput End...[%{public}d]\n", userId_);
}
}
IMSA_HILOGI("PerUserSession::OnStartInput End. currentClient is nullptr");
}
/*! Stop input. Called by an input client.
+9 -7
View File
@@ -117,13 +117,15 @@ namespace MiscServices {
return ErrorCode::NO_ERROR;
}
/*! Remove an input method engine.
\n It's called when a package is removed from the system.
\param packageName the package name of installed package.
\param[out] isSecurityIme check if the removed ime is a security ime.
\return ErrorCode::NO_ERROR The removed package is an IME package, and is removed from the input method management system
\return ErrorCode::ERROR_NOT_IME_PACKAGE The removed package is not an IME package.
*/
/**
* Remove an input method engine.
* It's called when a package is removed from the system.
* @param packageName the package name of installed package.
* @param isSecurityIme check if the removed ime is a security ime.
* @return ErrorCode::NO_ERROR The removed package is an IME package,
* and is removed from the input method management system
* ErrorCode::ERROR_NOT_IME_PACKAGE The removed package is not an IME package.
*/
int PerUserSetting::OnPackageRemoved(std::u16string& packageName, bool isSecurityIme)
{
if (isSecurityIme) {