diff options
author | Amith Yamasani <yamasani@google.com> | 2012-10-07 08:17:46 -0700 |
---|---|---|
committer | Amith Yamasani <yamasani@google.com> | 2012-10-07 15:56:34 -0700 |
commit | 64442c11555d828a41af0b8a58ab933357889061 (patch) | |
tree | 4a4050e4932bfd85f00a23915660dc8ed01aa1c4 /core/java/android/server | |
parent | 1ad0fd9c04ae2e352c59129b979145e662f25cbc (diff) | |
download | frameworks_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.java | 83 | ||||
-rw-r--r-- | core/java/android/server/search/Searchables.java | 104 |
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()); + } + } + } + } } |