RESTRICT AUTOMERGE Update CTS shim APKs

Because the CTS and pi-dev branches are no longer in sync, we can't
guarantee the version of the shim on the device. So, we now have to
inspect the device and use the correct version of the update APK
in order to upgrade it.

Built here:
https://android-build.googleplex.com/builds/branch-dashboard/ub-ctsshim-dev?build_id=5374186

./arm/CtsShimPrivUpgrade_v28.apk
package: name='com.android.cts.priv.ctsshim'
versionCode='28'
versionName='9-5374186'
compileSdkVersion='28'
compileSdkVersionCodename='9'
sdkVersion:'24'
targetSdkVersion:'28'

./arm/CtsShimPrivUpgradeWrongSHA_v28.apk
package: name='com.android.cts.priv.ctsshim'
versionCode='28'
versionName='WrongSHA'
compileSdkVersion='28'
compileSdkVersionCodename='9'
sdkVersion:'24'
targetSdkVersion:'28'

./x86/CtsShimPrivUpgrade_v28.apk
package: name='com.android.cts.priv.ctsshim'
versionCode='28'
versionName='9-5374186'
compileSdkVersion='28'
compileSdkVersionCodename='9'
sdkVersion:'24'
targetSdkVersion:'28'

./x86/CtsShimPrivUpgradeWrongSHA_v28.apk
package: name='com.android.cts.priv.ctsshim'
versionCode='28'
versionName='WrongSHA'
compileSdkVersion='28'
compileSdkVersionCodename='9'
sdkVersion:'24'
targetSdkVersion:'28'

Bug: 121306802
Test: Flash pi-release on sailfish
Test: cts-tradefed run commandAndExit cts-dev --module CtsAppSecurityHostTestCases --test android.appsecurity.cts.PrivilegedUpdateTests
Test: Flash AOSP pie-dev [with aosp/929880 applied] on sailfish
Test: cts-tradefed run commandAndExit cts-dev --module CtsAppSecurityHostTestCases --test android.appsecurity.cts.PrivilegedUpdateTests
Change-Id: Ifda7c004bd2a4b70ee15608f9a716b37535b9ea4
diff --git a/hostsidetests/appsecurity/src/android/appsecurity/cts/PrivilegedUpdateTests.java b/hostsidetests/appsecurity/src/android/appsecurity/cts/PrivilegedUpdateTests.java
index 5f59d34..8cc141d 100644
--- a/hostsidetests/appsecurity/src/android/appsecurity/cts/PrivilegedUpdateTests.java
+++ b/hostsidetests/appsecurity/src/android/appsecurity/cts/PrivilegedUpdateTests.java
@@ -17,23 +17,42 @@
 package android.appsecurity.cts;
 
 import android.platform.test.annotations.AppModeFull;
+
 import com.android.compatibility.common.tradefed.build.CompatibilityBuildHelper;
 import com.android.ddmlib.Log;
 import com.android.tradefed.build.IBuildInfo;
 import com.android.tradefed.device.DeviceNotAvailableException;
 import com.android.tradefed.device.ITestDevice;
+import com.android.tradefed.metrics.proto.MetricMeasurement.Metric;
+import com.android.tradefed.result.ITestInvocationListener;
+import com.android.tradefed.result.TestDescription;
+import com.android.tradefed.testtype.AndroidJUnitTest;
 import com.android.tradefed.testtype.DeviceTestCase;
 import com.android.tradefed.testtype.IAbi;
 import com.android.tradefed.testtype.IAbiReceiver;
 import com.android.tradefed.testtype.IBuildReceiver;
+import com.android.tradefed.testtype.InstrumentationTest;
 import com.android.tradefed.util.AbiFormatter;
 import com.android.tradefed.util.AbiUtils;
 
+import java.util.HashMap;
+
 /**
  * Tests that verify intent filters.
  */
-@AppModeFull // TODO: Needs porting to instant
+@AppModeFull(reason="Instant applications can never be system or privileged")
 public class PrivilegedUpdateTests extends DeviceTestCase implements IAbiReceiver, IBuildReceiver {
+    //---------- BEGIN: To handle updated target SDK; remove as b/128436757 ----------
+    private static final String SHIM_UPDATE_NEW_APK = "CtsShimPrivUpgradePrebuilt_v28.apk";
+    private static final String SHIM_UPDATE_NEW_FAIL_APK = "CtsShimPrivUpgradeWrongSHAPrebuilt_v28.apk";
+    private static final String TEST_PREPARER_APK = "CtsPrivilegedUpdatePreparer.apk";
+    private static final String TEST_PREPARER_PKG = "com.android.cts.privilegedupdate.preparer";
+    private static final String TARGET_SDK_METHOD = "getTargetSdk";
+    private static final String TARGET_SDK_KEY = "target_sdk";
+    private static final int DEFAULT_TARGET_SDK = 24;
+    private static final int NEW_TARGET_SDK = 28;
+    private int mTargetSdk = 0;
+    //---------- END: To handle updated target SDK; remove as b/128436757 ----------
     private static final String TAG = "PrivilegedUpdateTests";
     private static final String SHIM_PKG = "com.android.cts.priv.ctsshim";
     /** Package name of the tests to be run */
@@ -82,6 +101,10 @@
 
         assertNull(getDevice().installPackage(mBuildHelper.getTestFile(TEST_APK), false));
         getDevice().executeShellCommand("pm enable " + SHIM_PKG);
+        if (mTargetSdk == 0) {
+            mTargetSdk = DEFAULT_TARGET_SDK;
+            setTargetSdk();
+        }
     }
 
     @Override
@@ -96,7 +119,7 @@
     public void testPrivilegedAppUpgradeRestricted() throws Exception {
         getDevice().uninstallPackage(SHIM_PKG);
         assertEquals(RESTRICTED_UPGRADE_FAILURE, getDevice().installPackage(
-                mBuildHelper.getTestFile(SHIM_UPDATE_FAIL_APK), true));
+                mBuildHelper.getTestFile(getUpdateApk(true)), true));
     }
 
     public void testSystemAppPriorities() throws Exception {
@@ -117,7 +140,7 @@
         
         try {
             assertNull(getDevice().installPackage(
-                    mBuildHelper.getTestFile(SHIM_UPDATE_APK), true));
+                    mBuildHelper.getTestFile(getUpdateApk(false)), true));
             runDeviceTests(TEST_PKG, ".PrivilegedUpdateTest", "testPrivilegedAppUpgradePriorities");
         } finally {
             getDevice().uninstallPackage(SHIM_PKG);
@@ -141,7 +164,7 @@
         runDeviceTests(TEST_PKG, ".PrivilegedAppDisableTest", "testPrivAppAndEnabled");
         try {
             assertNull(getDevice().installPackage(
-                    mBuildHelper.getTestFile(SHIM_UPDATE_APK), true));
+                    mBuildHelper.getTestFile(getUpdateApk(false)), true));
             getDevice().executeShellCommand("pm disable-user " + SHIM_PKG);
             runDeviceTests(TEST_PKG, ".PrivilegedAppDisableTest", "testUpdatedPrivAppAndDisabled");
             getDevice().executeShellCommand("pm enable " + SHIM_PKG);
@@ -155,4 +178,43 @@
             throws DeviceNotAvailableException {
         Utils.runDeviceTests(getDevice(), packageName, testClassName, testMethodName);
     }
+
+    //---------- BEGIN: To handle updated target SDK; remove as b/128436757 ----------
+    private String getUpdateApk(boolean fail) {
+        if (mTargetSdk == NEW_TARGET_SDK) {
+            if (fail) {
+                return SHIM_UPDATE_NEW_FAIL_APK;
+            }
+            return SHIM_UPDATE_NEW_APK;
+        }
+        if (fail) {
+            return SHIM_UPDATE_FAIL_APK;
+        }
+        return SHIM_UPDATE_APK;
+    }
+
+    private void setTargetSdk() throws Exception {
+        ITestInvocationListener listener = new TargetSdkListener();
+        AndroidJUnitTest instrTest = new AndroidJUnitTest();
+        instrTest.setInstallFile(mBuildHelper.getTestFile(TEST_PREPARER_APK));
+        instrTest.setDevice(getDevice());
+        instrTest.setPackageName(TEST_PREPARER_PKG);
+        instrTest.run(listener);
+    }
+
+    /* Special listener to retrieve the target sdk for the cts shim */
+    private class TargetSdkListener implements ITestInvocationListener {
+        @Override
+        public void testEnded(TestDescription test, HashMap<String, Metric> metrics) {
+            final Metric targetMetric = metrics.get(TARGET_SDK_KEY);
+            if (targetMetric == null) {
+                return;
+            }
+            try {
+                mTargetSdk = Integer.parseInt(targetMetric.getMeasurements().getSingleString());
+            } catch (NumberFormatException ignore) { }
+        }
+    }
+    //---------- END: To handle updated target SDK; remove as b/128436757 ----------
+
 }
diff --git a/hostsidetests/appsecurity/test-apps/PrivilegedUpdateApp/Android.mk b/hostsidetests/appsecurity/test-apps/PrivilegedUpdateApp/Android.mk
index 4c8dcd5..2ced2b9 100644
--- a/hostsidetests/appsecurity/test-apps/PrivilegedUpdateApp/Android.mk
+++ b/hostsidetests/appsecurity/test-apps/PrivilegedUpdateApp/Android.mk
@@ -57,6 +57,26 @@
 include $(BUILD_PREBUILT)
 
 ###########################################################
+# Variant: Privileged app upgrade
+
+include $(CLEAR_VARS)
+
+LOCAL_MODULE := CtsShimPrivUpgradePrebuilt_v28
+LOCAL_MODULE_TAGS := tests
+LOCAL_MODULE_CLASS := APPS
+LOCAL_BUILT_MODULE_STEM := package.apk
+# Make sure the build system doesn't try to resign the APK
+LOCAL_CERTIFICATE := PRESIGNED
+LOCAL_COMPATIBILITY_SUITE := cts vts general-tests
+
+# The 'arm' apk has both arm and arm64 so's. Same for x86/x86_64.
+my_apk_dir := $(subst arm64,arm,$(TARGET_ARCH))
+my_apk_dir := $(subst x86_64,x86,$(my_apk_dir))
+LOCAL_REPLACE_PREBUILT_APK_INSTALLED := $(LOCAL_PATH)/apk/$(my_apk_dir)/CtsShimPrivUpgrade_v28.apk
+
+include $(BUILD_PREBUILT)
+
+###########################################################
 # Variant: Privileged app upgrade (wrong SHA)
 
 include $(CLEAR_VARS)
@@ -73,4 +93,21 @@
 
 include $(BUILD_PREBUILT)
 
+###########################################################
+# Variant: Privileged app upgrade (wrong SHA)
+
+include $(CLEAR_VARS)
+
+LOCAL_MODULE := CtsShimPrivUpgradeWrongSHAPrebuilt_v28
+LOCAL_MODULE_TAGS := tests
+LOCAL_MODULE_CLASS := APPS
+LOCAL_BUILT_MODULE_STEM := package.apk
+# Make sure the build system doesn't try to resign the APK
+LOCAL_CERTIFICATE := PRESIGNED
+LOCAL_COMPATIBILITY_SUITE := cts vts general-tests
+
+LOCAL_REPLACE_PREBUILT_APK_INSTALLED := $(LOCAL_PATH)/apk/$(my_apk_dir)/CtsShimPrivUpgradeWrongSHA_v28.apk
+
+include $(BUILD_PREBUILT)
+
 my_apk_dir :=
diff --git a/hostsidetests/appsecurity/test-apps/PrivilegedUpdateApp/apk/arm/CtsShimPrivUpgradeWrongSHA_v28.apk b/hostsidetests/appsecurity/test-apps/PrivilegedUpdateApp/apk/arm/CtsShimPrivUpgradeWrongSHA_v28.apk
new file mode 100644
index 0000000..2faf2d4
--- /dev/null
+++ b/hostsidetests/appsecurity/test-apps/PrivilegedUpdateApp/apk/arm/CtsShimPrivUpgradeWrongSHA_v28.apk
Binary files differ
diff --git a/hostsidetests/appsecurity/test-apps/PrivilegedUpdateApp/apk/arm/CtsShimPrivUpgrade_v28.apk b/hostsidetests/appsecurity/test-apps/PrivilegedUpdateApp/apk/arm/CtsShimPrivUpgrade_v28.apk
new file mode 100644
index 0000000..93f6f19
--- /dev/null
+++ b/hostsidetests/appsecurity/test-apps/PrivilegedUpdateApp/apk/arm/CtsShimPrivUpgrade_v28.apk
Binary files differ
diff --git a/hostsidetests/appsecurity/test-apps/PrivilegedUpdateApp/apk/x86/CtsShimPrivUpgradeWrongSHA_v28.apk b/hostsidetests/appsecurity/test-apps/PrivilegedUpdateApp/apk/x86/CtsShimPrivUpgradeWrongSHA_v28.apk
new file mode 100644
index 0000000..d7e0826
--- /dev/null
+++ b/hostsidetests/appsecurity/test-apps/PrivilegedUpdateApp/apk/x86/CtsShimPrivUpgradeWrongSHA_v28.apk
Binary files differ
diff --git a/hostsidetests/appsecurity/test-apps/PrivilegedUpdateApp/apk/x86/CtsShimPrivUpgrade_v28.apk b/hostsidetests/appsecurity/test-apps/PrivilegedUpdateApp/apk/x86/CtsShimPrivUpgrade_v28.apk
new file mode 100644
index 0000000..f0cc8b6
--- /dev/null
+++ b/hostsidetests/appsecurity/test-apps/PrivilegedUpdateApp/apk/x86/CtsShimPrivUpgrade_v28.apk
Binary files differ
diff --git a/hostsidetests/appsecurity/test-apps/PrivilegedUpdatePreparer/Android.mk b/hostsidetests/appsecurity/test-apps/PrivilegedUpdatePreparer/Android.mk
new file mode 100644
index 0000000..77d2b82
--- /dev/null
+++ b/hostsidetests/appsecurity/test-apps/PrivilegedUpdatePreparer/Android.mk
@@ -0,0 +1,35 @@
+#
+# 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.
+#
+
+LOCAL_PATH := $(call my-dir)
+
+include $(CLEAR_VARS)
+
+LOCAL_MODULE_TAGS := tests
+LOCAL_SDK_VERSION := current
+#LOCAL_STATIC_JAVA_LIBRARIES := android-support-test compatibility-device-util ctstestrunner
+LOCAL_STATIC_JAVA_LIBRARIES := compatibility-device-util
+#LOCAL_JAVA_LIBRARIES := android.test.base.stubs
+# Tag this module as a cts test artifact
+LOCAL_COMPATIBILITY_SUITE := cts vts general-tests
+LOCAL_PROGUARD_ENABLED := disabled
+LOCAL_DEX_PREOPT := false
+LOCAL_PACKAGE_NAME := CtsPrivilegedUpdatePreparer
+
+LOCAL_SRC_FILES := $(call all-java-files-under, src)
+
+include $(BUILD_CTS_PACKAGE)
+
diff --git a/hostsidetests/appsecurity/test-apps/PrivilegedUpdatePreparer/AndroidManifest.xml b/hostsidetests/appsecurity/test-apps/PrivilegedUpdatePreparer/AndroidManifest.xml
new file mode 100644
index 0000000..026fd94
--- /dev/null
+++ b/hostsidetests/appsecurity/test-apps/PrivilegedUpdatePreparer/AndroidManifest.xml
@@ -0,0 +1,29 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- 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.
+-->
+
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+        package="com.android.cts.privilegedupdate.preparer">
+
+    <application>
+        <uses-library android:name="android.test.runner" />
+    </application>
+
+    <instrumentation
+        android:name="android.support.test.runner.AndroidJUnitRunner"
+        android:targetPackage="com.android.cts.privilegedupdate.preparer" />
+
+</manifest>
+
diff --git a/hostsidetests/appsecurity/test-apps/PrivilegedUpdatePreparer/src/com/android/cts/privilegedupdate/preparer/PrivilegedUpdateTestPreparer.java b/hostsidetests/appsecurity/test-apps/PrivilegedUpdatePreparer/src/com/android/cts/privilegedupdate/preparer/PrivilegedUpdateTestPreparer.java
new file mode 100644
index 0000000..ffdaf3a
--- /dev/null
+++ b/hostsidetests/appsecurity/test-apps/PrivilegedUpdatePreparer/src/com/android/cts/privilegedupdate/preparer/PrivilegedUpdateTestPreparer.java
@@ -0,0 +1,43 @@
+/*
+ * 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.cts.privilegedupdate.preparer;
+
+import android.app.Instrumentation;
+import android.content.pm.PackageInfo;
+import android.content.pm.PackageManager;
+import android.os.Bundle;
+import android.support.test.InstrumentationRegistry;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.JUnit4;
+
+@RunWith(JUnit4.class)
+public class PrivilegedUpdateTestPreparer {
+    /** Package name of the privileged CTS shim */
+    private static final String PRIVILEGED_SHIM_PKG = "com.android.cts.priv.ctsshim";
+
+    @Test
+    public void getTargetSdk() throws Exception {
+        final Instrumentation inst = InstrumentationRegistry.getInstrumentation();
+        final PackageManager pm = inst.getContext().getPackageManager();
+        final PackageInfo pi = pm.getPackageInfo(PRIVILEGED_SHIM_PKG, 0);
+        final Bundle targetSdkBundle = new Bundle();
+        targetSdkBundle.putString("target_sdk", Integer.toString(pi.applicationInfo.targetSdkVersion));
+        inst.sendStatus(2, targetSdkBundle);
+    }
+}