summaryrefslogtreecommitdiffstats
path: root/core/java
diff options
context:
space:
mode:
authorDianne Hackborn <hackbod@google.com>2009-07-14 12:51:00 -0700
committerDianne Hackborn <hackbod@google.com>2009-07-14 12:51:00 -0700
commitdace230043314d6fab1c5ced4b031eaccd814c25 (patch)
tree0c2fbb477f5d94641cee6aa892600b6d34bc96d3 /core/java
parentae4f31706fa0589ede00dfce344779a1570cd2f3 (diff)
parentb06ea706530e6d19eb2a1a9a7ae6c5dd77d80af0 (diff)
downloadframeworks_base-dace230043314d6fab1c5ced4b031eaccd814c25.zip
frameworks_base-dace230043314d6fab1c5ced4b031eaccd814c25.tar.gz
frameworks_base-dace230043314d6fab1c5ced4b031eaccd814c25.tar.bz2
resolved conflicts for merge of b06ea706 to master
Diffstat (limited to 'core/java')
-rw-r--r--core/java/android/app/Activity.java41
-rw-r--r--core/java/android/app/ActivityManagerNative.java50
-rw-r--r--core/java/android/app/ActivityThread.java24
-rw-r--r--core/java/android/app/ApplicationThreadNative.java7
-rw-r--r--core/java/android/app/IActivityController.aidl55
-rw-r--r--core/java/android/app/IActivityManager.java11
-rw-r--r--core/java/android/app/IActivityWatcher.aidl39
-rw-r--r--core/java/android/app/IApplicationThread.java2
-rw-r--r--core/java/android/app/ISearchManager.aidl3
-rw-r--r--core/java/android/app/SearchDialog.java3
-rw-r--r--core/java/android/app/SearchManager.java13
-rw-r--r--core/java/android/content/SyncStorageEngine.java1
-rw-r--r--core/java/android/os/RemoteCallbackList.java24
-rw-r--r--core/java/android/server/search/SearchDialogWrapper.java91
-rw-r--r--core/java/android/server/search/SearchManagerService.java24
15 files changed, 287 insertions, 101 deletions
diff --git a/core/java/android/app/Activity.java b/core/java/android/app/Activity.java
index 6c2560d..4ac3b9e 100644
--- a/core/java/android/app/Activity.java
+++ b/core/java/android/app/Activity.java
@@ -612,6 +612,7 @@ public class Activity extends ContextThemeWrapper
// set by the thread after the constructor and before onCreate(Bundle savedInstanceState) is called.
private Instrumentation mInstrumentation;
private IBinder mToken;
+ private int mIdent;
/*package*/ String mEmbeddedID;
private Application mApplication;
/*package*/ Intent mIntent;
@@ -789,9 +790,6 @@ public class Activity extends ContextThemeWrapper
protected void onCreate(Bundle savedInstanceState) {
mVisibleFromClient = mWindow.getWindowStyle().getBoolean(
com.android.internal.R.styleable.Window_windowNoDisplay, true);
- // uses super.getSystemService() since this.getSystemService() looks at the
- // mSearchManager field.
- mSearchManager = (SearchManager) super.getSystemService(Context.SEARCH_SERVICE);
mCalled = true;
}
@@ -2531,6 +2529,7 @@ public class Activity extends ContextThemeWrapper
*/
public void startSearch(String initialQuery, boolean selectInitialQuery,
Bundle appSearchData, boolean globalSearch) {
+ ensureSearchManager();
mSearchManager.startSearch(initialQuery, selectInitialQuery, getComponentName(),
appSearchData, globalSearch);
}
@@ -3241,6 +3240,24 @@ public class Activity extends ContextThemeWrapper
return getSharedPreferences(getLocalClassName(), mode);
}
+ private void ensureSearchManager() {
+ if (mSearchManager != null) {
+ return;
+ }
+
+ // uses super.getSystemService() since this.getSystemService() looks at the
+ // mSearchManager field.
+ mSearchManager = (SearchManager) super.getSystemService(Context.SEARCH_SERVICE);
+ int ident = mIdent;
+ if (ident == 0) {
+ if (mParent != null) ident = mParent.mIdent;
+ if (ident == 0) {
+ throw new IllegalArgumentException("no ident");
+ }
+ }
+ mSearchManager.setIdent(ident);
+ }
+
@Override
public Object getSystemService(String name) {
if (getBaseContext() == null) {
@@ -3251,6 +3268,7 @@ public class Activity extends ContextThemeWrapper
if (WINDOW_SERVICE.equals(name)) {
return mWindowManager;
} else if (SEARCH_SERVICE.equals(name)) {
+ ensureSearchManager();
return mSearchManager;
}
return super.getSystemService(name);
@@ -3450,14 +3468,17 @@ public class Activity extends ContextThemeWrapper
Application application, Intent intent, ActivityInfo info, CharSequence title,
Activity parent, String id, Object lastNonConfigurationInstance,
Configuration config) {
- attach(context, aThread, instr, token, application, intent, info, title, parent, id,
+ attach(context, aThread, instr, token, 0, application, intent, info, title, parent, id,
lastNonConfigurationInstance, null, config);
}
- final void attach(Context context, ActivityThread aThread, Instrumentation instr, IBinder token,
- Application application, Intent intent, ActivityInfo info, CharSequence title,
- Activity parent, String id, Object lastNonConfigurationInstance,
- HashMap<String,Object> lastNonConfigurationChildInstances, Configuration config) {
+ final void attach(Context context, ActivityThread aThread,
+ Instrumentation instr, IBinder token, int ident,
+ Application application, Intent intent, ActivityInfo info,
+ CharSequence title, Activity parent, String id,
+ Object lastNonConfigurationInstance,
+ HashMap<String,Object> lastNonConfigurationChildInstances,
+ Configuration config) {
attachBaseContext(context);
mWindow = PolicyManager.makeNewWindow(this);
@@ -3470,6 +3491,7 @@ public class Activity extends ContextThemeWrapper
mMainThread = aThread;
mInstrumentation = instr;
mToken = token;
+ mIdent = ident;
mApplication = application;
mIntent = intent;
mComponent = intent.getComponent();
@@ -3554,9 +3576,6 @@ public class Activity extends ContextThemeWrapper
final void performPause() {
onPause();
-
- // dismiss the search dialog if it is open
- mSearchManager.stopSearch();
}
final void performUserLeaving() {
diff --git a/core/java/android/app/ActivityManagerNative.java b/core/java/android/app/ActivityManagerNative.java
index dfa8139..ec7714d 100644
--- a/core/java/android/app/ActivityManagerNative.java
+++ b/core/java/android/app/ActivityManagerNative.java
@@ -881,11 +881,11 @@ public abstract class ActivityManagerNative extends Binder implements IActivityM
return true;
}
- case SET_ACTIVITY_WATCHER_TRANSACTION: {
+ case SET_ACTIVITY_CONTROLLER_TRANSACTION: {
data.enforceInterface(IActivityManager.descriptor);
- IActivityWatcher watcher = IActivityWatcher.Stub.asInterface(
+ IActivityController watcher = IActivityController.Stub.asInterface(
data.readStrongBinder());
- setActivityWatcher(watcher);
+ setActivityController(watcher);
return true;
}
@@ -1052,6 +1052,22 @@ public abstract class ActivityManagerNative extends Binder implements IActivityM
reply.writeNoException();
return true;
}
+
+ case REGISTER_ACTIVITY_WATCHER_TRANSACTION: {
+ data.enforceInterface(IActivityManager.descriptor);
+ IActivityWatcher watcher = IActivityWatcher.Stub.asInterface(
+ data.readStrongBinder());
+ registerActivityWatcher(watcher);
+ return true;
+ }
+
+ case UNREGISTER_ACTIVITY_WATCHER_TRANSACTION: {
+ data.enforceInterface(IActivityManager.descriptor);
+ IActivityWatcher watcher = IActivityWatcher.Stub.asInterface(
+ data.readStrongBinder());
+ unregisterActivityWatcher(watcher);
+ return true;
+ }
}
return super.onTransact(code, data, reply, flags);
@@ -2105,13 +2121,13 @@ class ActivityManagerProxy implements IActivityManager
data.recycle();
reply.recycle();
}
- public void setActivityWatcher(IActivityWatcher watcher) throws RemoteException
+ public void setActivityController(IActivityController watcher) throws RemoteException
{
Parcel data = Parcel.obtain();
Parcel reply = Parcel.obtain();
data.writeInterfaceToken(IActivityManager.descriptor);
data.writeStrongBinder(watcher != null ? watcher.asBinder() : null);
- mRemote.transact(SET_ACTIVITY_WATCHER_TRANSACTION, data, reply, 0);
+ mRemote.transact(SET_ACTIVITY_CONTROLLER_TRANSACTION, data, reply, 0);
reply.readException();
data.recycle();
reply.recycle();
@@ -2290,5 +2306,29 @@ class ActivityManagerProxy implements IActivityManager
data.recycle();
}
+ public void registerActivityWatcher(IActivityWatcher watcher)
+ throws RemoteException {
+ Parcel data = Parcel.obtain();
+ Parcel reply = Parcel.obtain();
+ data.writeInterfaceToken(IActivityManager.descriptor);
+ data.writeStrongBinder(watcher != null ? watcher.asBinder() : null);
+ mRemote.transact(REGISTER_ACTIVITY_WATCHER_TRANSACTION, data, reply, 0);
+ reply.readException();
+ data.recycle();
+ reply.recycle();
+ }
+
+ public void unregisterActivityWatcher(IActivityWatcher watcher)
+ throws RemoteException {
+ Parcel data = Parcel.obtain();
+ Parcel reply = Parcel.obtain();
+ data.writeInterfaceToken(IActivityManager.descriptor);
+ data.writeStrongBinder(watcher != null ? watcher.asBinder() : null);
+ mRemote.transact(UNREGISTER_ACTIVITY_WATCHER_TRANSACTION, data, reply, 0);
+ reply.readException();
+ data.recycle();
+ reply.recycle();
+ }
+
private IBinder mRemote;
}
diff --git a/core/java/android/app/ActivityThread.java b/core/java/android/app/ActivityThread.java
index 27e8fb5..f2814f2 100644
--- a/core/java/android/app/ActivityThread.java
+++ b/core/java/android/app/ActivityThread.java
@@ -1090,6 +1090,7 @@ public final class ActivityThread {
private static final class ActivityRecord {
IBinder token;
+ int ident;
Intent intent;
Bundle state;
Activity activity;
@@ -1299,12 +1300,13 @@ public final class ActivityThread {
// we use token to identify this activity without having to send the
// activity itself back to the activity manager. (matters more with ipc)
- public final void scheduleLaunchActivity(Intent intent, IBinder token,
+ public final void scheduleLaunchActivity(Intent intent, IBinder token, int ident,
ActivityInfo info, Bundle state, List<ResultInfo> pendingResults,
List<Intent> pendingNewIntents, boolean notResumed, boolean isForward) {
ActivityRecord r = new ActivityRecord();
r.token = token;
+ r.ident = ident;
r.intent = intent;
r.activityInfo = info;
r.state = state;
@@ -2197,21 +2199,11 @@ public final class ActivityThread {
}
public final Activity startActivityNow(Activity parent, String id,
- Intent intent, IBinder token, Bundle state) {
- ActivityInfo aInfo = resolveActivityInfo(intent);
- return startActivityNow(parent, id, intent, aInfo, token, state);
- }
-
- public final Activity startActivityNow(Activity parent, String id,
- Intent intent, ActivityInfo activityInfo, IBinder token, Bundle state) {
- return startActivityNow(parent, id, intent, activityInfo, token, state, null);
- }
-
- public final Activity startActivityNow(Activity parent, String id,
Intent intent, ActivityInfo activityInfo, IBinder token, Bundle state,
Object lastNonConfigurationInstance) {
ActivityRecord r = new ActivityRecord();
r.token = token;
+ r.ident = 0;
r.intent = intent;
r.state = state;
r.parent = parent;
@@ -2335,10 +2327,10 @@ public final class ActivityThread {
appContext.setOuterContext(activity);
CharSequence title = r.activityInfo.loadLabel(appContext.getPackageManager());
Configuration config = new Configuration(mConfiguration);
- activity.attach(appContext, this, getInstrumentation(), r.token, app,
- r.intent, r.activityInfo, title, r.parent, r.embeddedID,
- r.lastNonConfigurationInstance, r.lastNonConfigurationChildInstances,
- config);
+ activity.attach(appContext, this, getInstrumentation(), r.token,
+ r.ident, app, r.intent, r.activityInfo, title, r.parent,
+ r.embeddedID, r.lastNonConfigurationInstance,
+ r.lastNonConfigurationChildInstances, config);
if (customIntent != null) {
activity.mIntent = customIntent;
diff --git a/core/java/android/app/ApplicationThreadNative.java b/core/java/android/app/ApplicationThreadNative.java
index b052c99..a3c6325 100644
--- a/core/java/android/app/ApplicationThreadNative.java
+++ b/core/java/android/app/ApplicationThreadNative.java
@@ -119,13 +119,15 @@ public abstract class ApplicationThreadNative extends Binder
data.enforceInterface(IApplicationThread.descriptor);
Intent intent = Intent.CREATOR.createFromParcel(data);
IBinder b = data.readStrongBinder();
+ int ident = data.readInt();
ActivityInfo info = ActivityInfo.CREATOR.createFromParcel(data);
Bundle state = data.readBundle();
List<ResultInfo> ri = data.createTypedArrayList(ResultInfo.CREATOR);
List<Intent> pi = data.createTypedArrayList(Intent.CREATOR);
boolean notResumed = data.readInt() != 0;
boolean isForward = data.readInt() != 0;
- scheduleLaunchActivity(intent, b, info, state, ri, pi, notResumed, isForward);
+ scheduleLaunchActivity(intent, b, ident, info, state, ri, pi,
+ notResumed, isForward);
return true;
}
@@ -442,7 +444,7 @@ class ApplicationThreadProxy implements IApplicationThread {
data.recycle();
}
- public final void scheduleLaunchActivity(Intent intent, IBinder token,
+ public final void scheduleLaunchActivity(Intent intent, IBinder token, int ident,
ActivityInfo info, Bundle state, List<ResultInfo> pendingResults,
List<Intent> pendingNewIntents, boolean notResumed, boolean isForward)
throws RemoteException {
@@ -450,6 +452,7 @@ class ApplicationThreadProxy implements IApplicationThread {
data.writeInterfaceToken(IApplicationThread.descriptor);
intent.writeToParcel(data, 0);
data.writeStrongBinder(token);
+ data.writeInt(ident);
info.writeToParcel(data, 0);
data.writeBundle(state);
data.writeTypedList(pendingResults);
diff --git a/core/java/android/app/IActivityController.aidl b/core/java/android/app/IActivityController.aidl
new file mode 100644
index 0000000..8f6b252
--- /dev/null
+++ b/core/java/android/app/IActivityController.aidl
@@ -0,0 +1,55 @@
+/*
+**
+** Copyright 2009, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+** http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+
+package android.app;
+
+import android.content.Intent;
+
+/**
+ * Testing interface to monitor what is happening in the activity manager
+ * while tests are running. Not for normal application development.
+ * {@hide}
+ */
+interface IActivityController
+{
+ /**
+ * The system is trying to start an activity. Return true to allow
+ * it to be started as normal, or false to cancel/reject this activity.
+ */
+ boolean activityStarting(in Intent intent, String pkg);
+
+ /**
+ * The system is trying to return to an activity. Return true to allow
+ * it to be resumed as normal, or false to cancel/reject this activity.
+ */
+ boolean activityResuming(String pkg);
+
+ /**
+ * An application process has crashed (in Java). Return true for the
+ * normal error recovery (app crash dialog) to occur, false to kill
+ * it immediately.
+ */
+ boolean appCrashed(String processName, int pid, String shortMsg,
+ String longMsg, in byte[] crashData);
+
+ /**
+ * An application process is not responding. Return 0 to show the "app
+ * not responding" dialog, 1 to continue waiting, or -1 to kill it
+ * immediately.
+ */
+ int appNotResponding(String processName, int pid, String processStats);
+}
diff --git a/core/java/android/app/IActivityManager.java b/core/java/android/app/IActivityManager.java
index 3ec7938..ee1b69b 100644
--- a/core/java/android/app/IActivityManager.java
+++ b/core/java/android/app/IActivityManager.java
@@ -216,7 +216,7 @@ public interface IActivityManager extends IInterface {
String packageName, boolean waitForDebugger, boolean persistent)
throws RemoteException;
public void setAlwaysFinish(boolean enabled) throws RemoteException;
- public void setActivityWatcher(IActivityWatcher watcher)
+ public void setActivityController(IActivityController watcher)
throws RemoteException;
public void enterSafeMode() throws RemoteException;
@@ -257,6 +257,11 @@ public interface IActivityManager extends IInterface {
public void stopAppSwitches() throws RemoteException;
public void resumeAppSwitches() throws RemoteException;
+ public void registerActivityWatcher(IActivityWatcher watcher)
+ throws RemoteException;
+ public void unregisterActivityWatcher(IActivityWatcher watcher)
+ throws RemoteException;
+
/*
* Private non-Binder interfaces
*/
@@ -372,7 +377,7 @@ public interface IActivityManager extends IInterface {
int CHECK_URI_PERMISSION_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+53;
int GRANT_URI_PERMISSION_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+54;
int REVOKE_URI_PERMISSION_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+55;
- int SET_ACTIVITY_WATCHER_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+56;
+ int SET_ACTIVITY_CONTROLLER_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+56;
int SHOW_WAITING_FOR_DEBUGGER_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+57;
int SIGNAL_PERSISTENT_PROCESSES_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+58;
int GET_RECENT_TASKS_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+59;
@@ -408,4 +413,6 @@ public interface IActivityManager extends IInterface {
int START_BACKUP_AGENT_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+89;
int BACKUP_AGENT_CREATED_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+90;
int UNBIND_BACKUP_AGENT_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+91;
+ int REGISTER_ACTIVITY_WATCHER_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+92;
+ int UNREGISTER_ACTIVITY_WATCHER_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+93;
}
diff --git a/core/java/android/app/IActivityWatcher.aidl b/core/java/android/app/IActivityWatcher.aidl
index f13a385..5d36e3f 100644
--- a/core/java/android/app/IActivityWatcher.aidl
+++ b/core/java/android/app/IActivityWatcher.aidl
@@ -1,6 +1,6 @@
-/* //device/java/android/android/app/IInstrumentationWatcher.aidl
+/*
**
-** Copyright 2007, The Android Open Source Project
+** Copyright 2009, The Android Open Source Project
**
** Licensed under the Apache License, Version 2.0 (the "License");
** you may not use this file except in compliance with the License.
@@ -17,39 +17,10 @@
package android.app;
-import android.content.Intent;
-
/**
- * Testing interface to monitor what is happening in the activity manager
- * while tests are running. Not for normal application development.
+ * Callback interface to watch the user's traversal through activities.
* {@hide}
*/
-interface IActivityWatcher
-{
- /**
- * The system is trying to start an activity. Return true to allow
- * it to be started as normal, or false to cancel/reject this activity.
- */
- boolean activityStarting(in Intent intent, String pkg);
-
- /**
- * The system is trying to return to an activity. Return true to allow
- * it to be resumed as normal, or false to cancel/reject this activity.
- */
- boolean activityResuming(String pkg);
-
- /**
- * An application process has crashed (in Java). Return true for the
- * normal error recovery (app crash dialog) to occur, false to kill
- * it immediately.
- */
- boolean appCrashed(String processName, int pid, String shortMsg,
- String longMsg, in byte[] crashData);
-
- /**
- * An application process is not responding. Return 0 to show the "app
- * not responding" dialog, 1 to continue waiting, or -1 to kill it
- * immediately.
- */
- int appNotResponding(String processName, int pid, String processStats);
+oneway interface IActivityWatcher {
+ void activityResuming(int activityId);
}
diff --git a/core/java/android/app/IApplicationThread.java b/core/java/android/app/IApplicationThread.java
index c0bc2a0..c915770 100644
--- a/core/java/android/app/IApplicationThread.java
+++ b/core/java/android/app/IApplicationThread.java
@@ -49,7 +49,7 @@ public interface IApplicationThread extends IInterface {
void scheduleWindowVisibility(IBinder token, boolean showWindow) throws RemoteException;
void scheduleResumeActivity(IBinder token, boolean isForward) throws RemoteException;
void scheduleSendResult(IBinder token, List<ResultInfo> results) throws RemoteException;
- void scheduleLaunchActivity(Intent intent, IBinder token,
+ void scheduleLaunchActivity(Intent intent, IBinder token, int ident,
ActivityInfo info, Bundle state, List<ResultInfo> pendingResults,
List<Intent> pendingNewIntents, boolean notResumed, boolean isForward)
throws RemoteException;
diff --git a/core/java/android/app/ISearchManager.aidl b/core/java/android/app/ISearchManager.aidl
index 5b62192..84a6085 100644
--- a/core/java/android/app/ISearchManager.aidl
+++ b/core/java/android/app/ISearchManager.aidl
@@ -34,6 +34,7 @@ interface ISearchManager {
in ComponentName launchActivity,
in Bundle appSearchData,
boolean globalSearch,
- ISearchManagerCallback searchManagerCallback);
+ ISearchManagerCallback searchManagerCallback,
+ int ident);
void stopSearch();
}
diff --git a/core/java/android/app/SearchDialog.java b/core/java/android/app/SearchDialog.java
index 9f44c7e..13eb034 100644
--- a/core/java/android/app/SearchDialog.java
+++ b/core/java/android/app/SearchDialog.java
@@ -752,6 +752,9 @@ public class SearchDialog extends Dialog implements OnItemClickListener, OnItemS
}
public void afterTextChanged(Editable s) {
+ if (mSearchable == null) {
+ return;
+ }
if (mSearchable.autoUrlDetect() && !mSearchAutoComplete.isPerformingCompletion()) {
// The user changed the query, check if it is a URL and if so change the search
// button in the soft keyboard to the 'Go' button.
diff --git a/core/java/android/app/SearchManager.java b/core/java/android/app/SearchManager.java
index 0291882..b795a54 100644
--- a/core/java/android/app/SearchManager.java
+++ b/core/java/android/app/SearchManager.java
@@ -1531,6 +1531,8 @@ public class SearchManager
private final Context mContext;
+ private int mIdent;
+
// package private since they are used by the inner class SearchManagerCallback
/* package */ boolean mIsShowing = false;
/* package */ final Handler mHandler;
@@ -1546,6 +1548,13 @@ public class SearchManager
ServiceManager.getService(Context.SEARCH_SERVICE));
}
+ /*package*/ void setIdent(int ident) {
+ if (mIdent != 0) {
+ throw new IllegalStateException("mIdent already set");
+ }
+ mIdent = ident;
+ }
+
/**
* Launch search UI.
*
@@ -1593,11 +1602,13 @@ public class SearchManager
boolean globalSearch) {
if (DBG) debug("startSearch(), mIsShowing=" + mIsShowing);
if (mIsShowing) return;
+ if (mIdent == 0) throw new IllegalArgumentException(
+ "Called from outside of an Activity context");
try {
mIsShowing = true;
// activate the search manager and start it up!
mService.startSearch(initialQuery, selectInitialQuery, launchActivity, appSearchData,
- globalSearch, mSearchManagerCallback);
+ globalSearch, mSearchManagerCallback, mIdent);
} catch (RemoteException ex) {
Log.e(TAG, "startSearch() failed: " + ex);
}
diff --git a/core/java/android/content/SyncStorageEngine.java b/core/java/android/content/SyncStorageEngine.java
index 13bcdd3..9d2efb5 100644
--- a/core/java/android/content/SyncStorageEngine.java
+++ b/core/java/android/content/SyncStorageEngine.java
@@ -326,6 +326,7 @@ public class SyncStorageEngine extends Handler {
}
reports.add(mChangeListeners.getBroadcastItem(i));
}
+ mChangeListeners.finishBroadcast();
}
if (DEBUG) Log.v(TAG, "reportChange " + which + " to: " + reports);
diff --git a/core/java/android/os/RemoteCallbackList.java b/core/java/android/os/RemoteCallbackList.java
index 5ab305e..b74af16 100644
--- a/core/java/android/os/RemoteCallbackList.java
+++ b/core/java/android/os/RemoteCallbackList.java
@@ -50,6 +50,7 @@ public class RemoteCallbackList<E extends IInterface> {
/*package*/ HashMap<IBinder, Callback> mCallbacks
= new HashMap<IBinder, Callback>();
private Object[] mActiveBroadcast;
+ private int mBroadcastCount = -1;
private boolean mKilled = false;
private final class Callback implements IBinder.DeathRecipient {
@@ -196,15 +197,16 @@ public class RemoteCallbackList<E extends IInterface> {
* This creates a copy of the callback list, which you can retrieve items
* from using {@link #getBroadcastItem}. Note that only one broadcast can
* be active at a time, so you must be sure to always call this from the
- * same thread (usually by scheduling with {@link Handler} or
+ * same thread (usually by scheduling with {@link Handler}) or
* do your own synchronization. You must call {@link #finishBroadcast}
* when done.
*
* <p>A typical loop delivering a broadcast looks like this:
*
* <pre>
- * final int N = callbacks.beginBroadcast();
- * for (int i=0; i&lt;N; i++) {
+ * int i = callbacks.beginBroadcast();
+ * while (i &gt; 0) {
+ * i--;
* try {
* callbacks.getBroadcastItem(i).somethingHappened();
* } catch (RemoteException e) {
@@ -223,7 +225,12 @@ public class RemoteCallbackList<E extends IInterface> {
*/
public int beginBroadcast() {
synchronized (mCallbacks) {
- final int N = mCallbacks.size();
+ if (mBroadcastCount > 0) {
+ throw new IllegalStateException(
+ "beginBroadcast() called while already in a broadcast");
+ }
+
+ final int N = mBroadcastCount = mCallbacks.size();
if (N <= 0) {
return 0;
}
@@ -282,12 +289,19 @@ public class RemoteCallbackList<E extends IInterface> {
* @see #beginBroadcast
*/
public void finishBroadcast() {
+ if (mBroadcastCount < 0) {
+ throw new IllegalStateException(
+ "finishBroadcast() called outside of a broadcast");
+ }
+
Object[] active = mActiveBroadcast;
if (active != null) {
- final int N = active.length;
+ final int N = mBroadcastCount;
for (int i=0; i<N; i++) {
active[i] = null;
}
}
+
+ mBroadcastCount = -1;
}
}
diff --git a/core/java/android/server/search/SearchDialogWrapper.java b/core/java/android/server/search/SearchDialogWrapper.java
index dbc1e7f..67be6a6 100644
--- a/core/java/android/server/search/SearchDialogWrapper.java
+++ b/core/java/android/server/search/SearchDialogWrapper.java
@@ -63,12 +63,13 @@ implements DialogInterface.OnCancelListener, DialogInterface.OnDismissListener {
private static final int MSG_START_SEARCH = 1;
// Takes no arguments
private static final int MSG_STOP_SEARCH = 2;
- // Takes no arguments
- private static final int MSG_ON_CONFIGURATION_CHANGED = 3;
+ // arg1 is activity id
+ private static final int MSG_ACTIVITY_RESUMING = 3;
private static final String KEY_INITIAL_QUERY = "q";
private static final String KEY_LAUNCH_ACTIVITY = "a";
private static final String KEY_APP_SEARCH_DATA = "d";
+ private static final String KEY_IDENT= "i";
// Context used for getting search UI resources
private final Context mContext;
@@ -82,9 +83,18 @@ implements DialogInterface.OnCancelListener, DialogInterface.OnDismissListener {
// If the search UI is visible, this is the callback for the client that showed it.
ISearchManagerCallback mCallback = null;
+ // Identity of last activity that started search.
+ private int mStartedIdent = 0;
+
+ // Identity of currently resumed activity.
+ private int mResumedIdent = 0;
+
// Allows disabling of search dialog for stress testing runs
private final boolean mDisabledOnBoot;
+ // True if we have registered our receivers.
+ private boolean mReceiverRegistered;
+
/**
* Creates a new search dialog wrapper and a search UI thread. The search dialog itself will
* be created some asynchronously on the search UI thread.
@@ -116,15 +126,21 @@ implements DialogInterface.OnCancelListener, DialogInterface.OnDismissListener {
}
private void registerBroadcastReceiver() {
- IntentFilter closeDialogsFilter = new IntentFilter(Intent.ACTION_CLOSE_SYSTEM_DIALOGS);
- mContext.registerReceiver(mBroadcastReceiver, closeDialogsFilter);
- IntentFilter configurationChangedFilter =
- new IntentFilter(Intent.ACTION_CONFIGURATION_CHANGED);
- mContext.registerReceiver(mBroadcastReceiver, configurationChangedFilter);
+ if (!mReceiverRegistered) {
+ IntentFilter filter = new IntentFilter(
+ Intent.ACTION_CLOSE_SYSTEM_DIALOGS);
+ filter.addAction(Intent.ACTION_CONFIGURATION_CHANGED);
+ mContext.registerReceiver(mBroadcastReceiver, filter, null,
+ mSearchUiThread);
+ mReceiverRegistered = true;
+ }
}
private void unregisterBroadcastReceiver() {
- mContext.unregisterReceiver(mBroadcastReceiver);
+ if (mReceiverRegistered) {
+ mContext.unregisterReceiver(mBroadcastReceiver);
+ mReceiverRegistered = false;
+ }
}
/**
@@ -136,10 +152,10 @@ implements DialogInterface.OnCancelListener, DialogInterface.OnDismissListener {
String action = intent.getAction();
if (Intent.ACTION_CLOSE_SYSTEM_DIALOGS.equals(action)) {
if (DBG) debug(Intent.ACTION_CLOSE_SYSTEM_DIALOGS);
- stopSearch();
+ performStopSearch();
} else if (Intent.ACTION_CONFIGURATION_CHANGED.equals(action)) {
if (DBG) debug(Intent.ACTION_CONFIGURATION_CHANGED);
- onConfigurationChanged();
+ performOnConfigurationChanged();
}
}
};
@@ -159,7 +175,8 @@ implements DialogInterface.OnCancelListener, DialogInterface.OnDismissListener {
final ComponentName launchActivity,
final Bundle appSearchData,
final boolean globalSearch,
- final ISearchManagerCallback searchManagerCallback) {
+ final ISearchManagerCallback searchManagerCallback,
+ int ident) {
if (DBG) debug("startSearch()");
Message msg = Message.obtain();
msg.what = MSG_START_SEARCH;
@@ -170,6 +187,7 @@ implements DialogInterface.OnCancelListener, DialogInterface.OnDismissListener {
msgData.putString(KEY_INITIAL_QUERY, initialQuery);
msgData.putParcelable(KEY_LAUNCH_ACTIVITY, launchActivity);
msgData.putBundle(KEY_APP_SEARCH_DATA, appSearchData);
+ msgData.putInt(KEY_IDENT, ident);
mSearchUiThread.sendMessage(msg);
}
@@ -183,12 +201,15 @@ implements DialogInterface.OnCancelListener, DialogInterface.OnDismissListener {
}
/**
- * Updates the search UI in response to a configuration change.
+ * Updates the currently resumed activity.
* Can be called from any thread.
*/
- void onConfigurationChanged() {
- if (DBG) debug("onConfigurationChanged()");
- mSearchUiThread.sendEmptyMessage(MSG_ON_CONFIGURATION_CHANGED);
+ public void activityResuming(int ident) {
+ if (DBG) debug("startSearch()");
+ Message msg = Message.obtain();
+ msg.what = MSG_ACTIVITY_RESUMING;
+ msg.arg1 = ident;
+ mSearchUiThread.sendMessage(msg);
}
//
@@ -213,8 +234,8 @@ implements DialogInterface.OnCancelListener, DialogInterface.OnDismissListener {
case MSG_STOP_SEARCH:
performStopSearch();
break;
- case MSG_ON_CONFIGURATION_CHANGED:
- performOnConfigurationChanged();
+ case MSG_ACTIVITY_RESUMING:
+ performActivityResuming(msg.arg1);
break;
}
}
@@ -228,12 +249,27 @@ implements DialogInterface.OnCancelListener, DialogInterface.OnDismissListener {
Bundle appSearchData = msgData.getBundle(KEY_APP_SEARCH_DATA);
boolean globalSearch = msg.arg2 != 0;
ISearchManagerCallback searchManagerCallback = (ISearchManagerCallback) msg.obj;
+ int ident = msgData.getInt(KEY_IDENT);
performStartSearch(initialQuery, selectInitialQuery, launchActivity,
- appSearchData, globalSearch, searchManagerCallback);
+ appSearchData, globalSearch, searchManagerCallback, ident);
}
}
+ 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.
* This must be called on the search UI thread.
@@ -243,7 +279,8 @@ implements DialogInterface.OnCancelListener, DialogInterface.OnDismissListener {
ComponentName launchActivity,
Bundle appSearchData,
boolean globalSearch,
- ISearchManagerCallback searchManagerCallback) {
+ ISearchManagerCallback searchManagerCallback,
+ int ident) {
if (DBG) debug("performStartSearch()");
if (mDisabledOnBoot) {
@@ -254,8 +291,11 @@ implements DialogInterface.OnCancelListener, DialogInterface.OnDismissListener {
registerBroadcastReceiver();
mCallback = searchManagerCallback;
+ mStartedIdent = ident;
+ if (DBG) Log.v(TAG, "******************* DIALOG: start");
mSearchDialog.show(initialQuery, selectInitialQuery, launchActivity, appSearchData,
globalSearch);
+ updateDialogVisibility();
}
/**
@@ -264,7 +304,20 @@ implements DialogInterface.OnCancelListener, DialogInterface.OnDismissListener {
*/
void performStopSearch() {
if (DBG) debug("performStopSearch()");
+ if (DBG) Log.v(TAG, "******************* DIALOG: cancel");
mSearchDialog.cancel();
+ mStartedIdent = 0;
+ }
+
+ /**
+ * Updates the resumed activity
+ * This must be called on the search UI thread.
+ */
+ void performActivityResuming(int ident) {
+ if (DBG) debug("performResumingActivity(): mStartedIdent="
+ + mStartedIdent + ", resuming: " + ident);
+ this.mResumedIdent = ident;
+ updateDialogVisibility();
}
/**
diff --git a/core/java/android/server/search/SearchManagerService.java b/core/java/android/server/search/SearchManagerService.java
index f9c0f1a..7629912 100644
--- a/core/java/android/server/search/SearchManagerService.java
+++ b/core/java/android/server/search/SearchManagerService.java
@@ -16,6 +16,8 @@
package android.server.search;
+import android.app.ActivityManagerNative;
+import android.app.IActivityWatcher;
import android.app.ISearchManager;
import android.app.ISearchManagerCallback;
import android.app.SearchManager;
@@ -26,6 +28,7 @@ import android.content.Intent;
import android.content.IntentFilter;
import android.os.Bundle;
import android.os.Handler;
+import android.os.RemoteException;
import android.util.Log;
import java.util.List;
@@ -71,8 +74,11 @@ public class SearchManagerService extends ISearchManager.Stub {
* Initializes the list of searchable activities and the search UI.
*/
void initialize() {
- ensureSearchablesCreated();
- ensureSearchDialogCreated();
+ try {
+ ActivityManagerNative.getDefault().registerActivityWatcher(
+ mActivityWatcher);
+ } catch (RemoteException e) {
+ }
}
private synchronized void ensureSearchablesCreated() {
@@ -126,6 +132,14 @@ public class SearchManagerService extends ISearchManager.Stub {
}
};
+ private IActivityWatcher.Stub mActivityWatcher = new IActivityWatcher.Stub() {
+ public void activityResuming(int activityId) throws RemoteException {
+ if (DBG) Log.i("foo", "********************** resuming: " + activityId);
+ if (mSearchDialog == null) return;
+ mSearchDialog.activityResuming(activityId);
+ }
+ };
+
/**
* Informs all listeners that the list of searchables has been updated.
*/
@@ -206,13 +220,15 @@ public class SearchManagerService extends ISearchManager.Stub {
ComponentName launchActivity,
Bundle appSearchData,
boolean globalSearch,
- ISearchManagerCallback searchManagerCallback) {
+ ISearchManagerCallback searchManagerCallback,
+ int ident) {
getSearchDialog().startSearch(initialQuery,
selectInitialQuery,
launchActivity,
appSearchData,
globalSearch,
- searchManagerCallback);
+ searchManagerCallback,
+ ident);
}
/**