diff --git a/core/java/com/android/internal/compat/IPlatformCompat.aidl b/core/java/com/android/internal/compat/IPlatformCompat.aidl index 9049c3aea7ecb..e415b41459ab5 100644 --- a/core/java/com/android/internal/compat/IPlatformCompat.aidl +++ b/core/java/com/android/internal/compat/IPlatformCompat.aidl @@ -33,14 +33,29 @@ interface IPlatformCompat * Reports that a compatibility change is affecting an app process now. * *

Note: for changes that are gated using {@link #isChangeEnabled(long, ApplicationInfo)}, - * you do not need to call this API directly. The change will be reported for you in the case - * that {@link #isChangeEnabled(long, ApplicationInfo)} returns {@code true}. + * you do not need to call this API directly. The change will be reported for you. * * @param changeId The ID of the compatibility change taking effect. - * @param appInfo Representing the affected app. + * @param appInfo Representing the affected app. */ void reportChange(long changeId, in ApplicationInfo appInfo); + /** + * Reports that a compatibility change is affecting an app process now. + * + *

Same as {@link #reportChange(long, ApplicationInfo)}, except it receives a package name + * instead of an {@link ApplicationInfo} + * object, and finds an app info object based on the package name. Returns {@code true} if + * there is no installed package by that name. + * + *

Note: for changes that are gated using {@link #isChangeEnabled(long, String)}, + * you do not need to call this API directly. The change will be reported for you. + * + * @param changeId The ID of the compatibility change taking effect. + * @param packageName The package name of the app in question. + */ + void reportChangeByPackageName(long changeId, in String packageName); + /** * Query if a given compatibility change is enabled for an app process. This method should * be called when implementing functionality on behalf of the affected app. @@ -49,13 +64,35 @@ interface IPlatformCompat * change, resulting in differing behaviour compared to earlier releases. If this method returns * {@code false}, the calling code should behave as it did in earlier releases. * - *

When this method returns {@code true}, it will also report the change as - * {@link #reportChange(long, ApplicationInfo)} would, so there is no need to call that method - * directly. + *

It will also report the change as {@link #reportChange(long, ApplicationInfo)} would, so + * there is no need to call that method directly. * * @param changeId The ID of the compatibility change in question. - * @param appInfo Representing the app in question. + * @param appInfo Representing the app in question. * @return {@code true} if the change is enabled for the current app. */ boolean isChangeEnabled(long changeId, in ApplicationInfo appInfo); + + /** + * Query if a given compatibility change is enabled for an app process. This method should + * be called when implementing functionality on behalf of the affected app. + * + *

Same as {@link #isChangeEnabled(long, ApplicationInfo)}, except it receives a package name + * instead of an {@link ApplicationInfo} + * object, and finds an app info object based on the package name. Returns {@code true} if + * there is no installed package by that name. + * + *

If this method returns {@code true}, the calling code should implement the compatibility + * change, resulting in differing behaviour compared to earlier releases. If this method + * returns + * {@code false}, the calling code should behave as it did in earlier releases. + * + *

It will also report the change as {@link #reportChange(long, String)} would, so there is + * no need to call that method directly. + * + * @param changeId The ID of the compatibility change in question. + * @param packageName The package name of the app in question. + * @return {@code true} if the change is enabled for the current app. + */ + boolean isChangeEnabledByPackageName(long changeId, in String packageName); } \ No newline at end of file diff --git a/services/core/java/com/android/server/compat/PlatformCompat.java b/services/core/java/com/android/server/compat/PlatformCompat.java index 81e507cd24cf7..33d8dec8b043d 100644 --- a/services/core/java/com/android/server/compat/PlatformCompat.java +++ b/services/core/java/com/android/server/compat/PlatformCompat.java @@ -18,6 +18,7 @@ package com.android.server.compat; import android.content.Context; import android.content.pm.ApplicationInfo; +import android.content.pm.PackageManager; import android.util.Slog; import android.util.StatsLog; @@ -48,6 +49,15 @@ public class PlatformCompat extends IPlatformCompat.Stub { reportChange(changeId, appInfo, StatsLog.APP_COMPATIBILITY_CHANGE_REPORTED__STATE__LOGGED); } + @Override + public void reportChangeByPackageName(long changeId, String packageName) { + ApplicationInfo appInfo = getApplicationInfo(packageName); + if (appInfo == null) { + return; + } + reportChange(changeId, appInfo); + } + @Override public boolean isChangeEnabled(long changeId, ApplicationInfo appInfo) { if (CompatConfig.get().isChangeEnabled(changeId, appInfo)) { @@ -60,12 +70,30 @@ public class PlatformCompat extends IPlatformCompat.Stub { return false; } + @Override + public boolean isChangeEnabledByPackageName(long changeId, String packageName) { + ApplicationInfo appInfo = getApplicationInfo(packageName); + if (appInfo == null) { + return true; + } + return isChangeEnabled(changeId, appInfo); + } + @Override protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { if (!DumpUtils.checkDumpAndUsageStatsPermission(mContext, "platform_compat", pw)) return; CompatConfig.get().dumpConfig(pw); } + private ApplicationInfo getApplicationInfo(String packageName) { + try { + return mContext.getPackageManager().getApplicationInfo(packageName, 0); + } catch (PackageManager.NameNotFoundException e) { + Slog.e(TAG, "No installed package " + packageName); + } + return null; + } + private void reportChange(long changeId, ApplicationInfo appInfo, int state) { int uid = appInfo.uid; //TODO(b/138374585): Implement rate limiting for the logs.