am 9c2a38ed: Merge "Fix resource reading for secondary users" into jb-mr1-dev

* commit '9c2a38ed10592a54d9bb753ef882632f7a8cd446':
  Fix resource reading for secondary users
This commit is contained in:
Amith Yamasani
2012-10-07 23:36:22 -07:00
committed by Android Git Automerger
7 changed files with 139 additions and 72 deletions

View File

@@ -1694,7 +1694,8 @@ class ContextImpl extends Context {
@Override
public Context createPackageContext(String packageName, int flags)
throws NameNotFoundException {
return createPackageContextAsUser(packageName, flags, Process.myUserHandle());
return createPackageContextAsUser(packageName, flags,
mUser != null ? mUser : Process.myUserHandle());
}
@Override

View File

@@ -24,10 +24,12 @@ import android.content.Context;
import android.content.pm.ActivityInfo;
import android.content.pm.PackageManager;
import android.content.pm.ProviderInfo;
import android.content.pm.PackageManager.NameNotFoundException;
import android.content.res.TypedArray;
import android.content.res.XmlResourceParser;
import android.os.Parcel;
import android.os.Parcelable;
import android.os.UserHandle;
import android.text.InputType;
import android.util.AttributeSet;
import android.util.Log;
@@ -510,16 +512,25 @@ public final class SearchableInfo implements Parcelable {
*
* @hide For use by SearchManagerService.
*/
public static SearchableInfo getActivityMetaData(Context context, ActivityInfo activityInfo) {
public static SearchableInfo getActivityMetaData(Context context, ActivityInfo activityInfo,
int userId) {
Context userContext = null;
try {
userContext = context.createPackageContextAsUser("system", 0,
new UserHandle(userId));
} catch (NameNotFoundException nnfe) {
Log.e(LOG_TAG, "Couldn't create package context for user " + userId);
return null;
}
// for each component, try to find metadata
XmlResourceParser xml =
activityInfo.loadXmlMetaData(context.getPackageManager(), MD_LABEL_SEARCHABLE);
activityInfo.loadXmlMetaData(userContext.getPackageManager(), MD_LABEL_SEARCHABLE);
if (xml == null) {
return null;
}
ComponentName cName = new ComponentName(activityInfo.packageName, activityInfo.name);
SearchableInfo searchable = getActivityMetaData(context, xml, cName);
SearchableInfo searchable = getActivityMetaData(userContext, xml, cName);
xml.close();
if (DBG) {

View File

@@ -218,7 +218,7 @@ public class PackageItemInfo {
}
return null;
}
protected void dumpFront(Printer pw, String prefix) {
if (name != null) {
pw.println(prefix + "name=" + name);

View File

@@ -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>();
}
Searchables searchables = mSearchables.get(userId);
private Searchables getSearchables(int userId) {
long origId = Binder.clearCallingIdentity();
boolean userExists = ((UserManager) mContext.getSystemService(Context.USER_SERVICE))
.getUserInfo(userId) != null;
Binder.restoreCallingIdentity(origId);
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);
try {
boolean userExists = ((UserManager) mContext.getSystemService(Context.USER_SERVICE))
.getUserInfo(userId) != null;
if (!userExists) return null;
} finally {
Binder.restoreCallingIdentity(origId);
}
synchronized (mSearchables) {
Searchables searchables = mSearchables.get(userId);
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;
}
}
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();
}
}
}
}

View File

@@ -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);
long ident = Binder.clearCallingIdentity();
try {
searchList = queryIntentActivities(intent, 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);
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());
}
}
}
}
}

View File

@@ -75,6 +75,7 @@ class AppErrorDialog extends BaseErrorDialog {
getWindow().addFlags(FLAG_SYSTEM_ERROR);
WindowManager.LayoutParams attrs = getWindow().getAttributes();
attrs.setTitle("Application Error: " + app.info.processName);
attrs.privateFlags |= WindowManager.LayoutParams.PRIVATE_FLAG_SHOW_FOR_ALL_USERS;
getWindow().setAttributes(attrs);
if (app.persistent) {
getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR);

View File

@@ -97,6 +97,7 @@ class AppNotRespondingDialog extends BaseErrorDialog {
getWindow().addFlags(FLAG_SYSTEM_ERROR);
WindowManager.LayoutParams attrs = getWindow().getAttributes();
attrs.setTitle("Application Not Responding: " + app.info.processName);
attrs.privateFlags = WindowManager.LayoutParams.PRIVATE_FLAG_SHOW_FOR_ALL_USERS;
getWindow().setAttributes(attrs);
}