Use user context when loading pip menu icons
There is a bug involving trying to load app icons when using secondary
users (or HSUM). Since we load icons using the systemui context which
is always user 0, we might not be able to load the icons if the app
is not installed on user 0.
Fixed by using the current user context when loading menu icons.
Bug: b/341192726
Flag: EXEMPT bugfix
Test: Follow repro steps as listed in BR, verify icons show.
Tested for both secondary user and HSUM.
Change-Id: I9297842ab90b91d4786d37c410f45b372859ee69
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipMenuView.java b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipMenuView.java
index c189642..0d7f7f6 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipMenuView.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipMenuView.java
@@ -34,11 +34,13 @@
import android.annotation.IntDef;
import android.annotation.NonNull;
import android.annotation.Nullable;
+import android.app.ActivityManager;
import android.app.PendingIntent;
import android.app.RemoteAction;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
+import android.content.pm.PackageManager;
import android.graphics.Color;
import android.graphics.Rect;
import android.graphics.drawable.Drawable;
@@ -151,6 +153,10 @@
// How long the shell will wait for the app to close the PiP if a custom action is set.
private final int mPipForceCloseDelay;
+ // Context for the currently active user. This may differ from the regular systemui Context
+ // in cases such as secondary users or HSUM.
+ private Context mContextForUser;
+
public PipMenuView(Context context, PhonePipMenuController controller,
ShellExecutor mainExecutor, Handler mainHandler,
PipUiEventLogger pipUiEventLogger) {
@@ -202,6 +208,7 @@
.getInteger(R.integer.config_pipExitAnimationDuration);
initAccessibility();
+ setContextForUser();
}
private void initAccessibility() {
@@ -476,7 +483,7 @@
actionView.setImageDrawable(null);
} else {
// TODO: Check if the action drawable has changed before we reload it
- action.getIcon().loadDrawableAsync(mContext, d -> {
+ action.getIcon().loadDrawableAsync(mContextForUser, d -> {
if (d != null) {
d.setTint(Color.WHITE);
actionView.setImageDrawable(d);
@@ -510,6 +517,33 @@
expandContainer.requestLayout();
}
+ /**
+ * Sets the Context for the current user. If the user is the same as systemui, then simply
+ * use systemui Context.
+ */
+ private void setContextForUser() {
+ int userId = ActivityManager.getCurrentUser();
+
+ if (mContext.getUserId() != userId) {
+ try {
+ mContextForUser = mContext.createPackageContextAsUser(mContext.getPackageName(),
+ Context.CONTEXT_RESTRICTED, new UserHandle(userId));
+ } catch (PackageManager.NameNotFoundException e) {
+ // Shouldn't happen, use systemui context as backup
+ ProtoLog.w(ShellProtoLogGroup.WM_SHELL_PICTURE_IN_PICTURE,
+ "%s: Failed to get context for user. Sysui userid=%d,"
+ + " current userid=%d, error=%s",
+ TAG,
+ mContext.getUserId(),
+ userId,
+ e);
+ mContextForUser = mContext;
+ }
+ } else {
+ mContextForUser = mContext;
+ }
+ }
+
private void notifyMenuStateChangeStart(int menuState, boolean resize, Runnable callback) {
mController.onMenuStateChangeStart(menuState, resize, callback);
}