Skip to content

Commit 1409c99

Browse files
Amith YamasaniAndroid Git Automerger
authored andcommitted
am 9c2a38e: Merge "Fix resource reading for secondary users" into jb-mr1-dev
* commit '9c2a38ed10592a54d9bb753ef882632f7a8cd446': Fix resource reading for secondary users
2 parents bb1c1d3 + 9c2a38e commit 1409c99

File tree

7 files changed

+139
-72
lines changed

7 files changed

+139
-72
lines changed

core/java/android/app/ContextImpl.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1694,7 +1694,8 @@ public void enforceUriPermission(
16941694
@Override
16951695
public Context createPackageContext(String packageName, int flags)
16961696
throws NameNotFoundException {
1697-
return createPackageContextAsUser(packageName, flags, Process.myUserHandle());
1697+
return createPackageContextAsUser(packageName, flags,
1698+
mUser != null ? mUser : Process.myUserHandle());
16981699
}
16991700

17001701
@Override

core/java/android/app/SearchableInfo.java

Lines changed: 14 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -24,10 +24,12 @@
2424
import android.content.pm.ActivityInfo;
2525
import android.content.pm.PackageManager;
2626
import android.content.pm.ProviderInfo;
27+
import android.content.pm.PackageManager.NameNotFoundException;
2728
import android.content.res.TypedArray;
2829
import android.content.res.XmlResourceParser;
2930
import android.os.Parcel;
3031
import android.os.Parcelable;
32+
import android.os.UserHandle;
3133
import android.text.InputType;
3234
import android.util.AttributeSet;
3335
import android.util.Log;
@@ -510,16 +512,25 @@ private void addActionKey(ActionKeyInfo keyInfo) {
510512
*
511513
* @hide For use by SearchManagerService.
512514
*/
513-
public static SearchableInfo getActivityMetaData(Context context, ActivityInfo activityInfo) {
515+
public static SearchableInfo getActivityMetaData(Context context, ActivityInfo activityInfo,
516+
int userId) {
517+
Context userContext = null;
518+
try {
519+
userContext = context.createPackageContextAsUser("system", 0,
520+
new UserHandle(userId));
521+
} catch (NameNotFoundException nnfe) {
522+
Log.e(LOG_TAG, "Couldn't create package context for user " + userId);
523+
return null;
524+
}
514525
// for each component, try to find metadata
515526
XmlResourceParser xml =
516-
activityInfo.loadXmlMetaData(context.getPackageManager(), MD_LABEL_SEARCHABLE);
527+
activityInfo.loadXmlMetaData(userContext.getPackageManager(), MD_LABEL_SEARCHABLE);
517528
if (xml == null) {
518529
return null;
519530
}
520531
ComponentName cName = new ComponentName(activityInfo.packageName, activityInfo.name);
521532

522-
SearchableInfo searchable = getActivityMetaData(context, xml, cName);
533+
SearchableInfo searchable = getActivityMetaData(userContext, xml, cName);
523534
xml.close();
524535

525536
if (DBG) {

core/java/android/content/pm/PackageItemInfo.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -218,7 +218,7 @@ public XmlResourceParser loadXmlMetaData(PackageManager pm, String name) {
218218
}
219219
return null;
220220
}
221-
221+
222222
protected void dumpFront(Printer pw, String prefix) {
223223
if (name != null) {
224224
pw.println(prefix + "name=" + name);

core/java/android/server/search/SearchManagerService.java

Lines changed: 59 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
package android.server.search;
1818

1919
import com.android.internal.content.PackageMonitor;
20+
import com.android.internal.util.IndentingPrintWriter;
2021

2122
import android.app.ActivityManager;
2223
import android.app.ActivityManagerNative;
@@ -44,6 +45,8 @@
4445
import android.util.Slog;
4546
import android.util.SparseArray;
4647

48+
import java.io.FileDescriptor;
49+
import java.io.PrintWriter;
4750
import java.util.List;
4851

4952
/**
@@ -59,9 +62,7 @@ public class SearchManagerService extends ISearchManager.Stub {
5962
private final Context mContext;
6063

6164
// This field is initialized lazily in getSearchables(), and then never modified.
62-
private SparseArray<Searchables> mSearchables;
63-
64-
private ContentObserver mGlobalSearchObserver;
65+
private final SparseArray<Searchables> mSearchables = new SparseArray<Searchables>();
6566

6667
/**
6768
* Initializes the Search Manager service in the provided system context.
@@ -73,29 +74,39 @@ public SearchManagerService(Context context) {
7374
mContext = context;
7475
mContext.registerReceiver(new BootCompletedReceiver(),
7576
new IntentFilter(Intent.ACTION_BOOT_COMPLETED));
76-
mGlobalSearchObserver = new GlobalSearchProviderObserver(
77-
mContext.getContentResolver());
77+
mContext.registerReceiver(new UserReceiver(),
78+
new IntentFilter(Intent.ACTION_USER_REMOVED));
79+
new MyPackageMonitor().register(context, null, UserHandle.ALL, true);
7880
}
7981

80-
private synchronized Searchables getSearchables(int userId) {
81-
if (mSearchables == null) {
82-
new MyPackageMonitor().register(mContext, null, true);
83-
mSearchables = new SparseArray<Searchables>();
82+
private Searchables getSearchables(int userId) {
83+
long origId = Binder.clearCallingIdentity();
84+
try {
85+
boolean userExists = ((UserManager) mContext.getSystemService(Context.USER_SERVICE))
86+
.getUserInfo(userId) != null;
87+
if (!userExists) return null;
88+
} finally {
89+
Binder.restoreCallingIdentity(origId);
8490
}
85-
Searchables searchables = mSearchables.get(userId);
91+
synchronized (mSearchables) {
92+
Searchables searchables = mSearchables.get(userId);
8693

87-
long origId = Binder.clearCallingIdentity();
88-
boolean userExists = ((UserManager) mContext.getSystemService(Context.USER_SERVICE))
89-
.getUserInfo(userId) != null;
90-
Binder.restoreCallingIdentity(origId);
94+
if (searchables == null) {
95+
Log.i(TAG, "Building list of searchable activities for userId=" + userId);
96+
searchables = new Searchables(mContext, userId);
97+
searchables.buildSearchableList();
98+
mSearchables.append(userId, searchables);
99+
}
100+
return searchables;
101+
}
102+
}
91103

92-
if (searchables == null && userExists) {
93-
Log.i(TAG, "Building list of searchable activities for userId=" + userId);
94-
searchables = new Searchables(mContext, userId);
95-
searchables.buildSearchableList();
96-
mSearchables.append(userId, searchables);
104+
private void onUserRemoved(int userId) {
105+
if (userId != UserHandle.USER_OWNER) {
106+
synchronized (mSearchables) {
107+
mSearchables.remove(userId);
108+
}
97109
}
98-
return searchables;
99110
}
100111

101112
/**
@@ -115,6 +126,13 @@ public void run() {
115126
}
116127
}
117128

129+
private final class UserReceiver extends BroadcastReceiver {
130+
@Override
131+
public void onReceive(Context context, Intent intent) {
132+
onUserRemoved(intent.getIntExtra(Intent.EXTRA_USER_HANDLE, UserHandle.USER_OWNER));
133+
}
134+
}
135+
118136
/**
119137
* Refreshes the "searchables" list when packages are added/removed.
120138
*/
@@ -131,16 +149,20 @@ public void onPackageModified(String pkg) {
131149
}
132150

133151
private void updateSearchables() {
134-
synchronized (SearchManagerService.this) {
152+
final int changingUserId = getChangingUserId();
153+
synchronized (mSearchables) {
135154
// Update list of searchable activities
136155
for (int i = 0; i < mSearchables.size(); i++) {
137-
getSearchables(mSearchables.keyAt(i)).buildSearchableList();
156+
if (changingUserId == mSearchables.keyAt(i)) {
157+
getSearchables(mSearchables.keyAt(i)).buildSearchableList();
158+
break;
159+
}
138160
}
139161
}
140162
// Inform all listeners that the list of searchables has been updated.
141163
Intent intent = new Intent(SearchManager.INTENT_ACTION_SEARCHABLES_CHANGED);
142164
intent.addFlags(Intent.FLAG_RECEIVER_REPLACE_PENDING);
143-
mContext.sendBroadcastAsUser(intent, UserHandle.ALL);
165+
mContext.sendBroadcastAsUser(intent, new UserHandle(changingUserId));
144166
}
145167
}
146168

@@ -158,7 +180,7 @@ public GlobalSearchProviderObserver(ContentResolver resolver) {
158180

159181
@Override
160182
public void onChange(boolean selfChange) {
161-
synchronized (SearchManagerService.this) {
183+
synchronized (mSearchables) {
162184
for (int i = 0; i < mSearchables.size(); i++) {
163185
getSearchables(mSearchables.keyAt(i)).buildSearchableList();
164186
}
@@ -258,4 +280,17 @@ public ComponentName getAssistIntent(int userHandle) {
258280
}
259281
return null;
260282
}
283+
284+
@Override
285+
public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
286+
IndentingPrintWriter ipw = new IndentingPrintWriter(pw, " ");
287+
synchronized (mSearchables) {
288+
for (int i = 0; i < mSearchables.size(); i++) {
289+
ipw.print("\nUser: "); ipw.println(mSearchables.keyAt(i));
290+
ipw.increaseIndent();
291+
mSearchables.valueAt(i).dump(fd, ipw, args);
292+
ipw.decreaseIndent();
293+
}
294+
}
295+
}
261296
}

core/java/android/server/search/Searchables.java

Lines changed: 61 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,8 @@
3434
import android.text.TextUtils;
3535
import android.util.Log;
3636

37+
import java.io.FileDescriptor;
38+
import java.io.PrintWriter;
3739
import java.util.ArrayList;
3840
import java.util.Collections;
3941
import java.util.Comparator;
@@ -210,59 +212,64 @@ public void buildSearchableList() {
210212
// Use intent resolver to generate list of ACTION_SEARCH & ACTION_WEB_SEARCH receivers.
211213
List<ResolveInfo> searchList;
212214
final Intent intent = new Intent(Intent.ACTION_SEARCH);
213-
214-
searchList = queryIntentActivities(intent, PackageManager.GET_META_DATA);
215-
216-
List<ResolveInfo> webSearchInfoList;
217-
final Intent webSearchIntent = new Intent(Intent.ACTION_WEB_SEARCH);
218-
webSearchInfoList = queryIntentActivities(webSearchIntent, PackageManager.GET_META_DATA);
219-
220-
// analyze each one, generate a Searchables record, and record
221-
if (searchList != null || webSearchInfoList != null) {
222-
int search_count = (searchList == null ? 0 : searchList.size());
223-
int web_search_count = (webSearchInfoList == null ? 0 : webSearchInfoList.size());
224-
int count = search_count + web_search_count;
225-
long token = Binder.clearCallingIdentity();
226-
for (int ii = 0; ii < count; ii++) {
227-
// for each component, try to find metadata
228-
ResolveInfo info = (ii < search_count)
229-
? searchList.get(ii)
230-
: webSearchInfoList.get(ii - search_count);
231-
ActivityInfo ai = info.activityInfo;
232-
// Check first to avoid duplicate entries.
233-
if (newSearchablesMap.get(new ComponentName(ai.packageName, ai.name)) == null) {
234-
SearchableInfo searchable = SearchableInfo.getActivityMetaData(mContext, ai);
235-
if (searchable != null) {
236-
newSearchablesList.add(searchable);
237-
newSearchablesMap.put(searchable.getSearchActivity(), searchable);
238-
if (searchable.shouldIncludeInGlobalSearch()) {
239-
newSearchablesInGlobalSearchList.add(searchable);
215+
216+
long ident = Binder.clearCallingIdentity();
217+
try {
218+
searchList = queryIntentActivities(intent, PackageManager.GET_META_DATA);
219+
220+
List<ResolveInfo> webSearchInfoList;
221+
final Intent webSearchIntent = new Intent(Intent.ACTION_WEB_SEARCH);
222+
webSearchInfoList = queryIntentActivities(webSearchIntent, PackageManager.GET_META_DATA);
223+
224+
// analyze each one, generate a Searchables record, and record
225+
if (searchList != null || webSearchInfoList != null) {
226+
int search_count = (searchList == null ? 0 : searchList.size());
227+
int web_search_count = (webSearchInfoList == null ? 0 : webSearchInfoList.size());
228+
int count = search_count + web_search_count;
229+
for (int ii = 0; ii < count; ii++) {
230+
// for each component, try to find metadata
231+
ResolveInfo info = (ii < search_count)
232+
? searchList.get(ii)
233+
: webSearchInfoList.get(ii - search_count);
234+
ActivityInfo ai = info.activityInfo;
235+
// Check first to avoid duplicate entries.
236+
if (newSearchablesMap.get(new ComponentName(ai.packageName, ai.name)) == null) {
237+
SearchableInfo searchable = SearchableInfo.getActivityMetaData(mContext, ai,
238+
mUserId);
239+
if (searchable != null) {
240+
newSearchablesList.add(searchable);
241+
newSearchablesMap.put(searchable.getSearchActivity(), searchable);
242+
if (searchable.shouldIncludeInGlobalSearch()) {
243+
newSearchablesInGlobalSearchList.add(searchable);
244+
}
240245
}
241246
}
242247
}
243248
}
244-
Binder.restoreCallingIdentity(token);
245-
}
246249

247-
List<ResolveInfo> newGlobalSearchActivities = findGlobalSearchActivities();
250+
List<ResolveInfo> newGlobalSearchActivities = findGlobalSearchActivities();
248251

249-
// Find the global search activity
250-
ComponentName newGlobalSearchActivity = findGlobalSearchActivity(
251-
newGlobalSearchActivities);
252+
// Find the global search activity
253+
ComponentName newGlobalSearchActivity = findGlobalSearchActivity(
254+
newGlobalSearchActivities);
252255

253-
// Find the web search activity
254-
ComponentName newWebSearchActivity = findWebSearchActivity(newGlobalSearchActivity);
256+
// Find the web search activity
257+
ComponentName newWebSearchActivity = findWebSearchActivity(newGlobalSearchActivity);
255258

256-
// Store a consistent set of new values
257-
synchronized (this) {
258-
mSearchablesMap = newSearchablesMap;
259-
mSearchablesList = newSearchablesList;
260-
mSearchablesInGlobalSearchList = newSearchablesInGlobalSearchList;
261-
mGlobalSearchActivities = newGlobalSearchActivities;
262-
mCurrentGlobalSearchActivity = newGlobalSearchActivity;
263-
mWebSearchActivity = newWebSearchActivity;
259+
// Store a consistent set of new values
260+
synchronized (this) {
261+
mSearchablesMap = newSearchablesMap;
262+
mSearchablesList = newSearchablesList;
263+
mSearchablesInGlobalSearchList = newSearchablesInGlobalSearchList;
264+
mGlobalSearchActivities = newGlobalSearchActivities;
265+
mCurrentGlobalSearchActivity = newGlobalSearchActivity;
266+
mWebSearchActivity = newWebSearchActivity;
267+
}
268+
} finally {
269+
Binder.restoreCallingIdentity(ident);
264270
}
265271
}
272+
266273
/**
267274
* Returns a sorted list of installed search providers as per
268275
* the following heuristics:
@@ -443,4 +450,15 @@ public synchronized ComponentName getGlobalSearchActivity() {
443450
public synchronized ComponentName getWebSearchActivity() {
444451
return mWebSearchActivity;
445452
}
453+
454+
void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
455+
pw.println("Searchable authorities:");
456+
synchronized (this) {
457+
if (mSearchablesList != null) {
458+
for (SearchableInfo info: mSearchablesList) {
459+
pw.print(" "); pw.println(info.getSuggestAuthority());
460+
}
461+
}
462+
}
463+
}
446464
}

services/java/com/android/server/am/AppErrorDialog.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,7 @@ public AppErrorDialog(Context context, ActivityManagerService service,
7575
getWindow().addFlags(FLAG_SYSTEM_ERROR);
7676
WindowManager.LayoutParams attrs = getWindow().getAttributes();
7777
attrs.setTitle("Application Error: " + app.info.processName);
78+
attrs.privateFlags |= WindowManager.LayoutParams.PRIVATE_FLAG_SHOW_FOR_ALL_USERS;
7879
getWindow().setAttributes(attrs);
7980
if (app.persistent) {
8081
getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR);

services/java/com/android/server/am/AppNotRespondingDialog.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -97,6 +97,7 @@ public AppNotRespondingDialog(ActivityManagerService service, Context context,
9797
getWindow().addFlags(FLAG_SYSTEM_ERROR);
9898
WindowManager.LayoutParams attrs = getWindow().getAttributes();
9999
attrs.setTitle("Application Not Responding: " + app.info.processName);
100+
attrs.privateFlags = WindowManager.LayoutParams.PRIVATE_FLAG_SHOW_FOR_ALL_USERS;
100101
getWindow().setAttributes(attrs);
101102
}
102103

0 commit comments

Comments
 (0)