Loading core/java/android/app/ContextImpl.java +2 −1 Original line number Diff line number Diff line Loading @@ -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 Loading core/java/android/app/SearchableInfo.java +14 −3 Original line number Diff line number Diff line Loading @@ -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; Loading Loading @@ -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) { Loading core/java/android/server/search/SearchManagerService.java +59 −24 Original line number Diff line number Diff line Loading @@ -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; Loading Loading @@ -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; /** Loading @@ -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. Loading @@ -73,23 +74,24 @@ public class SearchManagerService extends ISearchManager.Stub { mContext = context; mContext.registerReceiver(new BootCompletedReceiver(), new IntentFilter(Intent.ACTION_BOOT_COMPLETED)); mGlobalSearchObserver = new GlobalSearchProviderObserver( mContext.getContentResolver()); } private synchronized Searchables getSearchables(int userId) { if (mSearchables == null) { new MyPackageMonitor().register(mContext, null, true); mSearchables = new SparseArray<Searchables>(); mContext.registerReceiver(new UserReceiver(), new IntentFilter(Intent.ACTION_USER_REMOVED)); new MyPackageMonitor().register(context, null, UserHandle.ALL, true); } Searchables searchables = mSearchables.get(userId); 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); } synchronized (mSearchables) { Searchables searchables = mSearchables.get(userId); if (searchables == null && userExists) { if (searchables == null) { Log.i(TAG, "Building list of searchable activities for userId=" + userId); searchables = new Searchables(mContext, userId); searchables.buildSearchableList(); Loading @@ -97,6 +99,15 @@ public class SearchManagerService extends ISearchManager.Stub { } return searchables; } } private void onUserRemoved(int userId) { if (userId != UserHandle.USER_OWNER) { synchronized (mSearchables) { mSearchables.remove(userId); } } } /** * Creates the initial searchables list after boot. Loading @@ -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. */ Loading @@ -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++) { 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)); } } Loading @@ -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(); } Loading Loading @@ -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(); } } } } core/java/android/server/search/Searchables.java +61 −43 Original line number Diff line number Diff line Loading @@ -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; Loading Loading @@ -211,6 +213,8 @@ public class Searchables { List<ResolveInfo> searchList; final Intent intent = new Intent(Intent.ACTION_SEARCH); long ident = Binder.clearCallingIdentity(); try { searchList = queryIntentActivities(intent, PackageManager.GET_META_DATA); List<ResolveInfo> webSearchInfoList; Loading @@ -222,7 +226,6 @@ public class Searchables { 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) Loading @@ -231,7 +234,8 @@ public class Searchables { 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); SearchableInfo searchable = SearchableInfo.getActivityMetaData(mContext, ai, mUserId); if (searchable != null) { newSearchablesList.add(searchable); newSearchablesMap.put(searchable.getSearchActivity(), searchable); Loading @@ -241,7 +245,6 @@ public class Searchables { } } } Binder.restoreCallingIdentity(token); } List<ResolveInfo> newGlobalSearchActivities = findGlobalSearchActivities(); Loading @@ -262,7 +265,11 @@ public class Searchables { mCurrentGlobalSearchActivity = newGlobalSearchActivity; mWebSearchActivity = newWebSearchActivity; } } finally { Binder.restoreCallingIdentity(ident); } } /** * Returns a sorted list of installed search providers as per * the following heuristics: Loading Loading @@ -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()); } } } } } services/java/com/android/server/am/AppErrorDialog.java +1 −0 Original line number Diff line number Diff line Loading @@ -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); Loading Loading
core/java/android/app/ContextImpl.java +2 −1 Original line number Diff line number Diff line Loading @@ -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 Loading
core/java/android/app/SearchableInfo.java +14 −3 Original line number Diff line number Diff line Loading @@ -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; Loading Loading @@ -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) { Loading
core/java/android/server/search/SearchManagerService.java +59 −24 Original line number Diff line number Diff line Loading @@ -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; Loading Loading @@ -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; /** Loading @@ -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. Loading @@ -73,23 +74,24 @@ public class SearchManagerService extends ISearchManager.Stub { mContext = context; mContext.registerReceiver(new BootCompletedReceiver(), new IntentFilter(Intent.ACTION_BOOT_COMPLETED)); mGlobalSearchObserver = new GlobalSearchProviderObserver( mContext.getContentResolver()); } private synchronized Searchables getSearchables(int userId) { if (mSearchables == null) { new MyPackageMonitor().register(mContext, null, true); mSearchables = new SparseArray<Searchables>(); mContext.registerReceiver(new UserReceiver(), new IntentFilter(Intent.ACTION_USER_REMOVED)); new MyPackageMonitor().register(context, null, UserHandle.ALL, true); } Searchables searchables = mSearchables.get(userId); 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); } synchronized (mSearchables) { Searchables searchables = mSearchables.get(userId); if (searchables == null && userExists) { if (searchables == null) { Log.i(TAG, "Building list of searchable activities for userId=" + userId); searchables = new Searchables(mContext, userId); searchables.buildSearchableList(); Loading @@ -97,6 +99,15 @@ public class SearchManagerService extends ISearchManager.Stub { } return searchables; } } private void onUserRemoved(int userId) { if (userId != UserHandle.USER_OWNER) { synchronized (mSearchables) { mSearchables.remove(userId); } } } /** * Creates the initial searchables list after boot. Loading @@ -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. */ Loading @@ -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++) { 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)); } } Loading @@ -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(); } Loading Loading @@ -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(); } } } }
core/java/android/server/search/Searchables.java +61 −43 Original line number Diff line number Diff line Loading @@ -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; Loading Loading @@ -211,6 +213,8 @@ public class Searchables { List<ResolveInfo> searchList; final Intent intent = new Intent(Intent.ACTION_SEARCH); long ident = Binder.clearCallingIdentity(); try { searchList = queryIntentActivities(intent, PackageManager.GET_META_DATA); List<ResolveInfo> webSearchInfoList; Loading @@ -222,7 +226,6 @@ public class Searchables { 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) Loading @@ -231,7 +234,8 @@ public class Searchables { 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); SearchableInfo searchable = SearchableInfo.getActivityMetaData(mContext, ai, mUserId); if (searchable != null) { newSearchablesList.add(searchable); newSearchablesMap.put(searchable.getSearchActivity(), searchable); Loading @@ -241,7 +245,6 @@ public class Searchables { } } } Binder.restoreCallingIdentity(token); } List<ResolveInfo> newGlobalSearchActivities = findGlobalSearchActivities(); Loading @@ -262,7 +265,11 @@ public class Searchables { mCurrentGlobalSearchActivity = newGlobalSearchActivity; mWebSearchActivity = newWebSearchActivity; } } finally { Binder.restoreCallingIdentity(ident); } } /** * Returns a sorted list of installed search providers as per * the following heuristics: Loading Loading @@ -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()); } } } } }
services/java/com/android/server/am/AppErrorDialog.java +1 −0 Original line number Diff line number Diff line Loading @@ -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); Loading