Merge "Hide the software input based on its state." into mnc-dev
This commit is contained in:
@@ -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;
|
||||
@@ -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)) {
|
||||
@@ -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;
|
||||
@@ -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) {
|
||||
@@ -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
|
||||
@@ -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;
|
||||
}
|
||||
@@ -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
|
||||
@@ -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();
|
||||
@@ -1690,62 +1680,82 @@ 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) {
|
||||
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 {
|
||||
if (!calledWithValidToken(token)) {
|
||||
final int uid = Binder.getCallingUid();
|
||||
Slog.e(TAG, "Ignoring setImeWindowStatus due to an invalid token. uid:" + uid
|
||||
+ " token:" + token);
|
||||
return;
|
||||
// apply policy for binder calls
|
||||
if (vis != 0 && isKeyguardLocked() && !mCurClientInKeyguard) {
|
||||
vis = 0;
|
||||
}
|
||||
synchronized (mMethodMap) {
|
||||
// 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();
|
||||
if (mStatusBar != null) {
|
||||
mStatusBar.setImeWindowStatus(token, vis, backDisposition,
|
||||
needsToShowImeSwitcher);
|
||||
}
|
||||
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);
|
||||
// mImeWindowVis should be updated before calling shouldShowImeSwitcherLocked().
|
||||
final boolean needsToShowImeSwitcher = shouldShowImeSwitcherLocked(vis);
|
||||
if (mStatusBar != null) {
|
||||
mStatusBar.setImeWindowStatus(token, vis, backDisposition,
|
||||
needsToShowImeSwitcher);
|
||||
}
|
||||
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(
|
||||
com.android.internal.R.color.system_notification_accent_color);
|
||||
mImeSwitcherNotification.setLatestEventInfo(
|
||||
mContext, title, summary, mImeSwitchPendingIntent);
|
||||
if ((mNotificationManager != null)
|
||||
&& !mWindowManagerService.hasNavigationBar()) {
|
||||
if (DEBUG) {
|
||||
Slog.d(TAG, "--- show notification: label = " + summary);
|
||||
}
|
||||
mNotificationManager.notifyAsUser(null,
|
||||
com.android.internal.R.string.select_input_method,
|
||||
mImeSwitcherNotification, UserHandle.ALL);
|
||||
mNotificationShown = true;
|
||||
mImeSwitcherNotification.color = mContext.getColor(
|
||||
com.android.internal.R.color.system_notification_accent_color);
|
||||
mImeSwitcherNotification.setLatestEventInfo(
|
||||
mContext, title, summary, mImeSwitchPendingIntent);
|
||||
if ((mNotificationManager != null)
|
||||
&& !mWindowManagerService.hasNavigationBar()) {
|
||||
if (DEBUG) {
|
||||
Slog.d(TAG, "--- show notification: label = " + summary);
|
||||
}
|
||||
} else {
|
||||
if (mNotificationShown && mNotificationManager != null) {
|
||||
if (DEBUG) {
|
||||
Slog.d(TAG, "--- hide notification");
|
||||
}
|
||||
mNotificationManager.cancelAsUser(null,
|
||||
com.android.internal.R.string.select_input_method, UserHandle.ALL);
|
||||
mNotificationShown = false;
|
||||
mNotificationManager.notifyAsUser(null,
|
||||
com.android.internal.R.string.select_input_method,
|
||||
mImeSwitcherNotification, UserHandle.ALL);
|
||||
mNotificationShown = true;
|
||||
}
|
||||
} else {
|
||||
if (mNotificationShown && mNotificationManager != null) {
|
||||
if (DEBUG) {
|
||||
Slog.d(TAG, "--- hide notification");
|
||||
}
|
||||
mNotificationManager.cancelAsUser(null,
|
||||
com.android.internal.R.string.select_input_method, UserHandle.ALL);
|
||||
mNotificationShown = false;
|
||||
}
|
||||
}
|
||||
} finally {
|
||||
@@ -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");
|
||||
@@ -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;
|
||||
@@ -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();
|
||||
}
|
||||
}
|
||||
@@ -3107,7 +3117,7 @@ public class InputMethodManagerService extends IInputMethodManager.Stub
|
||||
mSwitchingDialog = null;
|
||||
}
|
||||
|
||||
updateImeWindowStatusLocked();
|
||||
updateSystemUiLocked(mCurToken, mImeWindowVis, mBackDisposition);
|
||||
mDialogBuilder = null;
|
||||
mIms = null;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user