No need to have these lines here, the tests are removed. am: f62186b2ac
am: cc7b096e1e

Change-Id: I44539a7712b5f267fdaba8b021d6610f9ac2d1ab
diff --git a/Android.mk b/Android.mk
index 94a0e94..ace234f 100644
--- a/Android.mk
+++ b/Android.mk
@@ -14,4 +14,8 @@
 # limitations under the License.
 #
 
+# TODO: Hide this directory from the build system.
+# So that when this directory is copied over to the new
+# repo test/suite_harness, things won't break. Uncomment after
+# the migration is done.
 include $(call all-subdir-makefiles)
diff --git a/OWNERS b/OWNERS
new file mode 100644
index 0000000..6112249
--- /dev/null
+++ b/OWNERS
@@ -0,0 +1,10 @@
+# Android EngProd Approvers
+guangzhu@google.com
+fdeng@google.com
+moonk@google.com
+jdesprez@google.com
+
+# Android Partner Eng Approvers
+aaronholden@google.com
+yuji@google.com
+nickrose@google.com
diff --git a/common/host-side/tradefed/src/com/android/compatibility/common/tradefed/testtype/retry/RetryFactoryTest.java b/common/host-side/tradefed/src/com/android/compatibility/common/tradefed/testtype/retry/RetryFactoryTest.java
index 0f6ba3d..7d6db59 100644
--- a/common/host-side/tradefed/src/com/android/compatibility/common/tradefed/testtype/retry/RetryFactoryTest.java
+++ b/common/host-side/tradefed/src/com/android/compatibility/common/tradefed/testtype/retry/RetryFactoryTest.java
@@ -202,6 +202,8 @@
         // TODO: we have access to the original command line, we should accommodate more re-run
         // scenario like when the original cts.xml config was not used.
         helper.validateBuildFingerprint(mDevice);
+        // ResultReporter when creating the xml will use the retry command line
+        helper.setBuildInfoRetryCommand(mBuildInfo);
         helper.setCommandLineOptionsFor(test);
         helper.setCommandLineOptionsFor(this);
         helper.populateRetryFilters();
diff --git a/common/host-side/tradefed/src/com/android/compatibility/common/tradefed/util/RetryFilterHelper.java b/common/host-side/tradefed/src/com/android/compatibility/common/tradefed/util/RetryFilterHelper.java
index cebac97..d39282c 100644
--- a/common/host-side/tradefed/src/com/android/compatibility/common/tradefed/util/RetryFilterHelper.java
+++ b/common/host-side/tradefed/src/com/android/compatibility/common/tradefed/util/RetryFilterHelper.java
@@ -24,6 +24,7 @@
 import com.android.compatibility.common.util.LightInvocationResult;
 import com.android.compatibility.common.util.ResultHandler;
 import com.android.compatibility.common.util.TestFilter;
+import com.android.tradefed.build.IBuildInfo;
 import com.android.tradefed.config.ArgsOptionParser;
 import com.android.tradefed.config.ConfigurationException;
 import com.android.tradefed.device.DeviceNotAvailableException;
@@ -161,6 +162,16 @@
     }
 
     /**
+     * Set the retry command line args on the {@link IBuildInfo} to carry the original command
+     * across retries.
+     */
+    public void setBuildInfoRetryCommand(IBuildInfo info) {
+        IInvocationResult result = new LightInvocationResult(getResult());
+        String retryCommandLineArgs = result.getCommandLineArgs();
+        new CompatibilityBuildHelper(info).setRetryCommandLineArgs(retryCommandLineArgs);
+    }
+
+    /**
      * Retrieve an instance of the result to retry using the instance variables referencing
      * the build and the desired session ID. While it is faster to load this result once and
      * store it as an instance variable, {@link IInvocationResult} objects are large, and
diff --git a/common/host-side/tradefed/tests/src/com/android/compatibility/common/tradefed/presubmit/CtsConfigLoadingTest.java b/common/host-side/tradefed/tests/src/com/android/compatibility/common/tradefed/presubmit/CtsConfigLoadingTest.java
index ce05ebf..0289b81 100644
--- a/common/host-side/tradefed/tests/src/com/android/compatibility/common/tradefed/presubmit/CtsConfigLoadingTest.java
+++ b/common/host-side/tradefed/tests/src/com/android/compatibility/common/tradefed/presubmit/CtsConfigLoadingTest.java
@@ -31,6 +31,8 @@
 import com.android.tradefed.testtype.HostTest;
 import com.android.tradefed.testtype.IRemoteTest;
 import com.android.tradefed.testtype.ITestFilterReceiver;
+import com.android.tradefed.testtype.suite.ITestSuite;
+import com.android.tradefed.testtype.suite.params.ModuleParameters;
 
 import org.junit.Assert;
 import org.junit.Test;
@@ -62,6 +64,7 @@
             "bionic",
             "bluetooth",
             "camera",
+            "deviceinfo",
             "deqp",
             "devtools",
             "framework",
@@ -217,6 +220,9 @@
                     + "field \"%s\", supported ones are: %s\nconfig: %s",
                     cmp, KNOWN_COMPONENTS, config), KNOWN_COMPONENTS.contains(cmp));
 
+            // Check that specified parameters are expected
+            checkModuleParameters(config.getName(), cd.getMetaData(ITestSuite.PARAMETER_KEY));
+
             // Ensure each CTS module is tagged with <option name="test-suite-tag" value="cts" />
             Assert.assertTrue(String.format(
                     "Module config %s does not contains "
@@ -236,4 +242,23 @@
             }
         }
     }
+
+    /**
+     * Test that all parameter metadata can be resolved.
+     */
+    private void checkModuleParameters(String configName, List<String> parameters)
+            throws ConfigurationException {
+        if (parameters == null) {
+            return;
+        }
+        for (String param : parameters) {
+            try {
+                ModuleParameters.valueOf(param.toUpperCase());
+            } catch (IllegalArgumentException e) {
+                throw new ConfigurationException(
+                        String.format("Config: %s includes an unknown parameter '%s'.",
+                                configName, param));
+            }
+        }
+    }
 }
diff --git a/common/host-side/tradefed/tests/src/com/android/compatibility/common/tradefed/result/SubPlanHelperTest.java b/common/host-side/tradefed/tests/src/com/android/compatibility/common/tradefed/result/SubPlanHelperTest.java
index 8912411..005e180 100644
--- a/common/host-side/tradefed/tests/src/com/android/compatibility/common/tradefed/result/SubPlanHelperTest.java
+++ b/common/host-side/tradefed/tests/src/com/android/compatibility/common/tradefed/result/SubPlanHelperTest.java
@@ -89,7 +89,7 @@
         mResultsDir = FileUtil.createTempDir("results");
         mResultDir = FileUtil.createTempDir("12345", mResultsDir);
         mSubPlansDir = FileUtil.createTempDir("subplans");
-        mBuildHelper = new SpctMockCompatibilityBuildHelper(new BuildInfo("0", "", ""));
+        mBuildHelper = new SpctMockCompatibilityBuildHelper(new BuildInfo("0", ""));
         populateResults();
 
         mSubPlanHelper = new SubPlanHelper();
diff --git a/common/host-side/tradefed/tests/src/com/android/compatibility/common/tradefed/targetprep/PropertyCheckTest.java b/common/host-side/tradefed/tests/src/com/android/compatibility/common/tradefed/targetprep/PropertyCheckTest.java
index 617fde6..9b34646 100644
--- a/common/host-side/tradefed/tests/src/com/android/compatibility/common/tradefed/targetprep/PropertyCheckTest.java
+++ b/common/host-side/tradefed/tests/src/com/android/compatibility/common/tradefed/targetprep/PropertyCheckTest.java
@@ -42,7 +42,7 @@
         super.setUp();
         mPropertyCheck = new PropertyCheck();
         mMockDevice = EasyMock.createMock(ITestDevice.class);
-        mMockBuildInfo = new DeviceBuildInfo("0", "", "");
+        mMockBuildInfo = new DeviceBuildInfo("0", "");
         mOptionSetter = new OptionSetter(mPropertyCheck);
         EasyMock.expect(mMockDevice.getProperty(PROPERTY)).andReturn(ACTUAL_VALUE).anyTimes();
         EasyMock.expect(mMockDevice.getDeviceDescriptor()).andReturn(null).anyTimes();
diff --git a/common/host-side/tradefed/tests/src/com/android/compatibility/common/tradefed/targetprep/SettingsPreparerTest.java b/common/host-side/tradefed/tests/src/com/android/compatibility/common/tradefed/targetprep/SettingsPreparerTest.java
index 7fbb39e..99f2601 100644
--- a/common/host-side/tradefed/tests/src/com/android/compatibility/common/tradefed/targetprep/SettingsPreparerTest.java
+++ b/common/host-side/tradefed/tests/src/com/android/compatibility/common/tradefed/targetprep/SettingsPreparerTest.java
@@ -46,7 +46,7 @@
         mSettingsPreparer = new SettingsPreparer();
         mMockDevice = EasyMock.createMock(ITestDevice.class);
         EasyMock.expect(mMockDevice.getDeviceDescriptor()).andReturn(null).anyTimes();
-        mMockBuildInfo = new BuildInfo("0", "", "");
+        mMockBuildInfo = new BuildInfo("0", "");
         mOptionSetter = new OptionSetter(mSettingsPreparer);
         mOptionSetter.setOptionValue("device-setting", "stay_on_while_plugged_in");
         mOptionSetter.setOptionValue("setting-type", "global");
diff --git a/common/host-side/tradefed/tests/src/com/android/compatibility/common/tradefed/testtype/retry/RetryFactoryTestTest.java b/common/host-side/tradefed/tests/src/com/android/compatibility/common/tradefed/testtype/retry/RetryFactoryTestTest.java
index b682cbf..39e24bd 100644
--- a/common/host-side/tradefed/tests/src/com/android/compatibility/common/tradefed/testtype/retry/RetryFactoryTestTest.java
+++ b/common/host-side/tradefed/tests/src/com/android/compatibility/common/tradefed/testtype/retry/RetryFactoryTestTest.java
@@ -118,6 +118,10 @@
                 // do nothing
             }
             @Override
+            public void setBuildInfoRetryCommand(IBuildInfo info) {
+                // do nothing
+            }
+            @Override
             public void populateFiltersBySubPlan() {
                 // do nothing
             }
diff --git a/common/util/src/com/android/compatibility/common/util/BackupUtils.java b/common/util/src/com/android/compatibility/common/util/BackupUtils.java
new file mode 100644
index 0000000..0cfe674
--- /dev/null
+++ b/common/util/src/com/android/compatibility/common/util/BackupUtils.java
@@ -0,0 +1,157 @@
+/*
+ * Copyright (C) 2018 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.compatibility.common.util;
+
+import static org.junit.Assert.assertTrue;
+
+import com.android.compatibility.common.util.LogcatInspector;
+
+import java.io.BufferedReader;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.nio.charset.StandardCharsets;
+
+/**
+ * Utility class for backup and restore.
+ */
+public abstract class BackupUtils {
+
+    /** The tag of the token */
+    private static final String TOKEN_TAG = "Current:";
+
+    /**
+     * Should execute adb shell {@param command} and return an {@link InputStream} with the result.
+     */
+    protected abstract InputStream executeShellCommand(String command) throws IOException;
+
+    /**
+     * Execute shell command "bmgr backupnow <packageName>" and assert success.
+     */
+    public void backupNowAndAssertSuccess(String packageName) throws IOException {
+        InputStream backupnowOutput = backupNow(packageName);
+        assertBackupIsSuccessful(packageName, backupnowOutput);
+    }
+
+    /**
+     * Execute shell command "bmgr backupnow <packageName>" and return output from this command.
+     */
+    private InputStream backupNow(String packageName) throws IOException {
+        return executeShellCommand("bmgr backupnow " + packageName);
+    }
+
+    /**
+     * Parsing the output of "bmgr backupnow" command and checking that the package under test
+     * was backed up successfully. Close the input stream finally.
+     *
+     * Expected format: "Package <packageName> with result: Success"
+     */
+    private void assertBackupIsSuccessful(String packageName, InputStream backupnowOutput)
+            throws IOException {
+        BufferedReader br = new BufferedReader(
+                new InputStreamReader(backupnowOutput, StandardCharsets.UTF_8));
+        try {
+            String str;
+            boolean success = false;
+            while ((str = br.readLine()) != null) {
+                if (str.contains(packageName)) {
+                    String result = str.split(":")[1].trim();
+                    if ("Success".equals(result)) {
+                        success = true;
+                        break;
+                    }
+                }
+            }
+            assertTrue("Couldn't find package in output or its backup wasn't successful", success);
+        } finally {
+            if (br != null) LogcatInspector.drainAndClose(br);
+        }
+    }
+
+    /**
+     * Execute shell command "bmgr restore <token> <packageName>" and assert success.
+     */
+    public void restoreAndAssertSuccess(String packageName) throws IOException {
+        InputStream dumpsysOutput = dumpsysBackup();
+        String token = getTokenOrFail(dumpsysOutput);
+        InputStream restoreOutput = restore(token, packageName);
+        assertRestoreIsSuccessful(restoreOutput);
+    }
+
+    /**
+     * Execute shell command "bmgr restore <token> <packageName>" and return output from this
+     * command.
+     */
+    private InputStream restore(String token, String packageName) throws IOException {
+        return executeShellCommand(String.format("bmgr restore %s %s", token, packageName));
+    }
+
+    /**
+     * Parsing the output of "bmgr restore" command and checking that the package under test
+     * was restored successfully. Close the input stream finally.
+     *
+     * Expected format: "restoreFinished: 0"
+     */
+    private void assertRestoreIsSuccessful(InputStream restoreOutput) throws IOException {
+        BufferedReader br = new BufferedReader(
+                new InputStreamReader(restoreOutput, StandardCharsets.UTF_8));
+        try {
+            String str;
+            boolean success = false;
+            while ((str = br.readLine()) != null) {
+                if (str.contains("restoreFinished: 0")) {
+                    success = true;
+                    break;
+                }
+            }
+            assertTrue("Restore not successful", success);
+        } finally {
+            if (br != null) LogcatInspector.drainAndClose(br);
+        }
+    }
+
+    /**
+     * Execute shell command "dumpsys backup" and return output from this command.
+     */
+    private InputStream dumpsysBackup() throws IOException {
+        return executeShellCommand("dumpsys backup");
+    }
+
+    /**
+     * Parsing the output of "dumpsys backup" command to get token. Close the input stream finally.
+     *
+     * Expected format: "Current: token"
+     */
+    private String getTokenOrFail(InputStream dumpsysOutput) throws IOException {
+        BufferedReader br = new BufferedReader(
+                new InputStreamReader(dumpsysOutput, StandardCharsets.UTF_8));
+        String token = null;
+        try {
+            String str;
+            while ((str = br.readLine()) != null) {
+                if (str.contains(TOKEN_TAG)) {
+                    token = str.split(TOKEN_TAG)[1].trim();
+                    break;
+                }
+            }
+            assertTrue("Couldn't find token in output", token != null);
+        } finally {
+            if (br != null) LogcatInspector.drainAndClose(br);
+        }
+        return token;
+    }
+}
\ No newline at end of file
diff --git a/common/util/src/com/android/compatibility/common/util/LogcatInspector.java b/common/util/src/com/android/compatibility/common/util/LogcatInspector.java
index ed82307..e427af6 100644
--- a/common/util/src/com/android/compatibility/common/util/LogcatInspector.java
+++ b/common/util/src/com/android/compatibility/common/util/LogcatInspector.java
@@ -118,7 +118,7 @@
         return stringIndex;
     }
 
-    private static void drainAndClose(BufferedReader reader) {
+    public static void drainAndClose(BufferedReader reader) {
         try {
             while (reader.read() >= 0) {
                 // do nothing.
diff --git a/tools/cts-tradefed/res/config/cts-known-failures.xml b/tools/cts-tradefed/res/config/cts-known-failures.xml
index a663506..6665f97 100644
--- a/tools/cts-tradefed/res/config/cts-known-failures.xml
+++ b/tools/cts-tradefed/res/config/cts-known-failures.xml
@@ -122,29 +122,9 @@
     <option name="compatibility:exclude-filter" value="CtsVideoTestCases android.video.cts.VideoEncoderDecoderTest#testVp9Goog0Perf1280x0720" />
     <option name="compatibility:exclude-filter" value="CtsVideoTestCases android.video.cts.VideoEncoderDecoderTest#testVp9Goog0Perf1920x1080" />
 
-    <!-- b/37482372 -->
-    <option name="compatibility:exclude-filter" value="CtsPreference2TestCases android.preference2.cts.PreferenceActivityFlowPortraitTest#multiWindowHistoryPreservePortraitTest" />
-    <option name="compatibility:exclude-filter" value="CtsPreference2TestCases android.preference2.cts.PreferenceActivityFlowPortraitTest#multiWindowInOutPortraitTest" />
-    <option name="compatibility:exclude-filter" value="CtsPreference2TestCases android.preference2.cts.PreferenceActivityFlowPortraitTest#multiWindowInitialHeaderOnBackPortraitTest" />
-    <option name="compatibility:exclude-filter" value="CtsPreference2TestCases android.preference2.cts.PreferenceActivityFlowPortraitTest#multiWindowInnerFragmentInOutPortraitTest" />
-    <option name="compatibility:exclude-filter" value="CtsPreference2TestCases android.preference2.cts.PreferenceActivityFlowPortraitTest#startWithFragmentAndInitTitleMultiWindowPortraitTest" />
-    <option name="compatibility:exclude-filter" value="CtsPreference2TestCases android.preference2.cts.PreferenceActivityFlowPortraitTest#startWithFragmentNoHeadersMultiWindowPortraitTest" />
-
     <!-- b/63916274 -->
     <option name="compatibility:exclude-filter" value="CtsTelecomTestCases android.telecom.cts.WiredHeadsetTest" />
 
-    <!-- b/38177396 -->
-    <option name="compatibility:exclude-filter" value="CtsPreference2TestCases android.preference2.cts.PreferenceActivityFlowLandscapeTest#multiWindowHistoryPreserveLandscapeTest" />
-    <option name="compatibility:exclude-filter" value="CtsPreference2TestCases android.preference2.cts.PreferenceActivityFlowLandscapeTest#multiWindowInOutLandscapeTest" />
-    <option name="compatibility:exclude-filter" value="CtsPreference2TestCases android.preference2.cts.PreferenceActivityFlowLandscapeTest#multiWindowInitialHeaderOnBackLandscapeTest" />
-    <option name="compatibility:exclude-filter" value="CtsPreference2TestCases android.preference2.cts.PreferenceActivityFlowLandscapeTest#multiWindowInnerFragmentInOutLandscapeTest" />
-    <option name="compatibility:exclude-filter" value="CtsPreference2TestCases android.preference2.cts.PreferenceActivityFlowLandscapeTest#startWithFragmentAndInitTitleMultiWindowLandscapeTest" />
-    <option name="compatibility:exclude-filter" value="CtsPreference2TestCases android.preference2.cts.PreferenceActivityFlowLandscapeTest#startWithFragmentNoHeadersMultiWindowLandscapeTest" />
-
-    <!-- b/62924649 -->
-    <option name="compatibility:exclude-filter" value="CtsPreference2TestCases android.preference2.cts.PreferenceActivityLegacyFlowTest#legacyActivityMultiWindowTest" />
-    <option name="compatibility:exclude-filter" value="CtsPreference2TestCases android.preference2.cts.PreferenceActivityLegacyFlowTest#legacyActivityMultiWindowToggleTest" />
-
     <!-- b/38224690 -->
     <option name="compatibility:exclude-filter" value="CtsMediaTestCases android.media.cts.NativeEncoderTest" />
 
diff --git a/tools/cts-tradefed/res/config/cts-suite.xml b/tools/cts-tradefed/res/config/cts-suite.xml
index f04b25b..ca2cb2c 100644
--- a/tools/cts-tradefed/res/config/cts-suite.xml
+++ b/tools/cts-tradefed/res/config/cts-suite.xml
@@ -13,7 +13,7 @@
      See the License for the specific language governing permissions and
      limitations under the License.
 -->
-<configuration description="Runs CTS as a suite">
+<configuration description="Runs CTS as a suite. Configuration for testing new changes.">
     <!-- running config -->
     <build_provider class="com.android.compatibility.common.tradefed.build.CompatibilityBuildProvider" />
     <test class="com.android.compatibility.common.tradefed.testtype.suite.CompatibilityTestSuite">
@@ -65,10 +65,5 @@
     <template-include name="metadata-reporters" default="empty" />
 
     <result_reporter class="com.android.compatibility.common.tradefed.result.ConsoleReporter" />
-    <result_reporter class="com.android.compatibility.common.tradefed.result.ResultReporter" />
-    <result_reporter class="com.android.compatibility.common.tradefed.result.suite.CertificationSuiteResultReporter">
-        <!-- Avoid double posting from this reporter until ResultReporter is removed -->
-        <option name="disable-result-posting" value="true" />
-    </result_reporter>
-
+    <result_reporter class="com.android.compatibility.common.tradefed.result.suite.CertificationSuiteResultReporter" />
 </configuration>
diff --git a/tools/cts-tradefed/res/config/cts-system-checkers.xml b/tools/cts-tradefed/res/config/cts-system-checkers.xml
index b3adb69..8585174 100644
--- a/tools/cts-tradefed/res/config/cts-system-checkers.xml
+++ b/tools/cts-tradefed/res/config/cts-system-checkers.xml
@@ -16,6 +16,7 @@
 <configuration description="CTS system checker configs">
     <system_checker class="com.android.compatibility.common.tradefed.targetprep.NetworkConnectivityChecker" />
     <system_checker class="com.android.tradefed.suite.checker.KeyguardStatusChecker" />
+    <system_checker class="com.android.tradefed.suite.checker.DeviceSettingChecker" />
     <system_checker class="com.android.tradefed.suite.checker.SystemServerStatusChecker" />
     <system_checker class="com.android.tradefed.suite.checker.SystemServerFileDescriptorChecker" />
 </configuration>