Resolve correct package info for other users apps

Also show the "badged" icon for managed profiles apps
This commit is contained in:
emanuele-f 2022-06-06 16:23:36 +02:00
parent fec54e9499
commit 4a44fa28af
3 changed files with 32 additions and 0 deletions

View File

@ -19,6 +19,7 @@
package com.emanuelef.remote_capture;
import android.annotation.SuppressLint;
import android.content.Context;
import android.content.pm.ApplicationInfo;
import android.content.pm.PackageInfo;
@ -34,13 +35,18 @@ import com.emanuelef.remote_capture.model.AppDescriptor;
import androidx.annotation.Nullable;
import androidx.core.content.ContextCompat;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.Arrays;
public class AppsResolver {
private static final String TAG = "AppsResolver";
public static final int PER_USER_RANGE = 100000;
private final SparseArray<AppDescriptor> mApps;
private final PackageManager mPm;
private final Context mContext;
private Method getPackageInfoAsUser;
private boolean mFallbackToGlobalResolution;
private Drawable mVirtualAppIcon;
public AppsResolver(Context context) {
@ -102,6 +108,7 @@ public class AppsResolver {
return new AppDescriptor(pm, pinfo);
}
@SuppressLint("DiscouragedPrivateApi")
public @Nullable AppDescriptor get(int uid, int pm_flags) {
AppDescriptor app = mApps.get(uid);
if(app != null)
@ -127,6 +134,22 @@ public class AppsResolver {
Arrays.sort(packages);
String packageName = packages[0];
if(!mFallbackToGlobalResolution && CaptureService.isCapturingAsRoot()) {
// Try to resolve for the specific user
try {
if(getPackageInfoAsUser == null)
getPackageInfoAsUser = PackageManager.class.getDeclaredMethod("getPackageInfoAsUser", String.class, int.class, int.class);
PackageInfo pinfo = (PackageInfo) getPackageInfoAsUser.invoke(mPm, packageName, pm_flags, uid / PER_USER_RANGE);
if(pinfo != null)
return new AppDescriptor(mPm, pinfo);
} catch (NoSuchMethodException | IllegalAccessException | InvocationTargetException e) {
Log.w(TAG, "getPackageInfoAsUser call fails, falling back to standard resolution");
e.printStackTrace();
mFallbackToGlobalResolution = true;
}
}
app = resolve(mPm, packageName, pm_flags);
if(app != null)
mApps.put(uid, app);

View File

@ -23,6 +23,8 @@ import android.content.pm.ApplicationInfo;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
import android.graphics.drawable.Drawable;
import android.os.Build;
import android.os.UserHandle;
import androidx.annotation.Nullable;
@ -89,6 +91,12 @@ public class AppDescriptor implements Comparable<AppDescriptor>, Serializable {
// NOTE: this call is expensive
mIcon = mPackageInfo.applicationInfo.loadIcon(mPm);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
UserHandle handle = UserHandle.getUserHandleForUid(mUid);
mIcon = mPm.getUserBadgedIcon(mIcon, handle);
}
//Log.d("Icon size", mIcon.getIntrinsicWidth() + "x" + mIcon.getIntrinsicHeight());
return mIcon;

View File

@ -153,6 +153,7 @@ public class MatchList {
}
if(tp == RuleType.APP) {
// TODO handle cross-users/profiles?
AppDescriptor app = AppsResolver.resolve(ctx.getPackageManager(), value, 0);
if(app != null)
value = app.getName();