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

Commit 855abe62 authored by Andrei Onea's avatar Andrei Onea
Browse files

Add permissions for using PlatformCompat methods

READ_COMPAT_CHANGE_CONFIG is required to read the current state of the
config, and OVERRIDE_COMPAT_CHANGE_CONFIG is required to add overrides.

Bug: 142650523
Test: atest PlatformCompatTest

Change-Id: I1c8cbb656e065a3273518e4cc2f4cc704c58f69f
parent 09a87d3f
Loading
Loading
Loading
Loading
+13 −0
Original line number Diff line number Diff line
@@ -4695,6 +4695,19 @@
    <permission android:name="android.permission.ACCESS_SHARED_LIBRARIES"
                android:protectionLevel="signature|installer" />

    <!-- Allows an app to log compat change usage.
         @hide  <p>Not for use by third-party applications.</p> -->
    <permission android:name="android.permission.LOG_COMPAT_CHANGE"
                android:protectionLevel="signature" />
    <!-- Allows an app to read compat change config.
         @hide  <p>Not for use by third-party applications.</p> -->
    <permission android:name="android.permission.READ_COMPAT_CHANGE_CONFIG"
                android:protectionLevel="signature" />
    <!-- Allows an app to override compat change config.
         @hide  <p>Not for use by third-party applications.</p> -->
    <permission android:name="android.permission.OVERRIDE_COMPAT_CHANGE_CONFIG"
                android:protectionLevel="signature" />

    <!-- Allows input events to be monitored. Very dangerous!  @hide -->
    <permission android:name="android.permission.MONITOR_INPUT"
                android:protectionLevel="signature" />
+40 −0
Original line number Diff line number Diff line
@@ -16,6 +16,11 @@

package com.android.server.compat;

import static android.Manifest.permission.LOG_COMPAT_CHANGE;
import static android.Manifest.permission.OVERRIDE_COMPAT_CHANGE_CONFIG;
import static android.Manifest.permission.READ_COMPAT_CHANGE_CONFIG;
import static android.content.pm.PackageManager.PERMISSION_GRANTED;

import android.app.ActivityManager;
import android.app.IActivityManager;
import android.content.Context;
@@ -67,12 +72,14 @@ public class PlatformCompat extends IPlatformCompat.Stub {

    @Override
    public void reportChange(long changeId, ApplicationInfo appInfo) {
        checkCompatChangeLogPermission();
        reportChange(changeId, appInfo.uid,
                StatsLog.APP_COMPATIBILITY_CHANGE_REPORTED__STATE__LOGGED);
    }

    @Override
    public void reportChangeByPackageName(long changeId, String packageName, int userId) {
        checkCompatChangeLogPermission();
        ApplicationInfo appInfo = getApplicationInfo(packageName, userId);
        if (appInfo == null) {
            return;
@@ -82,11 +89,13 @@ public class PlatformCompat extends IPlatformCompat.Stub {

    @Override
    public void reportChangeByUid(long changeId, int uid) {
        checkCompatChangeLogPermission();
        reportChange(changeId, uid, StatsLog.APP_COMPATIBILITY_CHANGE_REPORTED__STATE__LOGGED);
    }

    @Override
    public boolean isChangeEnabled(long changeId, ApplicationInfo appInfo) {
        checkCompatChangeReadPermission();
        if (mCompatConfig.isChangeEnabled(changeId, appInfo)) {
            reportChange(changeId, appInfo.uid,
                    StatsLog.APP_COMPATIBILITY_CHANGE_REPORTED__STATE__ENABLED);
@@ -99,6 +108,7 @@ public class PlatformCompat extends IPlatformCompat.Stub {

    @Override
    public boolean isChangeEnabledByPackageName(long changeId, String packageName, int userId) {
        checkCompatChangeReadPermission();
        ApplicationInfo appInfo = getApplicationInfo(packageName, userId);
        if (appInfo == null) {
            return true;
@@ -108,6 +118,7 @@ public class PlatformCompat extends IPlatformCompat.Stub {

    @Override
    public boolean isChangeEnabledByUid(long changeId, int uid) {
        checkCompatChangeReadPermission();
        String[] packages = mContext.getPackageManager().getPackagesForUid(uid);
        if (packages == null || packages.length == 0) {
            return true;
@@ -140,6 +151,7 @@ public class PlatformCompat extends IPlatformCompat.Stub {
    @Override
    public void setOverrides(CompatibilityChangeConfig overrides, String packageName)
            throws RemoteException, SecurityException {
        checkCompatChangeOverridePermission();
        mCompatConfig.addOverrides(overrides, packageName);
        killPackage(packageName);
    }
@@ -147,11 +159,13 @@ public class PlatformCompat extends IPlatformCompat.Stub {
    @Override
    public void setOverridesForTest(CompatibilityChangeConfig overrides, String packageName)
            throws RemoteException, SecurityException {
        checkCompatChangeOverridePermission();
        mCompatConfig.addOverrides(overrides, packageName);
    }

    @Override
    public void clearOverrides(String packageName) throws RemoteException, SecurityException {
        checkCompatChangeOverridePermission();
        mCompatConfig.removePackageOverrides(packageName);
        killPackage(packageName);
    }
@@ -159,12 +173,14 @@ public class PlatformCompat extends IPlatformCompat.Stub {
    @Override
    public void clearOverridesForTest(String packageName)
            throws RemoteException, SecurityException {
        checkCompatChangeOverridePermission();
        mCompatConfig.removePackageOverrides(packageName);
    }

    @Override
    public boolean clearOverride(long changeId, String packageName)
            throws RemoteException, SecurityException {
        checkCompatChangeOverridePermission();
        boolean existed = mCompatConfig.removeOverride(changeId, packageName);
        killPackage(packageName);
        return existed;
@@ -172,11 +188,13 @@ public class PlatformCompat extends IPlatformCompat.Stub {

    @Override
    public CompatibilityChangeConfig getAppConfig(ApplicationInfo appInfo) {
        checkCompatChangeReadPermission();
        return mCompatConfig.getAppConfig(appInfo);
    }

    @Override
    public CompatibilityChangeInfo[] listAllChanges() {
        checkCompatChangeReadPermission();
        return mCompatConfig.dumpChanges();
    }

@@ -215,6 +233,7 @@ public class PlatformCompat extends IPlatformCompat.Stub {

    @Override
    protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
        checkCompatChangeReadPermission();
        if (!DumpUtils.checkDumpAndUsageStatsPermission(mContext, "platform_compat", pw)) return;
        mCompatConfig.dumpConfig(pw);
    }
@@ -276,4 +295,25 @@ public class PlatformCompat extends IPlatformCompat.Stub {
            Binder.restoreCallingIdentity(identity);
        }
    }

    private void checkCompatChangeLogPermission() throws SecurityException {
        if (mContext.checkCallingOrSelfPermission(LOG_COMPAT_CHANGE)
                != PERMISSION_GRANTED) {
            throw new SecurityException("Cannot log compat change usage");
        }
    }

    private void checkCompatChangeReadPermission() throws SecurityException {
        if (mContext.checkCallingOrSelfPermission(READ_COMPAT_CHANGE_CONFIG)
                != PERMISSION_GRANTED) {
            throw new SecurityException("Cannot read compat change");
        }
    }

    private void checkCompatChangeOverridePermission() throws SecurityException {
        if (mContext.checkCallingOrSelfPermission(OVERRIDE_COMPAT_CHANGE_CONFIG)
                != PERMISSION_GRANTED) {
            throw new SecurityException("Cannot override compat change");
        }
    }
}
+2 −0
Original line number Diff line number Diff line
@@ -65,6 +65,8 @@
    <uses-permission android:name="android.permission.FOREGROUND_SERVICE"/>
    <uses-permission android:name="android.permission.SUSPEND_APPS"/>
    <uses-permission android:name="android.permission.CONTROL_KEYGUARD"/>
    <uses-permission android:name="android.permission.READ_COMPAT_CHANGE_CONFIG"/>
    <uses-permission android:name="android.permission.LOG_COMPAT_CHANGE"/>
    <uses-permission android:name="android.permission.MANAGE_BIND_INSTANT_SERVICE"/>
    <uses-permission android:name="android.permission.CONTROL_DISPLAY_COLOR_TRANSFORMS" />
    <uses-permission android:name="android.permission.READ_DEVICE_CONFIG" />
+0 −1
Original line number Diff line number Diff line
@@ -18,7 +18,6 @@ android_test {
    name: "PlatformCompatGating",
    // Only compile source java files in this apk.
    srcs: ["src/**/*.java"],
    certificate: "platform",
    libs: [
        "android.test.runner",
        "android.test.base",
+7 −0
Original line number Diff line number Diff line
@@ -16,7 +16,9 @@

package android.compat.testing;

import android.Manifest;
import android.app.Instrumentation;
import android.app.UiAutomation;
import android.compat.Compatibility;
import android.compat.Compatibility.ChangeConfig;
import android.content.Context;
@@ -83,12 +85,16 @@ public class PlatformCompatChangeRule extends CoreCompatChangeRule {
        @Override
        public void evaluate() throws Throwable {
            Instrumentation instrumentation = InstrumentationRegistry.getInstrumentation();
            UiAutomation uiAutomation = instrumentation.getUiAutomation();
            String packageName = instrumentation.getTargetContext().getPackageName();
            IPlatformCompat platformCompat = IPlatformCompat.Stub
                    .asInterface(ServiceManager.getService(Context.PLATFORM_COMPAT_SERVICE));
            if (platformCompat == null) {
                throw new IllegalStateException("Could not get IPlatformCompat service!");
            }
            uiAutomation.adoptShellPermissionIdentity(
                    Manifest.permission.READ_COMPAT_CHANGE_CONFIG,
                    Manifest.permission.OVERRIDE_COMPAT_CHANGE_CONFIG);
            Compatibility.setOverrides(mConfig);
            try {
                platformCompat.setOverridesForTest(new CompatibilityChangeConfig(mConfig),
@@ -101,6 +107,7 @@ public class PlatformCompatChangeRule extends CoreCompatChangeRule {
            } catch (RemoteException e) {
                throw new RuntimeException("Could not call IPlatformCompat binder method!", e);
            } finally {
                uiAutomation.dropShellPermissionIdentity();
                Compatibility.clearOverrides();
            }
        }