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

Commit e879968f authored by Anna Trostanetski's avatar Anna Trostanetski Committed by Gerrit Code Review
Browse files

Merge "Revert "Cache binder calls in CompatChanges""

parents f1a0c3ab 9c6ecc90
Loading
Loading
Loading
Loading
+0 −86
Original line number Original line Diff line number Diff line
/*
 * Copyright (C) 2020 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 android.app.compat;

import android.app.PropertyInvalidatedCache;
import android.content.Context;
import android.os.Binder;
import android.os.RemoteException;
import android.os.ServiceManager;

import com.android.internal.compat.IPlatformCompat;

/**
 * Handles caching of calls to {@link com.android.internal.compat.IPlatformCompat}
 * @hide
 */
public final class ChangeIdStateCache
        extends PropertyInvalidatedCache<ChangeIdStateQuery, Boolean> {
    private static final String CACHE_KEY = "cache_key.is_compat_change_enabled";
    private static final int MAX_ENTRIES = 20;
    private static boolean sDisabled = false;

    /** @hide */
    public ChangeIdStateCache() {
        super(MAX_ENTRIES, CACHE_KEY);
    }

    /**
     * Disable cache.
     *
     * <p>Should only be used in unit tests.
     * @hide
     */
    public static void disable() {
        sDisabled = true;
    }

    /**
     * Invalidate the cache.
     *
     * <p>Can only be called by the system server process.
     * @hide
     */
    public static void invalidate() {
        if (!sDisabled) {
            PropertyInvalidatedCache.invalidateCache(CACHE_KEY);
        }
    }

    @Override
    protected Boolean recompute(ChangeIdStateQuery query) {
        IPlatformCompat platformCompat = IPlatformCompat.Stub.asInterface(
                ServiceManager.getService(Context.PLATFORM_COMPAT_SERVICE));
        final long token = Binder.clearCallingIdentity();
        try {
            if (query.type == ChangeIdStateQuery.QUERY_BY_PACKAGE_NAME) {
                return platformCompat.isChangeEnabledByPackageName(query.changeId,
                                                                   query.packageName,
                                                                   query.userId);
            } else if (query.type == ChangeIdStateQuery.QUERY_BY_UID) {
                return platformCompat.isChangeEnabledByUid(query.changeId, query.uid);
            } else {
                throw new IllegalArgumentException("Invalid query type: " + query.type);
            }
        } catch (RemoteException e) {
            e.rethrowFromSystemServer();
        } finally {
            Binder.restoreCallingIdentity(token);
        }
        throw new IllegalStateException("Could not recompute value!");
    }
}
+0 −87
Original line number Original line Diff line number Diff line
/*
 * Copyright (C) 2020 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 android.app.compat;

import android.annotation.IntDef;
import android.annotation.NonNull;

import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.util.Objects;


/**
 * A key type for caching calls to {@link com.android.internal.compat.IPlatformCompat}
 *
 * <p>For {@link com.android.internal.compat.IPlatformCompat#isChangeEnabledByPackageName}
 * and {@link com.android.internal.compat.IPlatformCompat#isChangeEnabledByUid}
 *
 * @hide
 */
final class ChangeIdStateQuery {

    static final int QUERY_BY_PACKAGE_NAME = 0;
    static final int QUERY_BY_UID = 1;
    @IntDef({QUERY_BY_PACKAGE_NAME, QUERY_BY_UID})
    @Retention(RetentionPolicy.SOURCE)
    @interface QueryType {}

    public @QueryType int type;
    public long changeId;
    public String packageName;
    public int uid;
    public int userId;

    private ChangeIdStateQuery(@QueryType int type, long changeId, String packageName,
                               int uid, int userId) {
        this.type = type;
        this.changeId = changeId;
        this.packageName = packageName;
        this.uid = uid;
        this.userId = userId;
    }

    static ChangeIdStateQuery byPackageName(long changeId, @NonNull String packageName,
                                            int userId) {
        return new ChangeIdStateQuery(QUERY_BY_PACKAGE_NAME, changeId, packageName, 0, userId);
    }

    static ChangeIdStateQuery byUid(long changeId, int uid) {
        return new ChangeIdStateQuery(QUERY_BY_UID, changeId, null, uid, 0);
    }

    @Override
    public boolean equals(Object other) {
        if (this == other) {
            return true;
        }
        if ((other == null) || !(other instanceof ChangeIdStateQuery)) {
            return false;
        }
        final ChangeIdStateQuery that = (ChangeIdStateQuery) other;
        return this.type == that.type
            && this.changeId == that.changeId
            && Objects.equals(this.packageName, that.packageName)
            && this.uid == that.uid
            && this.userId == that.userId;
    }

    @Override
    public int hashCode() {
        return Objects.hash(type, changeId, packageName, uid, userId);
    }
}
+27 −5
Original line number Original line Diff line number Diff line
@@ -19,8 +19,14 @@ package android.app.compat;
import android.annotation.NonNull;
import android.annotation.NonNull;
import android.annotation.SystemApi;
import android.annotation.SystemApi;
import android.compat.Compatibility;
import android.compat.Compatibility;
import android.content.Context;
import android.os.Binder;
import android.os.RemoteException;
import android.os.ServiceManager;
import android.os.UserHandle;
import android.os.UserHandle;


import com.android.internal.compat.IPlatformCompat;

/**
/**
 * CompatChanges APIs - to be used by platform code only (including mainline
 * CompatChanges APIs - to be used by platform code only (including mainline
 * modules).
 * modules).
@@ -29,7 +35,6 @@ import android.os.UserHandle;
 */
 */
@SystemApi
@SystemApi
public final class CompatChanges {
public final class CompatChanges {
    private static final ChangeIdStateCache QUERY_CACHE = new ChangeIdStateCache();
    private CompatChanges() {}
    private CompatChanges() {}


    /**
    /**
@@ -64,8 +69,17 @@ public final class CompatChanges {
     */
     */
    public static boolean isChangeEnabled(long changeId, @NonNull String packageName,
    public static boolean isChangeEnabled(long changeId, @NonNull String packageName,
            @NonNull UserHandle user) {
            @NonNull UserHandle user) {
        return QUERY_CACHE.query(ChangeIdStateQuery.byPackageName(changeId, packageName,
        IPlatformCompat platformCompat = IPlatformCompat.Stub.asInterface(
                                                           user.getIdentifier()));
                ServiceManager.getService(Context.PLATFORM_COMPAT_SERVICE));
        final long token = Binder.clearCallingIdentity();
        try {
            return platformCompat.isChangeEnabledByPackageName(changeId, packageName,
                    user.getIdentifier());
        } catch (RemoteException e) {
            throw e.rethrowFromSystemServer();
        } finally {
            Binder.restoreCallingIdentity(token);
        }
    }
    }


    /**
    /**
@@ -87,7 +101,15 @@ public final class CompatChanges {
     * @return {@code true} if the change is enabled for the current app.
     * @return {@code true} if the change is enabled for the current app.
     */
     */
    public static boolean isChangeEnabled(long changeId, int uid) {
    public static boolean isChangeEnabled(long changeId, int uid) {
        return QUERY_CACHE.query(ChangeIdStateQuery.byUid(changeId, uid));
        IPlatformCompat platformCompat = IPlatformCompat.Stub.asInterface(
                ServiceManager.getService(Context.PLATFORM_COMPAT_SERVICE));
        final long token = Binder.clearCallingIdentity();
        try {
            return platformCompat.isChangeEnabledByUid(changeId, uid);
        } catch (RemoteException e) {
            throw e.rethrowFromSystemServer();
        } finally {
            Binder.restoreCallingIdentity(token);
        }
    }
    }

}
}
+0 −10
Original line number Original line Diff line number Diff line
@@ -16,7 +16,6 @@


package com.android.server.compat;
package com.android.server.compat;


import android.app.compat.ChangeIdStateCache;
import android.compat.Compatibility.ChangeConfig;
import android.compat.Compatibility.ChangeConfig;
import android.content.Context;
import android.content.Context;
import android.content.pm.ApplicationInfo;
import android.content.pm.ApplicationInfo;
@@ -79,7 +78,6 @@ final class CompatConfig {
    void addChange(CompatChange change) {
    void addChange(CompatChange change) {
        synchronized (mChanges) {
        synchronized (mChanges) {
            mChanges.put(change.getId(), change);
            mChanges.put(change.getId(), change);
            invalidateCache();
        }
        }
    }
    }


@@ -172,7 +170,6 @@ final class CompatConfig {
                addChange(c);
                addChange(c);
            }
            }
            c.addPackageOverride(packageName, enabled);
            c.addPackageOverride(packageName, enabled);
            invalidateCache();
        }
        }
        return alreadyKnown;
        return alreadyKnown;
    }
    }
@@ -229,7 +226,6 @@ final class CompatConfig {
                // Should never occur, since validator is in the same process.
                // Should never occur, since validator is in the same process.
                throw new RuntimeException("Unable to call override validator!", e);
                throw new RuntimeException("Unable to call override validator!", e);
            }
            }
            invalidateCache();
        }
        }
        return overrideExists;
        return overrideExists;
    }
    }
@@ -252,7 +248,6 @@ final class CompatConfig {
                addOverride(changeId, packageName, false);
                addOverride(changeId, packageName, false);


            }
            }
            invalidateCache();
        }
        }
    }
    }


@@ -282,7 +277,6 @@ final class CompatConfig {
                    throw new RuntimeException("Unable to call override validator!", e);
                    throw new RuntimeException("Unable to call override validator!", e);
                }
                }
            }
            }
            invalidateCache();
        }
        }
    }
    }


@@ -402,8 +396,4 @@ final class CompatConfig {
    IOverrideValidator getOverrideValidator() {
    IOverrideValidator getOverrideValidator() {
        return mOverrideValidator;
        return mOverrideValidator;
    }
    }

    private void invalidateCache() {
        ChangeIdStateCache.invalidate();
    }
}
}
+0 −2
Original line number Original line Diff line number Diff line
@@ -24,7 +24,6 @@ import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;
import static org.mockito.Mockito.when;
import static org.testng.Assert.assertThrows;
import static org.testng.Assert.assertThrows;


import android.app.compat.ChangeIdStateCache;
import android.content.Context;
import android.content.Context;
import android.content.pm.ApplicationInfo;
import android.content.pm.ApplicationInfo;
import android.content.pm.PackageManager;
import android.content.pm.PackageManager;
@@ -75,7 +74,6 @@ public class CompatConfigTest {
        // Assume userdebug/eng non-final build
        // Assume userdebug/eng non-final build
        when(mBuildClassifier.isDebuggableBuild()).thenReturn(true);
        when(mBuildClassifier.isDebuggableBuild()).thenReturn(true);
        when(mBuildClassifier.isFinalBuild()).thenReturn(false);
        when(mBuildClassifier.isFinalBuild()).thenReturn(false);
        ChangeIdStateCache.disable();
    }
    }


    @Test
    @Test
Loading