From 98edc951712823dbf5db2b7e9c203a0e98fc616b Mon Sep 17 00:00:00 2001 From: Amith Yamasani Date: Tue, 25 Sep 2012 14:09:27 -0700 Subject: [PATCH] Load resources for the correct user For apps that are only installed on secondary users, the SystemUI is unable to see them by default. Added some methods to explicitly pass the userId of the user the resources are requested for by the StatusBarIcon Bug: 7214384 Also fix binding to remote views Bug: 7192802 Change-Id: I5d6c5f624aa37fb231f3467f9764c8d99077a91d --- core/java/android/app/ActivityThread.java | 7 ++++++- .../android/app/ApplicationPackageManager.java | 15 +++++++++++++++ core/java/android/app/ContextImpl.java | 3 ++- core/java/android/content/pm/PackageManager.java | 4 ++++ .../android/internal/statusbar/StatusBarIcon.java | 14 ++++++++++---- .../android/systemui/statusbar/BaseStatusBar.java | 2 ++ .../systemui/statusbar/StatusBarIconView.java | 3 ++- .../android/systemui/statusbar/phone/Ticker.java | 2 +- .../systemui/statusbar/tablet/TabletTicker.java | 3 ++- .../com/android/server/AppWidgetServiceImpl.java | 6 +++--- .../android/server/StatusBarManagerService.java | 4 +++- .../src/android/test/mock/MockPackageManager.java | 7 +++++++ 12 files changed, 57 insertions(+), 13 deletions(-) diff --git a/core/java/android/app/ActivityThread.java b/core/java/android/app/ActivityThread.java index e613e042a847f..d4b204f8528e2 100644 --- a/core/java/android/app/ActivityThread.java +++ b/core/java/android/app/ActivityThread.java @@ -1740,6 +1740,11 @@ public final class ActivityThread { public final LoadedApk getPackageInfo(String packageName, CompatibilityInfo compatInfo, int flags) { + return getPackageInfo(packageName, compatInfo, flags, UserHandle.myUserId()); + } + + public final LoadedApk getPackageInfo(String packageName, CompatibilityInfo compatInfo, + int flags, int userId) { synchronized (mPackages) { WeakReference ref; if ((flags&Context.CONTEXT_INCLUDE_CODE) != 0) { @@ -1768,7 +1773,7 @@ public final class ActivityThread { ApplicationInfo ai = null; try { ai = getPackageManager().getApplicationInfo(packageName, - PackageManager.GET_SHARED_LIBRARY_FILES, UserHandle.myUserId()); + PackageManager.GET_SHARED_LIBRARY_FILES, userId); } catch (RemoteException e) { // Ignore } diff --git a/core/java/android/app/ApplicationPackageManager.java b/core/java/android/app/ApplicationPackageManager.java index 18503f613afc0..e77fe6eb07eb9 100644 --- a/core/java/android/app/ApplicationPackageManager.java +++ b/core/java/android/app/ApplicationPackageManager.java @@ -759,6 +759,21 @@ final class ApplicationPackageManager extends PackageManager { getApplicationInfo(appPackageName, 0)); } + /** @hide */ + @Override + public Resources getResourcesForApplicationAsUser(String appPackageName, int userId) + throws NameNotFoundException { + try { + ApplicationInfo ai = mPM.getApplicationInfo(appPackageName, 0, userId); + if (ai != null) { + return getResourcesForApplication(ai); + } + } catch (RemoteException e) { + throw new RuntimeException("Package manager has died", e); + } + throw new NameNotFoundException("Package " + appPackageName + " doesn't exist"); + } + int mCachedSafeMode = -1; @Override public boolean isSafeMode() { try { diff --git a/core/java/android/app/ContextImpl.java b/core/java/android/app/ContextImpl.java index 6df0c3733612e..45bb305b3e69e 100644 --- a/core/java/android/app/ContextImpl.java +++ b/core/java/android/app/ContextImpl.java @@ -1707,7 +1707,8 @@ class ContextImpl extends Context { } LoadedApk pi = - mMainThread.getPackageInfo(packageName, mResources.getCompatibilityInfo(), flags); + mMainThread.getPackageInfo(packageName, mResources.getCompatibilityInfo(), flags, + user.getIdentifier()); if (pi != null) { ContextImpl c = new ContextImpl(); c.mRestricted = (flags & CONTEXT_RESTRICTED) == CONTEXT_RESTRICTED; diff --git a/core/java/android/content/pm/PackageManager.java b/core/java/android/content/pm/PackageManager.java index 291726a782975..8ba19881f0970 100644 --- a/core/java/android/content/pm/PackageManager.java +++ b/core/java/android/content/pm/PackageManager.java @@ -2341,6 +2341,10 @@ public abstract class PackageManager { public abstract Resources getResourcesForApplication(String appPackageName) throws NameNotFoundException; + /** @hide */ + public abstract Resources getResourcesForApplicationAsUser(String appPackageName, int userId) + throws NameNotFoundException; + /** * Retrieve overall information about an application package defined * in a package archive file diff --git a/core/java/com/android/internal/statusbar/StatusBarIcon.java b/core/java/com/android/internal/statusbar/StatusBarIcon.java index 3333c822edaa2..e0792cb376461 100644 --- a/core/java/com/android/internal/statusbar/StatusBarIcon.java +++ b/core/java/com/android/internal/statusbar/StatusBarIcon.java @@ -18,18 +18,21 @@ package com.android.internal.statusbar; import android.os.Parcel; import android.os.Parcelable; +import android.os.UserHandle; public class StatusBarIcon implements Parcelable { public String iconPackage; + public UserHandle user; public int iconId; public int iconLevel; public boolean visible = true; public int number; public CharSequence contentDescription; - public StatusBarIcon(String iconPackage, int iconId, int iconLevel, int number, + public StatusBarIcon(String iconPackage, UserHandle user, int iconId, int iconLevel, int number, CharSequence contentDescription) { this.iconPackage = iconPackage; + this.user = user; this.iconId = iconId; this.iconLevel = iconLevel; this.number = number; @@ -38,15 +41,16 @@ public class StatusBarIcon implements Parcelable { @Override public String toString() { - return "StatusBarIcon(pkg=" + this.iconPackage + " id=0x" + Integer.toHexString(this.iconId) + return "StatusBarIcon(pkg=" + this.iconPackage + "user=" + user.getIdentifier() + + " id=0x" + Integer.toHexString(this.iconId) + " level=" + this.iconLevel + " visible=" + visible + " num=" + this.number + " )"; } @Override public StatusBarIcon clone() { - StatusBarIcon that = new StatusBarIcon(this.iconPackage, this.iconId, this.iconLevel, - this.number, this.contentDescription); + StatusBarIcon that = new StatusBarIcon(this.iconPackage, this.user, this.iconId, + this.iconLevel, this.number, this.contentDescription); that.visible = this.visible; return that; } @@ -60,6 +64,7 @@ public class StatusBarIcon implements Parcelable { public void readFromParcel(Parcel in) { this.iconPackage = in.readString(); + this.user = (UserHandle) in.readParcelable(null); this.iconId = in.readInt(); this.iconLevel = in.readInt(); this.visible = in.readInt() != 0; @@ -69,6 +74,7 @@ public class StatusBarIcon implements Parcelable { public void writeToParcel(Parcel out, int flags) { out.writeString(this.iconPackage); + out.writeParcelable(this.user, 0); out.writeInt(this.iconId); out.writeInt(this.iconLevel); out.writeInt(this.visible ? 1 : 0); diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/BaseStatusBar.java b/packages/SystemUI/src/com/android/systemui/statusbar/BaseStatusBar.java index 8cf44454f8e81..6b753643aa76b 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/BaseStatusBar.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/BaseStatusBar.java @@ -860,6 +860,7 @@ public abstract class BaseStatusBar extends SystemUI implements iconView.setScaleType(ImageView.ScaleType.CENTER_INSIDE); final StatusBarIcon ic = new StatusBarIcon(notification.pkg, + notification.user, notification.notification.icon, notification.notification.iconLevel, notification.notification.number, @@ -1012,6 +1013,7 @@ public abstract class BaseStatusBar extends SystemUI implements } // Update the icon. final StatusBarIcon ic = new StatusBarIcon(notification.pkg, + notification.user, notification.notification.icon, notification.notification.iconLevel, notification.notification.number, notification.notification.tickerText); diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/StatusBarIconView.java b/packages/SystemUI/src/com/android/systemui/statusbar/StatusBarIconView.java index 6a9e8386b11ec..5e810ba40f72f 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/StatusBarIconView.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/StatusBarIconView.java @@ -165,7 +165,8 @@ public class StatusBarIconView extends AnimatedImageView { if (icon.iconPackage != null) { try { - r = context.getPackageManager().getResourcesForApplication(icon.iconPackage); + r = context.getPackageManager().getResourcesForApplicationAsUser(icon.iconPackage, + icon.user.getIdentifier()); } catch (PackageManager.NameNotFoundException ex) { Slog.e(TAG, "Icon package not found: " + icon.iconPackage); return null; diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/Ticker.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/Ticker.java index f5ceed0369b5c..67846a3b76524 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/Ticker.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/Ticker.java @@ -192,7 +192,7 @@ public abstract class Ticker { } final Drawable icon = StatusBarIconView.getIcon(mContext, - new StatusBarIcon(n.pkg, n.notification.icon, n.notification.iconLevel, 0, + new StatusBarIcon(n.pkg, n.user, n.notification.icon, n.notification.iconLevel, 0, n.notification.tickerText)); final Segment newSegment = new Segment(n, icon, n.notification.tickerText); diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/tablet/TabletTicker.java b/packages/SystemUI/src/com/android/systemui/statusbar/tablet/TabletTicker.java index 932b035509a50..ea97941e7630f 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/tablet/TabletTicker.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/tablet/TabletTicker.java @@ -288,7 +288,8 @@ public class TabletTicker } else if (n.tickerText != null) { group = (ViewGroup)inflater.inflate(R.layout.system_bar_ticker_compat, mWindow, false); final Drawable icon = StatusBarIconView.getIcon(mContext, - new StatusBarIcon(notification.pkg, n.icon, n.iconLevel, 0, n.tickerText)); + new StatusBarIcon(notification.pkg, notification.user, n.icon, n.iconLevel, 0, + n.tickerText)); ImageView iv = (ImageView)group.findViewById(iconId); iv.setImageDrawable(icon); iv.setVisibility(View.VISIBLE); diff --git a/services/java/com/android/server/AppWidgetServiceImpl.java b/services/java/com/android/server/AppWidgetServiceImpl.java index fa8f4b43cdbd1..8ec67c401b203 100644 --- a/services/java/com/android/server/AppWidgetServiceImpl.java +++ b/services/java/com/android/server/AppWidgetServiceImpl.java @@ -657,13 +657,13 @@ class AppWidgetServiceImpl { } final ComponentName componentName = intent.getComponent(); try { - final ServiceInfo si = mContext.getPackageManager().getServiceInfo(componentName, - PackageManager.GET_PERMISSIONS); + final ServiceInfo si = AppGlobals.getPackageManager().getServiceInfo(componentName, + PackageManager.GET_PERMISSIONS, mUserId); if (!android.Manifest.permission.BIND_REMOTEVIEWS.equals(si.permission)) { throw new SecurityException("Selected service does not require " + android.Manifest.permission.BIND_REMOTEVIEWS + ": " + componentName); } - } catch (PackageManager.NameNotFoundException e) { + } catch (RemoteException e) { throw new IllegalArgumentException("Unknown component " + componentName); } diff --git a/services/java/com/android/server/StatusBarManagerService.java b/services/java/com/android/server/StatusBarManagerService.java index 9f53fadbd1912..46dcedcefc6ce 100644 --- a/services/java/com/android/server/StatusBarManagerService.java +++ b/services/java/com/android/server/StatusBarManagerService.java @@ -26,6 +26,7 @@ import android.os.Binder; import android.os.Handler; import android.os.IBinder; import android.os.RemoteException; +import android.os.UserHandle; import android.util.Slog; import com.android.internal.statusbar.IStatusBar; @@ -179,7 +180,8 @@ public class StatusBarManagerService extends IStatusBarService.Stub throw new SecurityException("invalid status bar icon slot: " + slot); } - StatusBarIcon icon = new StatusBarIcon(iconPackage, iconId, iconLevel, 0, + StatusBarIcon icon = new StatusBarIcon(iconPackage, UserHandle.OWNER, iconId, + iconLevel, 0, contentDescription); //Slog.d(TAG, "setIcon slot=" + slot + " index=" + index + " icon=" + icon); mIcons.setIcon(index, icon); diff --git a/test-runner/src/android/test/mock/MockPackageManager.java b/test-runner/src/android/test/mock/MockPackageManager.java index 7b7a7b3e69ca2..2eba4e1165427 100644 --- a/test-runner/src/android/test/mock/MockPackageManager.java +++ b/test-runner/src/android/test/mock/MockPackageManager.java @@ -40,6 +40,7 @@ import android.content.pm.ResolveInfo; import android.content.pm.ServiceInfo; import android.content.pm.VerificationParams; import android.content.pm.VerifierDeviceIdentity; +import android.content.pm.PackageManager.NameNotFoundException; import android.content.res.Resources; import android.content.res.XmlResourceParser; import android.graphics.drawable.Drawable; @@ -371,6 +372,12 @@ public class MockPackageManager extends PackageManager { throw new UnsupportedOperationException(); } + /** @hide */ + @Override + public Resources getResourcesForApplicationAsUser(String appPackageName, int userId) { + throw new UnsupportedOperationException(); + } + @Override public PackageInfo getPackageArchiveInfo(String archiveFilePath, int flags) { throw new UnsupportedOperationException();