From ea997f222c791fa58520b995da93cd08e9362b1b Mon Sep 17 00:00:00 2001 From: Andrei Onea Date: Thu, 12 Sep 2019 18:08:59 +0100 Subject: [PATCH] Add extra compat change overriding methods. This CL adds two new methods to the IPlatformCompat binder interface for toggling multiple compat changes at once, and for clearing all the overrides for a given package name. Bug: 140367850 Test: http://aosp/1113771 Change-Id: I02d08d76e42da308856408dadc2c8c73c7ff20d1 --- .../compat/CompatibilityChangeConfig.aidl | 19 ++++ .../compat/CompatibilityChangeConfig.java | 95 +++++++++++++++++++ .../internal/compat/IPlatformCompat.aidl | 21 +++- .../android/server/compat/CompatConfig.java | 38 ++++++++ .../android/server/compat/PlatformCompat.java | 12 +++ 5 files changed, 184 insertions(+), 1 deletion(-) create mode 100644 core/java/com/android/internal/compat/CompatibilityChangeConfig.aidl create mode 100644 core/java/com/android/internal/compat/CompatibilityChangeConfig.java diff --git a/core/java/com/android/internal/compat/CompatibilityChangeConfig.aidl b/core/java/com/android/internal/compat/CompatibilityChangeConfig.aidl new file mode 100644 index 0000000000000..434c1b819582e --- /dev/null +++ b/core/java/com/android/internal/compat/CompatibilityChangeConfig.aidl @@ -0,0 +1,19 @@ +/* + * Copyright (C) 2019 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.internal.compat; + +parcelable CompatibilityChangeConfig; diff --git a/core/java/com/android/internal/compat/CompatibilityChangeConfig.java b/core/java/com/android/internal/compat/CompatibilityChangeConfig.java new file mode 100644 index 0000000000000..fd2ada08edc10 --- /dev/null +++ b/core/java/com/android/internal/compat/CompatibilityChangeConfig.java @@ -0,0 +1,95 @@ +/* + * Copyright (C) 2019 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.internal.compat; + + +import android.compat.Compatibility.ChangeConfig; +import android.os.Parcel; +import android.os.Parcelable; + +import java.util.HashSet; +import java.util.Set; + +/** + * Parcelable containing compat config overrides for a given application. + * @hide + */ +public final class CompatibilityChangeConfig implements Parcelable { + private final ChangeConfig mChangeConfig; + + public CompatibilityChangeConfig(ChangeConfig changeConfig) { + mChangeConfig = changeConfig; + } + + /** + * Changes forced to be enabled. + */ + public Set enabledChanges() { + return mChangeConfig.forceEnabledSet(); + } + + /** + * Changes forced to be disabled. + */ + public Set disabledChanges() { + return mChangeConfig.forceDisabledSet(); + } + + private CompatibilityChangeConfig(Parcel in) { + long[] enabledArray = in.createLongArray(); + long[] disabledArray = in.createLongArray(); + Set enabled = toLongSet(enabledArray); + Set disabled = toLongSet(disabledArray); + mChangeConfig = new ChangeConfig(enabled, disabled); + } + + private static Set toLongSet(long[] values) { + Set ret = new HashSet<>(); + for (long value: values) { + ret.add(value); + } + return ret; + } + + @Override + public int describeContents() { + return 0; + } + + @Override + public void writeToParcel(Parcel dest, int flags) { + long[] enabled = mChangeConfig.forceEnabledChangesArray(); + long[] disabled = mChangeConfig.forceDisabledChangesArray(); + + dest.writeLongArray(enabled); + dest.writeLongArray(disabled); + } + + public static final Parcelable.Creator CREATOR = + new Parcelable.Creator() { + + @Override + public CompatibilityChangeConfig createFromParcel(Parcel in) { + return new CompatibilityChangeConfig(in); + } + + @Override + public CompatibilityChangeConfig[] newArray(int size) { + return new CompatibilityChangeConfig[size]; + } + }; +} diff --git a/core/java/com/android/internal/compat/IPlatformCompat.aidl b/core/java/com/android/internal/compat/IPlatformCompat.aidl index 4d8378a345999..4099cfa51b333 100644 --- a/core/java/com/android/internal/compat/IPlatformCompat.aidl +++ b/core/java/com/android/internal/compat/IPlatformCompat.aidl @@ -18,6 +18,8 @@ package com.android.internal.compat; import android.content.pm.ApplicationInfo; +parcelable CompatibilityChangeConfig; + /** * Platform private API for talking with the PlatformCompat service. * @@ -125,4 +127,21 @@ interface IPlatformCompat * @return {@code true} if the change is enabled for the current app. */ boolean isChangeEnabledByUid(long changeId, int uid); -} \ No newline at end of file + + /** + * Add overrides to compatibility changes. + * + * @param overrides Parcelable containing the compat change overrides to be applied. + * @param packageName The package name of the app whose changes will be overridden. + * + */ + void setOverrides(in CompatibilityChangeConfig overrides, in String packageName); + + /** + * Revert overrides to compatibility changes. + * + * @param packageName The package name of the app whose overrides will be cleared. + * + */ + void clearOverrides(in String packageName); +} diff --git a/services/core/java/com/android/server/compat/CompatConfig.java b/services/core/java/com/android/server/compat/CompatConfig.java index 027e2fb5ccaa8..0fabd9aef3737 100644 --- a/services/core/java/com/android/server/compat/CompatConfig.java +++ b/services/core/java/com/android/server/compat/CompatConfig.java @@ -25,6 +25,7 @@ import android.util.Slog; import com.android.internal.annotations.GuardedBy; import com.android.internal.annotations.VisibleForTesting; +import com.android.internal.compat.CompatibilityChangeConfig; import com.android.server.compat.config.Change; import com.android.server.compat.config.XmlParser; @@ -186,6 +187,43 @@ public final class CompatConfig { } return overrideExists; } + /** + * Overrides the enabled state for a given change and app. This method is intended to be used + * *only* for debugging purposes. + * + *

Note, package overrides are not persistent and will be lost on system or runtime restart. + * + * @param overrides list of overrides to default changes config. + * @param packageName app for which the overrides will be applied. + */ + public void addOverrides( + CompatibilityChangeConfig overrides, String packageName) { + synchronized (mChanges) { + for (Long changeId: overrides.enabledChanges()) { + addOverride(changeId, packageName, true); + } + for (Long changeId: overrides.disabledChanges()) { + addOverride(changeId, packageName, false); + } + } + } + + /** + * Removes all overrides previously added via {@link #addOverride(long, String, boolean)} or + * {@link #addAppOverrides(CompatibilityChangeConfig, String)} for a certain package. + * + *

This restores the default behaviour for the given change and app, once any app + * processes have been restarted. + * + * @param packageName The package for which the overrides should be purged. + */ + public void removePackageOverrides(String packageName) { + synchronized (mChanges) { + for (int i = 0; i < mChanges.size(); ++i) { + mChanges.valueAt(i).removePackageOverride(packageName); + } + } + } /** * Dumps the current list of compatibility config information. diff --git a/services/core/java/com/android/server/compat/PlatformCompat.java b/services/core/java/com/android/server/compat/PlatformCompat.java index 852b26d1ff07d..de2f6eb1f0687 100644 --- a/services/core/java/com/android/server/compat/PlatformCompat.java +++ b/services/core/java/com/android/server/compat/PlatformCompat.java @@ -23,6 +23,7 @@ import android.util.Slog; import android.util.StatsLog; import com.android.internal.compat.ChangeReporter; +import com.android.internal.compat.CompatibilityChangeConfig; import com.android.internal.compat.IPlatformCompat; import com.android.internal.util.DumpUtils; @@ -99,6 +100,17 @@ public class PlatformCompat extends IPlatformCompat.Stub { return enabled; } + @Override + public void setOverrides(CompatibilityChangeConfig overrides, String packageName) { + CompatConfig.get().addOverrides(overrides, packageName); + } + + @Override + public void clearOverrides(String packageName) { + CompatConfig config = CompatConfig.get(); + config.removePackageOverrides(packageName); + } + @Override protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { if (!DumpUtils.checkDumpAndUsageStatsPermission(mContext, "platform_compat", pw)) return;