Merge change 7903 into donut

* changes:
  Fix back key handling for search dialog.
This commit is contained in:
Android (Google) Code Review
2009-07-20 14:14:27 -07:00
5 changed files with 79 additions and 66 deletions

View File

@@ -37,4 +37,5 @@ interface ISearchManager {
ISearchManagerCallback searchManagerCallback, ISearchManagerCallback searchManagerCallback,
int ident); int ident);
void stopSearch(); void stopSearch();
boolean isVisible();
} }

View File

@@ -354,7 +354,6 @@ public class SearchDialog extends Dialog implements OnItemClickListener, OnItemS
} }
show(); show();
} }
updateUI(); updateUI();
return true; return true;
@@ -490,6 +489,7 @@ public class SearchDialog extends Dialog implements OnItemClickListener, OnItemS
*/ */
private void updateUI() { private void updateUI() {
if (mSearchable != null) { if (mSearchable != null) {
mDecor.setVisibility(View.VISIBLE);
updateSearchAutoComplete(); updateSearchAutoComplete();
updateSearchButton(); updateSearchButton();
updateSearchAppIcon(); updateSearchAppIcon();
@@ -994,7 +994,7 @@ public class SearchDialog extends Dialog implements OnItemClickListener, OnItemS
}; };
@Override @Override
public void dismiss() { public void hide() {
if (!isShowing()) return; if (!isShowing()) return;
// We made sure the IME was displayed, so also make sure it is closed // We made sure the IME was displayed, so also make sure it is closed
@@ -1005,10 +1005,10 @@ public class SearchDialog extends Dialog implements OnItemClickListener, OnItemS
imm.hideSoftInputFromWindow( imm.hideSoftInputFromWindow(
getWindow().getDecorView().getWindowToken(), 0); getWindow().getDecorView().getWindowToken(), 0);
} }
super.dismiss(); super.hide();
} }
/** /**
* React to the user typing while in the suggestions list. First, check for action * React to the user typing while in the suggestions list. First, check for action
* keys. If not handled, try refocusing regular characters into the EditText. * keys. If not handled, try refocusing regular characters into the EditText.
@@ -1234,8 +1234,8 @@ public class SearchDialog extends Dialog implements OnItemClickListener, OnItemS
} }
/** /**
* Launches an intent and dismisses the search dialog (unless the intent * Launches an intent, including any special intent handling. Doesn't dismiss the dialog
* is one of the special intents that modifies the state of the search dialog). * since that will be handled in {@link SearchDialogWrapper#performActivityResuming}
*/ */
private void launchIntent(Intent intent) { private void launchIntent(Intent intent) {
if (intent == null) { if (intent == null) {
@@ -1244,7 +1244,7 @@ public class SearchDialog extends Dialog implements OnItemClickListener, OnItemS
if (handleSpecialIntent(intent)){ if (handleSpecialIntent(intent)){
return; return;
} }
dismiss(); Log.d(LOG_TAG, "launching " + intent);
getContext().startActivity(intent); getContext().startActivity(intent);
} }

View File

@@ -1534,7 +1534,6 @@ public class SearchManager
private int mIdent; private int mIdent;
// package private since they are used by the inner class SearchManagerCallback // package private since they are used by the inner class SearchManagerCallback
/* package */ boolean mIsShowing = false;
/* package */ final Handler mHandler; /* package */ final Handler mHandler;
/* package */ OnDismissListener mDismissListener = null; /* package */ OnDismissListener mDismissListener = null;
/* package */ OnCancelListener mCancelListener = null; /* package */ OnCancelListener mCancelListener = null;
@@ -1600,12 +1599,9 @@ public class SearchManager
ComponentName launchActivity, ComponentName launchActivity,
Bundle appSearchData, Bundle appSearchData,
boolean globalSearch) { boolean globalSearch) {
if (DBG) debug("startSearch(), mIsShowing=" + mIsShowing);
if (mIsShowing) return;
if (mIdent == 0) throw new IllegalArgumentException( if (mIdent == 0) throw new IllegalArgumentException(
"Called from outside of an Activity context"); "Called from outside of an Activity context");
try { try {
mIsShowing = true;
// activate the search manager and start it up! // activate the search manager and start it up!
mService.startSearch(initialQuery, selectInitialQuery, launchActivity, appSearchData, mService.startSearch(initialQuery, selectInitialQuery, launchActivity, appSearchData,
globalSearch, mSearchManagerCallback, mIdent); globalSearch, mSearchManagerCallback, mIdent);
@@ -1626,15 +1622,10 @@ public class SearchManager
* @see #startSearch * @see #startSearch
*/ */
public void stopSearch() { public void stopSearch() {
if (DBG) debug("stopSearch(), mIsShowing=" + mIsShowing); if (DBG) debug("stopSearch()");
if (!mIsShowing) return;
try { try {
mService.stopSearch(); mService.stopSearch();
// onDismiss will also clear this, but we do it here too since onDismiss() is
// called asynchronously.
mIsShowing = false;
} catch (RemoteException ex) { } catch (RemoteException ex) {
Log.e(TAG, "stopSearch() failed: " + ex);
} }
} }
@@ -1648,8 +1639,13 @@ public class SearchManager
* @hide * @hide
*/ */
public boolean isVisible() { public boolean isVisible() {
if (DBG) debug("isVisible(), mIsShowing=" + mIsShowing); if (DBG) debug("isVisible()");
return mIsShowing; try {
return mService.isVisible();
} catch (RemoteException e) {
Log.e(TAG, "isVisible() failed: " + e);
return false;
}
} }
/** /**
@@ -1701,7 +1697,6 @@ public class SearchManager
private final Runnable mFireOnDismiss = new Runnable() { private final Runnable mFireOnDismiss = new Runnable() {
public void run() { public void run() {
if (DBG) debug("mFireOnDismiss"); if (DBG) debug("mFireOnDismiss");
mIsShowing = false;
if (mDismissListener != null) { if (mDismissListener != null) {
mDismissListener.onDismiss(); mDismissListener.onDismiss();
} }
@@ -1711,7 +1706,6 @@ public class SearchManager
private final Runnable mFireOnCancel = new Runnable() { private final Runnable mFireOnCancel = new Runnable() {
public void run() { public void run() {
if (DBG) debug("mFireOnCancel"); if (DBG) debug("mFireOnCancel");
// doesn't need to clear mIsShowing since onDismiss() always gets called too
if (mCancelListener != null) { if (mCancelListener != null) {
mCancelListener.onCancel(); mCancelListener.onCancel();
} }

View File

@@ -45,8 +45,6 @@ implements DialogInterface.OnCancelListener, DialogInterface.OnDismissListener {
private static final String TAG = "SearchManagerService"; private static final String TAG = "SearchManagerService";
private static final boolean DBG = false; private static final boolean DBG = false;
private static final String DISABLE_SEARCH_PROPERTY = "dev.disablesearchdialog";
private static final String SEARCH_UI_THREAD_NAME = "SearchDialog"; private static final String SEARCH_UI_THREAD_NAME = "SearchDialog";
private static final int SEARCH_UI_THREAD_PRIORITY = private static final int SEARCH_UI_THREAD_PRIORITY =
android.os.Process.THREAD_PRIORITY_DEFAULT; android.os.Process.THREAD_PRIORITY_DEFAULT;
@@ -88,12 +86,11 @@ implements DialogInterface.OnCancelListener, DialogInterface.OnDismissListener {
// Identity of currently resumed activity. // Identity of currently resumed activity.
private int mResumedIdent = 0; private int mResumedIdent = 0;
// Allows disabling of search dialog for stress testing runs
private final boolean mDisabledOnBoot;
// True if we have registered our receivers. // True if we have registered our receivers.
private boolean mReceiverRegistered; private boolean mReceiverRegistered;
private volatile boolean mVisible = false;
/** /**
* Creates a new search dialog wrapper and a search UI thread. The search dialog itself will * Creates a new search dialog wrapper and a search UI thread. The search dialog itself will
@@ -104,8 +101,6 @@ implements DialogInterface.OnCancelListener, DialogInterface.OnDismissListener {
public SearchDialogWrapper(Context context) { public SearchDialogWrapper(Context context) {
mContext = context; mContext = context;
mDisabledOnBoot = !TextUtils.isEmpty(SystemProperties.get(DISABLE_SEARCH_PROPERTY));
// Create the search UI thread // Create the search UI thread
HandlerThread t = new HandlerThread(SEARCH_UI_THREAD_NAME, SEARCH_UI_THREAD_PRIORITY); HandlerThread t = new HandlerThread(SEARCH_UI_THREAD_NAME, SEARCH_UI_THREAD_PRIORITY);
t.start(); t.start();
@@ -115,6 +110,10 @@ implements DialogInterface.OnCancelListener, DialogInterface.OnDismissListener {
mSearchUiThread.sendEmptyMessage(MSG_INIT); mSearchUiThread.sendEmptyMessage(MSG_INIT);
} }
public boolean isVisible() {
return mVisible;
}
/** /**
* Initializes the search UI. * Initializes the search UI.
* Must be called from the search UI thread. * Must be called from the search UI thread.
@@ -151,8 +150,10 @@ implements DialogInterface.OnCancelListener, DialogInterface.OnDismissListener {
public void onReceive(Context context, Intent intent) { public void onReceive(Context context, Intent intent) {
String action = intent.getAction(); String action = intent.getAction();
if (Intent.ACTION_CLOSE_SYSTEM_DIALOGS.equals(action)) { if (Intent.ACTION_CLOSE_SYSTEM_DIALOGS.equals(action)) {
if (DBG) debug(Intent.ACTION_CLOSE_SYSTEM_DIALOGS); if (!"search".equals(intent.getStringExtra("reason"))) {
performStopSearch(); if (DBG) debug(Intent.ACTION_CLOSE_SYSTEM_DIALOGS);
performStopSearch();
}
} else if (Intent.ACTION_CONFIGURATION_CHANGED.equals(action)) { } else if (Intent.ACTION_CONFIGURATION_CHANGED.equals(action)) {
if (DBG) debug(Intent.ACTION_CONFIGURATION_CHANGED); if (DBG) debug(Intent.ACTION_CONFIGURATION_CHANGED);
performOnConfigurationChanged(); performOnConfigurationChanged();
@@ -205,7 +206,7 @@ implements DialogInterface.OnCancelListener, DialogInterface.OnDismissListener {
* Can be called from any thread. * Can be called from any thread.
*/ */
public void activityResuming(int ident) { public void activityResuming(int ident) {
if (DBG) debug("startSearch()"); if (DBG) debug("activityResuming(ident=" + ident + ")");
Message msg = Message.obtain(); Message msg = Message.obtain();
msg.what = MSG_ACTIVITY_RESUMING; msg.what = MSG_ACTIVITY_RESUMING;
msg.arg1 = ident; msg.arg1 = ident;
@@ -256,20 +257,6 @@ implements DialogInterface.OnCancelListener, DialogInterface.OnDismissListener {
} }
void updateDialogVisibility() {
if (mStartedIdent != 0) {
// mResumedIdent == 0 means we have just booted and the user
// hasn't yet gone anywhere.
if (mResumedIdent == 0 || mStartedIdent == mResumedIdent) {
if (DBG) Log.v(TAG, "******************* DIALOG: show");
mSearchDialog.show();
} else {
if (DBG) Log.v(TAG, "******************* DIALOG: hide");
mSearchDialog.hide();
}
}
}
/** /**
* Actually launches the search UI. * Actually launches the search UI.
* This must be called on the search UI thread. * This must be called on the search UI thread.
@@ -283,19 +270,20 @@ implements DialogInterface.OnCancelListener, DialogInterface.OnDismissListener {
int ident) { int ident) {
if (DBG) debug("performStartSearch()"); if (DBG) debug("performStartSearch()");
if (mDisabledOnBoot) {
Log.d(TAG, "ignoring start search request because " + DISABLE_SEARCH_PROPERTY
+ " system property is set.");
return;
}
registerBroadcastReceiver(); registerBroadcastReceiver();
mCallback = searchManagerCallback; mCallback = searchManagerCallback;
// clean up any hidden dialog that we were waiting to resume
if (mStartedIdent != 0) {
mSearchDialog.dismiss();
}
mStartedIdent = ident; mStartedIdent = ident;
if (DBG) Log.v(TAG, "******************* DIALOG: start"); if (DBG) Log.v(TAG, "******************* DIALOG: start");
mSearchDialog.show(initialQuery, selectInitialQuery, launchActivity, appSearchData, mSearchDialog.show(initialQuery, selectInitialQuery, launchActivity, appSearchData,
globalSearch); globalSearch);
updateDialogVisibility(); mVisible = true;
} }
/** /**
@@ -306,6 +294,7 @@ implements DialogInterface.OnCancelListener, DialogInterface.OnDismissListener {
if (DBG) debug("performStopSearch()"); if (DBG) debug("performStopSearch()");
if (DBG) Log.v(TAG, "******************* DIALOG: cancel"); if (DBG) Log.v(TAG, "******************* DIALOG: cancel");
mSearchDialog.cancel(); mSearchDialog.cancel();
mVisible = false;
mStartedIdent = 0; mStartedIdent = 0;
} }
@@ -317,7 +306,21 @@ implements DialogInterface.OnCancelListener, DialogInterface.OnDismissListener {
if (DBG) debug("performResumingActivity(): mStartedIdent=" if (DBG) debug("performResumingActivity(): mStartedIdent="
+ mStartedIdent + ", resuming: " + ident); + mStartedIdent + ", resuming: " + ident);
this.mResumedIdent = ident; this.mResumedIdent = ident;
updateDialogVisibility(); if (mStartedIdent != 0) {
if (mStartedIdent == mResumedIdent) {
// we are resuming into the activity where we previously hid the dialog, bring it
// back
if (DBG) Log.v(TAG, "******************* DIALOG: show");
mSearchDialog.show();
mVisible = true;
} else {
// resuming into some other activity; hide ourselves in case we ever come back
// so we can show ourselves quickly again
if (DBG) Log.v(TAG, "******************* DIALOG: hide");
mSearchDialog.hide();
mVisible = false;
}
}
} }
/** /**
@@ -333,27 +336,38 @@ implements DialogInterface.OnCancelListener, DialogInterface.OnDismissListener {
*/ */
public void onDismiss(DialogInterface dialog) { public void onDismiss(DialogInterface dialog) {
if (DBG) debug("onDismiss()"); if (DBG) debug("onDismiss()");
if (mCallback != null) { mStartedIdent = 0;
try { mVisible = false;
// should be safe to do on the search UI thread, since it's a oneway interface callOnDismiss();
mCallback.onDismiss();
} catch (DeadObjectException ex) { // we don't need the callback anymore, release it
// The process that hosted the callback has died, do nothing mCallback = null;
} catch (RemoteException ex) {
Log.e(TAG, "onDismiss() failed: " + ex);
}
// we don't need the callback anymore, release it
mCallback = null;
}
unregisterBroadcastReceiver(); unregisterBroadcastReceiver();
} }
/** /**
* Called by {@link SearchDialog} when the user or activity cancels search. * Called by {@link SearchDialog} when the user or activity cancels search.
* Whenever this method is called, {@link #onDismiss} is always called afterwards. * Whenever this method is called, {@link #onDismiss} is always called afterwards.
*/ */
public void onCancel(DialogInterface dialog) { public void onCancel(DialogInterface dialog) {
if (DBG) debug("onCancel()"); if (DBG) debug("onCancel()");
callOnCancel();
}
private void callOnDismiss() {
if (mCallback == null) return;
try {
// should be safe to do on the search UI thread, since it's a oneway interface
mCallback.onDismiss();
} catch (DeadObjectException ex) {
// The process that hosted the callback has died, do nothing
} catch (RemoteException ex) {
Log.e(TAG, "onDismiss() failed: " + ex);
}
}
private void callOnCancel() {
if (mCallback != null) { if (mCallback != null) {
try { try {
// should be safe to do on the search UI thread, since it's a oneway interface // should be safe to do on the search UI thread, since it's a oneway interface

View File

@@ -238,4 +238,8 @@ public class SearchManagerService extends ISearchManager.Stub {
getSearchDialog().stopSearch(); getSearchDialog().stopSearch();
} }
public boolean isVisible() {
return mSearchDialog != null && mSearchDialog.isVisible();
}
} }