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
diff --git a/core/java/android/app/ActivityThread.java b/core/java/android/app/ActivityThread.java
index e613e04..d4b204f 100644
--- a/core/java/android/app/ActivityThread.java
+++ b/core/java/android/app/ActivityThread.java
@@ -1740,6 +1740,11 @@
 
     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<LoadedApk> ref;
             if ((flags&Context.CONTEXT_INCLUDE_CODE) != 0) {
@@ -1768,7 +1773,7 @@
         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 18503f6..e77fe6e 100644
--- a/core/java/android/app/ApplicationPackageManager.java
+++ b/core/java/android/app/ApplicationPackageManager.java
@@ -759,6 +759,21 @@
             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 6df0c37..45bb305 100644
--- a/core/java/android/app/ContextImpl.java
+++ b/core/java/android/app/ContextImpl.java
@@ -1707,7 +1707,8 @@
         }
 
         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 291726a..8ba1988 100644
--- a/core/java/android/content/pm/PackageManager.java
+++ b/core/java/android/content/pm/PackageManager.java
@@ -2341,6 +2341,10 @@
     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 3333c82..e0792cb 100644
--- a/core/java/com/android/internal/statusbar/StatusBarIcon.java
+++ b/core/java/com/android/internal/statusbar/StatusBarIcon.java
@@ -18,18 +18,21 @@
 
 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 @@
 
     @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 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 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 8cf4445..6b75364 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 @@
         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 @@
                 }
                 // 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 6a9e838..5e810ba 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 @@
 
         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 f5ceed0..67846a3 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 @@
         }
 
         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 932b035..ea97941 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 @@
         } 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 fa8f4b4..8ec67c4 100644
--- a/services/java/com/android/server/AppWidgetServiceImpl.java
+++ b/services/java/com/android/server/AppWidgetServiceImpl.java
@@ -657,13 +657,13 @@
             }
             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 9f53fad..46dcedc 100644
--- a/services/java/com/android/server/StatusBarManagerService.java
+++ b/services/java/com/android/server/StatusBarManagerService.java
@@ -26,6 +26,7 @@
 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 @@
                 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 7b7a7b3..2eba4e1 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.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 @@
         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();