use of com.android.internal.view.InputBindResult in project android_frameworks_base by ParanoidAndroid.
the class InputMethodManagerService method startInputInnerLocked.
InputBindResult startInputInnerLocked() {
if (mCurMethodId == null) {
return mNoBinding;
}
if (!mSystemReady) {
// party code.
return new InputBindResult(null, null, mCurMethodId, mCurSeq);
}
InputMethodInfo info = mMethodMap.get(mCurMethodId);
if (info == null) {
throw new IllegalArgumentException("Unknown id: " + mCurMethodId);
}
unbindCurrentMethodLocked(false, true);
mCurIntent = new Intent(InputMethod.SERVICE_INTERFACE);
mCurIntent.setComponent(info.getComponent());
mCurIntent.putExtra(Intent.EXTRA_CLIENT_LABEL, com.android.internal.R.string.input_method_binding_label);
mCurIntent.putExtra(Intent.EXTRA_CLIENT_INTENT, PendingIntent.getActivity(mContext, 0, new Intent(Settings.ACTION_INPUT_METHOD_SETTINGS), 0));
if (bindCurrentInputMethodService(mCurIntent, this, Context.BIND_AUTO_CREATE | Context.BIND_NOT_VISIBLE)) {
mLastBindTime = SystemClock.uptimeMillis();
mHaveConnection = true;
mCurId = info.getId();
mCurToken = new Binder();
try {
if (true || DEBUG)
Slog.v(TAG, "Adding window token: " + mCurToken);
mIWindowManager.addWindowToken(mCurToken, WindowManager.LayoutParams.TYPE_INPUT_METHOD);
} catch (RemoteException e) {
}
return new InputBindResult(null, null, mCurId, mCurSeq);
} else {
mCurIntent = null;
Slog.w(TAG, "Failure connecting to input method service: " + mCurIntent);
}
return null;
}
use of com.android.internal.view.InputBindResult in project android_frameworks_base by ParanoidAndroid.
the class InputMethodManagerService method handleMessage.
@Override
public boolean handleMessage(Message msg) {
SomeArgs args;
switch(msg.what) {
case MSG_SHOW_IM_PICKER:
showInputMethodMenu();
return true;
case MSG_SHOW_IM_SUBTYPE_PICKER:
showInputMethodSubtypeMenu();
return true;
case MSG_SHOW_IM_SUBTYPE_ENABLER:
args = (SomeArgs) msg.obj;
showInputMethodAndSubtypeEnabler((String) args.arg1);
args.recycle();
return true;
case MSG_SHOW_IM_CONFIG:
showConfigureInputMethods();
return true;
case MSG_UNBIND_INPUT:
try {
((IInputMethod) msg.obj).unbindInput();
} catch (RemoteException e) {
// There is nothing interesting about the method dying.
}
return true;
case MSG_BIND_INPUT:
args = (SomeArgs) msg.obj;
try {
((IInputMethod) args.arg1).bindInput((InputBinding) args.arg2);
} catch (RemoteException e) {
}
args.recycle();
return true;
case MSG_SHOW_SOFT_INPUT:
args = (SomeArgs) msg.obj;
try {
if (DEBUG)
Slog.v(TAG, "Calling " + args.arg1 + ".showSoftInput(" + msg.arg1 + ", " + args.arg2 + ")");
((IInputMethod) args.arg1).showSoftInput(msg.arg1, (ResultReceiver) args.arg2);
} catch (RemoteException e) {
}
args.recycle();
return true;
case MSG_HIDE_SOFT_INPUT:
args = (SomeArgs) msg.obj;
try {
if (DEBUG)
Slog.v(TAG, "Calling " + args.arg1 + ".hideSoftInput(0, " + args.arg2 + ")");
((IInputMethod) args.arg1).hideSoftInput(0, (ResultReceiver) args.arg2);
} catch (RemoteException e) {
}
args.recycle();
return true;
case MSG_ATTACH_TOKEN:
args = (SomeArgs) msg.obj;
try {
if (DEBUG)
Slog.v(TAG, "Sending attach of token: " + args.arg2);
((IInputMethod) args.arg1).attachToken((IBinder) args.arg2);
} catch (RemoteException e) {
}
args.recycle();
return true;
case MSG_CREATE_SESSION:
{
args = (SomeArgs) msg.obj;
IInputMethod method = (IInputMethod) args.arg1;
InputChannel channel = (InputChannel) args.arg2;
try {
method.createSession(channel, (IInputSessionCallback) args.arg3);
} catch (RemoteException e) {
} finally {
// because the remote proxy will get its own copy when unparceled.
if (channel != null && Binder.isProxy(method)) {
channel.dispose();
}
}
args.recycle();
return true;
}
case MSG_START_INPUT:
args = (SomeArgs) msg.obj;
try {
SessionState session = (SessionState) args.arg1;
setEnabledSessionInMainThread(session);
session.method.startInput((IInputContext) args.arg2, (EditorInfo) args.arg3);
} catch (RemoteException e) {
}
args.recycle();
return true;
case MSG_RESTART_INPUT:
args = (SomeArgs) msg.obj;
try {
SessionState session = (SessionState) args.arg1;
setEnabledSessionInMainThread(session);
session.method.restartInput((IInputContext) args.arg2, (EditorInfo) args.arg3);
} catch (RemoteException e) {
}
args.recycle();
return true;
case MSG_UNBIND_METHOD:
try {
((IInputMethodClient) msg.obj).onUnbindMethod(msg.arg1);
} catch (RemoteException e) {
// There is nothing interesting about the last client dying.
}
return true;
case MSG_BIND_METHOD:
{
args = (SomeArgs) msg.obj;
IInputMethodClient client = (IInputMethodClient) args.arg1;
InputBindResult res = (InputBindResult) args.arg2;
try {
client.onBindMethod(res);
} catch (RemoteException e) {
Slog.w(TAG, "Client died receiving input method " + args.arg2);
} finally {
// because the remote proxy will get its own copy when unparceled.
if (res.channel != null && Binder.isProxy(client)) {
res.channel.dispose();
}
}
args.recycle();
return true;
}
case MSG_SET_ACTIVE:
try {
((ClientState) msg.obj).client.setActive(msg.arg1 != 0);
} catch (RemoteException e) {
Slog.w(TAG, "Got RemoteException sending setActive(false) notification to pid " + ((ClientState) msg.obj).pid + " uid " + ((ClientState) msg.obj).uid);
}
return true;
// --------------------------------------------------------------
case MSG_HARD_KEYBOARD_SWITCH_CHANGED:
mHardKeyboardListener.handleHardKeyboardStatusChange(msg.arg1 == 1, msg.arg2 == 1);
return true;
}
return false;
}
use of com.android.internal.view.InputBindResult in project android_frameworks_base by ParanoidAndroid.
the class InputMethodManager method startInputInner.
boolean startInputInner(IBinder windowGainingFocus, int controlFlags, int softInputMode, int windowFlags) {
final View view;
synchronized (mH) {
view = mServedView;
// Make sure we have a window token for the served view.
if (DEBUG)
Log.v(TAG, "Starting input: view=" + view);
if (view == null) {
if (DEBUG)
Log.v(TAG, "ABORT input: no served view!");
return false;
}
}
// Now we need to get an input connection from the served view.
// This is complicated in a couple ways: we can't be holding our lock
// when calling out to the view, and we need to make sure we call into
// the view on the same thread that is driving its view hierarchy.
Handler vh = view.getHandler();
if (vh == null) {
// screen without a connection.
if (DEBUG)
Log.v(TAG, "ABORT input: no handler for view! Close current input.");
closeCurrentInput();
return false;
}
if (vh.getLooper() != Looper.myLooper()) {
// we need to reschedule our work for over there.
if (DEBUG)
Log.v(TAG, "Starting input: reschedule to view thread");
vh.post(new Runnable() {
@Override
public void run() {
startInputInner(null, 0, 0, 0);
}
});
return false;
}
// Okay we are now ready to call into the served view and have it
// do its stuff.
// Life is good: let's hook everything up!
EditorInfo tba = new EditorInfo();
tba.packageName = view.getContext().getPackageName();
tba.fieldId = view.getId();
InputConnection ic = view.onCreateInputConnection(tba);
if (DEBUG)
Log.v(TAG, "Starting input: tba=" + tba + " ic=" + ic);
synchronized (mH) {
// changed.
if (mServedView != view || !mServedConnecting) {
// Something else happened, so abort.
if (DEBUG)
Log.v(TAG, "Starting input: finished by someone else (view=" + mServedView + " conn=" + mServedConnecting + ")");
return false;
}
// connected so we want to restart it.
if (mCurrentTextBoxAttribute == null) {
controlFlags |= CONTROL_START_INITIAL;
}
// Hook 'em up and let 'er rip.
mCurrentTextBoxAttribute = tba;
mServedConnecting = false;
// Notify the served view that its previous input connection is finished
notifyInputConnectionFinished();
mServedInputConnection = ic;
ControlledInputConnectionWrapper servedContext;
if (ic != null) {
mCursorSelStart = tba.initialSelStart;
mCursorSelEnd = tba.initialSelEnd;
mCursorCandStart = -1;
mCursorCandEnd = -1;
mCursorRect.setEmpty();
servedContext = new ControlledInputConnectionWrapper(vh.getLooper(), ic, this);
} else {
servedContext = null;
}
if (mServedInputConnectionWrapper != null) {
mServedInputConnectionWrapper.deactivate();
}
mServedInputConnectionWrapper = servedContext;
try {
if (DEBUG)
Log.v(TAG, "START INPUT: " + view + " ic=" + ic + " tba=" + tba + " controlFlags=#" + Integer.toHexString(controlFlags));
InputBindResult res;
if (windowGainingFocus != null) {
res = mService.windowGainedFocus(mClient, windowGainingFocus, controlFlags, softInputMode, windowFlags, tba, servedContext);
} else {
res = mService.startInput(mClient, servedContext, tba, controlFlags);
}
if (DEBUG)
Log.v(TAG, "Starting input: Bind result=" + res);
if (res != null) {
if (res.id != null) {
setInputChannelLocked(res.channel);
mBindSequence = res.sequence;
mCurMethod = res.method;
mCurId = res.id;
} else {
if (res.channel != null && res.channel != mCurChannel) {
res.channel.dispose();
}
if (mCurMethod == null) {
// This means there is no input method available.
if (DEBUG)
Log.v(TAG, "ABORT input: no input method!");
return true;
}
}
}
if (mCurMethod != null && mCompletions != null) {
try {
mCurMethod.displayCompletions(mCompletions);
} catch (RemoteException e) {
}
}
} catch (RemoteException e) {
Log.w(TAG, "IME died: " + mCurId, e);
}
}
return true;
}
use of com.android.internal.view.InputBindResult in project android_frameworks_base by DirtyUnicorns.
the class InputMethodManagerService method windowGainedFocus.
private InputBindResult windowGainedFocus(/* @InputMethodClient.StartInputReason */
final int startInputReason, IInputMethodClient client, IBinder windowToken, int controlFlags, int softInputMode, int windowFlags, EditorInfo attribute, IInputContext inputContext, /* @InputConnectionInspector.missingMethods */
final int missingMethods) {
// Needs to check the validity before clearing calling identity
final boolean calledFromValidUser = calledFromValidUser();
InputBindResult res = null;
long ident = Binder.clearCallingIdentity();
try {
synchronized (mMethodMap) {
if (DEBUG)
Slog.v(TAG, "windowGainedFocus: reason=" + InputMethodClient.getStartInputReason(startInputReason) + " client=" + client.asBinder() + " inputContext=" + inputContext + " missingMethods=" + InputConnectionInspector.getMissingMethodFlagsAsString(missingMethods) + " attribute=" + attribute + " controlFlags=#" + Integer.toHexString(controlFlags) + " softInputMode=#" + Integer.toHexString(softInputMode) + " windowFlags=#" + Integer.toHexString(windowFlags));
ClientState cs = mClients.get(client.asBinder());
if (cs == null) {
throw new IllegalArgumentException("unknown client " + client.asBinder());
}
try {
if (!mIWindowManager.inputMethodClientHasFocus(cs.client)) {
// Check with the window manager to make sure this client actually
// has a window with focus. If not, reject. This is thread safe
// because if the focus changes some time before or after, the
// next client receiving focus that has any interest in input will
// be calling through here after that change happens.
Slog.w(TAG, "Focus gain on non-focused client " + cs.client + " (uid=" + cs.uid + " pid=" + cs.pid + ")");
return null;
}
} catch (RemoteException e) {
}
if (!calledFromValidUser) {
Slog.w(TAG, "A background user is requesting window. Hiding IME.");
Slog.w(TAG, "If you want to interect with IME, you need " + "android.permission.INTERACT_ACROSS_USERS_FULL");
hideCurrentInputLocked(0, null);
return null;
}
if (mCurFocusedWindow == windowToken) {
Slog.w(TAG, "Window already focused, ignoring focus gain of: " + client + " attribute=" + attribute + ", token = " + windowToken);
if (attribute != null) {
return startInputUncheckedLocked(cs, inputContext, missingMethods, attribute, controlFlags);
}
return null;
}
mCurFocusedWindow = windowToken;
mCurFocusedWindowClient = cs;
// Should we auto-show the IME even if the caller has not
// specified what should be done with it?
// We only do this automatically if the window can resize
// to accommodate the IME (so what the user sees will give
// them good context without input information being obscured
// by the IME) or if running on a large screen where there
// is more room for the target window + IME.
final boolean doAutoShow = (softInputMode & WindowManager.LayoutParams.SOFT_INPUT_MASK_ADJUST) == WindowManager.LayoutParams.SOFT_INPUT_ADJUST_RESIZE || mRes.getConfiguration().isLayoutSizeAtLeast(Configuration.SCREENLAYOUT_SIZE_LARGE);
final boolean isTextEditor = (controlFlags & InputMethodManager.CONTROL_WINDOW_IS_TEXT_EDITOR) != 0;
// We want to start input before showing the IME, but after closing
// it. We want to do this after closing it to help the IME disappear
// more quickly (not get stuck behind it initializing itself for the
// new focused input, even if its window wants to hide the IME).
boolean didStart = false;
switch(softInputMode & WindowManager.LayoutParams.SOFT_INPUT_MASK_STATE) {
case WindowManager.LayoutParams.SOFT_INPUT_STATE_UNSPECIFIED:
if (!isTextEditor || !doAutoShow) {
if (WindowManager.LayoutParams.mayUseInputMethod(windowFlags)) {
// soft input window if it is shown.
if (DEBUG)
Slog.v(TAG, "Unspecified window will hide input");
hideCurrentInputLocked(InputMethodManager.HIDE_NOT_ALWAYS, null);
}
} else if (isTextEditor && doAutoShow && (softInputMode & WindowManager.LayoutParams.SOFT_INPUT_IS_FORWARD_NAVIGATION) != 0) {
// is more room for the target window + IME.
if (DEBUG)
Slog.v(TAG, "Unspecified window will show input");
if (attribute != null) {
res = startInputUncheckedLocked(cs, inputContext, missingMethods, attribute, controlFlags);
didStart = true;
}
showCurrentInputLocked(InputMethodManager.SHOW_IMPLICIT, null);
}
break;
case WindowManager.LayoutParams.SOFT_INPUT_STATE_UNCHANGED:
// Do nothing.
break;
case WindowManager.LayoutParams.SOFT_INPUT_STATE_HIDDEN:
if ((softInputMode & WindowManager.LayoutParams.SOFT_INPUT_IS_FORWARD_NAVIGATION) != 0) {
if (DEBUG)
Slog.v(TAG, "Window asks to hide input going forward");
hideCurrentInputLocked(0, null);
}
break;
case WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_HIDDEN:
if (DEBUG)
Slog.v(TAG, "Window asks to hide input");
hideCurrentInputLocked(0, null);
break;
case WindowManager.LayoutParams.SOFT_INPUT_STATE_VISIBLE:
if ((softInputMode & WindowManager.LayoutParams.SOFT_INPUT_IS_FORWARD_NAVIGATION) != 0) {
if (DEBUG)
Slog.v(TAG, "Window asks to show input going forward");
if (attribute != null) {
res = startInputUncheckedLocked(cs, inputContext, missingMethods, attribute, controlFlags);
didStart = true;
}
showCurrentInputLocked(InputMethodManager.SHOW_IMPLICIT, null);
}
break;
case WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_VISIBLE:
if (DEBUG)
Slog.v(TAG, "Window asks to always show input");
if (attribute != null) {
res = startInputUncheckedLocked(cs, inputContext, missingMethods, attribute, controlFlags);
didStart = true;
}
showCurrentInputLocked(InputMethodManager.SHOW_IMPLICIT, null);
break;
}
if (!didStart && attribute != null) {
res = startInputUncheckedLocked(cs, inputContext, missingMethods, attribute, controlFlags);
}
}
} finally {
Binder.restoreCallingIdentity(ident);
}
return res;
}
use of com.android.internal.view.InputBindResult in project android_frameworks_base by DirtyUnicorns.
the class InputMethodManagerService method handleMessage.
@Override
public boolean handleMessage(Message msg) {
SomeArgs args;
switch(msg.what) {
case MSG_SHOW_IM_SUBTYPE_PICKER:
final boolean showAuxSubtypes;
switch(msg.arg1) {
case InputMethodManager.SHOW_IM_PICKER_MODE_AUTO:
// This is undocumented so far, but IMM#showInputMethodPicker() has been
// implemented so that auxiliary subtypes will be excluded when the soft
// keyboard is invisible.
showAuxSubtypes = mInputShown;
break;
case InputMethodManager.SHOW_IM_PICKER_MODE_INCLUDE_AUXILIARY_SUBTYPES:
showAuxSubtypes = true;
break;
case InputMethodManager.SHOW_IM_PICKER_MODE_EXCLUDE_AUXILIARY_SUBTYPES:
showAuxSubtypes = false;
break;
default:
Slog.e(TAG, "Unknown subtype picker mode = " + msg.arg1);
return false;
}
showInputMethodMenu(showAuxSubtypes);
return true;
case MSG_SHOW_IM_SUBTYPE_ENABLER:
showInputMethodAndSubtypeEnabler((String) msg.obj);
return true;
case MSG_SHOW_IM_CONFIG:
showConfigureInputMethods();
return true;
case MSG_UNBIND_INPUT:
try {
((IInputMethod) msg.obj).unbindInput();
} catch (RemoteException e) {
// There is nothing interesting about the method dying.
}
return true;
case MSG_BIND_INPUT:
args = (SomeArgs) msg.obj;
try {
((IInputMethod) args.arg1).bindInput((InputBinding) args.arg2);
} catch (RemoteException e) {
}
args.recycle();
return true;
case MSG_SHOW_SOFT_INPUT:
args = (SomeArgs) msg.obj;
try {
if (DEBUG)
Slog.v(TAG, "Calling " + args.arg1 + ".showSoftInput(" + msg.arg1 + ", " + args.arg2 + ")");
((IInputMethod) args.arg1).showSoftInput(msg.arg1, (ResultReceiver) args.arg2);
} catch (RemoteException e) {
}
args.recycle();
return true;
case MSG_HIDE_SOFT_INPUT:
args = (SomeArgs) msg.obj;
try {
if (DEBUG)
Slog.v(TAG, "Calling " + args.arg1 + ".hideSoftInput(0, " + args.arg2 + ")");
((IInputMethod) args.arg1).hideSoftInput(0, (ResultReceiver) args.arg2);
} catch (RemoteException e) {
}
args.recycle();
return true;
case MSG_HIDE_CURRENT_INPUT_METHOD:
synchronized (mMethodMap) {
hideCurrentInputLocked(0, null);
}
return true;
case MSG_ATTACH_TOKEN:
args = (SomeArgs) msg.obj;
try {
if (DEBUG)
Slog.v(TAG, "Sending attach of token: " + args.arg2);
((IInputMethod) args.arg1).attachToken((IBinder) args.arg2);
} catch (RemoteException e) {
}
args.recycle();
return true;
case MSG_CREATE_SESSION:
{
args = (SomeArgs) msg.obj;
IInputMethod method = (IInputMethod) args.arg1;
InputChannel channel = (InputChannel) args.arg2;
try {
method.createSession(channel, (IInputSessionCallback) args.arg3);
} catch (RemoteException e) {
} finally {
// because the remote proxy will get its own copy when unparceled.
if (channel != null && Binder.isProxy(method)) {
channel.dispose();
}
}
args.recycle();
return true;
}
case MSG_START_INPUT:
{
int missingMethods = msg.arg1;
args = (SomeArgs) msg.obj;
try {
SessionState session = (SessionState) args.arg1;
setEnabledSessionInMainThread(session);
session.method.startInput((IInputContext) args.arg2, missingMethods, (EditorInfo) args.arg3);
} catch (RemoteException e) {
}
args.recycle();
return true;
}
case MSG_RESTART_INPUT:
{
int missingMethods = msg.arg1;
args = (SomeArgs) msg.obj;
try {
SessionState session = (SessionState) args.arg1;
setEnabledSessionInMainThread(session);
session.method.restartInput((IInputContext) args.arg2, missingMethods, (EditorInfo) args.arg3);
} catch (RemoteException e) {
}
args.recycle();
return true;
}
case MSG_UNBIND_CLIENT:
try {
((IInputMethodClient) msg.obj).onUnbindMethod(msg.arg1, msg.arg2);
} catch (RemoteException e) {
// There is nothing interesting about the last client dying.
}
return true;
case MSG_BIND_CLIENT:
{
args = (SomeArgs) msg.obj;
IInputMethodClient client = (IInputMethodClient) args.arg1;
InputBindResult res = (InputBindResult) args.arg2;
try {
client.onBindMethod(res);
} catch (RemoteException e) {
Slog.w(TAG, "Client died receiving input method " + args.arg2);
} finally {
// because the remote proxy will get its own copy when unparceled.
if (res.channel != null && Binder.isProxy(client)) {
res.channel.dispose();
}
}
args.recycle();
return true;
}
case MSG_SET_ACTIVE:
try {
((ClientState) msg.obj).client.setActive(msg.arg1 != 0);
} catch (RemoteException e) {
Slog.w(TAG, "Got RemoteException sending setActive(false) notification to pid " + ((ClientState) msg.obj).pid + " uid " + ((ClientState) msg.obj).uid);
}
return true;
case MSG_SET_INTERACTIVE:
handleSetInteractive(msg.arg1 != 0);
return true;
case MSG_SWITCH_IME:
handleSwitchInputMethod(msg.arg1 != 0);
return true;
case MSG_SET_USER_ACTION_NOTIFICATION_SEQUENCE_NUMBER:
{
final int sequenceNumber = msg.arg1;
final ClientState clientState = (ClientState) msg.obj;
try {
clientState.client.setUserActionNotificationSequenceNumber(sequenceNumber);
} catch (RemoteException e) {
Slog.w(TAG, "Got RemoteException sending " + "setUserActionNotificationSequenceNumber(" + sequenceNumber + ") notification to pid " + clientState.pid + " uid " + clientState.uid);
}
return true;
}
// --------------------------------------------------------------
case MSG_HARD_KEYBOARD_SWITCH_CHANGED:
mHardKeyboardListener.handleHardKeyboardStatusChange(msg.arg1 == 1);
return true;
case MSG_SYSTEM_UNLOCK_USER:
final int userId = msg.arg1;
onUnlockUser(userId);
return true;
}
return false;
}
Aggregations