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

Commit 381813c4 authored by Mark White's avatar Mark White
Browse files

Update Compat Framework so all system uid apps are treated as targeting current sdk

Previously if there were some system uid apps targeting an older sdk, then all sytem uid-based compat framework checks would return behaviour of the older sdk.

Flag: com.android.server.compat.system_uid_target_system_sdk
Bug: 282922910
Change-Id: Ia92f3ac378c18edc45015a80103da87097bb5233
parent 2fe03850
Loading
Loading
Loading
Loading
+16 −0
Original line number Diff line number Diff line
@@ -63,6 +63,7 @@ aconfig_declarations_group {
        "android.server.app.flags-aconfig-java",
        "android.service.autofill.flags-aconfig-java",
        "android.service.chooser.flags-aconfig-java",
        "android.service.compat.flags-aconfig-java",
        "android.service.controls.flags-aconfig-java",
        "android.service.dreams.flags-aconfig-java",
        "android.service.notification.flags-aconfig-java",
@@ -861,6 +862,21 @@ java_aconfig_library {
    defaults: ["framework-minus-apex-aconfig-java-defaults"],
}

aconfig_declarations {
    name: "android.service.compat.flags-aconfig",
    package: "com.android.server.compat",
    container: "system",
    srcs: [
        "services/core/java/com/android/server/compat/*.aconfig",
    ],
}

java_aconfig_library {
    name: "android.service.compat.flags-aconfig-java",
    aconfig_declarations: "android.service.compat.flags-aconfig",
    defaults: ["framework-minus-apex-aconfig-java-defaults"],
}

// Multi user
aconfig_declarations {
    name: "android.multiuser.flags-aconfig",
+13 −2
Original line number Diff line number Diff line
@@ -242,7 +242,8 @@ public class PlatformCompat extends IPlatformCompat.Stub {
        boolean enabled = true;
        final int userId = UserHandle.getUserId(uid);
        for (String packageName : packages) {
            final var appInfo = getApplicationInfo(packageName, userId);
            final var appInfo =
                fixTargetSdk(getApplicationInfo(packageName, userId), uid);
            enabled &= isChangeEnabledInternal(changeId, appInfo);
        }
        return enabled;
@@ -261,7 +262,8 @@ public class PlatformCompat extends IPlatformCompat.Stub {
        boolean enabled = true;
        final int userId = UserHandle.getUserId(uid);
        for (String packageName : packages) {
            final var appInfo = getApplicationInfo(packageName, userId);
            final var appInfo =
                fixTargetSdk(getApplicationInfo(packageName, userId), uid);
            enabled &= isChangeEnabledInternalNoLogging(changeId, appInfo);
        }
        return enabled;
@@ -504,6 +506,15 @@ public class PlatformCompat extends IPlatformCompat.Stub {
                packageName, 0, Process.myUid(), userId);
    }

    private ApplicationInfo fixTargetSdk(ApplicationInfo appInfo, int uid) {
        // b/282922910 - we don't want apps sharing system uid and targeting
        // older target sdk to impact all system uid apps
        if (Flags.systemUidTargetSystemSdk() && uid == Process.SYSTEM_UID) {
            appInfo.targetSdkVersion = Build.VERSION.SDK_INT;
        }
        return appInfo;
    }

    private void killPackage(String packageName) {
        int uid = LocalServices.getService(PackageManagerInternal.class).getPackageUid(packageName,
                0, UserHandle.myUserId());
+10 −0
Original line number Diff line number Diff line
package: "com.android.server.compat"
container: "system"

flag {
    name: "system_uid_target_system_sdk"
    namespace: "app_compat"
    description: "Compat framework feature flag for forcing all system uid apps to target system sdk"
    bug: "29702703"
    is_fixed_read_only: true
}
+84 −0
Original line number Diff line number Diff line
@@ -20,6 +20,7 @@ import static com.google.common.truth.Truth.assertThat;

import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.Mockito.anyInt;
import static org.mockito.Mockito.anyLong;
import static org.mockito.Mockito.never;
import static org.mockito.Mockito.reset;
import static org.mockito.Mockito.verify;
@@ -33,6 +34,11 @@ import android.content.pm.ApplicationInfo;
import android.content.pm.PackageManager;
import android.content.pm.PackageManagerInternal;
import android.os.Build;
import android.os.Process;

import android.platform.test.annotations.DisableFlags;
import android.platform.test.annotations.EnableFlags;
import android.platform.test.flag.junit.SetFlagsRule;

import androidx.test.runner.AndroidJUnit4;

@@ -43,6 +49,7 @@ import com.android.internal.compat.CompatibilityChangeInfo;
import com.android.server.LocalServices;

import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mock;
@@ -55,6 +62,8 @@ import java.util.Set;
public class PlatformCompatTest {
    private static final String PACKAGE_NAME = "my.package";

    @Rule public final SetFlagsRule mSetFlagsRule = new SetFlagsRule();

    @Mock
    private Context mContext;
    @Mock
@@ -441,4 +450,79 @@ public class PlatformCompatTest {
        assertThat(mPlatformCompat.isChangeEnabled(3L, systemAppInfo)).isTrue();
        verify(mChangeReporter).reportChange(123, 3L, ChangeReporter.STATE_ENABLED, true, false);
    }

    @DisableFlags(Flags.FLAG_SYSTEM_UID_TARGET_SYSTEM_SDK)
    @Test
    public void testSharedSystemUidFlagOff() throws Exception {
        testSharedSystemUid(false);
    }

    @EnableFlags(Flags.FLAG_SYSTEM_UID_TARGET_SYSTEM_SDK)
    @Test
    public void testSharedSystemUidFlagOn() throws Exception {
        testSharedSystemUid(true);
    }

    private void testSharedSystemUid(Boolean expectSystemUidTargetSystemSdk) throws Exception {
        final String systemUidPackageNameTargetsR = "systemuid.package1";
        final String systemUidPackageNameTargetsQ = "systemuid.package2";
        final String nonSystemUidPackageNameTargetsR = "nonsystemuid.package1";
        final String nonSystemUidPackageNameTargetsQ = "nonsystemuid.package2";
        final int nonSystemUid = 123;

        mCompatConfig =
                CompatConfigBuilder.create(mBuildClassifier, mContext)
                        .addEnableSinceSdkChangeWithId(Build.VERSION_CODES.R, 1L)
                        .build();
        mCompatConfig.forceNonDebuggableFinalForTest(true);
        mPlatformCompat =
                new PlatformCompat(mContext, mCompatConfig, mBuildClassifier, mChangeReporter);

        ApplicationInfo systemUidAppInfo1 = ApplicationInfoBuilder.create()
            .withPackageName(systemUidPackageNameTargetsR)
            .withUid(Process.SYSTEM_UID)
            .withTargetSdk(Build.VERSION_CODES.R)
            .build();
        when(mPackageManagerInternal.getApplicationInfo(
                 eq(systemUidPackageNameTargetsR), anyLong(), anyInt(), anyInt()))
            .thenReturn(systemUidAppInfo1);

        ApplicationInfo systemUidAppInfo2 = ApplicationInfoBuilder.create()
            .withPackageName(systemUidPackageNameTargetsQ)
            .withUid(Process.SYSTEM_UID)
            .withTargetSdk(Build.VERSION_CODES.Q)
            .build();
        when(mPackageManagerInternal.getApplicationInfo(
                 eq(systemUidPackageNameTargetsQ), anyLong(), anyInt(), anyInt()))
            .thenReturn(systemUidAppInfo2);

        ApplicationInfo nonSystemUidAppInfo1 = ApplicationInfoBuilder.create()
            .withPackageName(nonSystemUidPackageNameTargetsR)
            .withUid(nonSystemUid)
            .withTargetSdk(Build.VERSION_CODES.R)
            .build();
        when(mPackageManagerInternal.getApplicationInfo(
                 eq(nonSystemUidPackageNameTargetsR), anyLong(), anyInt(), anyInt()))
            .thenReturn(nonSystemUidAppInfo1);

        ApplicationInfo nonSystemUidAppInfo2 = ApplicationInfoBuilder.create()
            .withPackageName(nonSystemUidPackageNameTargetsQ)
            .withUid(nonSystemUid)
            .withTargetSdk(Build.VERSION_CODES.Q)
            .build();
        when(mPackageManagerInternal.getApplicationInfo(
                 eq(nonSystemUidPackageNameTargetsQ), anyLong(), anyInt(), anyInt()))
            .thenReturn(nonSystemUidAppInfo2);

        when(mPackageManager.getPackagesForUid(eq(Process.SYSTEM_UID)))
            .thenReturn(new String[] {systemUidPackageNameTargetsR, systemUidPackageNameTargetsQ});
        when(mPackageManager.getPackagesForUid(eq(nonSystemUid)))
            .thenReturn(new String[] {
                            nonSystemUidPackageNameTargetsR, nonSystemUidPackageNameTargetsQ
                        });

        assertThat(mPlatformCompat.isChangeEnabledByUid(1L, Process.SYSTEM_UID))
            .isEqualTo(expectSystemUidTargetSystemSdk);
        assertThat(mPlatformCompat.isChangeEnabledByUid(1L, nonSystemUid)).isFalse();
    }
}