!172 修复输入法切换功能

Merge pull request !172 from 赵凌岚/master
This commit is contained in:
openharmony_ci 2022-07-21 04:15:53 +00:00 committed by Gitee
commit f866716f16
No known key found for this signature in database
GPG Key ID: 173E9B9CA92EEF8F
15 changed files with 79 additions and 73 deletions

View File

@ -44,8 +44,8 @@ namespace MiscServices {
static sptr<InputMethodAbility> GetInstance();
sptr<IInputMethodCore> OnConnect();
bool InsertText(const std::string text);
void setImeListener(sptr<JsInputMethodEngineListener> &imeListener);
void setKdListener(sptr<JsKeyboardDelegateListener> &kdListener);
void setImeListener(sptr<JsInputMethodEngineListener> imeListener);
void setKdListener(sptr<JsKeyboardDelegateListener> kdListener);
void DeleteForward(int32_t length);
void DeleteBackward(int32_t length);
void HideKeyboardSelf();

View File

@ -117,7 +117,7 @@ namespace MiscServices {
SetCoreAndAgent();
}
void InputMethodAbility::setImeListener(sptr<JsInputMethodEngineListener> &imeListener)
void InputMethodAbility::setImeListener(sptr<JsInputMethodEngineListener> imeListener)
{
IMSA_HILOGI("InputMethodAbility::setImeListener");
if (!imeListener_) {
@ -125,7 +125,7 @@ namespace MiscServices {
}
}
void InputMethodAbility::setKdListener(sptr<JsKeyboardDelegateListener> &kdListener)
void InputMethodAbility::setKdListener(sptr<JsKeyboardDelegateListener> kdListener)
{
IMSA_HILOGI("InputMethodAbility::setKdListener");
if (!kdListener_) {

View File

@ -75,7 +75,7 @@ namespace MiscServices {
int32_t GetInputPattern();
void HideCurrentInput();
void SetCallingWindow(uint32_t windowId);
int32_t SwitchInputMethod(InputMethodProperty *target);
int32_t SwitchInputMethod(const InputMethodProperty &target);
private:
InputMethodController();

View File

@ -56,7 +56,7 @@ namespace MiscServices {
int32_t listInputMethodEnabled(std::vector<InputMethodProperty*> *properties) override;
int32_t listInputMethod(std::vector<InputMethodProperty*> *properties) override;
int32_t listKeyboardType(const std::u16string& imeId, std::vector<KeyboardType*> *types) override;
int32_t SwitchInputMethod(InputMethodProperty* target);
int32_t SwitchInputMethod(const InputMethodProperty &target);
private:
static inline BrokerDelegator<InputMethodSystemAbilityProxy> delegator_;

View File

@ -470,7 +470,7 @@ using namespace MessageID;
agent->SetCallingWindow(windowId);
}
int32_t InputMethodController::SwitchInputMethod(InputMethodProperty *target)
int32_t InputMethodController::SwitchInputMethod(const InputMethodProperty &target)
{
IMSA_HILOGI("InputMethodController::SwitchInputMethod");
if (!mImms) {

View File

@ -438,23 +438,24 @@ namespace MiscServices {
return NO_ERROR;
}
int32_t InputMethodSystemAbilityProxy::SwitchInputMethod(InputMethodProperty* target)
int32_t InputMethodSystemAbilityProxy::SwitchInputMethod(const InputMethodProperty &target)
{
IMSA_HILOGI("InputMethodSystemAbilityProxy::switchInputMethod");
IMSA_HILOGI("InputMethodSystemAbilityProxy::SwitchInputMethod");
MessageParcel data, reply;
MessageOption option;
if (!data.WriteInterfaceToken(GetDescriptor())) {
return false;
return ERROR_EX_PARCELABLE;
}
if (!target->Marshalling(data)) {
if (!target.Marshalling(data)) {
IMSA_HILOGE("InputMethodSystemAbilityProxy::switchInputMethod Failed to marshall target to data!");
delete target;
return false;
return ERROR_IME_PROPERTY_MARSHALL;
}
delete target;
auto ret = Remote()->SendRequest(SWITCH_INPUT_METHOD, data, reply, option);
if (ret != 0) {
return ERROR_STATUS_FAILED_TRANSACTION;
}
ret = reply.ReadInt32();
return ret;
}

View File

@ -96,22 +96,23 @@ namespace MiscServices {
return engine.CreateUndefined();
}
InputMethodProperty *target = new InputMethodProperty();
InputMethodProperty target;
NativeObject *object = ConvertNativeValueTo<NativeObject>(info.argv[0]);
if (object == nullptr) {
IMSA_HILOGE("JsInputMethodRegistry::OnSwitchInputMethod Failed to get object");
return engine.CreateUndefined();
}
if (!GetInputMethodPropertyFromJs(engine, object, *target)) {
if (!GetInputMethodPropertyFromJs(engine, object, target)) {
return engine.CreateUndefined();
}
bool isSwitchSuccess = false;
if (!InputMethodController::GetInstance()->SwitchInputMethod(target)) {
IMSA_HILOGE("JsInputMethodRegistry::OnSwitchInputMethod success!");
isSwitchSuccess = true;
} else {
IMSA_HILOGE("JsInputMethodRegistry::OnSwitchInputMethod isSwitchSuccess is false !");
IMSA_HILOGE("JsInputMethodRegistry::OnSwitchInputMethod failed!");
}
NativeValue *result = CreateJsValue(engine, isSwitchSuccess);

View File

@ -32,8 +32,8 @@ namespace OHOS {
static NativeValue* UnRegisterCallback(NativeEngine* engine, NativeCallbackInfo* info);
private:
sptr<JsInputMethodEngineListener> imeListener_;
std::mutex mtx_;
sptr<JsInputMethodEngineListener> imeListener_;
NativeValue* OnRegisterCallback(NativeEngine& engine, NativeCallbackInfo& info);
NativeValue* OnUnRegisterCallback(NativeEngine& engine, NativeCallbackInfo& info);
std::shared_ptr<AppExecFwk::EventHandler> GetMainHandler();

View File

@ -42,14 +42,15 @@ namespace MiscServices {
void OnSetCallingWindow(uint32_t windowId);
private:
std::mutex mMutex;
std::recursive_mutex mapMutex;
void AddCallback(std::string type, NativeValue* jsListenerObject);
void CallJsMethod(std::string methodName, NativeValue* const* argv = nullptr, size_t argc = 0);
bool CallJsMethodReturnBool(std::string methodName, NativeValue* const* argv = nullptr, size_t argc = 0);
void RemoveCallback(NativeValue* jsListenerObject);
bool IfCallbackRegistered(std::string type, NativeValue* jsListenerObject);
NativeEngine* engine_ = nullptr;
std::mutex mMutex;
std::map<std::string, std::vector<std::unique_ptr<NativeReference>>> jsCbMap_;
std::map<std::string, std::vector<std::shared_ptr<NativeReference>>> jsCbMap_;
std::shared_ptr<AppExecFwk::EventHandler> mainHandler_ = nullptr;
};
} // namespace MiscServices

View File

@ -28,49 +28,43 @@ namespace MiscServices {
IMSA_HILOGI("JsInputMethodEngineListener::RegisterListenerWithType callback already registered!");
return;
}
std::unique_ptr<NativeReference> callbackRef;
callbackRef.reset(engine.CreateReference(value, 1));
AddCallback(type, value);
}
void JsInputMethodEngineListener::AddCallback(std::string type, NativeValue* jsListenerObject)
{
IMSA_HILOGI("JsInputMethodEngineListener::AddCallback is called");
IMSA_HILOGI("JsInputMethodEngineListener::AddCallback is called : %{public}s", type.c_str());
std::lock_guard<std::mutex> lock(mMutex);
std::unique_ptr<NativeReference> callbackRef;
callbackRef.reset(engine_->CreateReference(jsListenerObject, 1));
jsCbMap_[type].push_back(std::move(callbackRef));
IMSA_HILOGI("JsInputMethodEngineListener::AddCallback success");
IMSA_HILOGI("jsCbMap_ size: %{public}d, and type[%{public}s] size: %{public}d!",
std::shared_ptr<NativeReference> callbackRef(engine_->CreateReference(jsListenerObject, 1));
if (callbackRef == nullptr) {
IMSA_HILOGI("JsInputMethodEngineListener::AddCallback fail, callbackRef is nullptr");
return;
}
std::lock_guard<std::recursive_mutex> lk(mapMutex);
jsCbMap_[type].push_back(callbackRef);
IMSA_HILOGI("AddCallback success! jsCbMap_ size: %{public}d, and type[%{public}s] size: %{public}d",
static_cast<uint32_t>(jsCbMap_.size()), type.c_str(), static_cast<uint32_t>(jsCbMap_[type].size()));
return;
}
void JsInputMethodEngineListener::UnregisterAllListenerWithType(std::string type)
{
IMSA_HILOGI("JsInputMethodEngineListener::UnregisterAllListenerWithType");
IMSA_HILOGI("JsInputMethodEngineListener::UnregisterAllListenerWithType : %{public}s", type.c_str());
// should do type check
std::lock_guard<std::recursive_mutex> lk(mapMutex);
if (jsCbMap_.empty() || jsCbMap_.find(type) == jsCbMap_.end()) {
IMSA_HILOGI("methodName %{public}s not registerted!", type.c_str());
return;
}
for (auto it = jsCbMap_[type].begin(); it != jsCbMap_[type].end();) {
jsCbMap_[type].erase(it);
}
// one type with multi jscallback, erase type when there is no callback in one type
if (jsCbMap_[type].empty()) {
jsCbMap_.erase(type);
}
return;
jsCbMap_.erase(type);
}
void JsInputMethodEngineListener::UnregisterListenerWithType(std::string type, NativeValue* value)
{
IMSA_HILOGI("JsInputMethodEngineListener::UnregisterListenerWithType");
IMSA_HILOGI("JsInputMethodEngineListener::UnregisterListenerWithType : %{public}s.", type.c_str());
// should do type check
std::lock_guard<std::recursive_mutex> lk(mapMutex);
if (jsCbMap_.empty() || jsCbMap_.find(type) == jsCbMap_.end()) {
IMSA_HILOGI("methodName %{public}s not registerted!", type.c_str());
IMSA_HILOGI("methodName %{public}s not registered!", type.c_str());
return;
}
for (auto it = jsCbMap_[type].begin(); it != jsCbMap_[type].end();) {
@ -79,21 +73,19 @@ namespace MiscServices {
break;
}
}
// one type with multi jscallback, erase type when there is no callback in one type
if (jsCbMap_[type].empty()) {
jsCbMap_.erase(type);
}
return;
}
bool JsInputMethodEngineListener::IfCallbackRegistered(std::string type, NativeValue* jsListenerObject)
{
IMSA_HILOGI("JsInputMethodEngineListener::IfCallbackRegistered");
std::lock_guard<std::recursive_mutex> lk(mapMutex);
if (jsCbMap_.empty() || jsCbMap_.find(type) == jsCbMap_.end()) {
IMSA_HILOGI("methodName %{public}s not registertd!", type.c_str());
return false;
}
for (auto iter = jsCbMap_[type].begin(); iter != jsCbMap_[type].end(); iter++) {
if (jsListenerObject->StrictEquals((*iter)->Get())) {
IMSA_HILOGI("JsInputMethodEngineListener::IfCallbackRegistered callback already registered!");
@ -105,19 +97,22 @@ namespace MiscServices {
void JsInputMethodEngineListener::CallJsMethod(std::string methodName, NativeValue* const* argv, size_t argc)
{
IMSA_HILOGI("JsInputMethodEngineListener::CallJsMethod");
IMSA_HILOGI("JsInputMethodEngineListener::CallJsMethod : %{public}s", methodName.c_str());
if (!engine_) {
IMSA_HILOGI("engine_ nullptr");
return;
}
std::lock_guard<std::recursive_mutex> lk(mapMutex);
if (jsCbMap_.empty() || jsCbMap_.find(methodName) == jsCbMap_.end()) {
IMSA_HILOGI("methodName %{public}s not registertd!", methodName.c_str());
return;
}
for (auto iter = jsCbMap_[methodName].begin(); iter != jsCbMap_[methodName].end(); iter++) {
engine_->CallFunction(engine_->CreateUndefined(), (*iter)->Get(), argv, argc);
for (auto iter : jsCbMap_[methodName]) {
if (iter == nullptr) {
IMSA_HILOGE("JsInputMethodEngineListener::CallJsMethod iter is null");
continue;
}
engine_->CallFunction(engine_->CreateUndefined(), iter->Get(), argv, argc);
}
}
@ -129,15 +124,16 @@ namespace MiscServices {
IMSA_HILOGI("engine_ nullptr");
return false;
}
std::lock_guard<std::recursive_mutex> lk(mapMutex);
if (jsCbMap_.empty() || jsCbMap_.find(methodName) == jsCbMap_.end()) {
IMSA_HILOGI("methodName %{public}s not registertd!", methodName.c_str());
IMSA_HILOGI("methodName %{public}s not registered!", methodName.c_str());
return false;
}
bool result = false;
for (auto iter = jsCbMap_[methodName].begin(); iter != jsCbMap_[methodName].end(); iter++) {
NativeValue* nativeValue = engine_->CallFunction(engine_->CreateUndefined(), (*iter)->Get(), argv, argc);
for (auto iter : jsCbMap_[methodName]) {
NativeValue *nativeValue =
engine_->CallFunction(engine_->CreateUndefined(), iter->Get(), argv, argc);
bool ret = false;
if (ConvertFromJsValue(*engine_, nativeValue, ret) && ret) {
result = true;

View File

@ -37,7 +37,7 @@ namespace MiscServices {
void HideCurrentInput(MessageParcel& data) override;
void displayOptionalInputMethod(MessageParcel& data) override;
virtual int32_t listInputMethodByUserId(int32_t userId, std::vector<InputMethodProperty*> *properties) = 0;
int32_t SwitchInputMethod(MessageParcel &data, MessageParcel &reply);
int32_t SwitchInputMethod(MessageParcel &data);
protected:
int32_t getUserId(int32_t uid);

View File

@ -25,11 +25,9 @@ namespace OHOS {
namespace MiscServices {
class Message {
public:
int32_t msgId_; // message id
int32_t msgId_ {0}; // message id
MessageParcel *msgContent_ = nullptr; // message content
MessageParcel *msgReply_ = nullptr; // message reply
Message(int32_t msgId, MessageParcel *msgContent);
Message(int32_t msgId, MessageParcel *msgContent, MessageParcel *msgReply);
explicit Message(const Message& msg);
Message& operator =(const Message& msg);
~Message();

View File

@ -290,9 +290,10 @@ namespace MiscServices {
want.SetElementName(imeId.substr(0, pos), imeId.substr(pos + 1));
int32_t result = abms->StartAbility(want);
if (result) {
IMSA_HILOGE("InputMethodSystemAbility::StartInputService fail. result = %{public}d", result);
IMSA_HILOGE("InputMethodSystemAbility::StartInputService failed, result = %{public}d", result);
isStartSuccess = false;
} else {
IMSA_HILOGE("InputMethodSystemAbility::StartInputService success.");
isStartSuccess = true;
}
}
@ -302,7 +303,7 @@ namespace MiscServices {
auto callback = [this, imeId]() { StartInputService(imeId); };
serviceHandler_->PostTask(callback, INIT_INTERVAL);
}
return isStartSuccess;
return isStartSuccess;
}
void InputMethodSystemAbility::StopInputService(std::string imeId)
@ -633,8 +634,7 @@ namespace MiscServices {
MessageParcel *data = msg->msgContent_;
int32_t userId = data->ReadInt32();
InputMethodProperty *target = InputMethodProperty::Unmarshalling(*data);
auto ret = OnSwitchInputMethod(userId, target);
msg->msgReply_->WriteInt32(ret);
OnSwitchInputMethod(userId, target);
break;
}
default: {
@ -990,9 +990,7 @@ namespace MiscServices {
}
std::string defaultIme = ParaHandle::GetDefaultIme(userId_);
std::string targetIme = "";
std::string imeId = Str16ToStr8(target->mPackageName) + "/" + Str16ToStr8(target->mAbilityName);
targetIme += imeId;
std::string targetIme = Str16ToStr8(target->mPackageName) + "/" + Str16ToStr8(target->mAbilityName);
IMSA_HILOGI("InputMethodSystemAbility::OnSwitchInputMethod DefaultIme : %{public}s, TargetIme : %{public}s",
defaultIme.c_str(), targetIme.c_str());
if (defaultIme != targetIme) {
@ -1002,7 +1000,15 @@ namespace MiscServices {
if (!StartInputService(targetIme)) {
return ErrorCode::ERROR_IME_START_FAILED;
}
ParaHandle::SetDefaultIme(userId_, targetIme);
bool setResult = ParaHandle::SetDefaultIme(userId_, targetIme);
if (setResult) {
IMSA_HILOGI("InputMethodSystemAbility::OnSwitchInputMethod SetDefaultIme Successfully.");
} else {
IMSA_HILOGI("InputMethodSystemAbility::OnSwitchInputMethod SetDefaultIme Failed. setResult = "
"%{public}d",
setResult);
return ErrorCode::ERROR_STATUS_PERMISSION_DENIED;
}
} else {
IMSA_HILOGI("InputMethodSystemAbility::OnSwitchInputMethod DefaultIme and TargetIme are the same one!");
}

View File

@ -171,7 +171,8 @@ namespace MiscServices {
break;
}
case SWITCH_INPUT_METHOD: {
SwitchInputMethod(data, reply);
int32_t ret = SwitchInputMethod(data);
reply.WriteInt32(ret);
break;
}
default: {
@ -308,13 +309,16 @@ namespace MiscServices {
MessageHandler::Instance()->SendMessage(msg);
}
int32_t InputMethodSystemAbilityStub::SwitchInputMethod(MessageParcel &data, MessageParcel &reply)
int32_t InputMethodSystemAbilityStub::SwitchInputMethod(MessageParcel &data)
{
IMSA_HILOGI("InputMethodSystemAbilityStub::switchInputMethod");
int32_t uid = IPCSkeleton::GetCallingUid();
int32_t userId = getUserId(uid);
MessageParcel *parcel = new MessageParcel();
auto *parcel = new (std::nothrow) MessageParcel();
if (parcel == nullptr) {
return ErrorCode::ERROR_EX_NULL_POINTER;
}
InputMethodProperty *target = InputMethodProperty::Unmarshalling(data);
parcel->WriteInt32(userId);
if (!target->Marshalling(*parcel)) {
@ -324,7 +328,10 @@ namespace MiscServices {
return ErrorCode::ERROR_IME_PROPERTY_MARSHALL;
}
delete target;
Message *msg = new Message(MSG_ID_SWITCH_INPUT_METHOD, parcel, &reply);
auto *msg = new (std::nothrow) Message(MSG_ID_SWITCH_INPUT_METHOD, parcel);
if (msg == nullptr) {
return ErrorCode::ERROR_EX_NULL_POINTER;
}
MessageHandler::Instance()->SendMessage(msg);
return ErrorCode::NO_ERROR;
}

View File

@ -30,10 +30,6 @@ namespace MiscServices {
}
}
Message::Message(int32_t msgId, MessageParcel *msgContent, MessageParcel *msgReply) : Message(msgId, msgContent)
{
msgReply_ = msgReply;
}
/*! Constructor
\param msg a source message
*/