summaryrefslogtreecommitdiffstats
path: root/core/java/android/server
diff options
context:
space:
mode:
authorAmith Yamasani <yamasani@google.com>2012-10-07 08:17:46 -0700
committerAmith Yamasani <yamasani@google.com>2012-10-07 15:56:34 -0700
commit64442c11555d828a41af0b8a58ab933357889061 (patch)
tree4a4050e4932bfd85f00a23915660dc8ed01aa1c4 /core/java/android/server
parent1ad0fd9c04ae2e352c59129b979145e662f25cbc (diff)
downloadframeworks_base-64442c11555d828a41af0b8a58ab933357889061.zip
frameworks_base-64442c11555d828a41af0b8a58ab933357889061.tar.gz
frameworks_base-64442c11555d828a41af0b8a58ab933357889061.tar.bz2
Fix resource reading for secondary users
Bug: 7086881 Load resources for the correct user. Also clean up package monitoring and locking. Added dump method to SearchManagerService. Sneaking in a change to make crash dialogs visible to current user. Change-Id: Id56dd15428d66084de995e28be242db27c15fda3
Diffstat (limited to 'core/java/android/server')
-rw-r--r--core/java/android/server/search/SearchManagerService.java83
-rw-r--r--core/java/android/server/search/Searchables.java104
2 files changed, 120 insertions, 67 deletions
diff --git a/core/java/android/server/search/SearchManagerService.java b/core/java/android/server/search/SearchManagerService.java
index bc3efdd..de4dd88 100644
--- a/core/java/android/server/search/SearchManagerService.java
+++ b/core/java/android/server/search/SearchManagerService.java
@@ -17,6 +17,7 @@
package android.server.search;
import com.android.internal.content.PackageMonitor;
+import com.android.internal.util.IndentingPrintWriter;
import android.app.ActivityManager;
import android.app.ActivityManagerNative;
@@ -44,6 +45,8 @@ import android.util.Log;
import android.util.Slog;
import android.util.SparseArray;
+import java.io.FileDescriptor;
+import java.io.PrintWriter;
import java.util.List;
/**
@@ -59,9 +62,7 @@ public class SearchManagerService extends ISearchManager.Stub {
private final Context mContext;
// This field is initialized lazily in getSearchables(), and then never modified.
- private SparseArray<Searchables> mSearchables;
-
- private ContentObserver mGlobalSearchObserver;
+ private final SparseArray<Searchables> mSearchables = new SparseArray<Searchables>();
/**
* Initializes the Search Manager service in the provided system context.
@@ -73,29 +74,39 @@ public class SearchManagerService extends ISearchManager.Stub {
mContext = context;
mContext.registerReceiver(new BootCompletedReceiver(),
new IntentFilter(Intent.ACTION_BOOT_COMPLETED));
- mGlobalSearchObserver = new GlobalSearchProviderObserver(
- mContext.getContentResolver());
+ mContext.registerReceiver(new UserReceiver(),
+ new IntentFilter(Intent.ACTION_USER_REMOVED));
+ new MyPackageMonitor().register(context, null, UserHandle.ALL, true);
}
- private synchronized Searchables getSearchables(int userId) {
- if (mSearchables == null) {
- new MyPackageMonitor().register(mContext, null, true);
- mSearchables = new SparseArray<Searchables>();
+ private Searchables getSearchables(int userId) {
+ long origId = Binder.clearCallingIdentity();
+ try {
+ boolean userExists = ((UserManager) mContext.getSystemService(Context.USER_SERVICE))
+ .getUserInfo(userId) != null;
+ if (!userExists) return null;
+ } finally {
+ Binder.restoreCallingIdentity(origId);
}
- Searchables searchables = mSearchables.get(userId);
+ synchronized (mSearchables) {
+ Searchables searchables = mSearchables.get(userId);
- long origId = Binder.clearCallingIdentity();
- boolean userExists = ((UserManager) mContext.getSystemService(Context.USER_SERVICE))
- .getUserInfo(userId) != null;
- Binder.restoreCallingIdentity(origId);
+ if (searchables == null) {
+ Log.i(TAG, "Building list of searchable activities for userId=" + userId);
+ searchables = new Searchables(mContext, userId);
+ searchables.buildSearchableList();
+ mSearchables.append(userId, searchables);
+ }
+ return searchables;
+ }
+ }
- if (searchables == null && userExists) {
- Log.i(TAG, "Building list of searchable activities for userId=" + userId);
- searchables = new Searchables(mContext, userId);
- searchables.buildSearchableList();
- mSearchables.append(userId, searchables);
+ private void onUserRemoved(int userId) {
+ if (userId != UserHandle.USER_OWNER) {
+ synchronized (mSearchables) {
+ mSearchables.remove(userId);
+ }
}
- return searchables;
}
/**
@@ -115,6 +126,13 @@ public class SearchManagerService extends ISearchManager.Stub {
}
}
+ private final class UserReceiver extends BroadcastReceiver {
+ @Override
+ public void onReceive(Context context, Intent intent) {
+ onUserRemoved(intent.getIntExtra(Intent.EXTRA_USER_HANDLE, UserHandle.USER_OWNER));
+ }
+ }
+
/**
* Refreshes the "searchables" list when packages are added/removed.
*/
@@ -131,16 +149,20 @@ public class SearchManagerService extends ISearchManager.Stub {
}
private void updateSearchables() {
- synchronized (SearchManagerService.this) {
+ final int changingUserId = getChangingUserId();
+ synchronized (mSearchables) {
// Update list of searchable activities
for (int i = 0; i < mSearchables.size(); i++) {
- getSearchables(mSearchables.keyAt(i)).buildSearchableList();
+ if (changingUserId == mSearchables.keyAt(i)) {
+ getSearchables(mSearchables.keyAt(i)).buildSearchableList();
+ break;
+ }
}
}
// Inform all listeners that the list of searchables has been updated.
Intent intent = new Intent(SearchManager.INTENT_ACTION_SEARCHABLES_CHANGED);
intent.addFlags(Intent.FLAG_RECEIVER_REPLACE_PENDING);
- mContext.sendBroadcastAsUser(intent, UserHandle.ALL);
+ mContext.sendBroadcastAsUser(intent, new UserHandle(changingUserId));
}
}
@@ -158,7 +180,7 @@ public class SearchManagerService extends ISearchManager.Stub {
@Override
public void onChange(boolean selfChange) {
- synchronized (SearchManagerService.this) {
+ synchronized (mSearchables) {
for (int i = 0; i < mSearchables.size(); i++) {
getSearchables(mSearchables.keyAt(i)).buildSearchableList();
}
@@ -258,4 +280,17 @@ public class SearchManagerService extends ISearchManager.Stub {
}
return null;
}
+
+ @Override
+ public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
+ IndentingPrintWriter ipw = new IndentingPrintWriter(pw, " ");
+ synchronized (mSearchables) {
+ for (int i = 0; i < mSearchables.size(); i++) {
+ ipw.print("\nUser: "); ipw.println(mSearchables.keyAt(i));
+ ipw.increaseIndent();
+ mSearchables.valueAt(i).dump(fd, ipw, args);
+ ipw.decreaseIndent();
+ }
+ }
+ }
}
diff --git a/core/java/android/server/search/Searchables.java b/core/java/android/server/search/Searchables.java
index 30ca340..a0095d6 100644
--- a/core/java/android/server/search/Searchables.java
+++ b/core/java/android/server/search/Searchables.java
@@ -34,6 +34,8 @@ import android.provider.Settings;
import android.text.TextUtils;
import android.util.Log;
+import java.io.FileDescriptor;
+import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
@@ -210,59 +212,64 @@ public class Searchables {
// Use intent resolver to generate list of ACTION_SEARCH & ACTION_WEB_SEARCH receivers.
List<ResolveInfo> searchList;
final Intent intent = new Intent(Intent.ACTION_SEARCH);
-
- searchList = queryIntentActivities(intent, PackageManager.GET_META_DATA);
-
- List<ResolveInfo> webSearchInfoList;
- final Intent webSearchIntent = new Intent(Intent.ACTION_WEB_SEARCH);
- webSearchInfoList = queryIntentActivities(webSearchIntent, PackageManager.GET_META_DATA);
-
- // analyze each one, generate a Searchables record, and record
- if (searchList != null || webSearchInfoList != null) {
- int search_count = (searchList == null ? 0 : searchList.size());
- int web_search_count = (webSearchInfoList == null ? 0 : webSearchInfoList.size());
- int count = search_count + web_search_count;
- long token = Binder.clearCallingIdentity();
- for (int ii = 0; ii < count; ii++) {
- // for each component, try to find metadata
- ResolveInfo info = (ii < search_count)
- ? searchList.get(ii)
- : webSearchInfoList.get(ii - search_count);
- ActivityInfo ai = info.activityInfo;
- // Check first to avoid duplicate entries.
- if (newSearchablesMap.get(new ComponentName(ai.packageName, ai.name)) == null) {
- SearchableInfo searchable = SearchableInfo.getActivityMetaData(mContext, ai);
- if (searchable != null) {
- newSearchablesList.add(searchable);
- newSearchablesMap.put(searchable.getSearchActivity(), searchable);
- if (searchable.shouldIncludeInGlobalSearch()) {
- newSearchablesInGlobalSearchList.add(searchable);
+
+ long ident = Binder.clearCallingIdentity();
+ try {
+ searchList = queryIntentActivities(intent, PackageManager.GET_META_DATA);
+
+ List<ResolveInfo> webSearchInfoList;
+ final Intent webSearchIntent = new Intent(Intent.ACTION_WEB_SEARCH);
+ webSearchInfoList = queryIntentActivities(webSearchIntent, PackageManager.GET_META_DATA);
+
+ // analyze each one, generate a Searchables record, and record
+ if (searchList != null || webSearchInfoList != null) {
+ int search_count = (searchList == null ? 0 : searchList.size());
+ int web_search_count = (webSearchInfoList == null ? 0 : webSearchInfoList.size());
+ int count = search_count + web_search_count;
+ for (int ii = 0; ii < count; ii++) {
+ // for each component, try to find metadata
+ ResolveInfo info = (ii < search_count)
+ ? searchList.get(ii)
+ : webSearchInfoList.get(ii - search_count);
+ ActivityInfo ai = info.activityInfo;
+ // Check first to avoid duplicate entries.
+ if (newSearchablesMap.get(new ComponentName(ai.packageName, ai.name)) == null) {
+ SearchableInfo searchable = SearchableInfo.getActivityMetaData(mContext, ai,
+ mUserId);
+ if (searchable != null) {
+ newSearchablesList.add(searchable);
+ newSearchablesMap.put(searchable.getSearchActivity(), searchable);
+ if (searchable.shouldIncludeInGlobalSearch()) {
+ newSearchablesInGlobalSearchList.add(searchable);
+ }
}
}
}
}
- Binder.restoreCallingIdentity(token);
- }
- List<ResolveInfo> newGlobalSearchActivities = findGlobalSearchActivities();
+ List<ResolveInfo> newGlobalSearchActivities = findGlobalSearchActivities();
- // Find the global search activity
- ComponentName newGlobalSearchActivity = findGlobalSearchActivity(
- newGlobalSearchActivities);
+ // Find the global search activity
+ ComponentName newGlobalSearchActivity = findGlobalSearchActivity(
+ newGlobalSearchActivities);
- // Find the web search activity
- ComponentName newWebSearchActivity = findWebSearchActivity(newGlobalSearchActivity);
+ // Find the web search activity
+ ComponentName newWebSearchActivity = findWebSearchActivity(newGlobalSearchActivity);
- // Store a consistent set of new values
- synchronized (this) {
- mSearchablesMap = newSearchablesMap;
- mSearchablesList = newSearchablesList;
- mSearchablesInGlobalSearchList = newSearchablesInGlobalSearchList;
- mGlobalSearchActivities = newGlobalSearchActivities;
- mCurrentGlobalSearchActivity = newGlobalSearchActivity;
- mWebSearchActivity = newWebSearchActivity;
+ // Store a consistent set of new values
+ synchronized (this) {
+ mSearchablesMap = newSearchablesMap;
+ mSearchablesList = newSearchablesList;
+ mSearchablesInGlobalSearchList = newSearchablesInGlobalSearchList;
+ mGlobalSearchActivities = newGlobalSearchActivities;
+ mCurrentGlobalSearchActivity = newGlobalSearchActivity;
+ mWebSearchActivity = newWebSearchActivity;
+ }
+ } finally {
+ Binder.restoreCallingIdentity(ident);
}
}
+
/**
* Returns a sorted list of installed search providers as per
* the following heuristics:
@@ -443,4 +450,15 @@ public class Searchables {
public synchronized ComponentName getWebSearchActivity() {
return mWebSearchActivity;
}
+
+ void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
+ pw.println("Searchable authorities:");
+ synchronized (this) {
+ if (mSearchablesList != null) {
+ for (SearchableInfo info: mSearchablesList) {
+ pw.print(" "); pw.println(info.getSuggestAuthority());
+ }
+ }
+ }
+ }
}