Merge "Avoid relying on undocumented behaviour in popup test." into marshmallow-cts-dev
diff --git a/CtsTestCaseList.mk b/CtsTestCaseList.mk
index 5f47671..c0bd3f3 100644
--- a/CtsTestCaseList.mk
+++ b/CtsTestCaseList.mk
@@ -78,7 +78,6 @@
 
 cts_support_packages := \
     CtsAccelerationTestStubs \
-    CtsBackupRestoreDeviceApp \
     CtsAlarmClockService \
     CtsAppTestStubs \
     CtsAssistService \
@@ -232,7 +231,6 @@
 # Host side only tests
 cts_host_libraries := \
     CtsAdbTests \
-    CtsBackupHostTestCases \
     CtsAppSecurityTests \
     CtsAtraceHostTestCases \
     CtsCppToolsTestCases \
diff --git a/hostsidetests/backup/Android.mk b/hostsidetests/backup/Android.mk
deleted file mode 100644
index 36d39dd..0000000
--- a/hostsidetests/backup/Android.mk
+++ /dev/null
@@ -1,38 +0,0 @@
-# Copyright (C) 2017 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_SRC_FILES := $(call all-java-files-under, src)
-
-LOCAL_JAVA_RESOURCE_DIRS := assets/
-
-LOCAL_MODULE_TAGS := optional
-
-LOCAL_PROGUARD_ENABLED := disabled
-
-# tag this module as a cts test artifact
-# LOCAL_COMPATIBILITY_SUITE := cts
-
-LOCAL_MODULE := CtsBackupHostTestCases
-
-LOCAL_JAVA_LIBRARIES := cts-tradefed tradefed-prebuilt
-
-LOCAL_CTS_TEST_PACKAGE := android.host.backup
-
-include $(BUILD_CTS_HOST_JAVA_LIBRARY)
-
-include $(call all-makefiles-under,$(LOCAL_PATH))
diff --git a/hostsidetests/backup/app/Android.mk b/hostsidetests/backup/app/Android.mk
deleted file mode 100644
index 074452b..0000000
--- a/hostsidetests/backup/app/Android.mk
+++ /dev/null
@@ -1,32 +0,0 @@
-# Copyright (C) 2017 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)
-
-# Don't include this package in any target
-LOCAL_MODULE_TAGS := tests
-# When built, explicitly put it in the data partition.
-LOCAL_MODULE_PATH := $(TARGET_OUT_DATA_APPS)
-
-LOCAL_STATIC_JAVA_LIBRARIES := android-support-test
-
-LOCAL_SRC_FILES := $(call all-java-files-under, src)
-
-LOCAL_PACKAGE_NAME := CtsBackupRestoreDeviceApp
-
-LOCAL_SDK_VERSION := current
-
-include $(BUILD_CTS_PACKAGE)
diff --git a/hostsidetests/backup/app/AndroidManifest.xml b/hostsidetests/backup/app/AndroidManifest.xml
deleted file mode 100644
index 0d3aee8..0000000
--- a/hostsidetests/backup/app/AndroidManifest.xml
+++ /dev/null
@@ -1,40 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-  ~ Copyright (C) 2017 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="android.backup.cts.backuprestoreapp">
-
-    <application
-        android:backupAgent="CtsBackupRestoreBackupAgent">
-        <uses-library android:name="android.test.runner" />
-
-        <activity
-            android:name=".KeyValueBackupRandomDataActivity"
-            android:launchMode="singleInstance">
-            <intent-filter>
-                <action android:name="android.intent.action.MAIN" />
-                <category android:name="android.intent.category.DEFAULT" />
-            </intent-filter>
-        </activity>
-
-    </application>
-
-    <instrumentation
-        android:name="android.support.test.runner.AndroidJUnitRunner"
-        android:targetPackage="android.backup.cts.backuprestoreapp" />
-
-</manifest>
diff --git a/hostsidetests/backup/app/src/android/backup/cts/backuprestoreapp/CtsBackupRestoreBackupAgent.java b/hostsidetests/backup/app/src/android/backup/cts/backuprestoreapp/CtsBackupRestoreBackupAgent.java
deleted file mode 100644
index e692fdd..0000000
--- a/hostsidetests/backup/app/src/android/backup/cts/backuprestoreapp/CtsBackupRestoreBackupAgent.java
+++ /dev/null
@@ -1,33 +0,0 @@
-/*
- * Copyright (C) 2017 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 android.backup.cts.backuprestoreapp;
-
-import android.app.backup.BackupAgentHelper;
-
-public class CtsBackupRestoreBackupAgent extends BackupAgentHelper {
-    private static final String KEY_BACKUP_TEST_PREFS_PREFIX = "backup-test-prefs";
-    private static final String KEY_BACKUP_TEST_FILES_PREFIX = "backup-test-files";
-
-    @Override
-    public void onCreate() {
-        super.onCreate();
-        addHelper(KEY_BACKUP_TEST_PREFS_PREFIX,
-                KeyValueBackupRandomDataActivity.getSharedPreferencesBackupHelper(this));
-        addHelper(KEY_BACKUP_TEST_FILES_PREFIX,
-                KeyValueBackupRandomDataActivity.getFileBackupHelper(this));
-    }
-}
diff --git a/hostsidetests/backup/app/src/android/backup/cts/backuprestoreapp/KeyValueBackupRandomDataActivity.java b/hostsidetests/backup/app/src/android/backup/cts/backuprestoreapp/KeyValueBackupRandomDataActivity.java
deleted file mode 100644
index 92db3f3..0000000
--- a/hostsidetests/backup/app/src/android/backup/cts/backuprestoreapp/KeyValueBackupRandomDataActivity.java
+++ /dev/null
@@ -1,228 +0,0 @@
-/*
- * Copyright (C) 2017 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 android.backup.cts.backuprestoreapp;
-
-import android.app.Activity;
-import android.app.backup.BackupManager;
-import android.app.backup.FileBackupHelper;
-import android.app.backup.SharedPreferencesBackupHelper;
-import android.content.Context;
-import android.content.SharedPreferences;
-import android.os.AsyncTask;
-import android.os.Bundle;
-import android.util.Log;
-
-import java.io.File;
-import java.io.FileNotFoundException;
-import java.io.PrintWriter;
-import java.util.Random;
-import java.util.Scanner;
-
-/**
- * Test activity that reads/writes to shared preferences and files.
- *
- * It uses logcat messages to send the data to the host side of the test.
- * The format of logcat messages: "DATA_PREF: VALUE".
- * VALUES_LOADED_MESSAGE is logged after all the values.
- *
- * Workflow onCreate:
- * - Read shared preferences and files
- * - If the values are default ones:
- *      - Randomly generate new values
- *      - Save new values to shared preferences and files
- *      - Load the new values.
- *
- * Migrated from BackupTestActivity in former BackupTest CTS Verfifier test.
- */
-public class KeyValueBackupRandomDataActivity extends Activity {
-    private static final String TAG = KeyValueBackupRandomDataActivity.class.getSimpleName();
-
-    private static final String TEST_PREFS_1 = "test-prefs-1";
-    private static final String INT_PREF = "int-pref";
-    private static final String BOOL_PREF = "bool-pref";
-
-    private static final String TEST_PREFS_2 = "test-prefs-2";
-    private static final String FLOAT_PREF = "float-pref";
-    private static final String LONG_PREF = "long-pref";
-    private static final String STRING_PREF = "string-pref";
-
-    private static final String TEST_FILE_1 = "test-file-1";
-    private static final String TEST_FILE_2 = "test-file-2";
-
-    private static final int DEFAULT_INT_VALUE = 0;
-    private static final boolean DEFAULT_BOOL_VALUE = false;
-    private static final float DEFAULT_FLOAT_VALUE = 0.0f;
-    private static final long DEFAULT_LONG_VALUE = 0L;
-    private static final String DEFAULT_STRING_VALUE = null;
-
-    private static final String VALUES_LOADED_MESSAGE = "ValuesLoaded";
-    private static final String EMPTY_STRING_LOG = "empty";
-
-    private boolean mDefaultValues = true;
-    private boolean mValuesWereGenerated;
-
-    @Override
-    public void onCreate(Bundle savedInstanceState) {
-        super.onCreate(savedInstanceState);
-
-        new LoadBackupItemsTask().execute();
-    }
-
-    public static SharedPreferencesBackupHelper getSharedPreferencesBackupHelper(Context context) {
-        return new SharedPreferencesBackupHelper(context, TEST_PREFS_1, TEST_PREFS_2);
-    }
-
-    public static FileBackupHelper getFileBackupHelper(Context context) {
-        return new FileBackupHelper(context, TEST_FILE_1, TEST_FILE_2);
-    }
-
-    class LoadBackupItemsTask extends AsyncTask<Void, Void, Void> {
-
-        @Override
-        protected Void doInBackground(Void... params) {
-            loadPreferenceGroup1();
-            loadPreferenceGroup2();
-            loadFile(TEST_FILE_1);
-            loadFile(TEST_FILE_2);
-            return null;
-        }
-
-        private void loadPreferenceGroup1() {
-            SharedPreferences prefs = getSharedPreferences(TEST_PREFS_1, MODE_PRIVATE);
-
-            int intValue = prefs.getInt(INT_PREF, DEFAULT_INT_VALUE);
-            Log.i(TAG, INT_PREF + ":" + intValue);
-
-            boolean boolValue = prefs.getBoolean(BOOL_PREF, DEFAULT_BOOL_VALUE);
-            Log.i(TAG, BOOL_PREF + ":" + boolValue);
-
-            mDefaultValues = mDefaultValues
-                    && intValue == DEFAULT_INT_VALUE
-                    && boolValue == DEFAULT_BOOL_VALUE;
-        }
-
-        private void loadPreferenceGroup2() {
-            SharedPreferences prefs = getSharedPreferences(TEST_PREFS_2, MODE_PRIVATE);
-
-            float floatValue = prefs.getFloat(FLOAT_PREF, DEFAULT_FLOAT_VALUE);
-            Log.i(TAG, FLOAT_PREF + ":" + floatValue);
-
-            long longValue = prefs.getLong(LONG_PREF, DEFAULT_LONG_VALUE);
-            Log.i(TAG, LONG_PREF + ":" + longValue);
-
-            String stringValue = prefs.getString(STRING_PREF, DEFAULT_STRING_VALUE);
-            Log.i(TAG, STRING_PREF + ":" + stringValue);
-
-            mDefaultValues = mDefaultValues
-                            && floatValue == DEFAULT_FLOAT_VALUE
-                            && longValue == DEFAULT_LONG_VALUE
-                            && stringValue == DEFAULT_STRING_VALUE;
-        }
-
-        private void loadFile(String fileName) {
-            StringBuilder contents = new StringBuilder();
-            Scanner scanner = null;
-            try {
-                scanner = new Scanner(new File(getFilesDir(), fileName));
-                while (scanner.hasNext()) {
-                    contents.append(scanner.nextLine());
-                }
-                scanner.close();
-            } catch (FileNotFoundException e) {
-                Log.i(TAG, "Couldn't find test file but this may be fine...");
-            } finally {
-                if (scanner != null) {
-                    scanner.close();
-                }
-            }
-            String logString = contents.toString();
-            logString = logString.isEmpty() ? EMPTY_STRING_LOG : logString;
-            Log.i(TAG, fileName + ":" + logString);
-
-            mDefaultValues = mDefaultValues && contents.toString().isEmpty();
-        }
-
-        @Override
-        protected void onPostExecute(Void param) {
-            super.onPostExecute(param);
-
-            if (mDefaultValues && !mValuesWereGenerated) {
-                new GenerateValuesTask().execute();
-            } else {
-                Log.i(TAG, VALUES_LOADED_MESSAGE);
-            }
-        }
-    }
-
-    class GenerateValuesTask extends AsyncTask<Void, Void, Exception> {
-
-        @Override
-        protected Exception doInBackground(Void... params) {
-            Random random = new Random();
-            generatePreferenceGroup1(random);
-            generatePreferenceGroup2(random);
-            try {
-                generateTestFile(TEST_FILE_1, random);
-                generateTestFile(TEST_FILE_2, random);
-            } catch (FileNotFoundException e) {
-                return e;
-            }
-            return null;
-        }
-
-        private void generatePreferenceGroup1(Random random) {
-            SharedPreferences prefs = getSharedPreferences(TEST_PREFS_1, MODE_PRIVATE);
-            SharedPreferences.Editor editor = prefs.edit();
-            editor.putInt(INT_PREF, (random.nextInt(100) + 1));
-            editor.putBoolean(BOOL_PREF, random.nextBoolean());
-            editor.commit();
-        }
-
-        private void generatePreferenceGroup2(Random random) {
-            SharedPreferences prefs = getSharedPreferences(TEST_PREFS_2, MODE_PRIVATE);
-            SharedPreferences.Editor editor = prefs.edit();
-            editor.putFloat(FLOAT_PREF, random.nextFloat());
-            editor.putLong(LONG_PREF, random.nextLong());
-            editor.putString(STRING_PREF, "Random number " + (random.nextInt(100) + 1));
-            editor.commit();
-        }
-
-        private void generateTestFile(String fileName, Random random)
-                throws FileNotFoundException {
-            File file = new File(getFilesDir(), fileName);
-            PrintWriter writer = new PrintWriter(file);
-            writer.write("Random number " + (random.nextInt(100) + 1));
-            writer.close();
-        }
-
-        @Override
-        protected void onPostExecute(Exception exception) {
-            super.onPostExecute(exception);
-            mValuesWereGenerated = true;
-
-            if (exception != null) {
-                Log.e(TAG, "Couldn't generate test data...", exception);
-            } else {
-                BackupManager backupManager = new BackupManager(
-                        KeyValueBackupRandomDataActivity.this);
-                backupManager.dataChanged();
-
-                new LoadBackupItemsTask().execute();
-            }
-        }
-    }
-}
diff --git a/hostsidetests/backup/src/android/backup/cts/backup/BackupRestoreHostSideTest.java b/hostsidetests/backup/src/android/backup/cts/backup/BackupRestoreHostSideTest.java
deleted file mode 100644
index d63ee8b..0000000
--- a/hostsidetests/backup/src/android/backup/cts/backup/BackupRestoreHostSideTest.java
+++ /dev/null
@@ -1,377 +0,0 @@
-/*
- * Copyright (C) 2017 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 android.backup.cts.backup;
-
-import com.android.cts.tradefed.build.CtsBuildHelper;
-import com.android.tradefed.build.IBuildInfo;
-import com.android.tradefed.device.DeviceNotAvailableException;
-import com.android.tradefed.device.ITestDevice;
-import com.android.tradefed.testtype.DeviceTestCase;
-import com.android.tradefed.testtype.IBuildReceiver;
-import com.android.tradefed.log.LogUtil.CLog;
-
-import java.io.FileNotFoundException;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.Map;
-import java.util.Scanner;
-import java.util.concurrent.TimeUnit;
-import java.util.regex.Matcher;
-import java.util.regex.Pattern;
-
-/**
- * Test for checking that key/value backup and restore works correctly.
- * It interacts with the app that generates random values and saves them in different shared
- * preferences and files. The app uses BackupAgentHelper to do key/value backup of those values.
- * The tests verifies that the values are restored after the app is uninstalled and reinstalled.
- *
- */
-public class BackupRestoreHostSideTest extends DeviceTestCase implements IBuildReceiver {
-
-    private static final String LOG_TAG = "BackupRestoreHostSideTest";
-
-    /** Value of PackageManager.FEATURE_BACKUP */
-    private static final String FEATURE_BACKUP = "android.software.backup";
-
-    private static final String LOCAL_TRANSPORT =
-            "android/com.android.internal.backup.LocalTransport";
-
-    /** The name of the APK of the app under test */
-    private static final String TEST_APP_APK = "CtsBackupRestoreDeviceApp.apk";
-
-    /** The package name of the APK */
-    private static final String PACKAGE_UNDER_TEST = "android.backup.cts.backuprestoreapp";
-
-    /** The class name of the main activity in the APK */
-    private static final String CLASS_UNDER_TEST = "KeyValueBackupRandomDataActivity";
-
-    /** The command to launch the main activity */
-    private static final String START_ACTIVITY_UNDER_TEST_COMMAND = String.format(
-            "am start -W -a android.intent.action.MAIN -n %s/%s.%s", PACKAGE_UNDER_TEST,
-            PACKAGE_UNDER_TEST,
-            CLASS_UNDER_TEST);
-
-    /** The command to clear the user data of the package */
-    private static final String CLEAR_DATA_IN_PACKAGE_UNDER_TEST_COMMAND = String.format(
-            "pm clear %s", PACKAGE_UNDER_TEST);
-
-    /**
-     * Time we wait before reading the logcat again if the message we want is not logged by the
-     * app yet.
-     */
-    private static final int SMALL_LOGCAT_DELAY_MS = 1000;
-
-    /**
-     * Message logged by the app after all the values were loaded from SharedPreferences and files.
-     */
-    private static final String VALUES_LOADED_MESSAGE = "ValuesLoaded";
-
-    /**
-     * Keys for various shared preferences and files saved/read by the app.
-     */
-    private static final String INT_PREF = "int-pref";
-    private static final String BOOL_PREF = "bool-pref";
-    private static final String FLOAT_PREF = "float-pref";
-    private static final String LONG_PREF = "long-pref";
-    private static final String STRING_PREF = "string-pref";
-    private static final String TEST_FILE_1 = "test-file-1";
-    private static final String TEST_FILE_2 = "test-file-2";
-
-    /** Number of the values saved/restored by the app (keys listed above) */
-    private static final int NUMBER_OF_VALUES = 7;
-
-    /**
-     * String equivalents of the default values of the shared preferences logged by the app.
-     * These values are logged by the app by default if it fails to generate or restore values.
-     */
-    private static final String DEFAULT_INT_STRING = Integer.toString(0);
-    private static final String DEFAULT_BOOL_STRING = Boolean.toString(false);
-    private static final String DEFAULT_FLOAT_STRING = Float.toString(0.0f);
-    private static final String DEFAULT_LONG_STRING = Long.toString(0L);
-    private static final String DEFAULT_STRING_STRING = "null";
-    private static final String DEFAULT_FILE_STRING = "empty";
-
-    private boolean mIsBackupSupported;
-    private boolean mWasBackupEnabled;
-    private String mOldTransport;
-    private ITestDevice mDevice;
-    private HashSet<String> mAvailableFeatures;
-    private CtsBuildHelper mBuild;
-
-    /**
-     * Map of the shared preferences/files values reported by the app.
-     * Format example: INT_PREF -> 17 (string, as found in the logcat).
-     */
-    private Map<String, String> mSavedValues;
-
-    @Override
-    public void setBuild(IBuildInfo buildInfo) {
-        mBuild = CtsBuildHelper.createBuildHelper(buildInfo);
-    }
-
-    @Override
-    public void setUp() throws DeviceNotAvailableException, Exception {
-        mDevice = getDevice();
-        mIsBackupSupported = hasDeviceFeature(FEATURE_BACKUP);
-        if(mIsBackupSupported){
-		// Enable backup and select local backup transport
-		assertTrue("LocalTransport should be available.", hasBackupTransport(LOCAL_TRANSPORT));
-		mWasBackupEnabled = enableBackup(true);
-		mOldTransport = setBackupTransport(LOCAL_TRANSPORT);
-		assertNotNull(mBuild);
-	}
-    }
-
-    @Override
-    public void tearDown() throws Exception {
-        if (mIsBackupSupported) {
-            setBackupTransport(mOldTransport);
-            enableBackup(mWasBackupEnabled);
-        }
-    }
-
-    public void testKeyValueBackupAndRestore() throws Exception {
-	if(!mIsBackupSupported){
-		return;
-	}
-	assertNull(mDevice.installPackage(mBuild.getTestApp(TEST_APP_APK), true));
-        // Clear app data if any
-        mDevice.executeShellCommand(CLEAR_DATA_IN_PACKAGE_UNDER_TEST_COMMAND);
-        // Clear logcat
-        mDevice.executeAdbCommand("logcat", "-c");
-        // Start the main activity of the app
-        mDevice.executeShellCommand(START_ACTIVITY_UNDER_TEST_COMMAND);
-
-        // The app will generate some random values onCreate. Save them to mSavedValues
-        saveDataValuesReportedByApp();
-
-        // If all the values are default, there is something wrong with the app
-        assertNotAllValuesAreDefault();
-
-        // Run backup
-        mDevice.executeShellCommand("bmgr run");
-
-        assertBackupFinished();
-
-        mDevice.uninstallPackage(PACKAGE_UNDER_TEST);
-
-        assertNull(mDevice.installPackage(mBuild.getTestApp(TEST_APP_APK), true));
-
-        mDevice.executeAdbCommand("logcat", "-c");
-
-        // Start the reinstalled app
-        mDevice.executeShellCommand(START_ACTIVITY_UNDER_TEST_COMMAND);
-
-        // If the app data was restored successfully, the app should not generate new values and
-        // the values reported by the app should match values saved in mSavedValues
-        assertValuesAreRestored();
-    }
-
-    /**
-     * Saves the data values reported by the app in {@code mSavedValues}.
-     */
-    private void saveDataValuesReportedByApp()
-            throws InterruptedException, DeviceNotAvailableException {
-        mSavedValues = readDataValuesFromLogcat();
-        assertEquals(NUMBER_OF_VALUES, mSavedValues.size());
-    }
-
-    /**
-     * Checks that at least some values in {@code mSavedValues} are different from corresponding
-     * default values.
-     */
-    private void assertNotAllValuesAreDefault() {
-        boolean allValuesAreDefault = mSavedValues.get(INT_PREF).equals(DEFAULT_INT_STRING)
-                && mSavedValues.get(BOOL_PREF).equals(DEFAULT_BOOL_STRING)
-                && mSavedValues.get(FLOAT_PREF).equals(DEFAULT_FLOAT_STRING)
-                && mSavedValues.get(LONG_PREF).equals(DEFAULT_LONG_STRING)
-                && mSavedValues.get(STRING_PREF).equals(DEFAULT_STRING_STRING)
-                && mSavedValues.get(TEST_FILE_1).equals(DEFAULT_FILE_STRING)
-                && mSavedValues.get(TEST_FILE_2).equals(DEFAULT_FILE_STRING);
-
-        assertFalse("The values were not changed from default.", allValuesAreDefault);
-    }
-
-    /**
-     * Parsing logcat after "bmgr run" command and checking that the backup pass is finished before
-     * we move on to avoid a race condition.
-     *
-     * Expected format: "BackupManagerService: Backup pass finished"
-     */
-    private void assertBackupFinished() throws DeviceNotAvailableException {
-        boolean backupFinished = false;
-        long timeout = System.currentTimeMillis() + TimeUnit.SECONDS.toMillis(10 * 60); // 10 min
-        while (timeout >= System.currentTimeMillis() && !backupFinished) {
-            String logs = getLogcatForClass("BackupManagerService");
-
-            Scanner in = new Scanner(logs);
-            while (in.hasNextLine()) {
-                String line = in.nextLine();
-                if (line.contains("Backup pass finished")) {
-                    backupFinished = true;
-                    break;
-                }
-            }
-            in.close();
-        }
-
-        assertTrue("The backup pass never finished.", backupFinished);
-    }
-
-    /**
-     * Reads the values logged by the app and verifies that they are the same as the ones we saved
-     * in {@code mSavedValues}.
-     */
-    private void assertValuesAreRestored()
-            throws InterruptedException, DeviceNotAvailableException {
-        Map<String, String> restoredValues = readDataValuesFromLogcat();
-
-        // Iterating through mSavedValues (vs. restoredValues) keyset to make sure all of the
-        // keys are reported in restored data
-        for (String dataType : mSavedValues.keySet()) {
-            assertEquals(mSavedValues.get(dataType), restoredValues.get(dataType));
-        }
-    }
-
-    /**
-     * Reads the values that app has reported via logcat and saves them in a map.
-     *
-     * The app logs the values once they are read from shared preferences or a file.
-     * If the values are default ones (i.e., it's the first run of the application), the app then
-     * generates random values and saves them in shared preferences or a file.
-     * Finally, the app reads the values from shared preferences or a file again and logs them.
-     * We are only interested in the final (generated or restored) values.
-     * The format of the log messages is "INT_PREF:17".
-     *
-     * @return Map of the values found in logcat.
-     */
-    private Map<String, String> readDataValuesFromLogcat()
-            throws InterruptedException, DeviceNotAvailableException {
-        Map<String, String> result = new HashMap<>();
-
-        long timeout = System.currentTimeMillis() + TimeUnit.SECONDS.toMillis(30);
-
-        // The app generates reads, generates and reads values in async tasks fired onCreate.
-        // It may take some time for all tasks to finish and for logs to appear, so we check logcat
-        // repeatedly until we read VALUES_LOADED_MESSAGE, which is the last message the app logs.
-        search:
-        while (timeout >= System.currentTimeMillis()) {
-            String logs = getLogcatForClass(CLASS_UNDER_TEST);
-
-            Scanner in = new Scanner(logs);
-            while (in.hasNextLine()) {
-                String line = in.nextLine();
-                // Filter by TAG.
-                if (line.startsWith("I/" + CLASS_UNDER_TEST)) {
-                    // Get rid of the TAG.
-                    String message = line.split(":", 2)[1].trim();
-
-                    // VALUES_LOADED_MESSAGE is logged by the app when all the values are loaded and
-                    // logged so we can stop expecting more lines at this point.
-                    if (message.equals(VALUES_LOADED_MESSAGE)) {
-                        break search;
-                    }
-
-                    // Values are logged by the app in the format "INT_PREF:17".
-                    String[] values = message.split(":");
-                    if (values.length == 2) {
-                        result.put(values[0], values[1]);
-                    }
-                }
-            }
-            in.close();
-
-            // In case the key has not been found, wait for the log to update before
-            // performing the next search.
-            Thread.sleep(SMALL_LOGCAT_DELAY_MS);
-        }
-        assertTrue("Timeout while reading the app values", timeout > System.currentTimeMillis());
-        return result;
-    }
-
-    /**
-     * Returns the logcat string with the tag {@param className} and clears everything else.
-     */
-    private String getLogcatForClass(String className) throws DeviceNotAvailableException {
-        return mDevice.executeAdbCommand("logcat", "-v", "brief", "-d",
-                className + ":I", "*:S");
-    }
-
-    // Copied over from BackupQuotaTest
-    private boolean enableBackup(boolean enable) throws Exception {
-        boolean previouslyEnabled;
-        String output = mDevice.executeShellCommand("bmgr enabled");
-        Pattern pattern = Pattern.compile("^Backup Manager currently (enabled|disabled)$");
-        Matcher matcher = pattern.matcher(output.trim());
-        if (matcher.find()) {
-            previouslyEnabled = "enabled".equals(matcher.group(1));
-        } else {
-            throw new RuntimeException("non-parsable output setting bmgr enabled: " + output);
-        }
-
-        mDevice.executeShellCommand("bmgr enable " + enable);
-        return previouslyEnabled;
-    }
-
-    // Copied over from BackupQuotaTest
-    private String setBackupTransport(String transport) throws Exception {
-        String output = mDevice.executeShellCommand("bmgr transport " + transport);
-        Pattern pattern = Pattern.compile("\\(formerly (.*)\\)$");
-        Matcher matcher = pattern.matcher(output);
-        if (matcher.find()) {
-            return matcher.group(1);
-        } else {
-            throw new RuntimeException("non-parsable output setting bmgr transport: " + output);
-        }
-    }
-
-    // Copied over from BackupQuotaTest
-    private boolean hasBackupTransport(String transport) throws Exception {
-	CLog.i("In method hasBackupTransport");
-        String output = mDevice.executeShellCommand("bmgr list transports");
-        for (String t : output.split(" ")) {
-            if (transport.equals(t.trim())) {
-                return true;
-            }
-        }
-        return false;
-    }
-
-    private boolean hasDeviceFeature(String requiredFeature) throws DeviceNotAvailableException {
-        if (mAvailableFeatures == null) {
-            String command = "pm list features";
-            String commandOutput = getDevice().executeShellCommand(command);
-	    CLog.i("Output for command " + command + ": " + commandOutput);
-
-            // Extract the id of the new user.
-            mAvailableFeatures = new HashSet<>();
-            for (String feature: commandOutput.split("\\s+")) {
-                // Each line in the output of the command has the format "feature:{FEATURE_VALUE}".
-                String[] tokens = feature.split(":");
-                assertTrue("\"" + feature + "\" expected to have format feature:{FEATURE_VALUE}",
-                        tokens.length > 1);
-                assertEquals(feature, "feature", tokens[0]);
-                mAvailableFeatures.add(tokens[1]);
-            }
-        }
-        boolean result = mAvailableFeatures.contains(requiredFeature);
-        if (!result) {
-		CLog.d("Device doesn't have required feature "+ requiredFeature + ". Test won't run.");
-        }
-        return result;
-    }
-}
diff --git a/tests/tests/app/src/android/app/cts/SystemFeaturesTest.java b/tests/tests/app/src/android/app/cts/SystemFeaturesTest.java
index bf61ead..b245db5 100644
--- a/tests/tests/app/src/android/app/cts/SystemFeaturesTest.java
+++ b/tests/tests/app/src/android/app/cts/SystemFeaturesTest.java
@@ -456,11 +456,12 @@
     }
 
     public void testUsbAccessory() {
-        // USB accessory mode is only a requirement for devices with USB ports supporting
-        // peripheral mode. As there is no public API to distinguish a device with only host
-        // mode support from having both peripheral and host support, the test may have
-        // false negatives.
-        assertAvailable(PackageManager.FEATURE_USB_ACCESSORY);
+        // Per CDD requirement all handheld Android devices must support AOA
+        if (!mPackageManager.hasSystemFeature(PackageManager.FEATURE_AUTOMOTIVE)
+               && !mPackageManager.hasSystemFeature(PackageManager.FEATURE_WATCH)
+               && !mPackageManager.hasSystemFeature(PackageManager.FEATURE_LEANBACK)) {
+            assertAvailable(PackageManager.FEATURE_USB_ACCESSORY);
+        }
     }
 
     public void testWifiFeature() throws Exception {