* Reports that a compatibility change is affecting an app process now.
*
* <p>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.
+ *
+ * <p>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.
+ *
+ * <p>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.
*
* 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.
*
- * <p>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.
+ * <p>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.
+ *
+ * <p>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.
+ *
+ * <p>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.
+ *
+ * <p>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
import android.content.Context;
import android.content.pm.ApplicationInfo;
+import android.content.pm.PackageManager;
import android.util.Slog;
import android.util.StatsLog;
}
@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)) {
reportChange(changeId, appInfo,
}
@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.