diff --git a/app/src/main/java/com/emanuelef/remote_capture/AppsResolver.java b/app/src/main/java/com/emanuelef/remote_capture/AppsResolver.java index e552c32b..4933aedb 100644 --- a/app/src/main/java/com/emanuelef/remote_capture/AppsResolver.java +++ b/app/src/main/java/com/emanuelef/remote_capture/AppsResolver.java @@ -93,6 +93,7 @@ public class AppsResolver { // Get the AppDescriptor corresponding to the given package name // No caching occurs. Virtual apps cannot be used. + // This is public to provide a fast resolution alternative to getAppByPackage public static AppDescriptor resolveInstalledApp(PackageManager pm, String packageName, int pm_flags) { PackageInfo pinfo; @@ -129,7 +130,9 @@ public class AppsResolver { } // Impose order to guarantee that a uid is always mapped to the same package name. - // + // The mapping may change if a package sharing this UID is installed/removed. + // For simplicity we ignore this change at runtime, and only address it in persistent data + // (e.g. in the MatchList to ensure that a user can always remove rules see #257) String packageName = packages[0]; for(String pkg: packages) { if(pkg.compareTo(packageName) < 0) diff --git a/app/src/main/java/com/emanuelef/remote_capture/model/MatchList.java b/app/src/main/java/com/emanuelef/remote_capture/model/MatchList.java index 4f31c54c..763eaeca 100644 --- a/app/src/main/java/com/emanuelef/remote_capture/model/MatchList.java +++ b/app/src/main/java/com/emanuelef/remote_capture/model/MatchList.java @@ -61,7 +61,7 @@ public class MatchList { private final ArrayMap mMatches = new ArrayMap<>(); private final ArraySet mUids = new ArraySet<>(); private final AppsResolver mResolver; - private boolean mFormatMigration = false; + private boolean mMigration = false; public enum RuleType { APP, @@ -129,10 +129,10 @@ public class MatchList { if(!serialized.isEmpty()) { fromJson(serialized); - if(mFormatMigration) { + if(mMigration) { Log.i(TAG, "Migration completed"); save(); - mFormatMigration = false; + mMigration = false; } } else clear(); @@ -211,15 +211,15 @@ public class MatchList { if(typeStr.equals("ROOT_DOMAIN")) { Log.i(TAG, String.format("ROOT_DOMAIN %s migrated", val)); type = RuleType.HOST; - mFormatMigration = true; + mMigration = true; } else { e.printStackTrace(); continue; } } - // Handle migration from old uid-based format if(type == RuleType.APP) { + // Handle migration from the old uid-based format try { int uid = Integer.parseInt(val); @@ -227,7 +227,7 @@ public class MatchList { if(app != null) { val = app.getPackageName(); Log.i(TAG, String.format("UID %d resolved to package %s", uid, val)); - mFormatMigration = true; + mMigration = true; } else { Log.w(TAG, "Ignoring unknown UID " + uid); continue; @@ -235,6 +235,16 @@ public class MatchList { } catch (NumberFormatException ignored) { // ok, package name } + + // Validate the uid->package_name mapping (see AppsResolver for more details). + // If the uid is mapped to a different package name, we must update the MatchList + // otherwise the user may not be able to remove the rule (see #257). + AppDescriptor app = mResolver.getAppByPackage(val, 0); + if((app != null) && !app.getPackageName().equals(val)) { + Log.i(TAG, "The UID " + app.getUid() + " mapping has changed from " + val + " to " + app.getPackageName()); + val = app.getPackageName(); + mMigration = true; + } } addRule(new Rule(type, val));