Merge "Plumb whether an input view is actually visible or not through from the IME to the status bar." into honeycomb

This commit is contained in:
Joe Onorato
2011-01-28 13:40:28 -08:00
committed by Android (Google) Code Review
13 changed files with 179 additions and 56 deletions

View File

@ -94279,6 +94279,17 @@
visibility="public" visibility="public"
> >
</constructor> </constructor>
<method name="getBackDisposition"
return="int"
abstract="false"
native="false"
synchronized="false"
static="false"
final="false"
deprecated="not deprecated"
visibility="public"
>
</method>
<method name="getCandidatesHiddenVisibility" <method name="getCandidatesHiddenVisibility"
return="int" return="int"
abstract="false" abstract="false"
@ -95004,6 +95015,19 @@
<parameter name="charCode" type="char"> <parameter name="charCode" type="char">
</parameter> </parameter>
</method> </method>
<method name="setBackDisposition"
return="void"
abstract="false"
native="false"
synchronized="false"
static="false"
final="false"
deprecated="not deprecated"
visibility="public"
>
<parameter name="disposition" type="int">
</parameter>
</method>
<method name="setCandidatesView" <method name="setCandidatesView"
return="void" return="void"
abstract="false" abstract="false"
@ -95130,6 +95154,39 @@
visibility="public" visibility="public"
> >
</method> </method>
<field name="BACK_DISPOSITION_DEFAULT"
type="int"
transient="false"
volatile="false"
value="0"
static="true"
final="true"
deprecated="not deprecated"
visibility="public"
>
</field>
<field name="BACK_DISPOSITION_WILL_DISMISS"
type="int"
transient="false"
volatile="false"
value="2"
static="true"
final="true"
deprecated="not deprecated"
visibility="public"
>
</field>
<field name="BACK_DISPOSITION_WILL_NOT_DISMISS"
type="int"
transient="false"
volatile="false"
value="1"
static="true"
final="true"
deprecated="not deprecated"
visibility="public"
>
</field>
</class> </class>
<class name="InputMethodService.InputMethodImpl" <class name="InputMethodService.InputMethodImpl"
extends="android.inputmethodservice.AbstractInputMethodService.AbstractInputMethodImpl" extends="android.inputmethodservice.AbstractInputMethodService.AbstractInputMethodImpl"

View File

@ -219,7 +219,34 @@ import java.io.PrintWriter;
public class InputMethodService extends AbstractInputMethodService { public class InputMethodService extends AbstractInputMethodService {
static final String TAG = "InputMethodService"; static final String TAG = "InputMethodService";
static final boolean DEBUG = false; static final boolean DEBUG = false;
/**
* The back button will close the input window.
*/
public static final int BACK_DISPOSITION_DEFAULT = 0; // based on window
/**
* This input method will not consume the back key.
*/
public static final int BACK_DISPOSITION_WILL_NOT_DISMISS = 1; // back
/**
* This input method will consume the back key.
*/
public static final int BACK_DISPOSITION_WILL_DISMISS = 2; // down
/**
* @hide
* The IME is active. It may or may not be visible.
*/
public static final int IME_ACTIVE = 0x1;
/**
* @hide
* The IME is visible.
*/
public static final int IME_VISIBLE = 0x2;
InputMethodManager mImm; InputMethodManager mImm;
int mTheme = 0; int mTheme = 0;
@ -271,6 +298,7 @@ public class InputMethodService extends AbstractInputMethodService {
boolean mIsInputViewShown; boolean mIsInputViewShown;
int mStatusIcon; int mStatusIcon;
int mBackDisposition;
final Insets mTmpInsets = new Insets(); final Insets mTmpInsets = new Insets();
final int[] mTmpLocation = new int[2]; final int[] mTmpLocation = new int[2];
@ -394,9 +422,9 @@ public class InputMethodService extends AbstractInputMethodService {
showWindow(true); showWindow(true);
} }
// If user uses hard keyboard, IME button should always be shown. // If user uses hard keyboard, IME button should always be shown.
if (!onEvaluateInputViewShown()) { boolean showing = onEvaluateInputViewShown();
mImm.setIMEButtonVisible(mToken, true); mImm.setImeWindowStatus(mToken, IME_ACTIVE | (showing ? IME_VISIBLE : 0),
} mBackDisposition);
if (resultReceiver != null) { if (resultReceiver != null) {
resultReceiver.send(wasVis != isInputViewShown() resultReceiver.send(wasVis != isInputViewShown()
? InputMethodManager.RESULT_SHOWN ? InputMethodManager.RESULT_SHOWN
@ -704,9 +732,9 @@ public class InputMethodService extends AbstractInputMethodService {
hideWindow(); hideWindow();
} }
// If user uses hard keyboard, IME button should always be shown. // If user uses hard keyboard, IME button should always be shown.
if (!onEvaluateInputViewShown()) { boolean showing = onEvaluateInputViewShown();
mImm.setIMEButtonVisible(mToken, true); mImm.setImeWindowStatus(mToken, IME_ACTIVE | (showing ? IME_VISIBLE : 0),
} mBackDisposition);
} }
} }
@ -736,6 +764,14 @@ public class InputMethodService extends AbstractInputMethodService {
return mWindow; return mWindow;
} }
public void setBackDisposition(int disposition) {
mBackDisposition = disposition;
}
public int getBackDisposition() {
return mBackDisposition;
}
/** /**
* Return the maximum width, in pixels, available the input method. * Return the maximum width, in pixels, available the input method.
* Input methods are positioned at the bottom of the screen and, unless * Input methods are positioned at the bottom of the screen and, unless
@ -1378,7 +1414,7 @@ public class InputMethodService extends AbstractInputMethodService {
if (!wasVisible) { if (!wasVisible) {
if (DEBUG) Log.v(TAG, "showWindow: showing!"); if (DEBUG) Log.v(TAG, "showWindow: showing!");
mImm.setIMEButtonVisible(mToken, true); mImm.setImeWindowStatus(mToken, IME_ACTIVE, mBackDisposition);
onWindowShown(); onWindowShown();
mWindow.show(); mWindow.show();
} }
@ -1394,7 +1430,7 @@ public class InputMethodService extends AbstractInputMethodService {
} }
mInputViewStarted = false; mInputViewStarted = false;
mCandidatesViewStarted = false; mCandidatesViewStarted = false;
mImm.setIMEButtonVisible(mToken, false); mImm.setImeWindowStatus(mToken, 0, mBackDisposition);
if (mWindowVisible) { if (mWindowVisible) {
mWindow.hide(); mWindow.hide();
mWindowVisible = false; mWindowVisible = false;

View File

@ -531,9 +531,9 @@ public final class InputMethodManager {
} }
/** @hide */ /** @hide */
public void setIMEButtonVisible(IBinder imeToken, boolean visible) { public void setImeWindowStatus(IBinder imeToken, int vis, int backDisposition) {
try { try {
mService.setIMEButtonVisible(imeToken, visible); mService.setImeWindowStatus(imeToken, vis, backDisposition);
} catch (RemoteException e) { } catch (RemoteException e) {
throw new RuntimeException(e); throw new RuntimeException(e);
} }

View File

@ -32,6 +32,6 @@ oneway interface IStatusBar
void animateCollapse(); void animateCollapse();
void setLightsOn(boolean on); void setLightsOn(boolean on);
void setMenuKeyVisible(boolean visible); void setMenuKeyVisible(boolean visible);
void setIMEButtonVisible(in IBinder token, boolean visible); void setImeWindowStatus(in IBinder token, int vis, int backDisposition);
} }

View File

@ -31,7 +31,7 @@ interface IStatusBarService
void setIconVisibility(String slot, boolean visible); void setIconVisibility(String slot, boolean visible);
void removeIcon(String slot); void removeIcon(String slot);
void setMenuKeyVisible(boolean visible); void setMenuKeyVisible(boolean visible);
void setIMEButtonVisible(in IBinder token, boolean visible); void setImeWindowStatus(in IBinder token, int vis, int backDisposition);
// ---- Methods below are for use by the status bar policy services ---- // ---- Methods below are for use by the status bar policy services ----
// You need the STATUS_BAR_SERVICE permission // You need the STATUS_BAR_SERVICE permission

View File

@ -59,7 +59,7 @@ interface IInputMethodManager {
void hideMySoftInput(in IBinder token, int flags); void hideMySoftInput(in IBinder token, int flags);
void showMySoftInput(in IBinder token, int flags); void showMySoftInput(in IBinder token, int flags);
void updateStatusIcon(in IBinder token, String packageName, int iconId); void updateStatusIcon(in IBinder token, String packageName, int iconId);
void setIMEButtonVisible(in IBinder token, boolean visible); void setImeWindowStatus(in IBinder token, int vis, int backDisposition);
InputMethodSubtype getCurrentInputMethodSubtype(); InputMethodSubtype getCurrentInputMethodSubtype();
boolean setCurrentInputMethodSubtype(in InputMethodSubtype subtype); boolean setCurrentInputMethodSubtype(in InputMethodSubtype subtype);
boolean switchToLastInputMethod(in IBinder token); boolean switchToLastInputMethod(in IBinder token);

View File

@ -82,7 +82,7 @@ public class CommandQueue extends IStatusBar.Stub {
public void animateCollapse(); public void animateCollapse();
public void setLightsOn(boolean on); public void setLightsOn(boolean on);
public void setMenuKeyVisible(boolean visible); public void setMenuKeyVisible(boolean visible);
public void setIMEButtonVisible(IBinder token, boolean visible); public void setImeWindowStatus(IBinder token, int vis, int backDisposition);
} }
public CommandQueue(Callbacks callbacks, StatusBarIconList list) { public CommandQueue(Callbacks callbacks, StatusBarIconList list) {
@ -165,10 +165,11 @@ public class CommandQueue extends IStatusBar.Stub {
} }
} }
public void setIMEButtonVisible(IBinder token, boolean visible) { public void setImeWindowStatus(IBinder token, int vis, int backDisposition) {
synchronized (mList) { synchronized (mList) {
mHandler.removeMessages(MSG_SHOW_IME_BUTTON); mHandler.removeMessages(MSG_SHOW_IME_BUTTON);
mHandler.obtainMessage(MSG_SHOW_IME_BUTTON, visible ? 1 : 0, 0, token).sendToTarget(); mHandler.obtainMessage(MSG_SHOW_IME_BUTTON, vis, backDisposition, token)
.sendToTarget();
} }
} }
@ -233,7 +234,7 @@ public class CommandQueue extends IStatusBar.Stub {
mCallbacks.setMenuKeyVisible(msg.arg1 != 0); mCallbacks.setMenuKeyVisible(msg.arg1 != 0);
break; break;
case MSG_SHOW_IME_BUTTON: case MSG_SHOW_IME_BUTTON:
mCallbacks.setIMEButtonVisible((IBinder)msg.obj, msg.arg1 != 0); mCallbacks.setImeWindowStatus((IBinder)msg.obj, msg.arg1, msg.arg2);
break; break;
} }
} }

View File

@ -67,7 +67,7 @@ public abstract class StatusBar extends SystemUI implements CommandQueue.Callbac
mCommandQueue = new CommandQueue(this, iconList); mCommandQueue = new CommandQueue(this, iconList);
mBarService = IStatusBarService.Stub.asInterface( mBarService = IStatusBarService.Stub.asInterface(
ServiceManager.getService(Context.STATUS_BAR_SERVICE)); ServiceManager.getService(Context.STATUS_BAR_SERVICE));
int[] switches = new int[4]; int[] switches = new int[5];
ArrayList<IBinder> binders = new ArrayList<IBinder>(); ArrayList<IBinder> binders = new ArrayList<IBinder>();
try { try {
mBarService.registerStatusBar(mCommandQueue, iconList, notificationKeys, notifications, mBarService.registerStatusBar(mCommandQueue, iconList, notificationKeys, notifications,
@ -80,7 +80,7 @@ public abstract class StatusBar extends SystemUI implements CommandQueue.Callbac
setLightsOn(switches[1] != 0); setLightsOn(switches[1] != 0);
setMenuKeyVisible(switches[2] != 0); setMenuKeyVisible(switches[2] != 0);
// StatusBarManagerService has a back up of IME token and it's restored here. // StatusBarManagerService has a back up of IME token and it's restored here.
setIMEButtonVisible(binders.get(0), switches[3] != 0); setImeWindowStatus(binders.get(0), switches[3], switches[4]);
// Set up the initial icon state // Set up the initial icon state
int N = iconList.size(); int N = iconList.size();

View File

@ -1020,7 +1020,7 @@ public class PhoneStatusBar extends StatusBar {
// Not supported // Not supported
public void setMenuKeyVisible(boolean visible) { } public void setMenuKeyVisible(boolean visible) { }
public void setIMEButtonVisible(IBinder token, boolean visible) { } public void setImeWindowStatus(IBinder token, int vis, int backDisposition) { }
private class Launcher implements View.OnClickListener { private class Launcher implements View.OnClickListener {
private PendingIntent mIntent; private PendingIntent mIntent;

View File

@ -53,7 +53,7 @@ public class InputMethodButton extends ImageView {
private final int mId; private final int mId;
private ImageView mIcon; private ImageView mIcon;
private IBinder mToken; private IBinder mToken;
private boolean mKeyboardVisible = false; private boolean mShowButton = false;
private boolean mScreenLocked = false; private boolean mScreenLocked = false;
private InputMethodInfo mShortcutInfo; private InputMethodInfo mShortcutInfo;
private InputMethodSubtype mShortcutSubtype; private InputMethodSubtype mShortcutSubtype;
@ -144,7 +144,7 @@ public class InputMethodButton extends ImageView {
// * There are no explicitly enabled (by the user) subtypes of the IME, or the IME doesn't have // * There are no explicitly enabled (by the user) subtypes of the IME, or the IME doesn't have
// its subtypes at all // its subtypes at all
private boolean needsToShowIMEButton() { private boolean needsToShowIMEButton() {
if (!mKeyboardVisible || mScreenLocked) return false; if (!mShowButton || mScreenLocked) return false;
List<InputMethodInfo> imis = mImm.getEnabledInputMethodList(); List<InputMethodInfo> imis = mImm.getEnabledInputMethodList();
final int size = imis.size(); final int size = imis.size();
final int visibility = loadInputMethodSelectorVisibility(); final int visibility = loadInputMethodSelectorVisibility();
@ -194,9 +194,9 @@ public class InputMethodButton extends ImageView {
} }
} }
public void setIMEButtonVisible(IBinder token, boolean keyboardVisible) { public void setImeWindowStatus(IBinder token, boolean showButton) {
mToken = token; mToken = token;
mKeyboardVisible = keyboardVisible; mShowButton = showButton;
refreshStatusIcon(); refreshStatusIcon();
} }

View File

@ -33,6 +33,7 @@ import android.content.Context;
import android.content.Intent; import android.content.Intent;
import android.content.res.Configuration; import android.content.res.Configuration;
import android.content.res.Resources; import android.content.res.Resources;
import android.inputmethodservice.InputMethodService;
import android.graphics.PixelFormat; import android.graphics.PixelFormat;
import android.graphics.Rect; import android.graphics.Rect;
import android.graphics.drawable.Drawable; import android.graphics.drawable.Drawable;
@ -863,17 +864,32 @@ public class TabletStatusBar extends StatusBar implements
if (visible) setLightsOn(true); if (visible) setLightsOn(true);
} }
public void setIMEButtonVisible(IBinder token, boolean visible) { public void setImeWindowStatus(IBinder token, int vis, int backDisposition) {
if (DEBUG) { mInputMethodSwitchButton.setImeWindowStatus(token,
Slog.d(TAG, (visible?"showing":"hiding") + " the IME button"); (vis & InputMethodService.IME_ACTIVE) != 0);
}
mInputMethodSwitchButton.setIMEButtonVisible(token, visible);
updateNotificationIcons(); updateNotificationIcons();
mInputMethodsPanel.setImeToken(token); mInputMethodsPanel.setImeToken(token);
mBackButton.setImageResource( int res;
visible ? R.drawable.ic_sysbar_back_ime : R.drawable.ic_sysbar_back); switch (backDisposition) {
case InputMethodService.BACK_DISPOSITION_WILL_NOT_DISMISS:
res = R.drawable.ic_sysbar_back;
break;
case InputMethodService.BACK_DISPOSITION_WILL_DISMISS:
res = R.drawable.ic_sysbar_back_ime;
break;
case InputMethodService.BACK_DISPOSITION_DEFAULT:
default:
if ((vis & InputMethodService.IME_VISIBLE) != 0) {
res = R.drawable.ic_sysbar_back_ime;
} else {
res = R.drawable.ic_sysbar_back;
}
break;
}
mBackButton.setImageResource(res);
if (FAKE_SPACE_BAR) { if (FAKE_SPACE_BAR) {
mFakeSpaceBar.setVisibility(visible ? View.VISIBLE : View.GONE); mFakeSpaceBar.setVisibility(((vis & InputMethodService.IME_VISIBLE) != 0)
? View.VISIBLE : View.GONE);
} }
} }

View File

@ -49,6 +49,7 @@ import android.content.res.Configuration;
import android.content.res.Resources; import android.content.res.Resources;
import android.content.res.TypedArray; import android.content.res.TypedArray;
import android.database.ContentObserver; import android.database.ContentObserver;
import android.inputmethodservice.InputMethodService;
import android.os.Binder; import android.os.Binder;
import android.os.Handler; import android.os.Handler;
import android.os.IBinder; import android.os.IBinder;
@ -311,6 +312,9 @@ public class InputMethodManagerService extends IInputMethodManager.Stub
*/ */
boolean mScreenOn = true; boolean mScreenOn = true;
int mBackDisposition = InputMethodService.BACK_DISPOSITION_DEFAULT;
int mImeWindowVis;
AlertDialog.Builder mDialogBuilder; AlertDialog.Builder mDialogBuilder;
AlertDialog mSwitchingDialog; AlertDialog mSwitchingDialog;
InputMethodInfo[] mIms; InputMethodInfo[] mIms;
@ -430,7 +434,9 @@ 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);
mStatusBar.setIMEButtonVisible(mCurToken, false); mImeWindowVis = 0;
mStatusBar.setImeWindowStatus(mCurToken, mImeWindowVis,
mBackDisposition);
if (!chooseNewDefaultIMELocked()) { if (!chooseNewDefaultIMELocked()) {
changed = true; changed = true;
curIm = null; curIm = null;
@ -982,17 +988,19 @@ public class InputMethodManagerService extends IInputMethodManager.Stub
} }
} }
public void setIMEButtonVisible(IBinder token, boolean visible) { public void setImeWindowStatus(IBinder token, int vis, int backDisposition) {
int uid = Binder.getCallingUid(); int uid = Binder.getCallingUid();
long ident = Binder.clearCallingIdentity(); long ident = Binder.clearCallingIdentity();
try { try {
if (token == null || mCurToken != token) { if (token == null || mCurToken != token) {
Slog.w(TAG, "Ignoring setIMEButtonVisible of uid " + uid + " token: " + token); Slog.w(TAG, "Ignoring setImeWindowStatus of uid " + uid + " token: " + token);
return; return;
} }
synchronized (mMethodMap) { synchronized (mMethodMap) {
mStatusBar.setIMEButtonVisible(token, visible); mImeWindowVis = vis;
mBackDisposition = backDisposition;
mStatusBar.setImeWindowStatus(token, vis, backDisposition);
} }
} finally { } finally {
Binder.restoreCallingIdentity(ident); Binder.restoreCallingIdentity(ident);
@ -1045,12 +1053,9 @@ public class InputMethodManagerService extends IInputMethodManager.Stub
} }
if (mCurMethod != null) { if (mCurMethod != null) {
try { try {
if (mInputShown) { mImeWindowVis = 0;
// If mInputShown is false, there is no IME button on the mStatusBar.setImeWindowStatus(mCurToken, mImeWindowVis,
// system bar. mBackDisposition);
// Thus there is no need to make it invisible explicitly.
mStatusBar.setIMEButtonVisible(mCurToken, true);
}
// If subtype is null, try to find the most applicable one from // If subtype is null, try to find the most applicable one from
// getCurrentInputMethodSubtype. // getCurrentInputMethodSubtype.
if (subtype == null) { if (subtype == null) {
@ -1168,11 +1173,14 @@ public class InputMethodManagerService extends IInputMethodManager.Stub
if (!mIWindowManager.inputMethodClientHasFocus(client)) { if (!mIWindowManager.inputMethodClientHasFocus(client)) {
if (DEBUG) Slog.w(TAG, "Ignoring hideSoftInput of uid " if (DEBUG) Slog.w(TAG, "Ignoring hideSoftInput of uid "
+ uid + ": " + client); + uid + ": " + client);
mStatusBar.setIMEButtonVisible(mCurToken, false); mImeWindowVis = 0;
mStatusBar.setImeWindowStatus(mCurToken, mImeWindowVis,
mBackDisposition);
return false; return false;
} }
} catch (RemoteException e) { } catch (RemoteException e) {
mStatusBar.setIMEButtonVisible(mCurToken, false); mImeWindowVis = 0;
mStatusBar.setImeWindowStatus(mCurToken, mImeWindowVis, mBackDisposition);
return false; return false;
} }
} }

View File

@ -73,8 +73,9 @@ public class StatusBarManagerService extends IStatusBarService.Stub
// We usually call it lights out mode, but double negatives are annoying // We usually call it lights out mode, but double negatives are annoying
boolean mLightsOn = true; boolean mLightsOn = true;
boolean mMenuVisible = false; boolean mMenuVisible = false;
boolean mIMEButtonVisible = false; int mImeWindowVis = 0;
IBinder mIMEToken = null; int mImeBackDisposition;
IBinder mImeToken = null;
private class DisableRecord implements IBinder.DeathRecipient { private class DisableRecord implements IBinder.DeathRecipient {
String pkg; String pkg;
@ -259,22 +260,25 @@ public class StatusBarManagerService extends IStatusBarService.Stub
} }
} }
public void setIMEButtonVisible(final IBinder token, final boolean visible) { public void setImeWindowStatus(final IBinder token, final int vis, final int backDisposition) {
enforceStatusBar(); enforceStatusBar();
if (SPEW) Slog.d(TAG, (visible?"showing":"hiding") + " IME Button"); if (SPEW) {
Slog.d(TAG, "swetImeWindowStatus vis=" + vis + " backDisposition=" + backDisposition);
}
synchronized(mLock) { synchronized(mLock) {
// In case of IME change, we need to call up setIMEButtonVisible() regardless of // In case of IME change, we need to call up setImeWindowStatus() regardless of
// mIMEButtonVisible because mIMEButtonVisible may not have been set to false when the // mImeWindowVis because mImeWindowVis may not have been set to false when the
// previous IME was destroyed. // previous IME was destroyed.
mIMEButtonVisible = visible; mImeWindowVis = vis;
mIMEToken = token; mImeBackDisposition = backDisposition;
mImeToken = token;
mHandler.post(new Runnable() { mHandler.post(new Runnable() {
public void run() { public void run() {
if (mBar != null) { if (mBar != null) {
try { try {
mBar.setIMEButtonVisible(token, visible); mBar.setImeWindowStatus(token, vis, backDisposition);
} catch (RemoteException ex) { } catch (RemoteException ex) {
} }
} }
@ -348,8 +352,9 @@ public class StatusBarManagerService extends IStatusBarService.Stub
switches[0] = gatherDisableActionsLocked(); switches[0] = gatherDisableActionsLocked();
switches[1] = mLightsOn ? 1 : 0; switches[1] = mLightsOn ? 1 : 0;
switches[2] = mMenuVisible ? 1 : 0; switches[2] = mMenuVisible ? 1 : 0;
switches[3] = mIMEButtonVisible ? 1 : 0; switches[3] = mImeWindowVis;
binders.add(mIMEToken); switches[4] = mImeBackDisposition;
binders.add(mImeToken);
} }
} }