Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit ea997f22 authored by Andrei Onea's avatar Andrei Onea
Browse files

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
parent 90a84e26
Loading
Loading
Loading
Loading
+19 −0
Original line number Diff line number Diff line
/*
 * 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;
+95 −0
Original line number Diff line number Diff line
/*
 * 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<Long> enabledChanges() {
        return mChangeConfig.forceEnabledSet();
    }

    /**
     * Changes forced to be disabled.
     */
    public Set<Long> disabledChanges() {
        return mChangeConfig.forceDisabledSet();
    }

    private CompatibilityChangeConfig(Parcel in) {
        long[] enabledArray = in.createLongArray();
        long[] disabledArray = in.createLongArray();
        Set<Long> enabled = toLongSet(enabledArray);
        Set<Long> disabled = toLongSet(disabledArray);
        mChangeConfig = new ChangeConfig(enabled, disabled);
    }

    private static Set<Long> toLongSet(long[] values) {
        Set<Long> 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<CompatibilityChangeConfig> CREATOR =
            new Parcelable.Creator<CompatibilityChangeConfig>() {

                @Override
                public CompatibilityChangeConfig createFromParcel(Parcel in) {
                    return new CompatibilityChangeConfig(in);
                }

                @Override
                public CompatibilityChangeConfig[] newArray(int size) {
                    return new CompatibilityChangeConfig[size];
                }
            };
}
+20 −1
Original line number Diff line number Diff line
@@ -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);

    /**
     * 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);
}
+38 −0
Original line number Diff line number Diff line
@@ -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.
     *
     * <p>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.
     *
     * <p>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.
+12 −0
Original line number Diff line number Diff line
@@ -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;