Merge "Update Compat Framework so all system uid apps are treated as targeting current sdk" into main
diff --git a/AconfigFlags.bp b/AconfigFlags.bp
index d582cb7..c6ce799 100644
--- a/AconfigFlags.bp
+++ b/AconfigFlags.bp
@@ -65,6 +65,7 @@
"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",
@@ -863,6 +864,21 @@
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",
diff --git a/services/core/java/com/android/server/compat/PlatformCompat.java b/services/core/java/com/android/server/compat/PlatformCompat.java
index a9fe8cb..8d64383 100644
--- a/services/core/java/com/android/server/compat/PlatformCompat.java
+++ b/services/core/java/com/android/server/compat/PlatformCompat.java
@@ -242,7 +242,8 @@
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 @@
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 @@
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());
diff --git a/services/core/java/com/android/server/compat/platform_compat_flags.aconfig b/services/core/java/com/android/server/compat/platform_compat_flags.aconfig
new file mode 100644
index 0000000..fb32323
--- /dev/null
+++ b/services/core/java/com/android/server/compat/platform_compat_flags.aconfig
@@ -0,0 +1,10 @@
+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
+}
diff --git a/services/tests/servicestests/src/com/android/server/compat/PlatformCompatTest.java b/services/tests/servicestests/src/com/android/server/compat/PlatformCompatTest.java
index 9df7a36..1d07540 100644
--- a/services/tests/servicestests/src/com/android/server/compat/PlatformCompatTest.java
+++ b/services/tests/servicestests/src/com/android/server/compat/PlatformCompatTest.java
@@ -20,6 +20,7 @@
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.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.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 @@
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 @@
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();
+ }
}