• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2021 Huawei Device Co., Ltd.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  *     http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 
16 #include "message_handler.h"
17 #include "input_control_channel_stub.h"
18 #include "i_input_control_channel.h"
19 #include "input_channel.h"
20 #include "input_method_agent_proxy.h"
21 #include "message_parcel.h"
22 
23 namespace OHOS {
24 namespace MiscServices {
25     /*! Constructor
26     \param userId the id of the user to whom the object is linking
27     */
InputControlChannelStub(int userId)28     InputControlChannelStub::InputControlChannelStub(int userId)
29     {
30         userId_ = userId;
31     }
32 
33     /*! Destructor
34     */
~InputControlChannelStub()35     InputControlChannelStub::~InputControlChannelStub()
36     {
37     }
38 
39     /*! Handle the transaction from the remote binder
40     \n Run in binder thread
41     \param code transaction code number
42     \param data the params from remote binder
43     \param[out] reply the result of the transaction replied to the remote binder
44     \param flags the flags of handling transaction
45     \return int32_t
46     */
OnRemoteRequest(uint32_t code,MessageParcel & data,MessageParcel & reply,MessageOption & option)47     int32_t InputControlChannelStub::OnRemoteRequest(uint32_t code, MessageParcel& data,
48                                                      MessageParcel& reply, MessageOption& option)
49     {
50         IMSA_HILOGI("InputControlChannelStub::OnRemoteRequest code = %{public}u", code);
51         auto descriptorToken = data.ReadInterfaceToken();
52         if (descriptorToken != GetDescriptor()) {
53             return ErrorCode::ERROR_STATUS_UNKNOWN_TRANSACTION;
54         }
55         switch (code) {
56             case HIDE_KEYBOARD_SELF: {
57                 int flag = data.ReadInt32();
58                 hideKeyboardSelf(flag);
59                 reply.WriteNoException();
60                 break;
61             }
62             case ADVANCE_TO_NEXT: {
63                 bool isCurrentIme = data.ReadInt32();
64                 bool ret = advanceToNext(isCurrentIme);
65                 reply.WriteNoException();
66                 reply.WriteBool(ret);
67                 break;
68             }
69             case SET_DISPLAY_MODE:  {
70                 int mode = data.ReadInt32();
71                 setDisplayMode(mode);
72                 reply.WriteNoException();
73                 break;
74             }
75             case ON_KEYBOARD_SHOWED: {
76                 onKeyboardShowed();
77                 reply.WriteNoException();
78                 break;
79             }
80             default: {
81                 return IRemoteStub::OnRemoteRequest(code, data, reply, option);
82             }
83         }
84         return NO_ERROR;
85     }
86 
87     /*! Called when input method service showed keyboard
88     \n This call is running in binder thread
89     */
onKeyboardShowed()90     void InputControlChannelStub::onKeyboardShowed()
91     {
92         IMSA_HILOGI("InputControlChannelStub::onKeyboardShowed");
93         {
94             std::unique_lock<std::mutex> lck(mtx);
95             keyboardReadyFlag = true;
96         }
97         cv.notify_one();
98     }
99 
100     /*! Send hideKeyboardSelf command to work thread.
101     \n This call is running in binder thread,
102         but the handling of hideKeyboardSelf is in the work thread of PerUserSession.
103     \see PerUserSession::OnHideKeyboardSelf
104     \param flags the flag value of hiding keyboard
105     */
hideKeyboardSelf(int flags)106     void InputControlChannelStub::hideKeyboardSelf(int flags)
107     {
108         IMSA_HILOGI("InputControlChannelStub::hideKeyboardSelf flags = %{public}d", flags);
109         MessageParcel *parcel = new MessageParcel();
110         parcel->WriteInt32(userId_);
111         parcel->WriteInt32(flags);
112 
113         Message *msg = new Message(MessageID::MSG_ID_HIDE_KEYBOARD_SELF, parcel);
114         MessageHandler::Instance()->SendMessage(msg);
115     }
116 
117     /*! Send advanceToNext command to work thread.
118     \n This call is running in binder thread,
119         but the handling of advanceToNext is in the work thread of InputMethodSystemAbility service
120     \n or in the work thread of PerUserSession
121     \see InputMethodSystemAbility::OnAdvanceToNext PerUserSession::OnAdvanceToNext
122     \see PerUserSetting::OnAdvanceToNext
123     \param isCurrentIme true - switch to next keyboard type within current input method engine
124                     \n false - switch to next input method engine
125     \return true
126     */
advanceToNext(bool isCurrentIme)127     bool InputControlChannelStub::advanceToNext(bool isCurrentIme)
128     {
129         IMSA_HILOGI("InputControlChannelStub::advanceToNext");
130         MessageParcel *parcel = new MessageParcel();
131         parcel->WriteInt32(userId_);
132         parcel->WriteBool(isCurrentIme);
133 
134         Message *msg = new Message(MessageID::MSG_ID_ADVANCE_TO_NEXT, parcel);
135         MessageHandler::Instance()->SendMessage(msg);
136         return true;
137     }
138 
139     /*! Send setDisplayMode command to work thread.
140     \n This call is running in binder thread,
141         but the handling of setDisplayMode is in the work thread of PerUserSession.
142     \see PerUserSession::OnSetDisplayMode
143     \param mode 0 - part screen mode, 1 - full screen mode
144     */
setDisplayMode(int mode)145     void InputControlChannelStub::setDisplayMode(int mode)
146     {
147         IMSA_HILOGI("InputControlChannelStub::setDisplayMode start");
148         MessageParcel *parcel = new MessageParcel();
149         parcel->WriteInt32(userId_);
150         parcel->WriteInt32(mode);
151 
152         Message *msg = new Message(MessageID::MSG_ID_SET_DISPLAY_MODE, parcel);
153         MessageHandler::Instance()->SendMessage(msg);
154     }
155 
156     /*! Reset ready flag to be false
157     \n This should be called before imsCore->startInput() in work thread of PerUserSession
158     */
ResetFlag()159     void InputControlChannelStub::ResetFlag()
160     {
161         IMSA_HILOGI("InputControlChannelStub::ResetFlag");
162         std::unique_lock<std::mutex> lck(mtx);
163         keyboardReadyFlag = false;
164         agentReadyFlag = false;
165     }
166 
167     /*! Wait for keyboard to be ready
168     \n This should be called in work thread of PerUserSession
169     \return true - onKeyboardShowed is called by input method service in time
170     \n false - onKeyboardShowed is not called by input method service in time
171     */
WaitKeyboardReady()172     bool InputControlChannelStub::WaitKeyboardReady()
173     {
174         IMSA_HILOGI("InputControlChannelStub::WaitKeyboardReady");
175         std::chrono::milliseconds millsec(sleepTime);
176         bool ret = false;
177         {
178             std::unique_lock<std::mutex> lck(mtx);
179             ret = cv.wait_for(lck, millsec, [this] {
180                 return keyboardReadyFlag;
181             });
182         }
183         return ret;
184     }
185 }
186 }
187