am ac1f0a1a: Merge "Hide the software input based on its state." into mnc-dev

* commit 'ac1f0a1a9169f8bbbddba68b0410d5530512da63':
  Hide the software input based on its state.
This commit is contained in:
Seigo Nonaka
2015-06-02 08:07:53 +00:00
committed by Android Git Automerger

View File

@@ -398,6 +398,23 @@ public class InputMethodManagerService extends IInputMethodManager.Stub
int mCurUserActionNotificationSequenceNumber = 0; int mCurUserActionNotificationSequenceNumber = 0;
int mBackDisposition = InputMethodService.BACK_DISPOSITION_DEFAULT; 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; int mImeWindowVis;
private AlertDialog.Builder mDialogBuilder; private AlertDialog.Builder mDialogBuilder;
@@ -459,12 +476,12 @@ public class InputMethodManagerService extends IInputMethodManager.Stub
final String action = intent.getAction(); final String action = intent.getAction();
if (Intent.ACTION_SCREEN_ON.equals(action)) { if (Intent.ACTION_SCREEN_ON.equals(action)) {
mScreenOn = true; mScreenOn = true;
refreshImeWindowVisibilityLocked(); updateSystemUi(mCurToken, mImeWindowVis, mBackDisposition);
updateActive(); updateActive();
return; return;
} else if (Intent.ACTION_SCREEN_OFF.equals(action)) { } else if (Intent.ACTION_SCREEN_OFF.equals(action)) {
mScreenOn = false; mScreenOn = false;
setImeWindowVisibilityStatusHiddenLocked(); updateSystemUi(mCurToken, 0 /* vis */, mBackDisposition);
updateActive(); updateActive();
return; return;
} else if (Intent.ACTION_CLOSE_SYSTEM_DIALOGS.equals(action)) { } else if (Intent.ACTION_CLOSE_SYSTEM_DIALOGS.equals(action)) {
@@ -660,7 +677,7 @@ public class InputMethodManagerService extends IInputMethodManager.Stub
// Uh oh, current input method is no longer around! // Uh oh, current input method is no longer around!
// Pick another one... // Pick another one...
Slog.i(TAG, "Current input method removed: " + curInputMethodId); Slog.i(TAG, "Current input method removed: " + curInputMethodId);
setImeWindowVisibilityStatusHiddenLocked(); updateSystemUiLocked(mCurToken, 0 /* vis */, mBackDisposition);
if (!chooseNewDefaultIMELocked()) { if (!chooseNewDefaultIMELocked()) {
changed = true; changed = true;
curIm = null; curIm = null;
@@ -1003,7 +1020,7 @@ public class InputMethodManagerService extends IInputMethodManager.Stub
mContext.getSystemService(Context.NOTIFICATION_SERVICE); mContext.getSystemService(Context.NOTIFICATION_SERVICE);
mStatusBar = statusBar; mStatusBar = statusBar;
statusBar.setIconVisibility("ime", false); statusBar.setIconVisibility("ime", false);
updateImeWindowStatusLocked(); updateSystemUiLocked(mCurToken, mImeWindowVis, mBackDisposition);
mShowOngoingImeSwitcherForPhones = mRes.getBoolean( mShowOngoingImeSwitcherForPhones = mRes.getBoolean(
com.android.internal.R.bool.show_ongoing_ime_switcher); com.android.internal.R.bool.show_ongoing_ime_switcher);
if (mShowOngoingImeSwitcherForPhones) { if (mShowOngoingImeSwitcherForPhones) {
@@ -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 // Check whether or not this is a valid IPC. Assumes an IPC is valid when either
// 1) it comes from the system process // 1) it comes from the system process
@@ -1541,7 +1531,7 @@ public class InputMethodManagerService extends IInputMethodManager.Stub
sessionState.session.finishSession(); sessionState.session.finishSession();
} catch (RemoteException e) { } catch (RemoteException e) {
Slog.w(TAG, "Session failed to close due to remote exception", e); Slog.w(TAG, "Session failed to close due to remote exception", e);
setImeWindowVisibilityStatusHiddenLocked(); updateSystemUiLocked(mCurToken, 0 /* vis */, mBackDisposition);
} }
sessionState.session = null; sessionState.session = null;
} }
@@ -1629,11 +1619,11 @@ public class InputMethodManagerService extends IInputMethodManager.Stub
} }
} }
private boolean shouldShowImeSwitcherLocked() { private boolean shouldShowImeSwitcherLocked(int visibility) {
if (!mShowOngoingImeSwitcherForPhones) return false; if (!mShowOngoingImeSwitcherForPhones) return false;
if (mSwitchingDialog != null) return false; if (mSwitchingDialog != null) return false;
if (isScreenLocked()) 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()) { if (mWindowManagerService.isHardKeyboardAvailable()) {
// When physical keyboard is attached, we show the ime switcher (or notification if // 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 // NavBar is not available) because SHOW_IME_WITH_HARD_KEYBOARD settings currently
@@ -1641,7 +1631,7 @@ public class InputMethodManagerService extends IInputMethodManager.Stub
// SHOW_IME_WITH_HARD_KEYBOARD settings finds a good place to live. // SHOW_IME_WITH_HARD_KEYBOARD settings finds a good place to live.
return true; return true;
} }
if ((mImeWindowVis & InputMethodService.IME_VISIBLE) == 0) return false; if ((visibility & InputMethodService.IME_VISIBLE) == 0) return false;
List<InputMethodInfo> imis = mSettings.getEnabledInputMethodListLocked(); List<InputMethodInfo> imis = mSettings.getEnabledInputMethodListLocked();
final int N = imis.size(); final int N = imis.size();
@@ -1690,62 +1680,82 @@ public class InputMethodManagerService extends IInputMethodManager.Stub
return mKeyguardManager != null && mKeyguardManager.isKeyguardLocked(); return mKeyguardManager != null && mKeyguardManager.isKeyguardLocked();
} }
// Caution! This method is called in this class. Handle multi-user carefully
@SuppressWarnings("deprecation") @SuppressWarnings("deprecation")
@Override @Override
public void setImeWindowStatus(IBinder token, int vis, int backDisposition) { public void setImeWindowStatus(IBinder token, int vis, int backDisposition) {
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(); final long ident = Binder.clearCallingIdentity();
try { try {
if (!calledWithValidToken(token)) { // apply policy for binder calls
final int uid = Binder.getCallingUid(); if (vis != 0 && isKeyguardLocked() && !mCurClientInKeyguard) {
Slog.e(TAG, "Ignoring setImeWindowStatus due to an invalid token. uid:" + uid vis = 0;
+ " token:" + token);
return;
} }
synchronized (mMethodMap) { // mImeWindowVis should be updated before calling shouldShowImeSwitcherLocked().
// apply policy for binder calls final boolean needsToShowImeSwitcher = shouldShowImeSwitcherLocked(vis);
if (vis != 0 && isKeyguardLocked() && !mCurClientInKeyguard) { if (mStatusBar != null) {
vis = 0; mStatusBar.setImeWindowStatus(token, vis, backDisposition,
} needsToShowImeSwitcher);
mImeWindowVis = vis; }
mBackDisposition = backDisposition; final InputMethodInfo imi = mMethodMap.get(mCurMethodId);
// mImeWindowVis should be updated before calling shouldShowImeSwitcherLocked(). if (imi != null && needsToShowImeSwitcher) {
final boolean needsToShowImeSwitcher = shouldShowImeSwitcherLocked(); // Used to load label
if (mStatusBar != null) { final CharSequence title = mRes.getText(
mStatusBar.setImeWindowStatus(token, vis, backDisposition, com.android.internal.R.string.select_input_method);
needsToShowImeSwitcher); final CharSequence summary = InputMethodUtils.getImeAndSubtypeDisplayName(
} mContext, imi, mCurrentSubtype);
final InputMethodInfo imi = mMethodMap.get(mCurMethodId);
if (imi != null && needsToShowImeSwitcher) {
// Used to load label
final CharSequence title = mRes.getText(
com.android.internal.R.string.select_input_method);
final CharSequence summary = InputMethodUtils.getImeAndSubtypeDisplayName(
mContext, imi, mCurrentSubtype);
mImeSwitcherNotification.color = mContext.getColor( mImeSwitcherNotification.color = mContext.getColor(
com.android.internal.R.color.system_notification_accent_color); com.android.internal.R.color.system_notification_accent_color);
mImeSwitcherNotification.setLatestEventInfo( mImeSwitcherNotification.setLatestEventInfo(
mContext, title, summary, mImeSwitchPendingIntent); mContext, title, summary, mImeSwitchPendingIntent);
if ((mNotificationManager != null) if ((mNotificationManager != null)
&& !mWindowManagerService.hasNavigationBar()) { && !mWindowManagerService.hasNavigationBar()) {
if (DEBUG) { if (DEBUG) {
Slog.d(TAG, "--- show notification: label = " + summary); Slog.d(TAG, "--- show notification: label = " + summary);
}
mNotificationManager.notifyAsUser(null,
com.android.internal.R.string.select_input_method,
mImeSwitcherNotification, UserHandle.ALL);
mNotificationShown = true;
} }
} else { mNotificationManager.notifyAsUser(null,
if (mNotificationShown && mNotificationManager != null) { com.android.internal.R.string.select_input_method,
if (DEBUG) { mImeSwitcherNotification, UserHandle.ALL);
Slog.d(TAG, "--- hide notification"); mNotificationShown = true;
} }
mNotificationManager.cancelAsUser(null, } else {
com.android.internal.R.string.select_input_method, UserHandle.ALL); if (mNotificationShown && mNotificationManager != null) {
mNotificationShown = false; if (DEBUG) {
Slog.d(TAG, "--- hide notification");
} }
mNotificationManager.cancelAsUser(null,
com.android.internal.R.string.select_input_method, UserHandle.ALL);
mNotificationShown = false;
} }
} }
} finally { } finally {
@@ -1912,7 +1922,7 @@ public class InputMethodManagerService extends IInputMethodManager.Stub
setSelectedInputMethodAndSubtypeLocked(info, subtypeId, true); setSelectedInputMethodAndSubtypeLocked(info, subtypeId, true);
if (mCurMethod != null) { if (mCurMethod != null) {
try { try {
refreshImeWindowVisibilityLocked(); updateSystemUiLocked(mCurToken, mImeWindowVis, mBackDisposition);
mCurMethod.changeInputMethodSubtype(newSubtype); mCurMethod.changeInputMethodSubtype(newSubtype);
} catch (RemoteException e) { } catch (RemoteException e) {
Slog.w(TAG, "Failed to call changeInputMethodSubtype"); Slog.w(TAG, "Failed to call changeInputMethodSubtype");
@@ -2074,7 +2084,7 @@ public class InputMethodManagerService extends IInputMethodManager.Stub
return false; return false;
} }
boolean res; boolean res;
if (mInputShown && mCurMethod != null) { if ((mImeWindowVis & InputMethodService.IME_ACTIVE) != 0 && mCurMethod != null) {
executeOrSendMessage(mCurMethod, mCaller.obtainMessageOO( executeOrSendMessage(mCurMethod, mCaller.obtainMessageOO(
MSG_HIDE_SOFT_INPUT, mCurMethod, resultReceiver)); MSG_HIDE_SOFT_INPUT, mCurMethod, resultReceiver));
res = true; res = true;
@@ -3048,7 +3058,7 @@ public class InputMethodManagerService extends IInputMethodManager.Stub
mSwitchingDialog.getWindow().getAttributes().privateFlags |= mSwitchingDialog.getWindow().getAttributes().privateFlags |=
WindowManager.LayoutParams.PRIVATE_FLAG_SHOW_FOR_ALL_USERS; WindowManager.LayoutParams.PRIVATE_FLAG_SHOW_FOR_ALL_USERS;
mSwitchingDialog.getWindow().getAttributes().setTitle("Select input method"); mSwitchingDialog.getWindow().getAttributes().setTitle("Select input method");
updateImeWindowStatusLocked(); updateSystemUi(mCurToken, mImeWindowVis, mBackDisposition);
mSwitchingDialog.show(); mSwitchingDialog.show();
} }
} }
@@ -3107,7 +3117,7 @@ public class InputMethodManagerService extends IInputMethodManager.Stub
mSwitchingDialog = null; mSwitchingDialog = null;
} }
updateImeWindowStatusLocked(); updateSystemUiLocked(mCurToken, mImeWindowVis, mBackDisposition);
mDialogBuilder = null; mDialogBuilder = null;
mIms = null; mIms = null;
} }