Loading services/core/java/com/android/server/InputMethodManagerService.java +97 −87 Original line number Diff line number Diff line Loading @@ -398,6 +398,23 @@ public class InputMethodManagerService extends IInputMethodManager.Stub int mCurUserActionNotificationSequenceNumber = 0; int mBackDisposition = InputMethodService.BACK_DISPOSITION_DEFAULT; /** * A set of status bits regarding the active IME. * * <p>This value is a combination of following two bits:</p> * <dl> * <dt>{@link InputMethodService#IME_ACTIVE}</dt> * <dd> * If this bit is ON, connected IME is ready to accept touch/key events. * </dd> * <dt>{@link InputMethodService#IME_VISIBLE}</dt> * <dd> * If this bit is ON, some of IME view, e.g. software input, candidate view, is visible. * </dd> * </dl> * <em>Do not update this value outside of setImeWindowStatus.</em> */ int mImeWindowVis; private AlertDialog.Builder mDialogBuilder; Loading Loading @@ -459,12 +476,12 @@ public class InputMethodManagerService extends IInputMethodManager.Stub final String action = intent.getAction(); if (Intent.ACTION_SCREEN_ON.equals(action)) { mScreenOn = true; refreshImeWindowVisibilityLocked(); updateSystemUi(mCurToken, mImeWindowVis, mBackDisposition); updateActive(); return; } else if (Intent.ACTION_SCREEN_OFF.equals(action)) { mScreenOn = false; setImeWindowVisibilityStatusHiddenLocked(); updateSystemUi(mCurToken, 0 /* vis */, mBackDisposition); updateActive(); return; } else if (Intent.ACTION_CLOSE_SYSTEM_DIALOGS.equals(action)) { Loading Loading @@ -660,7 +677,7 @@ public class InputMethodManagerService extends IInputMethodManager.Stub // Uh oh, current input method is no longer around! // Pick another one... Slog.i(TAG, "Current input method removed: " + curInputMethodId); setImeWindowVisibilityStatusHiddenLocked(); updateSystemUiLocked(mCurToken, 0 /* vis */, mBackDisposition); if (!chooseNewDefaultIMELocked()) { changed = true; curIm = null; Loading Loading @@ -1003,7 +1020,7 @@ public class InputMethodManagerService extends IInputMethodManager.Stub mContext.getSystemService(Context.NOTIFICATION_SERVICE); mStatusBar = statusBar; statusBar.setIconVisibility("ime", false); updateImeWindowStatusLocked(); updateSystemUiLocked(mCurToken, mImeWindowVis, mBackDisposition); mShowOngoingImeSwitcherForPhones = mRes.getBoolean( com.android.internal.R.bool.show_ongoing_ime_switcher); if (mShowOngoingImeSwitcherForPhones) { Loading @@ -1029,33 +1046,6 @@ public class InputMethodManagerService extends IInputMethodManager.Stub } } private void setImeWindowVisibilityStatusHiddenLocked() { mImeWindowVis = 0; updateImeWindowStatusLocked(); } private void refreshImeWindowVisibilityLocked() { final Configuration conf = mRes.getConfiguration(); final boolean haveHardKeyboard = conf.keyboard != Configuration.KEYBOARD_NOKEYS; final boolean hardKeyShown = haveHardKeyboard && conf.hardKeyboardHidden != Configuration.HARDKEYBOARDHIDDEN_YES; final boolean isScreenLocked = isKeyguardLocked(); final boolean inputActive = !isScreenLocked && (mInputShown || hardKeyShown); // We assume the softkeyboard is shown when the input is active as long as the // hard keyboard is not shown. final boolean inputVisible = inputActive && !hardKeyShown; mImeWindowVis = (inputActive ? InputMethodService.IME_ACTIVE : 0) | (inputVisible ? InputMethodService.IME_VISIBLE : 0); updateImeWindowStatusLocked(); } private void updateImeWindowStatusLocked() { setImeWindowStatus(mCurToken, mImeWindowVis, mBackDisposition); } // --------------------------------------------------------------------------------------- // Check whether or not this is a valid IPC. Assumes an IPC is valid when either // 1) it comes from the system process Loading Loading @@ -1541,7 +1531,7 @@ public class InputMethodManagerService extends IInputMethodManager.Stub sessionState.session.finishSession(); } catch (RemoteException e) { Slog.w(TAG, "Session failed to close due to remote exception", e); setImeWindowVisibilityStatusHiddenLocked(); updateSystemUiLocked(mCurToken, 0 /* vis */, mBackDisposition); } sessionState.session = null; } Loading Loading @@ -1629,11 +1619,11 @@ public class InputMethodManagerService extends IInputMethodManager.Stub } } private boolean shouldShowImeSwitcherLocked() { private boolean shouldShowImeSwitcherLocked(int visibility) { if (!mShowOngoingImeSwitcherForPhones) return false; if (mSwitchingDialog != null) return false; if (isScreenLocked()) return false; if ((mImeWindowVis & InputMethodService.IME_ACTIVE) == 0) return false; if ((visibility & InputMethodService.IME_ACTIVE) == 0) return false; if (mWindowManagerService.isHardKeyboardAvailable()) { // When physical keyboard is attached, we show the ime switcher (or notification if // NavBar is not available) because SHOW_IME_WITH_HARD_KEYBOARD settings currently Loading @@ -1641,7 +1631,7 @@ public class InputMethodManagerService extends IInputMethodManager.Stub // SHOW_IME_WITH_HARD_KEYBOARD settings finds a good place to live. return true; } if ((mImeWindowVis & InputMethodService.IME_VISIBLE) == 0) return false; if ((visibility & InputMethodService.IME_VISIBLE) == 0) return false; List<InputMethodInfo> imis = mSettings.getEnabledInputMethodListLocked(); final int N = imis.size(); Loading Loading @@ -1690,27 +1680,48 @@ public class InputMethodManagerService extends IInputMethodManager.Stub return mKeyguardManager != null && mKeyguardManager.isKeyguardLocked(); } // Caution! This method is called in this class. Handle multi-user carefully @SuppressWarnings("deprecation") @Override public void setImeWindowStatus(IBinder token, int vis, int backDisposition) { final long ident = Binder.clearCallingIdentity(); try { if (!calledWithValidToken(token)) { final int uid = Binder.getCallingUid(); Slog.e(TAG, "Ignoring setImeWindowStatus due to an invalid token. uid:" + uid + " token:" + token); return; } synchronized (mMethodMap) { mImeWindowVis = vis; mBackDisposition = backDisposition; updateSystemUiLocked(token, vis, backDisposition); } } private void updateSystemUi(IBinder token, int vis, int backDisposition) { synchronized (mMethodMap) { updateSystemUiLocked(token, vis, backDisposition); } } // Caution! This method is called in this class. Handle multi-user carefully private void updateSystemUiLocked(IBinder token, int vis, int backDisposition) { if (!calledWithValidToken(token)) { final int uid = Binder.getCallingUid(); Slog.e(TAG, "Ignoring updateSystemUiLocked due to an invalid token. uid:" + uid + " token:" + token); return; } // TODO: Move this clearing calling identity block to setImeWindowStatus after making sure // all updateSystemUi happens on system previlege. final long ident = Binder.clearCallingIdentity(); try { // apply policy for binder calls if (vis != 0 && isKeyguardLocked() && !mCurClientInKeyguard) { vis = 0; } mImeWindowVis = vis; mBackDisposition = backDisposition; // mImeWindowVis should be updated before calling shouldShowImeSwitcherLocked(). final boolean needsToShowImeSwitcher = shouldShowImeSwitcherLocked(); final boolean needsToShowImeSwitcher = shouldShowImeSwitcherLocked(vis); if (mStatusBar != null) { mStatusBar.setImeWindowStatus(token, vis, backDisposition, needsToShowImeSwitcher); Loading Loading @@ -1747,7 +1758,6 @@ public class InputMethodManagerService extends IInputMethodManager.Stub mNotificationShown = false; } } } } finally { Binder.restoreCallingIdentity(ident); } Loading Loading @@ -1912,7 +1922,7 @@ public class InputMethodManagerService extends IInputMethodManager.Stub setSelectedInputMethodAndSubtypeLocked(info, subtypeId, true); if (mCurMethod != null) { try { refreshImeWindowVisibilityLocked(); updateSystemUiLocked(mCurToken, mImeWindowVis, mBackDisposition); mCurMethod.changeInputMethodSubtype(newSubtype); } catch (RemoteException e) { Slog.w(TAG, "Failed to call changeInputMethodSubtype"); Loading Loading @@ -2074,7 +2084,7 @@ public class InputMethodManagerService extends IInputMethodManager.Stub return false; } boolean res; if (mInputShown && mCurMethod != null) { if ((mImeWindowVis & InputMethodService.IME_ACTIVE) != 0 && mCurMethod != null) { executeOrSendMessage(mCurMethod, mCaller.obtainMessageOO( MSG_HIDE_SOFT_INPUT, mCurMethod, resultReceiver)); res = true; Loading Loading @@ -3048,7 +3058,7 @@ public class InputMethodManagerService extends IInputMethodManager.Stub mSwitchingDialog.getWindow().getAttributes().privateFlags |= WindowManager.LayoutParams.PRIVATE_FLAG_SHOW_FOR_ALL_USERS; mSwitchingDialog.getWindow().getAttributes().setTitle("Select input method"); updateImeWindowStatusLocked(); updateSystemUi(mCurToken, mImeWindowVis, mBackDisposition); mSwitchingDialog.show(); } } Loading Loading @@ -3107,7 +3117,7 @@ public class InputMethodManagerService extends IInputMethodManager.Stub mSwitchingDialog = null; } updateImeWindowStatusLocked(); updateSystemUiLocked(mCurToken, mImeWindowVis, mBackDisposition); mDialogBuilder = null; mIms = null; } Loading Loading
services/core/java/com/android/server/InputMethodManagerService.java +97 −87 Original line number Diff line number Diff line Loading @@ -398,6 +398,23 @@ public class InputMethodManagerService extends IInputMethodManager.Stub int mCurUserActionNotificationSequenceNumber = 0; int mBackDisposition = InputMethodService.BACK_DISPOSITION_DEFAULT; /** * A set of status bits regarding the active IME. * * <p>This value is a combination of following two bits:</p> * <dl> * <dt>{@link InputMethodService#IME_ACTIVE}</dt> * <dd> * If this bit is ON, connected IME is ready to accept touch/key events. * </dd> * <dt>{@link InputMethodService#IME_VISIBLE}</dt> * <dd> * If this bit is ON, some of IME view, e.g. software input, candidate view, is visible. * </dd> * </dl> * <em>Do not update this value outside of setImeWindowStatus.</em> */ int mImeWindowVis; private AlertDialog.Builder mDialogBuilder; Loading Loading @@ -459,12 +476,12 @@ public class InputMethodManagerService extends IInputMethodManager.Stub final String action = intent.getAction(); if (Intent.ACTION_SCREEN_ON.equals(action)) { mScreenOn = true; refreshImeWindowVisibilityLocked(); updateSystemUi(mCurToken, mImeWindowVis, mBackDisposition); updateActive(); return; } else if (Intent.ACTION_SCREEN_OFF.equals(action)) { mScreenOn = false; setImeWindowVisibilityStatusHiddenLocked(); updateSystemUi(mCurToken, 0 /* vis */, mBackDisposition); updateActive(); return; } else if (Intent.ACTION_CLOSE_SYSTEM_DIALOGS.equals(action)) { Loading Loading @@ -660,7 +677,7 @@ public class InputMethodManagerService extends IInputMethodManager.Stub // Uh oh, current input method is no longer around! // Pick another one... Slog.i(TAG, "Current input method removed: " + curInputMethodId); setImeWindowVisibilityStatusHiddenLocked(); updateSystemUiLocked(mCurToken, 0 /* vis */, mBackDisposition); if (!chooseNewDefaultIMELocked()) { changed = true; curIm = null; Loading Loading @@ -1003,7 +1020,7 @@ public class InputMethodManagerService extends IInputMethodManager.Stub mContext.getSystemService(Context.NOTIFICATION_SERVICE); mStatusBar = statusBar; statusBar.setIconVisibility("ime", false); updateImeWindowStatusLocked(); updateSystemUiLocked(mCurToken, mImeWindowVis, mBackDisposition); mShowOngoingImeSwitcherForPhones = mRes.getBoolean( com.android.internal.R.bool.show_ongoing_ime_switcher); if (mShowOngoingImeSwitcherForPhones) { Loading @@ -1029,33 +1046,6 @@ public class InputMethodManagerService extends IInputMethodManager.Stub } } private void setImeWindowVisibilityStatusHiddenLocked() { mImeWindowVis = 0; updateImeWindowStatusLocked(); } private void refreshImeWindowVisibilityLocked() { final Configuration conf = mRes.getConfiguration(); final boolean haveHardKeyboard = conf.keyboard != Configuration.KEYBOARD_NOKEYS; final boolean hardKeyShown = haveHardKeyboard && conf.hardKeyboardHidden != Configuration.HARDKEYBOARDHIDDEN_YES; final boolean isScreenLocked = isKeyguardLocked(); final boolean inputActive = !isScreenLocked && (mInputShown || hardKeyShown); // We assume the softkeyboard is shown when the input is active as long as the // hard keyboard is not shown. final boolean inputVisible = inputActive && !hardKeyShown; mImeWindowVis = (inputActive ? InputMethodService.IME_ACTIVE : 0) | (inputVisible ? InputMethodService.IME_VISIBLE : 0); updateImeWindowStatusLocked(); } private void updateImeWindowStatusLocked() { setImeWindowStatus(mCurToken, mImeWindowVis, mBackDisposition); } // --------------------------------------------------------------------------------------- // Check whether or not this is a valid IPC. Assumes an IPC is valid when either // 1) it comes from the system process Loading Loading @@ -1541,7 +1531,7 @@ public class InputMethodManagerService extends IInputMethodManager.Stub sessionState.session.finishSession(); } catch (RemoteException e) { Slog.w(TAG, "Session failed to close due to remote exception", e); setImeWindowVisibilityStatusHiddenLocked(); updateSystemUiLocked(mCurToken, 0 /* vis */, mBackDisposition); } sessionState.session = null; } Loading Loading @@ -1629,11 +1619,11 @@ public class InputMethodManagerService extends IInputMethodManager.Stub } } private boolean shouldShowImeSwitcherLocked() { private boolean shouldShowImeSwitcherLocked(int visibility) { if (!mShowOngoingImeSwitcherForPhones) return false; if (mSwitchingDialog != null) return false; if (isScreenLocked()) return false; if ((mImeWindowVis & InputMethodService.IME_ACTIVE) == 0) return false; if ((visibility & InputMethodService.IME_ACTIVE) == 0) return false; if (mWindowManagerService.isHardKeyboardAvailable()) { // When physical keyboard is attached, we show the ime switcher (or notification if // NavBar is not available) because SHOW_IME_WITH_HARD_KEYBOARD settings currently Loading @@ -1641,7 +1631,7 @@ public class InputMethodManagerService extends IInputMethodManager.Stub // SHOW_IME_WITH_HARD_KEYBOARD settings finds a good place to live. return true; } if ((mImeWindowVis & InputMethodService.IME_VISIBLE) == 0) return false; if ((visibility & InputMethodService.IME_VISIBLE) == 0) return false; List<InputMethodInfo> imis = mSettings.getEnabledInputMethodListLocked(); final int N = imis.size(); Loading Loading @@ -1690,27 +1680,48 @@ public class InputMethodManagerService extends IInputMethodManager.Stub return mKeyguardManager != null && mKeyguardManager.isKeyguardLocked(); } // Caution! This method is called in this class. Handle multi-user carefully @SuppressWarnings("deprecation") @Override public void setImeWindowStatus(IBinder token, int vis, int backDisposition) { final long ident = Binder.clearCallingIdentity(); try { if (!calledWithValidToken(token)) { final int uid = Binder.getCallingUid(); Slog.e(TAG, "Ignoring setImeWindowStatus due to an invalid token. uid:" + uid + " token:" + token); return; } synchronized (mMethodMap) { mImeWindowVis = vis; mBackDisposition = backDisposition; updateSystemUiLocked(token, vis, backDisposition); } } private void updateSystemUi(IBinder token, int vis, int backDisposition) { synchronized (mMethodMap) { updateSystemUiLocked(token, vis, backDisposition); } } // Caution! This method is called in this class. Handle multi-user carefully private void updateSystemUiLocked(IBinder token, int vis, int backDisposition) { if (!calledWithValidToken(token)) { final int uid = Binder.getCallingUid(); Slog.e(TAG, "Ignoring updateSystemUiLocked due to an invalid token. uid:" + uid + " token:" + token); return; } // TODO: Move this clearing calling identity block to setImeWindowStatus after making sure // all updateSystemUi happens on system previlege. final long ident = Binder.clearCallingIdentity(); try { // apply policy for binder calls if (vis != 0 && isKeyguardLocked() && !mCurClientInKeyguard) { vis = 0; } mImeWindowVis = vis; mBackDisposition = backDisposition; // mImeWindowVis should be updated before calling shouldShowImeSwitcherLocked(). final boolean needsToShowImeSwitcher = shouldShowImeSwitcherLocked(); final boolean needsToShowImeSwitcher = shouldShowImeSwitcherLocked(vis); if (mStatusBar != null) { mStatusBar.setImeWindowStatus(token, vis, backDisposition, needsToShowImeSwitcher); Loading Loading @@ -1747,7 +1758,6 @@ public class InputMethodManagerService extends IInputMethodManager.Stub mNotificationShown = false; } } } } finally { Binder.restoreCallingIdentity(ident); } Loading Loading @@ -1912,7 +1922,7 @@ public class InputMethodManagerService extends IInputMethodManager.Stub setSelectedInputMethodAndSubtypeLocked(info, subtypeId, true); if (mCurMethod != null) { try { refreshImeWindowVisibilityLocked(); updateSystemUiLocked(mCurToken, mImeWindowVis, mBackDisposition); mCurMethod.changeInputMethodSubtype(newSubtype); } catch (RemoteException e) { Slog.w(TAG, "Failed to call changeInputMethodSubtype"); Loading Loading @@ -2074,7 +2084,7 @@ public class InputMethodManagerService extends IInputMethodManager.Stub return false; } boolean res; if (mInputShown && mCurMethod != null) { if ((mImeWindowVis & InputMethodService.IME_ACTIVE) != 0 && mCurMethod != null) { executeOrSendMessage(mCurMethod, mCaller.obtainMessageOO( MSG_HIDE_SOFT_INPUT, mCurMethod, resultReceiver)); res = true; Loading Loading @@ -3048,7 +3058,7 @@ public class InputMethodManagerService extends IInputMethodManager.Stub mSwitchingDialog.getWindow().getAttributes().privateFlags |= WindowManager.LayoutParams.PRIVATE_FLAG_SHOW_FOR_ALL_USERS; mSwitchingDialog.getWindow().getAttributes().setTitle("Select input method"); updateImeWindowStatusLocked(); updateSystemUi(mCurToken, mImeWindowVis, mBackDisposition); mSwitchingDialog.show(); } } Loading Loading @@ -3107,7 +3117,7 @@ public class InputMethodManagerService extends IInputMethodManager.Stub mSwitchingDialog = null; } updateImeWindowStatusLocked(); updateSystemUiLocked(mCurToken, mImeWindowVis, mBackDisposition); mDialogBuilder = null; mIms = null; } Loading