DO NOT MERGE: Add CTS for ExifInterfaceTest am: c9578025e6 am: c49c00b90f am: 463df16c1d  -s ours am: 491023f144  -s ours am: cde495acb1 am: b48f7aa608 am: ae37bfa343  -s ours am: 724cb658fc am: 58776e4411 am: f8b7f9a52e
am: 2f1ec44dec  -s ours

Change-Id: I76389088bcf04dadf919918e6959ec35851221a9
diff --git a/Android.mk b/Android.mk
index 4251262..95ef508 100644
--- a/Android.mk
+++ b/Android.mk
@@ -14,6 +14,16 @@
 # limitations under the License.
 #
 
-include cts/CtsBuild.mk
+include cts/OldCtsBuild.mk
 include cts/CtsCoverage.mk
 include $(call all-subdir-makefiles)
+
+
+# Have the default build also build the tools for CTS so it is possible
+# to build individual tests with mmm without doing extra targets first.
+files: \
+    $(CTS_JAVA_TEST_SCANNER_DOCLET) \
+    $(CTS_JAVA_TEST_SCANNER) \
+    $(CTS_NATIVE_TEST_SCANNER) \
+    $(CTS_XML_GENERATOR)
+
diff --git a/CtsBuild.mk b/CtsBuild.mk
deleted file mode 100644
index ba158ce..0000000
--- a/CtsBuild.mk
+++ /dev/null
@@ -1,49 +0,0 @@
-# Copyright (C) 2011 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)
-
-# Functions to get the paths of the build outputs.
-
-define cts-get-lib-paths
-	$(foreach lib,$(1),$(CTS_TESTCASES_OUT)/$(lib).jar)
-endef
-
-define cts-get-ui-lib-paths
-	$(foreach lib,$(1),$(CTS_TESTCASES_OUT)/$(lib).jar)
-endef
-
-define cts-get-native-paths
-	$(foreach exe,$(1),$(CTS_TESTCASES_OUT)/$(exe)$(2))
-endef
-
-define cts-get-package-paths
-	$(foreach pkg,$(1),$(CTS_TESTCASES_OUT)/$(pkg).apk)
-endef
-
-define cts-get-test-xmls
-	$(foreach name,$(1),$(CTS_TESTCASES_OUT)/$(name).xml)
-endef
-
-define cts-get-executable-paths
-	$(foreach executable,$(1),$(CTS_TESTCASES_OUT)/$(executable))
-endef
-
-define cts-get-deqp-api-test-xmls
-	$(foreach file,$(call find-files-in-subdirs, external/deqp/android/cts/master, 'com.drawelements.deqp.$(1).*xml', .),$(CTS_TESTCASES_OUT)/$(file))
-endef
-
-define cts-get-deqp-test-xmls
-	$(foreach api,$(1),$(call cts-get-deqp-api-test-xmls,$(api)))
-endef
diff --git a/CtsCoverage.mk b/CtsCoverage.mk
index 1fb98dc..8cc8a96 100644
--- a/CtsCoverage.mk
+++ b/CtsCoverage.mk
@@ -36,7 +36,7 @@
 
 cts_api_coverage_dependencies := $(cts_api_coverage_exe) $(dexdeps_exe) $(api_xml_description)
 
-android_cts_zip := $(HOST_OUT)/cts/android-cts.zip
+android_cts_zip := $(HOST_OUT)/old-cts/old-android-cts.zip
 cts_verifier_apk := $(call intermediates-dir-for,APPS,CtsVerifier)/package.apk
 
 $(cts-test-coverage-report): PRIVATE_TEST_CASES := $(CTS_TESTCASES_OUT)
diff --git a/CtsTestCaseList.mk b/CtsTestCaseList.mk
deleted file mode 100644
index 00ba034..0000000
--- a/CtsTestCaseList.mk
+++ /dev/null
@@ -1,302 +0,0 @@
-# Copyright (C) 2010 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.
-
-cts_security_apps_list := \
-    CtsAppAccessData \
-    CtsAppWithData \
-    CtsDocumentProvider \
-    CtsDocumentClient \
-    CtsExternalStorageApp \
-    CtsInstrumentationAppDiffCert \
-    CtsNetSecPolicyUsesCleartextTrafficFalse \
-    CtsNetSecPolicyUsesCleartextTrafficTrue \
-    CtsNetSecPolicyUsesCleartextTrafficUnspecified \
-    CtsUsePermissionApp \
-    CtsUsePermissionAppCompat \
-    CtsPermissionDeclareApp \
-    CtsPermissionDeclareAppCompat \
-    CtsReadExternalStorageApp \
-    CtsSharedUidInstall \
-    CtsSharedUidInstallDiffCert \
-    CtsSimpleAppInstall \
-    CtsSimpleAppInstallDiffCert \
-    CtsSplitApp \
-    CtsSplitApp_x86 \
-    CtsSplitApp_x86_64 \
-    CtsSplitApp_armeabi-v7a \
-    CtsSplitApp_armeabi \
-    CtsSplitApp_arm64-v8a \
-    CtsSplitApp_mips64 \
-    CtsSplitApp_mips \
-    CtsSplitAppDiffRevision \
-    CtsSplitAppDiffVersion \
-    CtsSplitAppDiffCert \
-    CtsSplitAppFeature \
-    CtsTargetInstrumentationApp \
-    CtsUsePermissionDiffCert \
-    CtsWriteExternalStorageApp \
-    CtsMultiUserStorageApp
-
-cts_security_keysets_list := \
-    CtsKeySetTestApp \
-    CtsKeySetPermDefSigningA \
-    CtsKeySetPermDefSigningB\
-    CtsKeySetPermUseSigningA \
-    CtsKeySetPermUseSigningB \
-    CtsKeySetSigningAUpgradeA \
-    CtsKeySetSigningBUpgradeA \
-    CtsKeySetSigningAUpgradeAAndB \
-    CtsKeySetSigningAUpgradeAOrB \
-    CtsKeySetSigningAUpgradeB \
-    CtsKeySetSigningBUpgradeB \
-    CtsKeySetSigningAAndBUpgradeA \
-    CtsKeySetSigningAAndCUpgradeB \
-    CtsKeySetSigningAUpgradeNone \
-    CtsKeySetSharedUserSigningAUpgradeB \
-    CtsKeySetSharedUserSigningBUpgradeB \
-    CtsKeySetSigningABadUpgradeB \
-    CtsKeySetSigningCBadAUpgradeAB \
-    CtsKeySetSigningANoDefUpgradeB \
-    CtsKeySetSigningAUpgradeEcA \
-    CtsKeySetSigningEcAUpgradeA
-
-cts_account_support_packages := \
-    CtsUnaffiliatedAccountAuthenticators
-
-cts_support_packages := \
-    CtsAccelerationTestStubs \
-    CtsAlarmClockService \
-    CtsAppTestStubs \
-    CtsAssistService \
-    CtsAssistApp \
-    CtsAtraceTestApp \
-    CtsCertInstallerApp \
-    CtsCppToolsApp \
-    CtsDeviceAdmin \
-    CtsDeviceOpenGl \
-    CtsWifiConfigCreator \
-    CtsDeviceAndProfileOwnerApp \
-    CtsDeviceAppUsageTestApp \
-    CtsDeviceInfo \
-    CtsDeviceOsTestApp \
-    CtsDeviceOwnerApp \
-    CtsDeviceTaskswitchingAppA \
-    CtsDeviceTaskswitchingAppB \
-    CtsDeviceTaskswitchingControl \
-    CtsDeviceUi \
-    CtsHostsideNetworkTestsApp \
-    CtsIntentReceiverApp \
-    CtsIntentSenderApp \
-    CtsLauncherAppsTests \
-    CtsLauncherAppsTestsSupport \
-    CtsLeanbackJank \
-    CtsManagedProfileApp \
-    CtsMonkeyApp \
-    CtsMonkeyApp2 \
-    CtsPackageInstallerApp \
-    CtsPermissionApp \
-    CtsSimpleApp \
-    CtsSimplePreMApp \
-    CtsSomeAccessibilityServices \
-    CtsThemeDeviceApp \
-    TestDeviceSetup \
-    CtsUiAutomatorApp \
-    CtsUsbSerialTestApp \
-    CtsVoiceInteractionService \
-    CtsVoiceInteractionApp \
-    CtsVoiceSettingsService \
-    CtsWidgetProviderApp \
-    CtsTrustedVoiceApp \
-    $(cts_account_support_packages) \
-    $(cts_security_apps_list) \
-    $(cts_security_keysets_list)
-
-cts_external_packages := \
-    com.replica.replicaisland \
-    com.drawelements.deqp
-
-# Any APKs that need to be copied to the CTS distribution's testcases
-# directory but do not require an associated test package XML.
-CTS_TEST_CASE_LIST := \
-    $(cts_support_packages) \
-    $(cts_external_packages)
-
-# Test packages that require an associated test package XML.
-cts_test_packages := \
-    CtsDeviceFilePerf \
-    CtsDeviceUi \
-    CtsDeviceDram \
-    CtsDeviceSimpleCpu \
-    CtsDeviceVideoPerf \
-    CtsDeviceOpenGl \
-    CtsDeviceTvProviderPerf \
-    CtsAccelerationTestCases \
-    CtsAccountManagerTestCases \
-    CtsAccessibilityServiceTestCases \
-    CtsAccessibilityTestCases \
-    CtsAdminTestCases \
-    CtsAlarmClockTestCases \
-    CtsAnimationTestCases \
-    CtsAppTestCases \
-    CtsAppWidgetTestCases \
-    CtsAssistTestCases \
-    CtsBluetoothTestCases \
-    CtsCalendarcommon2TestCases \
-    CtsCallLogTestCases \
-    CtsCameraTestCases \
-    CtsContentTestCases \
-    CtsDatabaseTestCases \
-    CtsDisplayTestCases \
-    CtsDpiTestCases \
-    CtsDpiTestCases2 \
-    CtsDreamsTestCases \
-    CtsDrmTestCases \
-    CtsEffectTestCases \
-    CtsGestureTestCases \
-    CtsGraphicsTestCases \
-    CtsGraphics2TestCases \
-    CtsHardwareTestCases \
-    CtsJankTestCases \
-    CtsLeanbackJankTestCases \
-    CtsJobSchedulerDeviceTestCases \
-    CtsJniTestCases \
-    CtsKeystoreTestCases \
-    CtsLibcoreLegacy22TestCases \
-    CtsLocationTestCases \
-    CtsLocation2TestCases \
-    CtsMediaStressTestCases \
-    CtsMediaTestCases \
-    CtsMidiTestCases \
-    CtsNativeOpenGLTestCases \
-    CtsNdefTestCases \
-    CtsNetSecPolicyUsesCleartextTrafficFalseTestCases \
-    CtsNetSecPolicyUsesCleartextTrafficTrueTestCases \
-    CtsNetSecPolicyUsesCleartextTrafficUnspecifiedTestCases \
-    CtsNetTestCases \
-    CtsNetTestCasesLegacyApi22 \
-    CtsNetTestCasesLegacyPermission22 \
-    CtsOpenGLTestCases \
-    CtsOpenGlPerfTestCases \
-    CtsOsTestCases \
-    CtsPermissionTestCases \
-    CtsPermission2TestCases \
-    CtsPreferenceTestCases \
-    CtsPreference2TestCases \
-    CtsPrintTestCases \
-    CtsProviderTestCases \
-    CtsRenderscriptTestCases \
-    CtsRenderscriptLegacyTestCases \
-    CtsRsCppTestCases \
-    CtsSaxTestCases \
-    CtsSecurityTestCases \
-    CtsSignatureTestCases \
-    CtsSpeechTestCases \
-    CtsSystemUiTestCases \
-    CtsTelecomTestCases \
-    CtsTelecomTestCases2 \
-    CtsTelephonyTestCases \
-    CtsTextTestCases \
-    CtsTextureViewTestCases \
-    CtsThemeTestCases \
-    CtsTransitionTestCases \
-    CtsTvTestCases \
-    CtsUiAutomationTestCases \
-    CtsUiRenderingTestCases \
-    CtsUsageStatsTestCases \
-    CtsUtilTestCases \
-    CtsViewTestCases \
-    CtsVoiceInteractionTestCases \
-    CtsVoiceSettingsTestCases \
-    CtsWebkitTestCases \
-    CtsWidgetTestCases
-
-# All APKs that need to be scanned by the coverage utilities.
-CTS_COVERAGE_TEST_CASE_LIST := \
-    $(cts_support_packages) \
-    $(cts_test_packages)
-
-# Host side only tests
-cts_host_libraries := \
-    CtsAdbTests \
-    CtsAppSecurityTests \
-    CtsAtraceHostTestCases \
-    CtsCppToolsTestCases \
-    CtsDevicePolicyManagerTestCases \
-    CtsDumpsysHostTestCases \
-    CtsHostJank \
-    CtsHostsideNetworkTests \
-    CtsHostUi \
-    CtsJdwpSecurityHostTestCases \
-    CtsMonkeyTestCases \
-    CtsMultiUserHostTestCases \
-    CtsOsHostTestCases \
-    CtsThemeHostTestCases \
-    CtsUsageHostTestCases \
-    CtsSecurityHostTestCases \
-    CtsTrustedVoiceHostTestCases \
-    CtsUsbTests
-
-# List of native tests. For 32 bit targets, assumes that there will be
-# one test executable, and it will end in 32. For 64 bit targets, assumes
-# that there will be two executables, one that ends in 32 for the 32
-# bit executable and one that ends in 64 for the 64 bit executable.
-cts_native_tests := \
-    NativeMediaTest_SL \
-    NativeMediaTest_XA \
-
-ifeq ($(HOST_OS)-$(HOST_ARCH),$(filter $(HOST_OS)-$(HOST_ARCH),linux-x86 linux-x86_64))
-cts_native_tests += bionic-unit-tests-cts
-endif
-
-cts_ui_tests := \
-    CtsUiAutomatorTests
-
-cts_device_jars := \
-    CtsDeviceJank \
-    CtsJdwpApp
-
-cts_target_junit_tests := \
-    CtsJdwp
-
-cts_deqp_test_apis := \
-    egl \
-    gles2 \
-    gles3 \
-    gles31
-
-# All the files that will end up under the repository/testcases
-# directory of the final CTS distribution.
-CTS_TEST_CASES := $(call cts-get-lib-paths,$(cts_host_libraries)) \
-    $(call cts-get-package-paths,$(cts_test_packages)) \
-    $(call cts-get-ui-lib-paths,$(cts_ui_tests)) \
-    $(call cts-get-ui-lib-paths,$(cts_device_jars)) \
-    $(call cts-get-ui-lib-paths,$(cts_target_junit_tests)) \
-    $(call cts-get-executable-paths,$(cts_device_executables)) \
-    $(call cts-get-native-paths,$(cts_native_tests),32)
-
-ifeq ($(TARGET_IS_64_BIT),true)
-CTS_TEST_CASES += $(call cts-get-native-paths,$(cts_native_tests),64)
-endif
-
-# All the XMLs that will end up under the repository/testcases
-# and that need to be created before making the final CTS distribution.
-CTS_TEST_XMLS := $(call cts-get-test-xmls,$(cts_host_libraries)) \
-    $(call cts-get-test-xmls,$(cts_test_packages)) \
-    $(call cts-get-test-xmls,$(cts_native_tests)) \
-    $(call cts-get-test-xmls,$(cts_target_junit_tests)) \
-    $(call cts-get-test-xmls,$(cts_ui_tests)) \
-    $(call cts-get-deqp-test-xmls,$(cts_deqp_test_apis))
-
-# The following files will be placed in the tools directory of the CTS distribution
-CTS_TOOLS_LIST :=
diff --git a/OldCtsBuild.mk b/OldCtsBuild.mk
new file mode 100644
index 0000000..c745885
--- /dev/null
+++ b/OldCtsBuild.mk
@@ -0,0 +1,45 @@
+# Copyright (C) 2011 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)
+
+# Functions to get the paths of the build outputs.
+
+define cts-get-lib-paths
+	$(foreach lib,$(1),$(CTS_TESTCASES_OUT)/$(lib).jar)
+endef
+
+define cts-get-ui-lib-paths
+	$(foreach lib,$(1),$(CTS_TESTCASES_OUT)/$(lib).jar)
+endef
+
+define cts-get-native-paths
+	$(foreach exe,$(1),$(CTS_TESTCASES_OUT)/$(exe)$(2))
+endef
+
+define cts-get-package-paths
+	$(foreach pkg,$(1),$(CTS_TESTCASES_OUT)/$(pkg).apk)
+endef
+
+define cts-get-test-xmls
+	$(foreach name,$(1),$(CTS_TESTCASES_OUT)/$(name).xml)
+endef
+
+define cts-get-executable-paths
+	$(foreach executable,$(1),$(CTS_TESTCASES_OUT)/$(executable))
+endef
+
+define cts-get-deqp-test-xmls
+	$(foreach api,$(1),$(CTS_TESTCASES_OUT)/com.drawelements.deqp.$(api).xml)
+endef
diff --git a/OldCtsTestCaseList.mk b/OldCtsTestCaseList.mk
new file mode 100644
index 0000000..685d9a0
--- /dev/null
+++ b/OldCtsTestCaseList.mk
@@ -0,0 +1,333 @@
+# Copyright (C) 2010 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.
+
+cts_security_apps_list := \
+    CtsAppAccessData \
+    CtsAppWithData \
+    CtsDocumentProvider \
+    CtsDocumentClient \
+    CtsEncryptionApp \
+    CtsExternalStorageApp \
+    CtsInstrumentationAppDiffCert \
+    CtsNetSecPolicyUsesCleartextTrafficFalse \
+    CtsNetSecPolicyUsesCleartextTrafficTrue \
+    CtsNetSecPolicyUsesCleartextTrafficUnspecified \
+    CtsNoRestartBase \
+    CtsNoRestartFeature \
+    CtsUsePermissionApp22 \
+    CtsUsePermissionApp23 \
+    CtsUsePermissionApp24 \
+    CtsPermissionDeclareApp \
+    CtsPermissionDeclareAppCompat \
+    CtsPrivilegedUpdateTests \
+    CtsReadExternalStorageApp \
+    CtsSharedUidInstall \
+    CtsSharedUidInstallDiffCert \
+    CtsShimPrivUpgradePrebuilt \
+    CtsShimPrivUpgradeWrongSHAPrebuilt \
+    CtsSimpleAppInstall \
+    CtsSimpleAppInstallDiffCert \
+    CtsSplitApp \
+    CtsSplitApp_x86 \
+    CtsSplitApp_x86_64 \
+    CtsSplitApp_armeabi-v7a \
+    CtsSplitApp_armeabi \
+    CtsSplitApp_arm64-v8a \
+    CtsSplitApp_mips64 \
+    CtsSplitApp_mips \
+    CtsSplitAppDiffRevision \
+    CtsSplitAppDiffVersion \
+    CtsSplitAppDiffCert \
+    CtsSplitAppFeature \
+    CtsTargetInstrumentationApp \
+    CtsUsePermissionDiffCert \
+    CtsUsesLibraryApp \
+    CtsWriteExternalStorageApp \
+    CtsMultiUserStorageApp
+
+cts_security_keysets_list := \
+    CtsKeySetTestApp \
+    CtsKeySetPermDefSigningA \
+    CtsKeySetPermDefSigningB\
+    CtsKeySetPermUseSigningA \
+    CtsKeySetPermUseSigningB \
+    CtsKeySetSigningAUpgradeA \
+    CtsKeySetSigningBUpgradeA \
+    CtsKeySetSigningAUpgradeAAndB \
+    CtsKeySetSigningAUpgradeAOrB \
+    CtsKeySetSigningAUpgradeB \
+    CtsKeySetSigningBUpgradeB \
+    CtsKeySetSigningAAndBUpgradeA \
+    CtsKeySetSigningAAndCUpgradeB \
+    CtsKeySetSigningAUpgradeNone \
+    CtsKeySetSharedUserSigningAUpgradeB \
+    CtsKeySetSharedUserSigningBUpgradeB \
+    CtsKeySetSigningABadUpgradeB \
+    CtsKeySetSigningCBadAUpgradeAB \
+    CtsKeySetSigningANoDefUpgradeB \
+    CtsKeySetSigningAUpgradeEcA \
+    CtsKeySetSigningEcAUpgradeA
+
+cts_account_support_packages := \
+    CtsUnaffiliatedAccountAuthenticators
+
+cts_support_packages := \
+    CtsAbiOverrideTestApp \
+    CtsAccountManagementDevicePolicyApp \
+    CtsAdminApp \
+    CtsAlarmClockService \
+    CtsAppRestrictionsManagingApp \
+    CtsAppRestrictionsTargetApp \
+    CtsAppTestStubs \
+    CtsAppUsageTestApp \
+    CtsAssistService \
+    CtsAssistApp \
+    CtsAtraceTestApp \
+    CtsBackupApp \
+    CtsCertInstallerApp \
+    CtsContactDirectoryProvider \
+    CtsCustomizationApp \
+    CtsCppToolsApp \
+    CtsDeviceAdminApp23 \
+    CtsDeviceAdminApp24 \
+    CtsDeviceAndProfileOwnerApp23 \
+    CtsDeviceAndProfileOwnerApp \
+    CtsDeviceInfo \
+    CtsDeviceOsTestApp \
+    CtsDeviceOwnerApp \
+    CtsDeviceServicesTestApp \
+    CtsDeviceTaskSwitchingAppA \
+    CtsDeviceTaskSwitchingAppB \
+    CtsDeviceTaskSwitchingControl \
+    CtsDragAndDropSourceApp \
+    CtsDragAndDropTargetApp \
+    CtsExternalServiceService \
+    CtsHostsideNetworkTestsApp \
+    CtsHostsideNetworkTestsApp2 \
+    CtsIntentReceiverApp \
+    CtsIntentSenderApp \
+    CtsLauncherAppsTests \
+    CtsLauncherAppsTestsSupport \
+    CtsLeanbackJankApp \
+    CtsManagedProfileApp \
+    CtsMonkeyApp \
+    CtsMonkeyApp2 \
+    CtsPackageInstallerApp \
+    CtsPermissionApp \
+    CtsProfileOwnerApp \
+    CtsSimpleApp \
+    CtsSimplePreMApp \
+    CtsSomeAccessibilityServices \
+    CtsSystemUiDeviceApp \
+    CtsThemeDeviceApp \
+    CtsUsbSerialTestApp \
+    CtsVoiceInteractionService \
+    CtsVoiceInteractionApp \
+    CtsVoiceSettingsService \
+    CtsVpnFirewallApp \
+    CtsWidgetProviderApp \
+    CtsWifiConfigCreator \
+    TestDeviceSetup \
+    $(cts_account_support_packages) \
+    $(cts_security_apps_list) \
+    $(cts_security_keysets_list)
+
+cts_external_packages := \
+    com.replica.replicaisland \
+    com.drawelements.deqp
+
+# Any APKs that need to be copied to the CTS distribution's testcases
+# directory but do not require an associated test package XML.
+CTS_TEST_CASE_LIST := \
+    $(cts_support_packages) \
+    $(cts_external_packages)
+
+# Test packages that require an associated test package XML.
+cts_test_packages := \
+    CtsIcuTestCases \
+    CtsAccelerationTestCases \
+    CtsAccountManagerTestCases \
+    CtsAccessibilityServiceTestCases \
+    CtsAccessibilityTestCases \
+    CtsAdminTestCases \
+    CtsAlarmClockTestCases \
+    CtsAnimationTestCases \
+    CtsAppTestCases \
+    CtsAppWidgetTestCases \
+    CtsAssistTestCases \
+    CtsBackupTestCases \
+    CtsBluetoothTestCases \
+    CtsCalendarcommon2TestCases \
+    CtsCallLogTestCases \
+    CtsCameraTestCases \
+    CtsCarTestCases \
+    CtsContentTestCases \
+    CtsDatabaseTestCases \
+    CtsDisplayTestCases \
+    CtsDpiTestCases \
+    CtsDpiTestCases2 \
+    CtsDramTestCases \
+    CtsDreamsTestCases \
+    CtsDrmTestCases \
+    CtsEffectTestCases \
+    CtsExternalServiceTestCases \
+    CtsFileSystemTestCases \
+    CtsGestureTestCases \
+    CtsGraphicsTestCases \
+    CtsGraphics2TestCases \
+    CtsHardwareTestCases \
+    CtsJankDeviceTestCases \
+    CtsLeanbackJankTestCases \
+    CtsJobSchedulerTestCases \
+    CtsJniTestCases \
+    CtsKeystoreTestCases \
+    CtsLibcoreLegacy22TestCases \
+    CtsLocationTestCases \
+    CtsLocation2TestCases \
+    CtsMediaStressTestCases \
+    CtsMediaTestCases \
+    CtsMidiTestCases \
+    CtsMultiUserTestCases \
+    CtsNdefTestCases \
+    CtsNetSecPolicyUsesCleartextTrafficFalseTestCases \
+    CtsNetSecPolicyUsesCleartextTrafficTrueTestCases \
+    CtsNetSecPolicyUsesCleartextTrafficUnspecifiedTestCases \
+    CtsNetTestCases \
+    CtsNetTestCasesLegacyApi22 \
+    CtsNetTestCasesLegacyPermission22 \
+    CtsNetSecConfigAttributeTestCases \
+    CtsNetSecConfigCleartextTrafficTestCases \
+    CtsNetSecConfigBasicDebugDisabledTestCases \
+    CtsNetSecConfigBasicDebugEnabledTestCases \
+    CtsNetSecConfigBasicDomainConfigTestCases \
+    CtsNetSecConfigInvalidPinTestCases \
+    CtsNetSecConfigNestedDomainConfigTestCases \
+    CtsNetSecConfigResourcesSrcTestCases \
+    CtsOpenGLTestCases \
+    CtsOpenGlPerfTestCases \
+    CtsOpenGlPerf2TestCases \
+    CtsOsTestCases \
+    CtsPermissionTestCases \
+    CtsPermission2TestCases \
+    CtsPreferenceTestCases \
+    CtsPreference2TestCases \
+    CtsPrintTestCases \
+    CtsProviderTestCases \
+    CtsRenderscriptTestCases \
+    CtsRenderscriptLegacyTestCases \
+    CtsRsBlasTestCases \
+    CtsRsCppTestCases \
+    CtsSaxTestCases \
+    CtsSecurityTestCases \
+    CtsSignatureTestCases \
+    CtsSimpleCpuTestCases \
+    CtsSpeechTestCases \
+    CtsSystemUiTestCases \
+    CtsTelecomTestCases \
+    CtsTelecomTestCases2 \
+    CtsTelephonyTestCases \
+    CtsTextTestCases \
+    CtsTextureViewTestCases \
+    CtsThemeDeviceTestCases \
+    CtsTransitionTestCases \
+    CtsTvProviderTestCases \
+    CtsTvTestCases \
+    CtsUiAutomationTestCases \
+    CtsUiRenderingTestCases \
+    CtsUiDeviceTestCases \
+    CtsUsageStatsTestCases \
+    CtsUtilTestCases \
+    CtsVideoTestCases \
+    CtsViewTestCases \
+    CtsVoiceInteractionTestCases \
+    CtsVoiceSettingsTestCases \
+    CtsWebkitTestCases \
+    CtsWidgetTestCases
+
+# All APKs that need to be scanned by the coverage utilities.
+CTS_COVERAGE_TEST_CASE_LIST := \
+    $(cts_support_packages) \
+    $(cts_test_packages)
+
+# Host side only tests
+cts_host_libraries := \
+    CtsAadbHostTestCases \
+    CtsAbiOverrideHostTestCases \
+    CtsAppSecurityHostTestCases \
+    CtsAppUsageHostTestCases \
+    CtsAtraceHostTestCases \
+    CtsCppToolsTestCases \
+    CtsDevicePolicyManagerTestCases \
+    CtsDragAndDropHostTestCases \
+    CtsDumpsysHostTestCases \
+    CtsHostsideNetworkTests \
+    CtsJdwpSecurityHostTestCases \
+    CtsMonkeyTestCases \
+    CtsOsHostTestCases \
+    CtsSecurityHostTestCases \
+    CtsServicesHostTestCases \
+    CtsThemeHostTestCases \
+    CtsUiHostTestCases \
+    CtsUsbTests \
+    CtsSystemUiHostTestCases
+
+# List of native tests. For 32 bit targets, assumes that there will be
+# one test executable, and it will end in 32. For 64 bit targets, assumes
+# that there will be two executables, one that ends in 32 for the 32
+# bit executable and one that ends in 64 for the 64 bit executable.
+cts_native_tests := \
+    CtsNativeMediaSlTestCases \
+    CtsNativeMediaXaTestCases \
+
+ifeq ($(HOST_OS)-$(HOST_ARCH),$(filter $(HOST_OS)-$(HOST_ARCH),linux-x86 linux-x86_64))
+cts_native_tests += CtsBionicTestCases
+cts_native_tests += CtsSimpleperfTestCases
+endif
+
+cts_device_jars := \
+    CtsJdwpApp
+
+cts_target_junit_tests := \
+    CtsJdwp \
+    CtsLibcoreOj
+
+cts_deqp_test_apis := \
+    egl \
+    gles2 \
+    gles3 \
+    gles31
+
+# All the files that will end up under the repository/testcases
+# directory of the final CTS distribution.
+CTS_TEST_CASES := $(call cts-get-lib-paths,$(cts_host_libraries)) \
+    $(call cts-get-package-paths,$(cts_test_packages)) \
+    $(call cts-get-ui-lib-paths,$(cts_device_jars)) \
+    $(call cts-get-ui-lib-paths,$(cts_target_junit_tests)) \
+    $(call cts-get-executable-paths,$(cts_device_executables)) \
+    $(call cts-get-native-paths,$(cts_native_tests),32)
+
+ifeq ($(TARGET_IS_64_BIT),true)
+CTS_TEST_CASES += $(call cts-get-native-paths,$(cts_native_tests),64)
+endif
+
+# All the XMLs that will end up under the repository/testcases
+# and that need to be created before making the final CTS distribution.
+CTS_TEST_XMLS := $(call cts-get-test-xmls,$(cts_host_libraries)) \
+    $(call cts-get-test-xmls,$(cts_test_packages)) \
+    $(call cts-get-test-xmls,$(cts_native_tests)) \
+    $(call cts-get-test-xmls,$(cts_target_junit_tests)) \
+    $(call cts-get-deqp-test-xmls,$(cts_deqp_test_apis))
+
+# The following files will be placed in the tools directory of the CTS distribution
+CTS_TOOLS_LIST :=
diff --git a/apps/CameraITS/CameraITS.pdf b/apps/CameraITS/CameraITS.pdf
index 8953af9..80b5e10 100644
--- a/apps/CameraITS/CameraITS.pdf
+++ b/apps/CameraITS/CameraITS.pdf
Binary files differ
diff --git a/apps/CameraITS/build/envsetup.sh b/apps/CameraITS/build/envsetup.sh
index 6069341..bcf294a 100644
--- a/apps/CameraITS/build/envsetup.sh
+++ b/apps/CameraITS/build/envsetup.sh
@@ -17,6 +17,8 @@
 # and that the unit tests for the modules passed (indicating that the setup
 # is correct).
 
+CAMERA_ITS_TOP=$PWD
+
 [[ "${BASH_SOURCE[0]}" != "${0}" ]] || \
     { echo ">> Script must be sourced with 'source $0'" >&2; exit 1; }
 
@@ -43,3 +45,6 @@
         echo ">> Unit test for $M failed" >&2
 done
 
+alias gpylint='gpylint --disable=F0401 --disable=C6304 --rcfile=$CAMERA_ITS_TOP"/build/scripts/gpylint_rcfile"'
+# F0401 ignores import errors since gpylint does not have the python paths
+# C6304 ignore Copyright line errors.
diff --git a/apps/CameraITS/build/scripts/gpylint_rcfile b/apps/CameraITS/build/scripts/gpylint_rcfile
new file mode 100644
index 0000000..43d3dbc
--- /dev/null
+++ b/apps/CameraITS/build/scripts/gpylint_rcfile
@@ -0,0 +1,388 @@
+[MESSAGES CONTROL]
+
+# Only show warnings with the listed confidence levels. Leave empty to show
+# all.
+confidence=
+
+# Disable the message, report, category or checker with the given id(s). You
+# can either give multiple identifiers separated by comma (,) or put this
+# option multiple times (only on the command line, not in the configuration
+# file where it should appear only once).You can also use "--disable=all" to
+# disable everything first and then reenable specific checks. For example, if
+# you want to run only the similarities checker, you can use "--disable=all
+# --enable=similarities". If you want to run only the classes checker, but have
+# no Warning level messages displayed, use"--disable=all --enable=classes
+# --disable=W"
+disable=design,similarities,no-self-use,attribute-defined-outside-init,locally-disabled,star-args,pointless-except,bad-option-value,global-statement,fixme,suppressed-message,useless-suppression
+
+# Enable the message, report, category or checker with the given id(s). You can
+# either give multiple identifier separated by comma (,) or put this option
+# multiple time. See also the "--disable" option for examples.
+#enable=
+
+
+[MODES]
+
+# DEPRECATED.
+disable-docstring=no
+
+# DEPRECATED, use --mode=base
+google=no
+
+# The configuration modes to activate (default: base).
+mode=base
+
+# The mode to use when import path setup fails (default: style).
+safe-mode=base
+
+# DEPRECATED, use --mode=style
+single-file=no
+
+# DEPRECATED, use --mode=test
+test=no
+
+# A pattern for file names that should activate test mode.
+test-filename-pattern=_(unit|reg)?test\.py$
+
+# The configuration mode to use for tests (default: test).
+test-mode=test
+
+
+[PATHS]
+
+# Directories to add to sys.path.
+#import-paths=
+
+# Inject some known modules.
+inject-known-modules=no
+
+# The import path resolver
+resolver=blaze
+
+
+[REPORTS]
+
+# Add a comment according to your evaluation note. This is used by the global
+# evaluation report (RP0004).
+comment=no
+
+# Python expression which should return a note less than 10 (10 is the highest
+# note). You have access to the variables errors warning, statement which
+# respectively contain the number of errors / warnings messages and the total
+# number of statements analyzed. This is used by the global evaluation report
+# (RP0004).
+evaluation=10.0 - ((float(5 * error + warning + refactor + convention) / statement) * 10)
+
+# Put messages in a separate file for each module / package specified on the
+# command line instead of printing them on stdout. Reports (if any) will be
+# written in a file name "pylint_global.[txt|html]".
+files-output=no
+
+# String to print as the module footer.
+#module-footer-template=
+
+# Template for the module header. %(filename)s will be replaced with the name
+# of the file under analysis.
+#module-header-template=
+
+# Template used to display messages. This is a python new-style format string
+# used to format the message information. See doc for all details
+#msg-template=
+
+# Set the output format. Available formats are text, parseable, colorized, msvs
+# (visual studio) and html. You can also give a reporter class, eg
+# mypackage.mymodule.MyReporterClass.
+output-format=sorted-text
+
+# Tells whether to display a full report or only the messages
+reports=no
+
+
+[BASIC]
+
+# Regular expression which should only match correct argument names
+argument-rgx=^[a-z][a-z0-9_]*$
+
+# Regular expression which should only match correct instance attribute names
+attr-rgx=^_{0,2}[a-z][a-z0-9_]*$
+
+# List of builtins function names that should not be used, separated by a comma
+bad-functions=input,apply,reduce
+
+# Bad variable names which should always be refused, separated by a comma
+bad-names=
+
+# Regular expression which should only match correct attribute names in class
+# bodies
+class-attribute-rgx=^(_?[A-Z][A-Z0-9_]*|__[a-z0-9_]+__|_?[a-z][a-z0-9_]*)$
+
+# Regular expression which should only match correct class names
+class-rgx=^_?[A-Z][a-zA-Z0-9]*$
+
+# Regular expression which should only match correct module level names
+const-rgx=^(_?[A-Z][A-Z0-9_]*|__[a-z0-9_]+__|_?[a-z][a-z0-9_]*)$
+
+# Minimum line length for functions/classes that require docstrings, shorter
+# ones are exempt.
+docstring-min-length=10
+
+# Regular expression which should only match correct function names
+# function-rgx=^(?:(?P<camel_case>_?[A-Z][a-zA-Z0-9]*)|(?P<snake_case>_?[a-z][a-z0-9_]*))$
+function-rgx=^(?:(?P<snake_case>_?[a-z][a-z0-9_]*))$
+
+# Good variable names which should always be accepted, separated by a comma
+good-names=main,_
+
+# Regular expression which should only match correct list comprehension /
+# generator expression variable names
+inlinevar-rgx=^[a-z][a-z0-9_]*$
+
+# Regular expression which should only match correct method names
+# method-rgx=^(?:(?P<exempt>__[a-z0-9_]+__|next)|(?P<camel_case>_{0,2}[A-Z][a-zA-Z0-9]*)|(?P<snake_case>_{0,2}[a-z][a-z0-9_]*))$
+method-rgx=^(?:(?P<exempt>__[a-z0-9_]+__|next)|(?P<snake_case>_{0,2}[a-z][a-z0-9_]*))$
+
+# Regular expression which should only match correct module names
+module-rgx=^(_?[a-z][a-z0-9_]*)|__init__|PRESUBMIT|PRESUBMIT_unittest$
+
+# Colon delimited types of objects which should have the same naming style,
+# separated by a comma
+name-group=function:method
+
+# Regular expression which should only match function or class names that do
+# not require a docstring.
+no-docstring-rgx=(__.*__|main)
+
+# Required attributes for module, separated by a comma
+required-attributes=
+
+# Regular expression which should only match correct variable names
+variable-rgx=^[a-z][a-z0-9_]*$
+
+
+[CLASSES]
+
+# List of method names used to declare (i.e. assign) instance attributes.
+defining-attr-methods=__init__,__new__,setUp
+
+# List of interface methods to ignore, separated by a comma. This is used for
+# instance to not check methods defines in Zope's Interface base class.
+ignore-iface-methods=isImplementedBy,deferred,extends,names,namesAndDescriptions,queryDescriptionFor,getBases,getDescriptionFor,getDoc,getName,getTaggedValue,getTaggedValueTags,isEqualOrExtendedBy,setTaggedValue,isImplementedByInstancesOf,adaptWith,is_implemented_by
+
+# List of valid names for the first argument in a class method.
+valid-classmethod-first-arg=cls,class_
+
+# List of valid names for the first argument in a metaclass class method.
+valid-metaclass-classmethod-first-arg=mcs
+
+
+[DESIGN]
+
+# Argument names that match this expression will be ignored. Default to name
+# with leading underscore
+ignored-argument-names=_.*
+
+# Maximum number of arguments for function / method
+max-args=5
+
+# Maximum number of attributes for a class (see R0902).
+max-attributes=7
+
+# Maximum number of branch for function / method body
+max-branches=12
+
+# Maximum number of locals for function / method body
+max-locals=15
+
+# Maximum number of parents for a class (see R0901).
+max-parents=7
+
+# Maximum number of public methods for a class (see R0904).
+max-public-methods=20
+
+# Maximum number of return / yield for function / method body
+max-returns=6
+
+# Maximum number of statements in function / method body
+max-statements=50
+
+# Minimum number of public methods for a class (see R0903).
+min-public-methods=2
+
+
+[EXCEPTIONS]
+
+# Exceptions that will emit a warning when being caught. Defaults to
+# "Exception"
+overgeneral-exceptions=StandardError,Exception
+
+
+[FORMAT]
+
+# Regexp for a line that is allowed to be longer than the limit.
+ignore-long-lines=(^\s*(import|from)\s|^__version__\s=\s['"]\$Id:|^\s*(# )?<?https?://\S+>?$)
+
+# String used as indentation unit. This is usually " " (4 spaces) or "\t" (1
+# tab).
+indent-string='    '
+
+# Maximum number of characters on a single line.
+max-line-length=80
+
+# Maximum number of lines in a module
+max-module-lines=99999
+
+# List of optional constructs for which whitespace checking is disabled
+no-space-check=
+
+# Allow the body of an if to be on the same line as the test if there is no
+# else.
+single-line-if-stmt=yes
+
+
+[GOOGLE AST]
+
+# List of module members that should be marked as deprecated.
+deprecated-members=string.atof,string.atoi,string.atol,string.capitalize,string.expandtabs,string.find,string.rfind,string.index,string.rindex,string.count,string.lower,string.split,string.rsplit,string.splitfields,string.join,string.joinfields,string.lstrip,string.rstrip,string.strip,string.swapcase,string.translate,string.upper,string.ljust,string.rjust,string.center,string.zfill,string.replace,sys.exitfunc
+
+# Maximum line length for lambdas.
+short-func-length=1
+
+
+[GOOGLE DOCSTRING]
+
+# List of exceptions that do not need to be mentioned in the Raises section of
+# a docstring.
+ignore-exceptions=NotImplementedError,StopIteration
+
+
+[GOOGLE IMPORTS]
+
+# List of modules that should be ignored if unused.
+ignore-unused-imports=google3
+
+
+[GOOGLE LINES]
+
+# Regexp for a proper copyright notice.
+copyright=Copyright \d{4} Google Inc\. +All Rights Reserved\.
+
+
+[GOOGLE TOKENS]
+
+# A regex for finding comments that do not have a space between leading comment
+# separators and textual content.
+comment-starts-without-space=\A#[^\s\w]*\w
+
+# Regexp for a proper TODO comment; the uid group, if any, should match the
+# user ID of the relevant person
+good-todo=# ?TODO\((?P<uid>[a-z][a-z0-9-]*)|b/(?P<bugid>[0-9]+)\):?
+
+# Number of spaces of indent required when the last token on the preceding line
+# is an open (, [, or {.
+indent-after-paren=4
+
+# Minimum number of spaces between the end of a line and an inline comment.
+min-comment-space=2
+
+# Regexp for a TODO comment, which may be incorrect.
+todo=(?i)#\s*todo
+
+
+[IMPORTS]
+
+# Deprecated modules which should not be used, separated by a comma
+deprecated-modules=regsub,TERMIOS,Bastion,rexec
+
+# Create a graph of external dependencies in the given file (report RP0402 must
+# not be disabled)
+ext-import-graph=
+
+# Create a graph of every (i.e. internal and external) dependencies in the
+# given file (report RP0402 must not be disabled)
+import-graph=
+
+# Create a graph of internal dependencies in the given file (report RP0402 must
+# not be disabled)
+int-import-graph=
+
+
+[LOGGING]
+
+# Logging modules to check that the string format arguments are in logging
+# function parameter format
+logging-modules=logging,google3.pyglib.logging
+
+
+[MASTER]
+
+# Add files or directories to the blacklist. They should be base names, not
+# paths.
+ignore=CVS
+
+# Arbitrary Python code to execute before linting.
+#init-hook=
+
+# List of plugins (as comma separated values of python modules names) to load,
+# usually to register additional checkers.
+load-plugins=
+
+# Pickle collected data for later comparisons.
+persistent=no
+
+# Use a custom configuration file for linting.
+#rcfile=
+
+
+[MISCELLANEOUS]
+
+# List of note tags to take in consideration, separated by a comma.
+notes=
+
+
+[SIMILARITIES]
+
+# Ignore comments when computing similarities.
+ignore-comments=yes
+
+# Ignore docstrings when computing similarities.
+ignore-docstrings=yes
+
+# Ignore imports when computing similarities.
+ignore-imports=no
+
+# Minimum lines number of a similarity.
+min-similarity-lines=4
+
+
+[TYPECHECK]
+
+# List of members which are set dynamically and missed by pylint inference
+# system, and so shouldn't trigger E0201 when accessed. Python regular
+# expressions are accepted.
+generated-members=REQUEST,acl_users,aq_parent
+
+# Tells whether missing members accessed in mixin class should be ignored. A
+# mixin class is detected if its name ends with "mixin" (case insensitive).
+ignore-mixin-members=yes
+
+# List of classes names for which member attributes should not be checked
+# (useful for classes with attributes dynamically set).
+ignored-classes=SQLObject
+
+# When zope mode is activated, add a predefined set of Zope acquired attributes
+# to generated-members.
+zope=no
+
+
+[VARIABLES]
+
+# List of additional names supposed to be defined in builtins. Remember that
+# you should avoid to define new builtins when possible.
+additional-builtins=
+
+# A regular expression matching the beginning of the name of dummy variables
+# (i.e. not used).
+dummy-variables-rgx=^\*{0,2}(_$|unused_|dummy_)
+
+# Tells whether we should check for unused import in __init__ files.
+init-import=no
diff --git a/apps/CameraITS/pymodules/its/caps.py b/apps/CameraITS/pymodules/its/caps.py
index 95f19d9..94b12f5 100644
--- a/apps/CameraITS/pymodules/its/caps.py
+++ b/apps/CameraITS/pymodules/its/caps.py
@@ -36,6 +36,30 @@
         print "Test skipped"
         sys.exit(SKIP_RET_CODE)
 
+def full_or_better(props):
+    """Returns whether a device is a FULL or better camera2 device.
+
+    Args:
+        props: Camera properties object.
+
+    Returns:
+        Boolean.
+    """
+    return props.has_key("android.info.supportedHardwareLevel") and \
+            props["android.info.supportedHardwareLevel"] != 2 and \
+            props["android.info.supportedHardwareLevel"] > 1
+
+def level3(props):
+    """Returns whether a device is a LEVEL3 capability camera2 device.
+
+    Args:
+        props: Camera properties object.
+
+    Returns:
+        Boolean.
+    """
+    return props.has_key("android.info.supportedHardwareLevel") and \
+           props["android.info.supportedHardwareLevel"] == 3
 
 def full(props):
     """Returns whether a device is a FULL capability camera2 device.
@@ -73,6 +97,19 @@
     return props.has_key("android.info.supportedHardwareLevel") and \
            props["android.info.supportedHardwareLevel"] == 2
 
+def radial_distortion_correction(props):
+    """Returns whether a device supports RADIAL_DISTORTION_CORRECTION
+    capabilities.
+
+    Args:
+        props: Camera properties object.
+
+    Returns:
+        Boolean.
+    """
+    return props.has_key("android.lens.radialDistortion") and \
+           props["android.lens.radialDistortion"] is not None
+
 def manual_sensor(props):
     """Returns whether a device supports MANUAL_SENSOR capabilities.
 
@@ -83,8 +120,7 @@
         Boolean.
     """
     return    props.has_key("android.request.availableCapabilities") and \
-              1 in props["android.request.availableCapabilities"] \
-           or full(props)
+              1 in props["android.request.availableCapabilities"]
 
 def manual_post_proc(props):
     """Returns whether a device supports MANUAL_POST_PROCESSING capabilities.
@@ -96,8 +132,7 @@
         Boolean.
     """
     return    props.has_key("android.request.availableCapabilities") and \
-              2 in props["android.request.availableCapabilities"] \
-           or full(props)
+              2 in props["android.request.availableCapabilities"]
 
 def raw(props):
     """Returns whether a device supports RAW capabilities.
@@ -144,6 +179,29 @@
     """
     return len(its.objects.get_available_output_sizes("raw12", props)) > 0
 
+def raw_output(props):
+    """Returns whether a device supports any of RAW output format.
+
+    Args:
+        props: Camera properties object.
+
+    Returns:
+        Boolean.
+    """
+    return raw16(props) or raw10(props) or raw12(props)
+
+def post_raw_sensitivity_boost(props):
+    """Returns whether a device supports post RAW sensitivity boost..
+
+    Args:
+        props: Camera properties object.
+
+    Returns:
+        Boolean.
+    """
+    return props.has_key("android.control.postRawSensitivityBoostRange") and \
+            props["android.control.postRawSensitivityBoostRange"] != [100, 100]
+
 def sensor_fusion(props):
     """Returns whether the camera and motion sensor timestamps for the device
     are in the same time domain and can be compared directly.
diff --git a/apps/CameraITS/pymodules/its/device.py b/apps/CameraITS/pymodules/its/device.py
index eb1ff3f..54bd0ad 100644
--- a/apps/CameraITS/pymodules/its/device.py
+++ b/apps/CameraITS/pymodules/its/device.py
@@ -88,6 +88,10 @@
     CAP_RAW_YUV_JPEG = [{"format":"raw"}, {"format":"yuv"}, {"format":"jpeg"}]
     CAP_DNG_YUV_JPEG = [{"format":"dng"}, {"format":"yuv"}, {"format":"jpeg"}]
 
+    # Predefine camera props. Save props extracted from the function,
+    # "get_camera_properties".
+    props = None
+
     # Initialize the socket port for the host to forward requests to the device.
     # This method assumes localhost's LOCK_PORT is available and will try to
     # use ports between CLIENT_PORT_START and CLIENT_PORT_START+MAX_NUM_PORTS-1
@@ -174,11 +178,16 @@
                 if len(s) > 7 and s[6] == "=":
                     duration = int(s[7:])
                 print "Rebooting device"
-                _run("%s reboot" % (self.adb));
+                _run("%s reboot" % (self.adb))
                 _run("%s wait-for-device" % (self.adb))
                 time.sleep(duration)
                 print "Reboot complete"
 
+        # Flush logcat so following code won't be misled by previous
+        # 'ItsService ready' log.
+        _run('%s logcat -c' % (self.adb))
+        time.sleep(1)
+
         # TODO: Figure out why "--user 0" is needed, and fix the problem.
         _run('%s shell am force-stop --user 0 %s' % (self.adb, self.PACKAGE))
         _run(('%s shell am startservice --user 0 -t text/plain '
@@ -322,9 +331,12 @@
         cmd = {}
         cmd["cmdName"] = "getSensorEvents"
         self.sock.send(json.dumps(cmd) + "\n")
+        timeout = self.SOCK_TIMEOUT + self.EXTRA_SOCK_TIMEOUT
+        self.sock.settimeout(timeout)
         data,_ = self.__read_response_from_socket()
         if data['tag'] != 'sensorEvents':
             raise its.error.Error('Invalid command response')
+        self.sock.settimeout(self.SOCK_TIMEOUT)
         return data['objValue']
 
     def get_camera_ids(self):
@@ -353,6 +365,7 @@
         data,_ = self.__read_response_from_socket()
         if data['tag'] != 'cameraProperties':
             raise its.error.Error('Invalid command response')
+        self.props = data['objValue']['cameraProperties']
         return data['objValue']['cameraProperties']
 
     def do_3a(self, regions_ae=[[0,0,1,1,1]],
@@ -612,15 +625,44 @@
                 cmd["outputSurfaces"] = [out_surfaces]
             else:
                 cmd["outputSurfaces"] = out_surfaces
-            formats = [c["format"] if c.has_key("format") else "yuv"
+            formats = [c["format"] if "format" in c else "yuv"
                        for c in cmd["outputSurfaces"]]
             formats = [s if s != "jpg" else "jpeg" for s in formats]
         else:
+            max_yuv_size = its.objects.get_available_output_sizes(
+                    "yuv", self.props)[0]
             formats = ['yuv']
+            cmd["outputSurfaces"] = [{"format": "yuv",
+                                      "width" : max_yuv_size[0],
+                                      "height": max_yuv_size[1]}]
         ncap = len(cmd["captureRequests"])
         nsurf = 1 if out_surfaces is None else len(cmd["outputSurfaces"])
+        # Only allow yuv output to multiple targets
+        yuv_surfaces = [s for s in cmd["outputSurfaces"] if s["format"]=="yuv"]
+        n_yuv = len(yuv_surfaces)
+        # Compute the buffer size of YUV targets
+        yuv_maxsize_1d = 0
+        for s in yuv_surfaces:
+            if not ("width" in s and "height" in s):
+                if self.props is None:
+                    raise its.error.Error('Camera props are unavailable')
+                yuv_maxsize_2d = its.objects.get_available_output_sizes(
+                    "yuv", self.props)[0]
+                yuv_maxsize_1d = yuv_maxsize_2d[0] * yuv_maxsize_2d[1] * 3 / 2
+                break
+        yuv_sizes = [c["width"]*c["height"]*3/2
+                     if "width" in c and "height" in c
+                     else yuv_maxsize_1d
+                     for c in yuv_surfaces]
+        # Currently we don't pass enough metadta from ItsService to distinguish
+        # different yuv stream of same buffer size
+        if len(yuv_sizes) != len(set(yuv_sizes)):
+            raise its.error.Error(
+                    'ITS does not support yuv outputs of same buffer size')
         if len(formats) > len(set(formats)):
-            raise its.error.Error('Duplicate format requested')
+            if n_yuv != len(formats) - len(set(formats)) + 1:
+                raise its.error.Error('Duplicate format requested')
+
         raw_formats = 0;
         raw_formats += 1 if "dng" in formats else 0
         raw_formats += 1 if "raw" in formats else 0
@@ -653,19 +695,24 @@
         # the burst, however individual images of different formats can come
         # out in any order for that capture.
         nbufs = 0
-        bufs = {"yuv":[], "raw":[], "raw10":[], "raw12":[],
+        bufs = {"raw":[], "raw10":[], "raw12":[],
                 "rawStats":[], "dng":[], "jpeg":[]}
+        yuv_bufs = {size:[] for size in yuv_sizes}
         mds = []
         widths = None
         heights = None
         while nbufs < ncap*nsurf or len(mds) < ncap:
             jsonObj,buf = self.__read_response_from_socket()
-            if jsonObj['tag'] in ['jpegImage', 'yuvImage', 'rawImage', \
+            if jsonObj['tag'] in ['jpegImage', 'rawImage', \
                     'raw10Image', 'raw12Image', 'rawStatsImage', 'dngImage'] \
                     and buf is not None:
                 fmt = jsonObj['tag'][:-5]
                 bufs[fmt].append(buf)
                 nbufs += 1
+            elif jsonObj['tag'] == 'yuvImage':
+                buf_size = numpy.product(buf.shape)
+                yuv_bufs[buf_size].append(buf)
+                nbufs += 1
             elif jsonObj['tag'] == 'captureResults':
                 mds.append(jsonObj['objValue']['captureResult'])
                 outputs = jsonObj['objValue']['outputs']
@@ -679,11 +726,15 @@
             objs = []
             for i in range(ncap):
                 obj = {}
-                obj["data"] = bufs[fmt][i]
                 obj["width"] = widths[j]
                 obj["height"] = heights[j]
                 obj["format"] = fmt
                 obj["metadata"] = mds[i]
+                if fmt == 'yuv':
+                    buf_size = widths[j] * heights[j] * 3 / 2
+                    obj["data"] = yuv_bufs[buf_size][i]
+                else:
+                    obj["data"] = bufs[fmt][i]
                 objs.append(obj)
             rets.append(objs if ncap>1 else objs[0])
         self.sock.settimeout(self.SOCK_TIMEOUT)
diff --git a/apps/CameraITS/tests/scene0/test_metadata.py b/apps/CameraITS/tests/scene0/test_metadata.py
index 44663bb..2914493 100644
--- a/apps/CameraITS/tests/scene0/test_metadata.py
+++ b/apps/CameraITS/tests/scene0/test_metadata.py
@@ -36,7 +36,7 @@
     print "Hardware level"
     print "  Legacy:", its.caps.legacy(props)
     print "  Limited:", its.caps.limited(props)
-    print "  Full:", its.caps.full(props)
+    print "  Full or better:", its.caps.full_or_better(props)
     print "Capabilities"
     print "  Manual sensor:", its.caps.manual_sensor(props)
     print "  Manual post-proc:", its.caps.manual_post_proc(props)
@@ -46,7 +46,7 @@
     # Test: hardware level should be a valid value.
     check('props.has_key("android.info.supportedHardwareLevel")')
     check('props["android.info.supportedHardwareLevel"] is not None')
-    check('props["android.info.supportedHardwareLevel"] in [0,1,2]')
+    check('props["android.info.supportedHardwareLevel"] in [0,1,2,3]')
     full = getval('props["android.info.supportedHardwareLevel"]') == 1
     manual_sensor = its.caps.manual_sensor(props)
 
diff --git a/apps/CameraITS/tests/scene1/test_ev_compensation_advanced.py b/apps/CameraITS/tests/scene1/test_ev_compensation_advanced.py
index 5fd8f73..c14f5a9 100644
--- a/apps/CameraITS/tests/scene1/test_ev_compensation_advanced.py
+++ b/apps/CameraITS/tests/scene1/test_ev_compensation_advanced.py
@@ -22,12 +22,17 @@
 import matplotlib.pyplot
 import numpy
 
+#AE must converge within this number of auto requests for EV
+THREASH_CONVERGE_FOR_EV = 8
+
 def main():
     """Tests that EV compensation is applied.
     """
+    LOCKED = 3
+
     NAME = os.path.basename(__file__).split(".")[0]
 
-    MAX_LUMA_DELTA_THRESH = 0.02
+    MAX_LUMA_DELTA_THRESH = 0.05
 
     with its.device.ItsSession() as cam:
         props = cam.get_camera_properties()
@@ -46,11 +51,13 @@
         imid = len(ev_steps) / 2
         ev_shifts = [pow(2, step * ev_per_step) for step in ev_steps]
         lumas = []
+
+        # Converge 3A, and lock AE once converged. skip AF trigger as
+        # dark/bright scene could make AF convergence fail and this test
+        # doesn't care the image sharpness.
+        cam.do_3a(ev_comp=0, lock_ae=True, do_af=False)
+
         for ev in ev_steps:
-            # Re-converge 3A, and lock AE once converged. skip AF trigger as
-            # dark/bright scene could make AF convergence fail and this test
-            # doesn't care the image sharpness.
-            cam.do_3a(ev_comp=ev, lock_ae=True, do_af=False)
 
             # Capture a single shot with the same EV comp and locked AE.
             req = its.objects.auto_capture_request()
@@ -62,15 +69,20 @@
             req["android.tonemap.curveRed"] = [0.0,0.0, 1.0,1.0]
             req["android.tonemap.curveGreen"] = [0.0,0.0, 1.0,1.0]
             req["android.tonemap.curveBlue"] = [0.0,0.0, 1.0,1.0]
-            cap = cam.do_capture(req)
-            y = its.image.convert_capture_to_planes(cap)[0]
-            tile = its.image.get_image_patch(y, 0.45,0.45,0.1,0.1)
-            lumas.append(its.image.compute_image_means(tile)[0])
+            caps = cam.do_capture([req]*THREASH_CONVERGE_FOR_EV)
+
+            for cap in caps:
+                if (cap['metadata']['android.control.aeState'] == LOCKED):
+                    y = its.image.convert_capture_to_planes(cap)[0]
+                    tile = its.image.get_image_patch(y, 0.45,0.45,0.1,0.1)
+                    lumas.append(its.image.compute_image_means(tile)[0])
+                    break
+            assert(cap['metadata']['android.control.aeState'] == LOCKED)
 
         print "ev_step_size_in_stops", ev_per_step
         shift_mid = ev_shifts[imid]
         luma_normal = lumas[imid] / shift_mid
-        expected_lumas = [luma_normal * ev_shift for ev_shift in ev_shifts]
+        expected_lumas = [min(1.0, luma_normal * ev_shift) for ev_shift in ev_shifts]
 
         pylab.plot(ev_steps, lumas, 'r')
         pylab.plot(ev_steps, expected_lumas, 'b')
diff --git a/apps/CameraITS/tests/scene1/test_ev_compensation_basic.py b/apps/CameraITS/tests/scene1/test_ev_compensation_basic.py
index e3755eb..49ccbcf 100644
--- a/apps/CameraITS/tests/scene1/test_ev_compensation_basic.py
+++ b/apps/CameraITS/tests/scene1/test_ev_compensation_basic.py
@@ -22,9 +22,14 @@
 import matplotlib.pyplot
 import numpy
 
+#AE must converge within this number of auto requests for EV
+THREASH_CONVERGE_FOR_EV = 8
+
 def main():
     """Tests that EV compensation is applied.
     """
+    LOCKED = 3
+
     NAME = os.path.basename(__file__).split(".")[0]
 
     with its.device.ItsSession() as cam:
@@ -37,20 +42,26 @@
         steps_per_ev = int(1.0 / ev_per_step)
         evs = range(-2 * steps_per_ev, 2 * steps_per_ev + 1, steps_per_ev)
         lumas = []
+
+        # Converge 3A, and lock AE once converged. skip AF trigger as
+        # dark/bright scene could make AF convergence fail and this test
+        # doesn't care the image sharpness.
+        cam.do_3a(ev_comp=0, lock_ae=True, do_af=False)
+
         for ev in evs:
-            # Re-converge 3A, and lock AE once converged. skip AF trigger as
-            # dark/bright scene could make AF convergence fail and this test
-            # doesn't care the image sharpness.
-            cam.do_3a(ev_comp=ev, lock_ae=True, do_af=False)
 
             # Capture a single shot with the same EV comp and locked AE.
             req = its.objects.auto_capture_request()
             req['android.control.aeExposureCompensation'] = ev
             req["android.control.aeLock"] = True
-            cap = cam.do_capture(req)
-            y = its.image.convert_capture_to_planes(cap)[0]
-            tile = its.image.get_image_patch(y, 0.45,0.45,0.1,0.1)
-            lumas.append(its.image.compute_image_means(tile)[0])
+            caps = cam.do_capture([req]*THREASH_CONVERGE_FOR_EV)
+            for cap in caps:
+                if (cap['metadata']['android.control.aeState'] == LOCKED):
+                    y = its.image.convert_capture_to_planes(cap)[0]
+                    tile = its.image.get_image_patch(y, 0.45,0.45,0.1,0.1)
+                    lumas.append(its.image.compute_image_means(tile)[0])
+                    break
+            assert(cap['metadata']['android.control.aeState'] == LOCKED)
 
         pylab.plot(evs, lumas, 'r')
         matplotlib.pyplot.savefig("%s_plot_means.png" % (NAME))
diff --git a/apps/CameraITS/tests/scene1/test_latching.py b/apps/CameraITS/tests/scene1/test_latching.py
index 176f01b..a7da421 100644
--- a/apps/CameraITS/tests/scene1/test_latching.py
+++ b/apps/CameraITS/tests/scene1/test_latching.py
@@ -33,8 +33,7 @@
 
     with its.device.ItsSession() as cam:
         props = cam.get_camera_properties()
-        its.caps.skip_unless(its.caps.full(props) and
-                             its.caps.per_frame_control(props))
+        its.caps.skip_unless(its.caps.full_or_better(props))
 
         _,fmt = its.objects.get_fastest_manual_capture_settings(props)
         e, s = its.target.get_target_exposure_combos(cam)["midExposureTime"]
diff --git a/apps/CameraITS/tests/scene1/test_post_raw_sensitivity_boost.py b/apps/CameraITS/tests/scene1/test_post_raw_sensitivity_boost.py
new file mode 100644
index 0000000..61b431c
--- /dev/null
+++ b/apps/CameraITS/tests/scene1/test_post_raw_sensitivity_boost.py
@@ -0,0 +1,160 @@
+# Copyright 2016 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.
+
+import its.device
+import its.caps
+import its.image
+import its.objects
+import its.target
+import os.path
+import pylab
+import matplotlib
+import matplotlib.pyplot
+
+def main():
+    """Capture a set of raw/yuv images with different
+        sensitivity/post Raw sensitivity boost combination
+        and check if the output pixel mean matches request settings
+    """
+    NAME = os.path.basename(__file__).split(".")[0]
+
+    # Each raw image
+    RATIO_THRESHOLD = 0.1
+    # Waive the check if raw pixel value is below this level (signal too small
+    # that small black level error converts to huge error in percentage)
+    RAW_PIXEL_VAL_THRESHOLD = 0.03
+
+    with its.device.ItsSession() as cam:
+        props = cam.get_camera_properties()
+        its.caps.skip_unless(its.caps.raw_output(props) and
+                             its.caps.post_raw_sensitivity_boost(props) and
+                             its.caps.compute_target_exposure(props) and
+                             its.caps.per_frame_control(props))
+
+        w,h = its.objects.get_available_output_sizes(
+                "yuv", props, (1920, 1080))[0]
+
+        if its.caps.raw16(props):
+            raw_format = 'raw'
+        elif its.caps.raw10(props):
+            raw_format = 'raw10'
+        elif its.caps.raw12(props):
+            raw_format = 'raw12'
+        else: # should not reach here
+            raise its.error.Error('Cannot find available RAW output format')
+
+        out_surfaces = [{"format": raw_format},
+                        {"format": "yuv", "width": w, "height": h}]
+
+        sens_min, sens_max = props['android.sensor.info.sensitivityRange']
+        sens_boost_min, sens_boost_max = \
+                props['android.control.postRawSensitivityBoostRange']
+
+
+        e_target, s_target = \
+                its.target.get_target_exposure_combos(cam)["midSensitivity"]
+
+        reqs = []
+        settings = []
+        s_boost = sens_boost_min
+        while s_boost <= sens_boost_max:
+            s_raw = int(round(s_target * 100.0 / s_boost))
+            if s_raw < sens_min or s_raw > sens_max:
+                break
+            req = its.objects.manual_capture_request(s_raw, e_target)
+            req['android.control.postRawSensitivityBoost'] = s_boost
+            reqs.append(req)
+            settings.append((s_raw, s_boost))
+            if s_boost == sens_boost_max:
+                break
+            s_boost *= 2
+            # Always try to test maximum sensitivity boost value
+            if s_boost > sens_boost_max:
+                s_boost = sens_boost_max
+
+        caps = cam.do_capture(reqs, out_surfaces)
+
+        raw_rgb_means = []
+        yuv_rgb_means = []
+        raw_caps, yuv_caps = caps
+        if not isinstance(raw_caps, list):
+            raw_caps = [raw_caps]
+        if not isinstance(yuv_caps, list):
+            yuv_caps = [yuv_caps]
+        for i in xrange(len(reqs)):
+            (s, s_boost) = settings[i]
+            raw_cap = raw_caps[i]
+            yuv_cap = yuv_caps[i]
+            raw_rgb = its.image.convert_capture_to_rgb_image(raw_cap, props=props)
+            yuv_rgb = its.image.convert_capture_to_rgb_image(yuv_cap)
+            raw_tile = its.image.get_image_patch(raw_rgb, 0.45,0.45,0.1,0.1)
+            yuv_tile = its.image.get_image_patch(yuv_rgb, 0.45,0.45,0.1,0.1)
+            raw_rgb_means.append(its.image.compute_image_means(raw_tile))
+            yuv_rgb_means.append(its.image.compute_image_means(yuv_tile))
+            its.image.write_image(raw_tile,
+                    "%s_raw_s=%04d_boost=%04d.jpg" % (NAME,s,s_boost))
+            its.image.write_image(yuv_tile,
+                    "%s_yuv_s=%04d_boost=%04d.jpg" % (NAME,s,s_boost))
+            print "s=%d, s_boost=%d: raw_means %s, yuv_means %s"%(
+                    s,s_boost,raw_rgb_means[-1], yuv_rgb_means[-1])
+
+        xs = range(len(reqs))
+        pylab.plot(xs, [rgb[0] for rgb in raw_rgb_means], 'r')
+        pylab.plot(xs, [rgb[1] for rgb in raw_rgb_means], 'g')
+        pylab.plot(xs, [rgb[2] for rgb in raw_rgb_means], 'b')
+        pylab.ylim([0,1])
+        matplotlib.pyplot.savefig("%s_raw_plot_means.png" % (NAME))
+        pylab.clf()
+        pylab.plot(xs, [rgb[0] for rgb in yuv_rgb_means], 'r')
+        pylab.plot(xs, [rgb[1] for rgb in yuv_rgb_means], 'g')
+        pylab.plot(xs, [rgb[2] for rgb in yuv_rgb_means], 'b')
+        pylab.ylim([0,1])
+        matplotlib.pyplot.savefig("%s_yuv_plot_means.png" % (NAME))
+
+        rgb_str = ["R", "G", "B"]
+        # Test that raw means is about 2x brighter than next step
+        for step in range(1, len(reqs)):
+            (s_prev, s_boost_prev) = settings[step - 1]
+            (s, s_boost) = settings[step]
+            expect_raw_ratio = s_prev / float(s)
+            raw_thres_min = expect_raw_ratio * (1 - RATIO_THRESHOLD)
+            raw_thres_max = expect_raw_ratio * (1 + RATIO_THRESHOLD)
+            for rgb in range(3):
+                ratio = raw_rgb_means[step - 1][rgb] / raw_rgb_means[step][rgb]
+                print ("Step (%d,%d) %s channel: %f, %f, ratio %f," +
+                       " threshold_min %f, threshold_max %f") % (
+                        step-1, step, rgb_str[rgb],
+                        raw_rgb_means[step - 1][rgb],
+                        raw_rgb_means[step][rgb],
+                        ratio, raw_thres_min, raw_thres_max)
+                if (raw_rgb_means[step][rgb] <= RAW_PIXEL_VAL_THRESHOLD):
+                    continue
+                assert(raw_thres_min < ratio < raw_thres_max)
+
+        # Test that each yuv step is about the same bright as their mean
+        yuv_thres_min = 1 - RATIO_THRESHOLD
+        yuv_thres_max = 1 + RATIO_THRESHOLD
+        for rgb in range(3):
+            vals = [val[rgb] for val in yuv_rgb_means]
+            for step in range(len(reqs)):
+                if (raw_rgb_means[step][rgb] <= RAW_PIXEL_VAL_THRESHOLD):
+                    vals = vals[:step]
+            mean = sum(vals) / len(vals)
+            print "%s channel vals %s mean %f"%(rgb_str[rgb], vals, mean)
+            for step in range(len(vals)):
+                ratio = vals[step] / mean
+                assert(yuv_thres_min < ratio < yuv_thres_max)
+
+if __name__ == '__main__':
+    main()
diff --git a/apps/CameraITS/tests/scene4/SampleTarget.pdf b/apps/CameraITS/tests/scene4/SampleTarget.pdf
new file mode 100644
index 0000000..e693b34
--- /dev/null
+++ b/apps/CameraITS/tests/scene4/SampleTarget.pdf
Binary files differ
diff --git a/apps/CameraITS/tests/scene4/test_aspect_ratio_and_crop.py b/apps/CameraITS/tests/scene4/test_aspect_ratio_and_crop.py
new file mode 100644
index 0000000..a5fc819
--- /dev/null
+++ b/apps/CameraITS/tests/scene4/test_aspect_ratio_and_crop.py
@@ -0,0 +1,408 @@
+# Copyright 2015 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.
+
+import its.image
+import its.caps
+import its.device
+import its.objects
+import os.path
+import cv2
+import numpy as np
+
+
+def main():
+    """ Test aspect ratio and check if images are cropped correctly under each
+    output size
+    Aspect ratio test runs on level3, full and limited devices. Crop test only
+    runs on full and level3 devices.
+    The test image is a black circle inside a black square. When raw capture is
+    available, set the height vs. width ratio of the circle in the full-frame
+    raw as ground truth. Then compare with images of request combinations of
+    different formats ("jpeg" and "yuv") and sizes.
+    If raw capture is unavailable, take a picture of the test image right in
+    front to eliminate shooting angle effect. the height vs. width ratio for
+    the circle should be close to 1. Considering shooting position error, aspect
+    ratio greater than 1.05 or smaller than 0.95 will fail the test.
+    """
+    NAME = os.path.basename(__file__).split(".")[0]
+    LARGE_SIZE = 2000   # Define the size of a large image
+    # pass/fail threshold of large size images for aspect ratio test
+    THRES_L_AR_TEST = 0.02
+    # pass/fail threshold of mini size images for aspect ratio test
+    THRES_XS_AR_TEST = 0.05
+    # pass/fail threshold of large size images for crop test
+    THRES_L_CP_TEST = 0.02
+    # pass/fail threshold of mini size images for crop test
+    THRES_XS_CP_TEST = 0.05
+    PREVIEW_SIZE = (1920, 1080) # preview size
+    aspect_ratio_gt = 1  # ground truth
+    failed_ar = []  # streams failed the aspect ration test
+    failed_crop = [] # streams failed the crop test
+    format_list = [] # format list for multiple capture objects.
+    # Do multi-capture of "iter" and "cmpr". Iterate through all the
+    # available sizes of "iter", and only use the size specified for "cmpr"
+    # Do single-capture to cover untouched sizes in multi-capture when needed.
+    format_list.append({"iter": "yuv", "iter_max": None,
+                        "cmpr": "yuv", "cmpr_size": PREVIEW_SIZE})
+    format_list.append({"iter": "yuv", "iter_max": PREVIEW_SIZE,
+                        "cmpr": "jpeg", "cmpr_size": None})
+    format_list.append({"iter": "yuv", "iter_max": PREVIEW_SIZE,
+                        "cmpr": "raw", "cmpr_size": None})
+    format_list.append({"iter": "jpeg", "iter_max": None,
+                        "cmpr": "raw", "cmpr_size": None})
+    format_list.append({"iter": "jpeg", "iter_max": None,
+                        "cmpr": "yuv", "cmpr_size": PREVIEW_SIZE})
+    with its.device.ItsSession() as cam:
+        props = cam.get_camera_properties()
+        # Todo: test for radial distortion enabled devices has not yet been
+        # implemented
+        its.caps.skip_unless(not its.caps.radial_distortion_correction(props))
+        full_device = its.caps.full_or_better(props)
+        limited_device = its.caps.limited(props)
+        its.caps.skip_unless(full_device or limited_device)
+        level3_device = its.caps.level3(props)
+        raw_avlb = its.caps.raw16(props)
+        run_crop_test = (level3_device or full_device) and raw_avlb
+        if not run_crop_test:
+            print "Crop test skipped"
+        # Converge 3A and get the estimates.
+        sens, exp, gains, xform, focus = cam.do_3a(get_results=True,
+                                                   lock_ae=True, lock_awb=True)
+        print "AE sensitivity %d, exposure %dms" % (sens, exp / 1000000.0)
+        print "AWB gains", gains
+        print "AWB transform", xform
+        print "AF distance", focus
+        req = its.objects.manual_capture_request(
+                sens, exp, True, props)
+        xform_rat = its.objects.float_to_rational(xform)
+        req["android.colorCorrection.gains"] = gains
+        req["android.colorCorrection.transform"] = xform_rat
+
+        # If raw capture is available, use it as ground truth.
+        if raw_avlb:
+            # Capture full-frame raw. Use its aspect ratio and circle center
+            # location as ground truth for the other jepg or yuv images.
+            out_surface = {"format": "raw"}
+            cap_raw = cam.do_capture(req, out_surface)
+            print "Captured %s %dx%d" % ("raw", cap_raw["width"],
+                                         cap_raw["height"])
+            img_raw = its.image.convert_capture_to_rgb_image(cap_raw,
+                                                             props=props)
+            size_raw = img_raw.shape
+            img_name = "%s_%s_w%d_h%d.png" \
+                       % (NAME, "raw", size_raw[1], size_raw[0])
+            aspect_ratio_gt, cc_ct_gt, circle_size_raw = measure_aspect_ratio(
+                                                         img_raw, 1, img_name)
+            # Normalize the circle size to 1/4 of the image size, so that
+            # circle size won"t affect the crop test result
+            factor_cp_thres = (min(size_raw[0:1])/4.0) / max(circle_size_raw)
+            thres_l_cp_test = THRES_L_CP_TEST * factor_cp_thres
+            thres_xs_cp_test = THRES_XS_CP_TEST * factor_cp_thres
+
+        # Take pictures of each settings with all the image sizes available.
+        for fmt in format_list:
+            fmt_iter = fmt["iter"]
+            fmt_cmpr = fmt["cmpr"]
+            dual_target = fmt_cmpr is not "none"
+            # Get the size of "cmpr"
+            if dual_target:
+                size_cmpr = its.objects.get_available_output_sizes(
+                        fmt_cmpr, props, fmt["cmpr_size"])[0]
+            for size_iter in its.objects.get_available_output_sizes(
+                    fmt_iter, props, fmt["iter_max"]):
+                w_iter = size_iter[0]
+                h_iter = size_iter[1]
+                # Skip testing same format/size combination
+                # ITS does not handle that properly now
+                if dual_target and \
+                        w_iter == size_cmpr[0] and \
+                        h_iter == size_cmpr[1] and \
+                        fmt_iter == fmt_cmpr:
+                    continue
+                out_surface = [{"width": w_iter,
+                                "height": h_iter,
+                                "format": fmt_iter}]
+                if dual_target:
+                    out_surface.append({"width": size_cmpr[0],
+                                        "height": size_cmpr[1],
+                                        "format": fmt_cmpr})
+                cap = cam.do_capture(req, out_surface)
+                if dual_target:
+                    frm_iter = cap[0]
+                else:
+                    frm_iter = cap
+                assert (frm_iter["format"] == fmt_iter)
+                assert (frm_iter["width"] == w_iter)
+                assert (frm_iter["height"] == h_iter)
+                print "Captured %s with %s %dx%d" \
+                        % (fmt_iter, fmt_cmpr, w_iter, h_iter)
+                img = its.image.convert_capture_to_rgb_image(frm_iter)
+                img_name = "%s_%s_with_%s_w%d_h%d.png" \
+                           % (NAME, fmt_iter, fmt_cmpr, w_iter, h_iter)
+                aspect_ratio, cc_ct, _ = measure_aspect_ratio(img, raw_avlb,
+                                                              img_name)
+                # check pass/fail for aspect ratio
+                # image size >= LARGE_SIZE: use THRES_L_AR_TEST
+                # image size == 0 (extreme case): THRES_XS_AR_TEST
+                # 0 < image size < LARGE_SIZE: scale between THRES_XS_AR_TEST
+                # and THRES_L_AR_TEST
+                thres_ar_test = max(THRES_L_AR_TEST,
+                        THRES_XS_AR_TEST + max(w_iter, h_iter) *
+                        (THRES_L_AR_TEST-THRES_XS_AR_TEST)/LARGE_SIZE)
+                thres_range_ar = (aspect_ratio_gt-thres_ar_test,
+                                  aspect_ratio_gt+thres_ar_test)
+                if aspect_ratio < thres_range_ar[0] \
+                        or aspect_ratio > thres_range_ar[1]:
+                    failed_ar.append({"fmt_iter": fmt_iter,
+                                      "fmt_cmpr": fmt_cmpr,
+                                      "w": w_iter, "h": h_iter,
+                                      "ar": aspect_ratio,
+                                      "valid_range": thres_range_ar})
+
+                # check pass/fail for crop
+                if run_crop_test:
+                    # image size >= LARGE_SIZE: use thres_l_cp_test
+                    # image size == 0 (extreme case): thres_xs_cp_test
+                    # 0 < image size < LARGE_SIZE: scale between
+                    # thres_xs_cp_test and thres_l_cp_test
+                    thres_hori_cp_test = max(thres_l_cp_test,
+                            thres_xs_cp_test + w_iter *
+                            (thres_l_cp_test-thres_xs_cp_test)/LARGE_SIZE)
+                    thres_range_h_cp = (cc_ct_gt["hori"]-thres_hori_cp_test,
+                                        cc_ct_gt["hori"]+thres_hori_cp_test)
+                    thres_vert_cp_test = max(thres_l_cp_test,
+                            thres_xs_cp_test + h_iter *
+                            (thres_l_cp_test-thres_xs_cp_test)/LARGE_SIZE)
+                    thres_range_v_cp = (cc_ct_gt["vert"]-thres_vert_cp_test,
+                                        cc_ct_gt["vert"]+thres_vert_cp_test)
+                    if cc_ct["hori"] < thres_range_h_cp[0] \
+                            or cc_ct["hori"] > thres_range_h_cp[1] \
+                            or cc_ct["vert"] < thres_range_v_cp[0] \
+                            or cc_ct["vert"] > thres_range_v_cp[1]:
+                        failed_crop.append({"fmt_iter": fmt_iter,
+                                            "fmt_cmpr": fmt_cmpr,
+                                            "w": w_iter, "h": h_iter,
+                                            "ct_hori": cc_ct["hori"],
+                                            "ct_vert": cc_ct["vert"],
+                                            "valid_range_h": thres_range_h_cp,
+                                            "valid_range_v": thres_range_v_cp})
+
+        # Print aspect ratio test results
+        failed_image_number_for_aspect_ratio_test = len(failed_ar)
+        if failed_image_number_for_aspect_ratio_test > 0:
+            print "\nAspect ratio test summary"
+            print "Images failed in the aspect ratio test:"
+            print "Aspect ratio value: width / height"
+        for fa in failed_ar:
+            print "%s with %s %dx%d: %.3f; valid range: %.3f ~ %.3f" % \
+                  (fa["fmt_iter"], fa["fmt_cmpr"], fa["w"], fa["h"], fa["ar"],
+                   fa["valid_range"][0], fa["valid_range"][1])
+
+        # Print crop test results
+        failed_image_number_for_crop_test = len(failed_crop)
+        if failed_image_number_for_crop_test > 0:
+            print "\nCrop test summary"
+            print "Images failed in the crop test:"
+            print "Circle center position, (horizontal x vertical), listed " \
+                  "below is relative to the image center."
+        for fc in failed_crop:
+            print "%s with %s %dx%d: %.3f x %.3f; " \
+                    "valid horizontal range: %.3f ~ %.3f; " \
+                    "valid vertical range: %.3f ~ %.3f" \
+                    % (fc["fmt_iter"], fc["fmt_cmpr"], fc["w"], fc["h"],
+                    fc["ct_hori"], fc["ct_vert"], fc["valid_range_h"][0],
+                    fc["valid_range_h"][1], fc["valid_range_v"][0],
+                    fc["valid_range_v"][1])
+
+        assert (failed_image_number_for_aspect_ratio_test == 0)
+        if level3_device:
+            assert (failed_image_number_for_crop_test == 0)
+
+
+def measure_aspect_ratio(img, raw_avlb, img_name):
+    """ Measure the aspect ratio of the black circle in the test image.
+
+    Args:
+        img: Numpy float image array in RGB, with pixel values in [0,1].
+        raw_avlb: True: raw capture is available; False: raw capture is not
+             available.
+        img_name: string with image info of format and size.
+    Returns:
+        aspect_ratio: aspect ratio number in float.
+        cc_ct: circle center position relative to the center of image.
+        (circle_w, circle_h): tuple of the circle size
+    """
+    size = img.shape
+    img = img * 255
+    # Gray image
+    img_gray = 0.299 * img[:,:,2] + 0.587 * img[:,:,1] + 0.114 * img[:,:,0]
+
+    # otsu threshold to binarize the image
+    ret3, img_bw = cv2.threshold(np.uint8(img_gray), 0, 255,
+            cv2.THRESH_BINARY + cv2.THRESH_OTSU)
+
+    # connected component
+    contours, hierarchy = cv2.findContours(255-img_bw, cv2.RETR_TREE,
+            cv2.CHAIN_APPROX_SIMPLE)
+
+    # Check each component and find the black circle
+    min_cmpt = size[0] * size[1] * 0.005
+    max_cmpt = size[0] * size[1] * 0.35
+    num_circle = 0
+    aspect_ratio = 0
+    for ct, hrch in zip(contours, hierarchy[0]):
+        # The radius of the circle is 1/3 of the length of the square, meaning
+        # around 1/3 of the area of the square
+        # Parental component should exist and the area is acceptable.
+        # The coutour of a circle should have at least 5 points
+        child_area = cv2.contourArea(ct)
+        if hrch[3] == -1 or child_area < min_cmpt or child_area > max_cmpt or \
+                len(ct) < 15:
+            continue
+        # Check the shapes of current component and its parent
+        child_shape = component_shape(ct)
+        parent = hrch[3]
+        prt_shape = component_shape(contours[parent])
+        prt_area = cv2.contourArea(contours[parent])
+        dist_x = abs(child_shape["ctx"]-prt_shape["ctx"])
+        dist_y = abs(child_shape["cty"]-prt_shape["cty"])
+        # 1. 0.56*Parent"s width < Child"s width < 0.76*Parent"s width.
+        # 2. 0.56*Parent"s height < Child"s height < 0.76*Parent"s height.
+        # 3. Child"s width > 0.1*Image width
+        # 4. Child"s height > 0.1*Image height
+        # 5. 0.25*Parent"s area < Child"s area < 0.45*Parent"s area
+        # 6. Child is a black, and Parent is white
+        # 7. Center of Child and center of parent should overlap
+        if prt_shape["width"] * 0.56 < child_shape["width"] \
+                < prt_shape["width"] * 0.76 \
+                and prt_shape["height"] * 0.56 < child_shape["height"] \
+                < prt_shape["height"] * 0.76 \
+                and child_shape["width"] > 0.1 * size[1] \
+                and child_shape["height"] > 0.1 * size[0] \
+                and 0.30 * prt_area < child_area < 0.50 * prt_area \
+                and img_bw[child_shape["cty"]][child_shape["ctx"]] == 0 \
+                and img_bw[child_shape["top"]][child_shape["left"]] == 255 \
+                and dist_x < 0.1 * child_shape["width"] \
+                and dist_y < 0.1 * child_shape["height"]:
+            # If raw capture is not available, check the camera is placed right
+            # in front of the test page:
+            # 1. Distances between parent and child horizontally on both side,0
+            #    dist_left and dist_right, should be close.
+            # 2. Distances between parent and child vertically on both side,
+            #    dist_top and dist_bottom, should be close.
+            if not raw_avlb:
+                dist_left = child_shape["left"] - prt_shape["left"]
+                dist_right = prt_shape["right"] - child_shape["right"]
+                dist_top = child_shape["top"] - prt_shape["top"]
+                dist_bottom = prt_shape["bottom"] - child_shape["bottom"]
+                if abs(dist_left-dist_right) > 0.05 * child_shape["width"] or \
+                        abs(dist_top-dist_bottom) > \
+                        0.05 * child_shape["height"]:
+                    continue
+            # Calculate aspect ratio
+            aspect_ratio = float(child_shape["width"]) / \
+                           float(child_shape["height"])
+            circle_ctx = child_shape["ctx"]
+            circle_cty = child_shape["cty"]
+            circle_w = float(child_shape["width"])
+            circle_h = float(child_shape["height"])
+            cc_ct = {"hori": float(child_shape["ctx"]-size[1]/2) / circle_w,
+                     "vert": float(child_shape["cty"]-size[0]/2) / circle_h}
+            num_circle += 1
+            # If more than one circle found, break
+            if num_circle == 2:
+                break
+
+    if num_circle == 0:
+        its.image.write_image(img/255, img_name, True)
+        print "No black circle was detected. Please take pictures according " \
+              "to instruction carefully!\n"
+        assert (num_circle == 1)
+
+    if num_circle > 1:
+        its.image.write_image(img/255, img_name, True)
+        print "More than one black circle was detected. Background of scene " \
+              "may be too complex.\n"
+        assert (num_circle == 1)
+
+    # draw circle center and image center, and save the image
+    line_width = max(1, max(size)/500)
+    move_text_dist = line_width * 3
+    cv2.line(img, (circle_ctx, circle_cty), (size[1]/2, size[0]/2),
+             (255, 0, 0), line_width)
+    if circle_cty > size[0]/2:
+        move_text_down_circle = 4
+        move_text_down_image = -1
+    else:
+        move_text_down_circle = -1
+        move_text_down_image = 4
+    if circle_ctx > size[1]/2:
+        move_text_right_circle = 2
+        move_text_right_image = -1
+    else:
+        move_text_right_circle = -1
+        move_text_right_image = 2
+    # circle center
+    text_circle_x = move_text_dist * move_text_right_circle + circle_ctx
+    text_circle_y = move_text_dist * move_text_down_circle + circle_cty
+    cv2.circle(img, (circle_ctx, circle_cty), line_width*2, (255, 0, 0), -1)
+    cv2.putText(img, "circle center", (text_circle_x, text_circle_y),
+                cv2.FONT_HERSHEY_SIMPLEX, line_width/2.0, (255, 0, 0),
+                line_width)
+    # image center
+    text_imgct_x = move_text_dist * move_text_right_image + size[1]/2
+    text_imgct_y = move_text_dist * move_text_down_image + size[0]/2
+    cv2.circle(img, (size[1]/2, size[0]/2), line_width*2, (255, 0, 0), -1)
+    cv2.putText(img, "image center", (text_imgct_x, text_imgct_y),
+                cv2.FONT_HERSHEY_SIMPLEX, line_width/2.0, (255, 0, 0),
+                line_width)
+    its.image.write_image(img/255, img_name, True)
+
+    print "Aspect ratio: %.3f" % aspect_ratio
+    print "Circle center position regarding to image center: %.3fx%.3f" % \
+            (cc_ct["vert"], cc_ct["hori"])
+    return aspect_ratio, cc_ct, (circle_w, circle_h)
+
+
+def component_shape(contour):
+    """ Measure the shape for a connected component in the aspect ratio test
+
+    Args:
+        contour: return from cv2.findContours. A list of pixel coordinates of
+        the contour.
+
+    Returns:
+        The most left, right, top, bottom pixel location, height, width, and
+        the center pixel location of the contour.
+    """
+    shape = {"left": np.inf, "right": 0, "top": np.inf, "bottom": 0,
+             "width": 0, "height": 0, "ctx": 0, "cty": 0}
+    for pt in contour:
+        if pt[0][0] < shape["left"]:
+            shape["left"] = pt[0][0]
+        if pt[0][0] > shape["right"]:
+            shape["right"] = pt[0][0]
+        if pt[0][1] < shape["top"]:
+            shape["top"] = pt[0][1]
+        if pt[0][1] > shape["bottom"]:
+            shape["bottom"] = pt[0][1]
+    shape["width"] = shape["right"] - shape["left"] + 1
+    shape["height"] = shape["bottom"] - shape["top"] + 1
+    shape["ctx"] = (shape["left"]+shape["right"])/2
+    shape["cty"] = (shape["top"]+shape["bottom"])/2
+    return shape
+
+
+if __name__ == "__main__":
+    main()
diff --git a/apps/CameraITS/tests/scene5/test_lens_shading_and_color_uniformity.py b/apps/CameraITS/tests/scene5/test_lens_shading_and_color_uniformity.py
new file mode 100644
index 0000000..282b82e
--- /dev/null
+++ b/apps/CameraITS/tests/scene5/test_lens_shading_and_color_uniformity.py
@@ -0,0 +1,250 @@
+# Copyright 2016 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.
+
+import its.image
+import its.caps
+import its.device
+import its.objects
+import os.path
+import numpy
+import cv2
+import math
+
+
+def main():
+    """ Test that the lens shading correction is applied appropriately, and
+    color of a monochrome uniform scene is evenly distributed, for example,
+    when a diffuser is placed in front of the camera.
+    Perform this test on a yuv frame with auto 3a. Lens shading is evaluated
+    based on the y channel. Measure the average y value for each sample block
+    specified, and then determine pass/fail by comparing with the center y
+    value.
+    The color uniformity test is evaluated in r/g and b/g space. At specified
+    radius of the image, the variance of r/g and b/g value need to be less than
+    a threshold in order to pass the test.
+    """
+    NAME = os.path.basename(__file__).split(".")[0]
+    # Sample block center location and length
+    Num_radius = 8
+    spb_r = 1/2./(Num_radius*2-1)
+    SPB_CT_LIST = numpy.arange(spb_r, 1/2., spb_r*2)
+
+    # Threshold for pass/fail
+    THRES_LS_CT = 0.9    # len shading allowance for center
+    THRES_LS_CN = 0.6    # len shading allowance for corner
+    THRES_LS_HIGH = 0.05 # max allowed percentage for a patch to be brighter
+                         # than center
+    THRES_UFMT = 0.1     # uniformity allowance
+    # Drawing color
+    RED = (1, 0, 0)   # blocks failed the test
+    GREEN = (0, 0.7, 0.3)   # blocks passed the test
+
+    with its.device.ItsSession() as cam:
+        props = cam.get_camera_properties()
+        # Converge 3A and get the estimates.
+        sens, exp, gains, xform, focus = cam.do_3a(get_results=True,
+                                                   do_af=False,
+                                                   lock_ae=True,
+                                                   lock_awb=True)
+        print "AE sensitivity %d, exposure %dms" % (sens, exp / 1000000.0)
+        print "AWB gains", gains
+        print "AWB transform", xform
+        print "AF distance", focus
+        req = its.objects.auto_capture_request()
+        img_size = its.objects.get_available_output_sizes("yuv", props)
+        w = img_size[0][0]
+        h = img_size[0][1]
+        out_surface = {"format": "yuv"}
+        cap = cam.do_capture(req, out_surface)
+        print "Captured yuv %dx%d" % (w, h)
+        # rgb image
+        img_rgb = its.image.convert_capture_to_rgb_image(cap)
+        img_g_pos = img_rgb[:, :, 1] + 0.001  # in case g channel is zero.
+        r_g = img_rgb[:, :, 0] / img_g_pos
+        b_g = img_rgb[:, :, 2] / img_g_pos
+        # y channel
+        img_y = its.image.convert_capture_to_planes(cap)[0]
+        its.image.write_image(img_y, "%s_y_plane.png" % NAME, True)
+
+        # Evaluation begins
+        # image with legend
+        img_legend_ls = numpy.copy(img_rgb)
+        img_legend_ufmt = numpy.copy(img_rgb)
+        line_width = max(2, int(max(h, w)/500))  # line width of legend
+        font_scale = line_width / 7.0   # font scale of the basic font size
+        text_height = cv2.getTextSize('gf', cv2.FONT_HERSHEY_SIMPLEX,
+                                      font_scale, line_width)[0][1]
+        text_offset = int(text_height*1.5)
+
+        # center block average Y value, r/g, and b/g
+        top = int((0.5-spb_r)*h)
+        bottom = int((0.5+spb_r)*h)
+        left = int((0.5-spb_r)*w)
+        right = int((0.5+spb_r)*w)
+        center_y = numpy.mean(img_y[top:bottom, left:right])
+        center_r_g = numpy.mean(r_g[top:bottom, left:right])
+        center_b_g = numpy.mean(b_g[top:bottom, left:right])
+        # add legend to lens Shading figure
+        cv2.rectangle(img_legend_ls, (left, top), (right, bottom), GREEN,
+                      line_width)
+        draw_legend(img_legend_ls, ["Y: %.2f" % center_y],
+                    [left+text_offset, bottom-text_offset],
+                    font_scale, text_offset, GREEN, int(line_width/2))
+        # add legend to color uniformity figure
+        cv2.rectangle(img_legend_ufmt, (left, top), (right, bottom), GREEN,
+                      line_width)
+        texts = ["r/g: %.2f" % center_r_g,
+                 "b/g: %.2f" % center_b_g]
+        draw_legend(img_legend_ufmt, texts,
+                    [left+text_offset, bottom-text_offset*2],
+                    font_scale, text_offset, GREEN, int(line_width/2))
+
+        # evaluate y and r/g, b/g for each block
+        ls_test_failed = []
+        cu_test_failed = []
+        ls_thres_h = center_y * (1 + THRES_LS_HIGH)
+        dist_max = math.sqrt(pow(w, 2)+pow(h, 2))/2
+        for spb_ct in SPB_CT_LIST:
+            # list sample block center location
+            num_sample = (1-spb_ct*2)/spb_r/2 + 1
+            ct_cord_x = numpy.concatenate(
+                        (numpy.arange(spb_ct, 1-spb_ct+spb_r, spb_r*2),
+                         spb_ct*numpy.ones((num_sample-1)),
+                         (1-spb_ct)*numpy.ones((num_sample-1)),
+                         numpy.arange(spb_ct, 1-spb_ct+spb_r, spb_r*2)))
+            ct_cord_y = numpy.concatenate(
+                        (spb_ct*numpy.ones(num_sample+1),
+                         numpy.arange(spb_ct+spb_r*2, 1-spb_ct, spb_r*2),
+                         numpy.arange(spb_ct+spb_r*2, 1-spb_ct, spb_r*2),
+                         (1-spb_ct)*numpy.ones(num_sample+1)))
+
+            blocks_info = []
+            max_r_g = 0
+            min_r_g = float("inf")
+            max_b_g = 0
+            min_b_g = float("inf")
+            for spb_ctx, spb_cty in zip(ct_cord_x, ct_cord_y):
+                top = int((spb_cty-spb_r)*h)
+                bottom = int((spb_cty+spb_r)*h)
+                left = int((spb_ctx-spb_r)*w)
+                right = int((spb_ctx+spb_r)*w)
+                dist_to_img_center = math.sqrt(pow(abs(spb_ctx-0.5)*w, 2)
+                                     + pow(abs(spb_cty-0.5)*h, 2))
+                ls_thres_l = ((THRES_LS_CT-THRES_LS_CN)*(1-dist_to_img_center
+                              /dist_max)+THRES_LS_CN) * center_y
+
+                # compute block average value
+                block_y = numpy.mean(img_y[top:bottom, left:right])
+                block_r_g = numpy.mean(r_g[top:bottom, left:right])
+                block_b_g = numpy.mean(b_g[top:bottom, left:right])
+                max_r_g = max(max_r_g, block_r_g)
+                min_r_g = min(min_r_g, block_r_g)
+                max_b_g = max(max_b_g, block_b_g)
+                min_b_g = min(min_b_g, block_b_g)
+                blocks_info.append({"pos": [top, bottom, left, right],
+                                    "block_r_g": block_r_g,
+                                    "block_b_g": block_b_g})
+                # check lens shading and draw legend
+                if block_y > ls_thres_h or block_y < ls_thres_l:
+                    ls_test_failed.append({"pos": [top, bottom, left,
+                                                   right],
+                                           "val": block_y,
+                                           "thres_l": ls_thres_l})
+                    legend_color = RED
+                else:
+                    legend_color = GREEN
+                text_bottom = bottom - text_offset
+                cv2.rectangle(img_legend_ls, (left, top), (right, bottom),
+                              legend_color, line_width)
+                draw_legend(img_legend_ls, ["Y: %.2f" % block_y],
+                            [left+text_offset, text_bottom], font_scale,
+                            text_offset, legend_color, int(line_width/2))
+
+            # check color uniformity and draw legend
+            ufmt_r_g = (max_r_g-min_r_g) / center_r_g
+            ufmt_b_g = (max_b_g-min_b_g) / center_b_g
+            if ufmt_r_g > THRES_UFMT or ufmt_b_g > THRES_UFMT:
+                cu_test_failed.append({"pos": spb_ct,
+                                       "ufmt_r_g": ufmt_r_g,
+                                       "ufmt_b_g": ufmt_b_g})
+                legend_color = RED
+            else:
+                legend_color = GREEN
+            for block in blocks_info:
+                top, bottom, left, right = block["pos"]
+                cv2.rectangle(img_legend_ufmt, (left, top), (right, bottom),
+                              legend_color, line_width)
+                texts = ["r/g: %.2f" % block["block_r_g"],
+                         "b/g: %.2f" % block["block_b_g"]]
+                text_bottom = bottom - text_offset * 2
+                draw_legend(img_legend_ufmt, texts,
+                            [left+text_offset, text_bottom], font_scale,
+                            text_offset, legend_color, int(line_width/2))
+
+        # Save images
+        its.image.write_image(img_legend_ufmt,
+                              "%s_color_uniformity_result.png" % NAME, True)
+        its.image.write_image(img_legend_ls,
+                              "%s_lens_shading_result.png" % NAME, True)
+
+        # print results
+        lens_shading_test_passed = True
+        color_uniformity_test_passed = True
+        if len(ls_test_failed) > 0:
+            lens_shading_test_passed = False
+            print "\nLens shading test summary"
+            print "Center block average Y value: %.3f" % center_y
+            print "Blocks failed in the lens shading test:"
+            for block in ls_test_failed:
+                top, bottom, left, right = block["pos"]
+                print "Block position: [top: %d, bottom: %d, left: %d, right: "\
+                      "%d]; average Y value: %.3f; valid value range: %.3f ~ " \
+                      "%.3f" % (top, bottom, left, right, block["val"],
+                      block["thres_l"], ls_thres_h)
+        if len(cu_test_failed) > 0:
+            color_uniformity_test_passed = False
+            print "\nColor uniformity test summary"
+            print "Valid color uniformity value range: 0 ~ ", THRES_UFMT
+            print "Areas that failed the color uniformity test:"
+            for rd in cu_test_failed:
+                print "Radius position: %.3f; r/g uniformity: %.3f; b/g " \
+                      "uniformity: %.3f" % (rd["pos"], rd["ufmt_r_g"],
+                      rd["ufmt_b_g"])
+        assert lens_shading_test_passed
+        assert color_uniformity_test_passed
+
+
+def draw_legend(img, texts, text_org, font_scale, text_offset, legend_color,
+                line_width):
+    """ Draw legend on an image.
+
+    Args:
+        img: Numpy float image array in RGB, with pixel values in [0,1].
+        texts: list of legends. Each element in the list is a line of legend.
+        text_org: tuple of the bottom left corner of the text position in
+            pixels, horizontal and vertical.
+        font_scale: float number. Font scale of the basic font size.
+        text_offset: text line width in pixels.
+        legend_color: text color in rgb value.
+        line_width: strokes width in pixels.
+    """
+    for text in texts:
+        cv2.putText(img, text, (text_org[0], text_org[1]),
+                    cv2.FONT_HERSHEY_SIMPLEX, font_scale,
+                    legend_color, line_width)
+        text_org[1] += text_offset
+
+
+if __name__ == '__main__':
+    main()
diff --git a/apps/CameraITS/tests/sensor_fusion/test_sensor_fusion.py b/apps/CameraITS/tests/sensor_fusion/test_sensor_fusion.py
index 53a7638..c4f9b84 100644
--- a/apps/CameraITS/tests/sensor_fusion/test_sensor_fusion.py
+++ b/apps/CameraITS/tests/sensor_fusion/test_sensor_fusion.py
@@ -15,6 +15,7 @@
 import its.image
 import its.device
 import its.objects
+import its.caps
 import time
 import math
 import pylab
@@ -31,11 +32,11 @@
 
 NAME = os.path.basename(__file__).split(".")[0]
 
-# Capture 210 QVGA frames (which is 7s at 30fps)
+# Capture 210 VGA frames (which is 7s at 30fps)
 N = 210
-W,H = 320,240
+W,H = 640,480
 
-FEATURE_PARAMS = dict( maxCorners = 50,
+FEATURE_PARAMS = dict( maxCorners = 80,
                        qualityLevel = 0.3,
                        minDistance = 7,
                        blockSize = 7 )
@@ -58,6 +59,11 @@
 THRESH_MAX_SHIFT_MS = 2
 THRESH_MIN_ROT = 0.001
 
+# lens facing
+FACING_FRONT = 0
+FACING_BACK = 1
+FACING_EXTERNAL = 2
+
 def main():
     """Test if image and motion sensor events are well synchronized.
 
@@ -98,7 +104,7 @@
 
     # Compute the camera rotation displacements (rad) between each pair of
     # adjacent frames.
-    cam_rots = get_cam_rotations(frames)
+    cam_rots = get_cam_rotations(frames, events["facing"])
     if max(abs(cam_rots)) < THRESH_MIN_ROT:
         print "Device wasn't moved enough"
         assert(0)
@@ -240,7 +246,7 @@
     gyro_rots = numpy.array(gyro_rots)
     return gyro_rots
 
-def get_cam_rotations(frames):
+def get_cam_rotations(frames, facing):
     """Get the rotations of the camera between each pair of frames.
 
     Takes N frames and returns N-1 angular displacements corresponding to the
@@ -264,8 +270,13 @@
         p1,st,_ = cv2.calcOpticalFlowPyrLK(gframe0, gframe1, p0, None,
                 **LK_PARAMS)
         tform = procrustes_rotation(p0[st==1], p1[st==1])
-        # TODO: Choose the sign for the rotation so the cam matches the gyro
-        rot = -math.atan2(tform[0, 1], tform[0, 0])
+        if facing == FACING_BACK:
+            rot = -math.atan2(tform[0, 1], tform[0, 0])
+        elif facing == FACING_FRONT:
+            rot = math.atan2(tform[0, 1], tform[0, 0])
+        else:
+            print "Unknown lens facing", facing
+            assert(0)
         rots.append(rot)
         if i == 1:
             # Save a debug visualization of the features that are being
@@ -273,7 +284,7 @@
             frame = frames[i]
             for x,y in p0[st==1]:
                 cv2.circle(frame, (x,y), 3, (100,100,255), -1)
-            its.image.write_image(frame, "%s_features.jpg"%(NAME))
+            its.image.write_image(frame, "%s_features.png"%(NAME))
     return numpy.array(rots)
 
 def get_cam_times(cam_events):
@@ -307,7 +318,7 @@
     n = len(events["cam"])
     frames = []
     for i in range(n):
-        img = Image.open("%s_frame%03d.jpg"%(NAME,i))
+        img = Image.open("%s_frame%03d.png"%(NAME,i))
         w,h = img.size[0:2]
         frames.append(numpy.array(img).reshape(h,w,3) / 255.0)
     return events, frames
@@ -323,16 +334,25 @@
         frames: List of RGB images as numpy arrays.
     """
     with its.device.ItsSession() as cam:
+        props = cam.get_camera_properties()
+        its.caps.skip_unless(its.caps.sensor_fusion(props) and
+                             its.caps.manual_sensor(props) and
+                             props['android.lens.facing'] != FACING_EXTERNAL)
+
         print "Starting sensor event collection"
         cam.start_sensor_events()
 
         # Sleep a few seconds for gyro events to stabilize.
-        time.sleep(5)
+        time.sleep(2)
 
         # TODO: Ensure that OIS is disabled; set to DISABLE and wait some time.
 
         # Capture the frames.
-        props = cam.get_camera_properties()
+        facing = props['android.lens.facing']
+        if facing != FACING_FRONT and facing != FACING_BACK:
+            print "Unknown lens facing", facing
+            assert(0)
+
         fmt = {"format":"yuv", "width":W, "height":H}
         s,e,_,_,_ = cam.do_3a(get_results=True)
         req = its.objects.manual_capture_request(s, e)
@@ -350,7 +370,8 @@
         exptimes = [c["metadata"]["android.sensor.exposureTime"] for c in caps]
         readouts = [c["metadata"]["android.sensor.rollingShutterSkew"]
                     for c in caps]
-        events = {"gyro": gyro, "cam": zip(starts,exptimes,readouts)}
+        events = {"gyro": gyro, "cam": zip(starts,exptimes,readouts),
+                  "facing": facing}
         with open("%s_events.txt"%(NAME), "w") as f:
             f.write(json.dumps(events))
 
@@ -360,7 +381,7 @@
         for i,c in enumerate(caps):
             img = its.image.convert_capture_to_rgb_image(c)
             frames.append(img)
-            its.image.write_image(img, "%s_frame%03d.jpg"%(NAME,i))
+            its.image.write_image(img, "%s_frame%03d.png"%(NAME,i))
 
         return events, frames
 
diff --git a/apps/CameraITS/tools/run_all_tests.py b/apps/CameraITS/tools/run_all_tests.py
index dd12512..301ea73 100644
--- a/apps/CameraITS/tools/run_all_tests.py
+++ b/apps/CameraITS/tools/run_all_tests.py
@@ -43,17 +43,36 @@
             "test_yuv_plus_jpeg"
         ],
         "scene2":[],
-        "scene3":[]
+        "scene3":[],
+        "scene4":[],
+        "scene5":[],
+        "sensor_fusion":[]
     }
 
     # Get all the scene0 and scene1 tests, which can be run using the same
     # physical setup.
-    scenes = ["scene0", "scene1", "scene2", "scene3"]
+    scenes = ["scene0", "scene1", "scene2", "scene3", "scene4", "scene5"]
+
     scene_req = {
         "scene0" : None,
         "scene1" : "A grey card covering at least the middle 30% of the scene",
         "scene2" : "A picture containing human faces",
-        "scene3" : "A chart containing sharp edges like ISO 12233"
+        "scene3" : "A chart containing sharp edges like ISO 12233",
+        "scene4" : "A specific test page of a circle covering at least the "
+                   "middle 50% of the scene. See CameraITS.pdf section 2.3.4 "
+                   "for more details",
+        "scene5" : "Capture images with a diffuser attached to the camera. See "
+                   "CameraITS.pdf section 2.3.4 for more details",
+        "sensor_fusion" : "Rotating checkboard pattern. See "
+                          "sensor_fusion/SensorFusion.pdf for detailed "
+                          "instructions. Note that this test will be skipped "
+                          "on devices not supporting REALTIME camera timestamp."
+                          "If that is the case, no scene setup is required and "
+                          "you can just answer Y when being asked if the scene "
+                          "is okay"
+    }
+    scene_extra_args = {
+        "scene5" : ["doAF=False"]
     }
     tests = []
     for d in scenes:
@@ -113,9 +132,11 @@
                 out_path = os.path.join(topdir, camera_id, scene+".jpg")
                 out_arg = "out=" + out_path
                 scene_arg = "scene=" + scene_req[scene]
+                extra_args = scene_extra_args.get(scene, [])
                 cmd = ['python',
                         os.path.join(os.getcwd(),"tools/validate_scene.py"),
-                        camera_id_arg, out_arg, scene_arg, device_id_arg]
+                        camera_id_arg, out_arg, scene_arg, device_id_arg] + \
+                        extra_args
                 retcode = subprocess.call(cmd,cwd=topdir)
                 assert(retcode == 0)
                 print "Start running tests for", scene
diff --git a/apps/CameraITS/tools/validate_scene.py b/apps/CameraITS/tools/validate_scene.py
index 1f35163..cfe14e2 100644
--- a/apps/CameraITS/tools/validate_scene.py
+++ b/apps/CameraITS/tools/validate_scene.py
@@ -26,6 +26,7 @@
     out_path = ""
     scene_name = ""
     scene_desc = "No requirement"
+    do_af = True
     for s in sys.argv[1:]:
         if s[:7] == "camera=" and len(s) > 7:
             camera_id = s[7:]
@@ -33,6 +34,8 @@
             out_path = s[4:]
         elif s[:6] == "scene=" and len(s) > 6:
             scene_desc = s[6:]
+        elif s[:5] == "doAF=" and len(s) > 5:
+            do_af = s[5:] == "True"
 
     if out_path != "":
         scene_name = re.split("/|\.", out_path)[-2]
@@ -46,7 +49,7 @@
                 " to frame the test scene: " + scene_name +
                 "\nThe scene setup should be: " + scene_desc )
         # Converge 3A prior to capture.
-        cam.do_3a(do_af=True, lock_ae=True, lock_awb=True)
+        cam.do_3a(do_af=do_af, lock_ae=True, lock_awb=True)
         props = cam.get_camera_properties()
         req = its.objects.fastest_auto_capture_request(props)
         if its.caps.ae_lock(props):
diff --git a/apps/CtsVerifier/Android.mk b/apps/CtsVerifier/Android.mk
index ad78a59..a52ea7a 100644
--- a/apps/CtsVerifier/Android.mk
+++ b/apps/CtsVerifier/Android.mk
@@ -27,28 +27,31 @@
 
 LOCAL_STATIC_JAVA_LIBRARIES := android-ex-camera2 \
                                android-support-v4 \
-                               compatibility-common-util-devicesidelib_v2 \
+                               compatibility-common-util-devicesidelib \
                                cts-sensors-tests \
+                               cts-location-tests \
                                ctstestrunner \
                                apache-commons-math \
                                androidplot \
                                ctsverifier-opencv \
-                               core-tests \
+                               core-tests-support \
                                android-support-v4  \
                                mockito-target \
                                mockwebserver \
-                               compatibility-device-util_v2 \
+                               compatibility-device-util \
 
 LOCAL_PACKAGE_NAME := CtsVerifier
 
-LOCAL_JNI_SHARED_LIBRARIES := libctsverifier_jni
+LOCAL_JNI_SHARED_LIBRARIES := libctsverifier_jni libaudioloopback_jni
 
 LOCAL_PROGUARD_FLAG_FILES := proguard.flags
 
-LOCAL_SDK_VERSION := current
+LOCAL_SDK_VERSION := test_current
 
 LOCAL_DEX_PREOPT := false
 
+LOCAL_JAVA_LANGUAGE_VERSION := 1.8
+
 include $(BUILD_PACKAGE)
 
 # Build CTS verifier framework as a libary.
@@ -73,8 +76,8 @@
     $(call all-Iaidl-files-under, src)
 
 LOCAL_STATIC_JAVA_LIBRARIES := android-support-v4 \
-                               compatibility-common-util-devicesidelib_v2 \
-                               compatibility-device-util_v2 \
+                               compatibility-common-util-devicesidelib \
+                               compatibility-device-util \
 
 include $(BUILD_STATIC_JAVA_LIBRARY)
 
diff --git a/apps/CtsVerifier/AndroidManifest.xml b/apps/CtsVerifier/AndroidManifest.xml
index b19dfaa..83f99c5 100644
--- a/apps/CtsVerifier/AndroidManifest.xml
+++ b/apps/CtsVerifier/AndroidManifest.xml
@@ -18,11 +18,12 @@
 <manifest xmlns:android="http://schemas.android.com/apk/res/android"
       package="com.android.cts.verifier"
       android:versionCode="5"
-      android:versionName="6.0_r2">
+      android:versionName="7.0_r0">
 
-    <uses-sdk android:minSdkVersion="19" android:targetSdkVersion="23"/>
+    <uses-sdk android:minSdkVersion="19" android:targetSdkVersion="24"/>
 
     <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
+    <uses-permission android:name="android.permission.ACCESS_LOCATION_EXTRA_COMMANDS"/>
     <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
     <uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
     <uses-permission android:name="android.permission.BLUETOOTH" />
@@ -44,6 +45,8 @@
                   android:required="false" />
     <uses-feature android:name="android.hardware.camera.autofocus"
                   android:required="false" />
+    <uses-feature android:name="android.software.vr.mode" android:required="false" />
+    <uses-feature android:name="android.hardware.vr.high_performance" android:required="false"/>
     <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
     <uses-permission android:name="android.permission.RECORD_AUDIO" />
     <uses-permission android:name="android.permission.WAKE_LOCK" />
@@ -55,9 +58,9 @@
     <uses-permission android:name="android.permission.READ_CONTACTS"/>
     <uses-permission android:name="android.permission.WRITE_CONTACTS"/>
     <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
-    <uses-permission android:name="com.android.providers.tv.permission.READ_EPG_DATA" />
     <uses-permission android:name="com.android.providers.tv.permission.WRITE_EPG_DATA" />
     <uses-permission android:name="android.permission.USE_FINGERPRINT"/>
+    <uses-permission android:name="android.permission.ACCESS_NOTIFICATION_POLICY" />
 
     <!-- Needed by the Audio Quality Verifier to store the sound samples that will be mailed. -->
     <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
@@ -142,6 +145,15 @@
                     android:value="android.software.backup" />
         </activity>
 
+        <activity android:name=".backup.BackupAccessibilityTestActivity" android:label="@string/backup_accessibility_test">
+            <intent-filter>
+                <action android:name="android.intent.action.MAIN" />
+                <category android:name="android.cts.intent.category.MANUAL_TEST" />
+            </intent-filter>
+            <meta-data android:name="test_required_features"
+                    android:value="android.software.backup" />
+        </activity>
+
         <activity android:name=".bluetooth.BluetoothTestActivity"
                 android:label="@string/bluetooth_test"
                 android:configChanges="keyboardHidden|orientation|screenSize">
@@ -427,6 +439,70 @@
             <meta-data android:name="test_required_features" android:value="android.hardware.location.gps" />
         </activity>
 
+        <activity android:name=".location.GnssMeasurementsConstellationTestsActivity"
+            android:label="@string/location_gnss_constellation_type_test"
+            android:screenOrientation="locked">
+            <intent-filter>
+                <action android:name="android.intent.action.MAIN"/>
+                <category android:name="android.cts.intent.category.MANUAL_TEST"/>
+            </intent-filter>
+            <meta-data android:name="test_category" android:value="@string/test_category_hardware"/>
+            <meta-data android:name="test_required_features" android:value="android.hardware.location.gps" />
+        </activity>
+
+        <activity android:name=".location.GnssMeasurementRegistrationTestsActivity"
+            android:label="@string/location_gnss_reg_test"
+            android:screenOrientation="locked">
+            <intent-filter>
+                <action android:name="android.intent.action.MAIN"/>
+                <category android:name="android.cts.intent.category.MANUAL_TEST"/>
+            </intent-filter>
+            <meta-data android:name="test_category" android:value="@string/test_category_hardware"/>
+            <meta-data android:name="test_required_features" android:value="android.hardware.location.gps" />
+        </activity>
+
+        <activity android:name=".location.GnssMeasurementValuesTestsActivity"
+            android:label="@string/location_gnss_value_test"
+            android:screenOrientation="locked">
+            <intent-filter>
+                <action android:name="android.intent.action.MAIN"/>
+                <category android:name="android.cts.intent.category.MANUAL_TEST"/>
+            </intent-filter>
+            <meta-data android:name="test_category" android:value="@string/test_category_hardware"/>
+            <meta-data android:name="test_required_features" android:value="android.hardware.location.gps" />
+        </activity>
+
+        <activity android:name=".location.GnssMeasurementWhenNoLocationTestsActivity"
+            android:label="@string/location_gnss_measure_no_location_test"
+            android:screenOrientation="locked">
+            <intent-filter>
+                <action android:name="android.intent.action.MAIN"/>
+                <category android:name="android.cts.intent.category.MANUAL_TEST"/>
+            </intent-filter>
+            <meta-data android:name="test_category" android:value="@string/test_category_hardware"/>
+            <meta-data android:name="test_required_features" android:value="android.hardware.location.gps" />
+        </activity>
+
+        <activity android:name=".location.GnssNavigationMessageTestsActivity"
+            android:label="@string/location_gnss_nav_msg_test"
+            android:screenOrientation="locked">
+            <intent-filter>
+                <action android:name="android.intent.action.MAIN"/>
+                <category android:name="android.cts.intent.category.MANUAL_TEST"/>
+            </intent-filter>
+            <meta-data android:name="test_category" android:value="@string/test_category_hardware"/>
+            <meta-data android:name="test_required_features" android:value="android.hardware.location.gps" />
+        </activity>
+
+        <activity android:name=".location.LocationListenerActivity"
+                android:label="@string/location_listener_activity"
+                android:configChanges="keyboardHidden|orientation|screenSize">
+            <intent-filter>
+                <action android:name="com.android.cts.verifier.location.SET_LOCATION_AND_CHECK" />
+                <category android:name="android.intent.category.DEFAULT"></category>
+                </intent-filter>
+        </activity>
+
         <activity android:name=".net.ConnectivityScreenOffTestActivity"
                 android:label="@string/network_screen_off_test">
             <intent-filter>
@@ -458,6 +534,16 @@
                 android:configChanges="keyboardHidden|orientation|screenSize">
         </activity>
 
+        <activity android:name="com.android.cts.verifier.nfc.hcef.HceFReaderTestActivity"
+                android:label="@string/nfc_hce_f_reader_tests"
+                android:configChanges="keyboardHidden|orientation|screenSize">
+        </activity>
+
+        <activity android:name="com.android.cts.verifier.nfc.hcef.HceFEmulatorTestActivity"
+                android:label="@string/nfc_hce_f_emulator_tests"
+                android:configChanges="keyboardHidden|orientation|screenSize">
+        </activity>
+
         <activity android:name=".nfc.NdefPushSenderActivity"
                 android:label="@string/nfc_ndef_push_sender"
                 android:configChanges="keyboardHidden|orientation|screenSize" />
@@ -562,6 +648,14 @@
                 android:label="@string/nfc_hce_other_conflicting_prefix_aids_emulator"
                 android:configChanges="keyboardHidden|orientation|screenSize" />
 
+        <activity android:name=".nfc.hcef.HceFEmulatorActivity"
+                android:label="@string/nfc_hce_f_emulator"
+                android:configChanges="keyboardHidden|orientation|screenSize" />
+
+        <activity android:name=".nfc.hcef.HceFReaderActivity"
+                android:label="@string/nfc_hce_f_reader"
+                android:configChanges="keyboardHidden|orientation|screenSize" />
+
         <!-- services used for testing NFC host-based card emulation -->
         <service android:name=".nfc.hce.PaymentService1" android:exported="true"
                  android:permission="android.permission.BIND_NFC_SERVICE"
@@ -691,6 +785,15 @@
             <meta-data android:name="android.nfc.cardemulation.host_apdu_service" android:resource="@xml/payment_aid_list_1"/>
         </service>
 
+        <service
+            android:name=".nfc.hcef.MyHostFelicaService"
+            android:enabled="true"
+            android:exported="true" android:permission="android.permission.BIND_NFC_SERVICE">
+            <intent-filter>
+                <action android:name="android.nfc.cardemulation.action.HOST_NFCF_SERVICE"/>
+            </intent-filter>
+            <meta-data android:name="android.nfc.cardemulation.host_nfcf_service" android:resource="@xml/felicaservice"/>
+        </service>
         <!-- Service used for Camera ITS tests -->
         <service android:name=".camera.its.ItsService" >
             <intent-filter>
@@ -872,6 +975,17 @@
                        android:value="android.hardware.sensor.accelerometer:android.hardware.sensor.stepcounter:android.hardware.sensor.stepdetector:android.hardware.sensor.heartrate:android.hardware.sensor.compass:android.hardware.sensor.ambient_temperature" />
         </activity>
 
+        <activity android:name=".sensors.DynamicSensorDiscoveryTestActivity"
+                  android:label="@string/snsr_dynamic_sensor_discovery_test"
+                  android:screenOrientation="locked">
+            <intent-filter>
+                <action android:name="android.intent.action.MAIN"/>
+                <category android:name="android.cts.intent.category.MANUAL_TEST"/>
+            </intent-filter>
+            <meta-data android:name="test_category" android:value="@string/test_category_sensors"/>
+            <meta-data android:name="test_excluded_features"
+                    android:value="android.software.leanback" />
+        </activity>
         <!-- End sensor tests definitions -->
 
         <activity android:name=".location.LocationModeOffTestActivity"
@@ -950,6 +1064,8 @@
             <meta-data android:name="test_required_features" android:value="android.hardware.camera.any"/>
         </activity>
 
+        <service android:name=".camera.intents.CameraContentJobService"
+            android:permission="android.permission.BIND_JOB_SERVICE" />
 
         <activity android:name=".camera.orientation.CameraOrientationActivity"
                  android:label="@string/camera_orientation"
@@ -1041,6 +1157,18 @@
             <meta-data android:name="test_excluded_features"
                     android:value="android.hardware.type.watch" />
         </activity>
+
+        <activity android:name=".usb.MtpHostTestActivity" android:label="@string/mtp_host_test">
+            <intent-filter>
+                <action android:name="android.intent.action.MAIN" />
+                <category android:name="android.cts.intent.category.MANUAL_TEST" />
+            </intent-filter>
+            <meta-data android:name="test_category" android:value="@string/test_category_hardware" />
+            <meta-data android:name="test_required_features" android:value="android.hardware.usb.host" />
+            <meta-data android:name="test_excluded_features" android:value="android.hardware.type.automotive" />
+            <meta-data android:name="test_excluded_features" android:value="android.hardware.type.television" />
+        </activity>
+
 <!-- Turned off Sensor Power Test in initial L release
         <activity android:name=".sensors.SensorPowerTestActivity"
                 android:label="@string/sensor_power_test"
@@ -1074,6 +1202,19 @@
             <meta-data android:name="test_category" android:value="@string/test_category_notifications" />
         </activity>
 
+        <activity android:name=".notifications.ConditionProviderVerifierActivity"
+                  android:label="@string/cp_test">
+            <intent-filter>
+                <action android:name="android.intent.action.MAIN" />
+                <category android:name="android.cts.intent.category.MANUAL_TEST" />
+            </intent-filter>
+            <meta-data android:name="test_category" android:value="@string/test_category_notifications" />
+            <meta-data android:name="test_excluded_features"
+                       android:value="android.hardware.type.television" />
+            <meta-data android:name="test_excluded_features"
+                       android:value="android.software.leanback" />
+        </activity>
+
         <activity android:name=".notifications.AttentionManagementVerifierActivity"
                 android:label="@string/attention_test">
             <intent-filter>
@@ -1097,14 +1238,64 @@
         </activity>
 
         <service android:name=".notifications.MockListener"
-                 android:exported="true"
-                 android:label="@string/nls_service_name"
-                 android:permission="android.permission.BIND_NOTIFICATION_LISTENER_SERVICE">
+          android:exported="true"
+          android:label="@string/nls_service_name"
+          android:permission="android.permission.BIND_NOTIFICATION_LISTENER_SERVICE">
             <intent-filter>
                 <action android:name="android.service.notification.NotificationListenerService" />
             </intent-filter>
         </service>
 
+        <activity android:name=".vr.VrListenerVerifierActivity"
+            android:label="@string/vr_tests">
+            <intent-filter>
+                <action android:name="android.intent.action.MAIN" />
+                <category android:name="android.cts.intent.category.MANUAL_TEST" />
+            </intent-filter>
+            <meta-data android:name="test_category" android:value="@string/test_category_vr" />
+            <meta-data android:name="test_required_features"
+                       android:value="android.software.vr.mode" />
+        </activity>
+
+        <activity android:name=".vr.MockVrActivity"
+            android:label="@string/vr_tests"
+            android:exported="false"
+            android:process=":TestVrActivity">
+            <intent-filter>
+                <action android:name="android.intent.action.MAIN" />
+                <category android:name="android.intent.category.DEFAULT" />
+            </intent-filter>
+        </activity>
+
+        <activity android:name=".vr.MockVrActivity2"
+            android:label="@string/vr_tests"
+            android:exported="false"
+            android:process=":TestVrActivity2">
+            <intent-filter>
+                <action android:name="android.intent.action.MAIN" />
+                <category android:name="android.intent.category.DEFAULT" />
+            </intent-filter>
+        </activity>
+
+        <service android:name=".vr.MockVrListenerService"
+            android:exported="true"
+            android:enabled="true"
+            android:label="@string/vr_service_name"
+            android:permission="android.permission.BIND_VR_LISTENER_SERVICE">
+            <intent-filter>
+                <action android:name="android.service.vr.VrListenerService" />
+            </intent-filter>
+        </service>
+
+        <service android:name=".notifications.MockConditionProvider"
+                 android:exported="true"
+                 android:label="@string/cp_service_name"
+                 android:permission="android.permission.BIND_CONDITION_PROVIDER_SERVICE">
+            <intent-filter>
+                <action android:name="android.service.notification.ConditionProviderService" />
+            </intent-filter>
+        </service>
+
         <service  android:name=".notifications.InteractiveVerifierActivity$DismissService"/>
 
         <activity android:name=".security.CAInstallNotificationVerifierActivity"
@@ -1247,7 +1438,7 @@
                        android:value="android.hardware.type.television:android.software.leanback" />
         </activity>
 -->
-          <activity
+        <activity
                 android:name="com.android.cts.verifier.sensors.DeviceSuspendTestActivity"
                 android:label="@string/snsr_device_suspend_test"
                 android:screenOrientation="nosensor" >
@@ -1378,10 +1569,26 @@
             <meta-data android:name="test_required_features" android:value="android.software.device_admin" />
         </activity>
 
+        <activity android:name=".managedprovisioning.DeviceOwnerNegativeTestActivity$TrampolineActivity" />
+
         <activity android:name=".managedprovisioning.DeviceOwnerPositiveTestActivity"
                 android:label="@string/positive_device_owner">
             <intent-filter>
                 <action android:name="android.intent.action.MAIN" />
+                <action android:name="com.android.cts.verifier.managedprovisioning.action.CHECK_DEVICE_OWNER" />
+                <category android:name="android.intent.category.DEFAULT" />
+                <category android:name="android.cts.intent.category.MANUAL_TEST" />
+            </intent-filter>
+            <meta-data android:name="test_category" android:value="@string/test_category_managed_provisioning" />
+            <meta-data android:name="test_required_features" android:value="android.software.device_admin" />
+        </activity>
+
+        <activity android:name=".managedprovisioning.DeviceOwnerRequestingBugreportTestActivity"
+                android:label="@string/device_owner_requesting_bugreport_tests">
+            <intent-filter>
+                <action android:name="android.intent.action.MAIN" />
+                <action android:name="com.android.cts.verifier.managedprovisioning.action.CHECK_DEVICE_OWNER_FOR_REQUESTING_BUGREPORT" />
+                <category android:name="android.intent.category.DEFAULT" />
                 <category android:name="android.cts.intent.category.MANUAL_TEST" />
             </intent-filter>
             <meta-data android:name="test_category" android:value="@string/test_category_managed_provisioning" />
@@ -1440,6 +1647,58 @@
             </intent-filter>
         </activity-alias>
 
+        <activity android:name=".managedprovisioning.OrganizationInfoTestActivity"
+                android:label="@string/provisioning_byod_organization_info">
+        </activity>
+
+        <activity android:name=".managedprovisioning.PolicyTransparencyTestListActivity"
+                android:label="@string/device_profile_owner_policy_transparency_test">
+            <intent-filter>
+                <action android:name="com.android.cts.verifier.managedprovisioning.action.CHECK_POLICY_TRANSPARENCY" />
+                <category android:name="android.intent.category.DEFAULT" />
+            </intent-filter>
+        </activity>
+
+        <activity android:name=".managedprovisioning.PolicyTransparencyTestActivity">
+            <intent-filter>
+                <action android:name="com.android.cts.verifier.managedprovisioning.action.SHOW_POLICY_TRANSPARENCY_TEST" />
+                <category android:name="android.intent.category.DEFAULT" />
+            </intent-filter>
+        </activity>
+
+        <activity android:name=".managedprovisioning.CommandReceiverActivity"
+                android:theme="@android:style/Theme.NoDisplay"
+                android:noHistory="true">
+            <intent-filter>
+                <action android:name="com.android.cts.verifier.managedprovisioning.action.EXECUTE_COMMAND" />
+                <category android:name="android.intent.category.DEFAULT" />
+            </intent-filter>
+        </activity>
+
+        <activity android:name=".managedprovisioning.SetSupportMessageActivity">
+            <intent-filter>
+                <action android:name="com.android.cts.verifier.managedprovisioning.action.SET_SUPPORT_MSG" />
+                <category android:name="android.intent.category.DEFAULT" />
+            </intent-filter>
+        </activity>
+
+        <service android:name=".managedprovisioning.PolicyTransparencyTestActivity$DummyInputMethod"
+                android:label="@string/dummy_input_method_label"
+                android:permission="android.permission.BIND_INPUT_METHOD">
+            <intent-filter>
+                <action android:name="android.view.InputMethod" />
+            </intent-filter>
+            <meta-data android:name="android.view.im" android:resource="@xml/dummy_method" />
+        </service>
+
+        <service android:name=".managedprovisioning.PolicyTransparencyTestActivity$DummyAccessibilityService"
+                android:label="@string/dummy_accessibility_service_label"
+                android:permission="android.permission.BIND_ACCESSIBILITY_SERVICE">
+            <intent-filter>
+                <action android:name="android.accessibilityservice.AccessibilityService" />
+            </intent-filter>
+        </service>
+
         <activity android:name=".managedprovisioning.AuthenticationBoundKeyTestActivity">
             <intent-filter>
                 <action android:name="com.android.cts.verifier.managedprovisioning.action.AUTH_BOUND_KEY_TEST" />
@@ -1462,6 +1721,18 @@
             <meta-data android:name="test_required_features" android:value="android.software.managed_users:android.software.device_admin" />
         </activity>
 
+        <activity android:name=".managedprovisioning.ByodProvisioningTestActivity"
+                android:label="@string/provisioning_tests_byod">
+            <intent-filter>
+                <action android:name="android.intent.action.MAIN" />
+                <category android:name="android.cts.intent.category.MANUAL_TEST" />
+            </intent-filter>
+            <meta-data android:name="test_category" android:value="@string/test_category_managed_provisioning" />
+            <meta-data android:name="test_required_features" android:value="android.software.managed_users:android.software.device_admin" />
+        </activity>
+
+        <activity android:name=".managedprovisioning.ByodProvisioningTestActivity$ProvisioningStartingActivity" />
+
         <activity android:name=".managedprovisioning.ByodHelperActivity">
             <intent-filter>
                 <action android:name="com.android.cts.verifier.managedprovisioning.BYOD_QUERY" />
@@ -1483,6 +1754,10 @@
                 <action android:name="com.android.cts.verifier.managedprovisioning.NOTIFICATION" />
                 <action android:name="com.android.cts.verifier.managedprovisioning.LOCKSCREEN_NOTIFICATION" />
                 <action android:name="com.android.cts.verifier.managedprovisioning.CLEAR_NOTIFICATION" />
+                <action android:name="com.android.cts.verifier.managedprovisioning.TEST_SELECT_WORK_CHALLENGE" />
+                <action android:name="com.android.cts.verifier.managedprovisioning.LAUNCH_CONFIRM_WORK_CREDENTIALS" />
+                <action android:name="com.android.cts.verifier.managedprovisioning.TEST_ORGANIZATION_INFO" />
+                <action android:name="com.android.cts.verifier.managedprovisioning.TEST_PARENT_PROFILE_PASSWORD" />
                 <category android:name="android.intent.category.DEFAULT"></category>
             </intent-filter>
         </activity>
@@ -1609,6 +1884,10 @@
             </intent-filter>
         </activity>
 
+        <activity android:name=".managedprovisioning.TurnOffWorkActivity"
+                android:label="@string/provisioning_byod_turn_off_work">
+        </activity>
+
         <receiver android:name=".managedprovisioning.DeviceAdminTestReceiver"
                 android:label="@string/afw_device_admin"
                 android:permission="android.permission.BIND_DEVICE_ADMIN">
@@ -1620,6 +1899,7 @@
             </intent-filter>
         </receiver>
 
+<!-- Comment out until b/28406044 is addressed
         <activity android:name=".jobscheduler.IdleConstraintTestActivity" android:label="@string/js_idle_test">
             <intent-filter>
                 <action android:name="android.intent.action.MAIN" />
@@ -1631,6 +1911,7 @@
             <meta-data android:name="test_excluded_features"
                     android:value="android.software.leanback" />
         </activity>
+-->
 
         <activity android:name=".jobscheduler.ChargingConstraintTestActivity" android:label="@string/js_charging_test">
             <intent-filter>
@@ -1844,6 +2125,16 @@
             <meta-data android:name="test_required_features" android:value="android.hardware.usb.host" />
         </activity>
 
+        <activity android:name=".audio.AudioFrequencyUnprocessedActivity"
+                  android:label="@string/audio_frequency_unprocessed_test">
+            <intent-filter>
+                <action android:name="android.intent.action.MAIN" />
+                <category android:name="android.cts.intent.category.MANUAL_TEST" />
+            </intent-filter>
+            <meta-data android:name="test_category" android:value="@string/test_category_audio" />
+            <meta-data android:name="test_required_features" android:value="android.hardware.microphone" />
+        </activity>
+
         <service android:name=".tv.MockTvInputService"
             android:permission="android.permission.BIND_TV_INPUT">
             <intent-filter>
diff --git a/apps/CtsVerifier/jni/audio_loopback/Android.mk b/apps/CtsVerifier/jni/audio_loopback/Android.mk
index 3dfbc34..0223e4f 100644
--- a/apps/CtsVerifier/jni/audio_loopback/Android.mk
+++ b/apps/CtsVerifier/jni/audio_loopback/Android.mk
@@ -3,26 +3,25 @@
 include $(CLEAR_VARS)
 
 LOCAL_MODULE      := libaudioloopback_jni
+
 LOCAL_MODULE_TAGS := optional
+
 LOCAL_SRC_FILES   := \
 	sles.cpp \
-	jni_sles.c
-
-LOCAL_C_INCLUDES := \
-        system/media/audio_utils/include \
-        frameworks/wilhelm/include
+	jni_sles.c \
+	audio_utils/atomic.c \
+	audio_utils/fifo.c \
+	audio_utils/roundup.c
 
 LOCAL_SHARED_LIBRARIES := \
-	libutils \
-	libcutils \
 	libOpenSLES \
-	libnbaio \
-	liblog \
-	libaudioutils
-
-LOCAL_PRELINK_MODULE := false
+	liblog
 
 LOCAL_LDFLAGS := -Wl,--hash-style=sysv
-LOCAL_CFLAGS := -DSTDC_HEADERS
+
+LOCAL_CFLAGS := -DSTDC_HEADERS \
+	-Werror -Wall
+
+LOCAL_SDK_VERSION := 23
 
 include $(BUILD_SHARED_LIBRARY)
diff --git a/apps/CtsVerifier/jni/audio_loopback/audio_utils/atomic.c b/apps/CtsVerifier/jni/audio_loopback/audio_utils/atomic.c
new file mode 100644
index 0000000..db2b3fc
--- /dev/null
+++ b/apps/CtsVerifier/jni/audio_loopback/audio_utils/atomic.c
@@ -0,0 +1,31 @@
+/*
+ * Copyright (C) 2015 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.
+ */
+
+#include "atomic.h"
+
+#include <stdatomic.h>
+
+int32_t android_atomic_acquire_load(volatile const int32_t* addr)
+{
+    volatile atomic_int_least32_t* a = (volatile atomic_int_least32_t*)addr;
+    return atomic_load_explicit(a, memory_order_acquire);
+}
+
+void android_atomic_release_store(int32_t value, volatile int32_t* addr)
+{
+    volatile atomic_int_least32_t* a = (volatile atomic_int_least32_t*)addr;
+    atomic_store_explicit(a, value, memory_order_release);
+}
diff --git a/apps/CtsVerifier/jni/audio_loopback/audio_utils/atomic.h b/apps/CtsVerifier/jni/audio_loopback/audio_utils/atomic.h
new file mode 100644
index 0000000..535c926
--- /dev/null
+++ b/apps/CtsVerifier/jni/audio_loopback/audio_utils/atomic.h
@@ -0,0 +1,33 @@
+/*
+ * Copyright (C) 2015 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.
+ */
+
+#ifndef ANDROID_AUDIO_ATOMIC_H
+#define ANDROID_AUDIO_ATOMIC_H
+
+#include <stdlib.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+int32_t android_atomic_acquire_load(volatile const int32_t* addr);
+void android_atomic_release_store(int32_t value, volatile int32_t* addr);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // ANDROID_AUDIO_ATOMIC_H
diff --git a/apps/CtsVerifier/jni/audio_loopback/audio_utils/fifo.c b/apps/CtsVerifier/jni/audio_loopback/audio_utils/fifo.c
new file mode 100644
index 0000000..ea9a8d1
--- /dev/null
+++ b/apps/CtsVerifier/jni/audio_loopback/audio_utils/fifo.c
@@ -0,0 +1,135 @@
+/*
+ * Copyright (C) 2015 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.
+ */
+
+//#define LOG_NDEBUG 0
+#define LOG_TAG "audio_utils_fifo"
+
+#include <stdlib.h>
+#include <string.h>
+#include "fifo.h"
+#include "roundup.h"
+#include "atomic.h"
+//#include <cutils/log.h>
+#define ALOG_ASSERT(exp)
+
+void audio_utils_fifo_init(struct audio_utils_fifo *fifo, size_t frameCount, size_t frameSize,
+        void *buffer)
+{
+    // We would need a 64-bit roundup to support larger frameCount.
+    ALOG_ASSERT(fifo != NULL && frameCount > 0 && frameSize > 0 && buffer != NULL);
+    fifo->mFrameCount = frameCount;
+    fifo->mFrameCountP2 = roundup(frameCount);
+    fifo->mFudgeFactor = fifo->mFrameCountP2 - fifo->mFrameCount;
+    fifo->mFrameSize = frameSize;
+    fifo->mBuffer = buffer;
+    fifo->mFront = 0;
+    fifo->mRear = 0;
+}
+
+void audio_utils_fifo_deinit(struct audio_utils_fifo *fifo __unused)
+{
+}
+
+// Return a new index as the sum of an old index (either mFront or mRear) and a specified increment.
+static inline int32_t audio_utils_fifo_sum(struct audio_utils_fifo *fifo, int32_t index,
+        uint32_t increment)
+{
+    if (fifo->mFudgeFactor) {
+        uint32_t mask = fifo->mFrameCountP2 - 1;
+        ALOG_ASSERT((index & mask) < fifo->mFrameCount);
+        ALOG_ASSERT(/*0 <= increment &&*/ increment <= fifo->mFrameCountP2);
+        if ((index & mask) + increment >= fifo->mFrameCount) {
+            increment += fifo->mFudgeFactor;
+        }
+        index += increment;
+        ALOG_ASSERT((index & mask) < fifo->mFrameCount);
+        return index;
+    } else {
+        return index + increment;
+    }
+}
+
+// Return the difference between two indices: rear - front, where 0 <= difference <= mFrameCount.
+static inline size_t audio_utils_fifo_diff(struct audio_utils_fifo *fifo, int32_t rear,
+        int32_t front)
+{
+    int32_t diff = rear - front;
+    if (fifo->mFudgeFactor) {
+        uint32_t mask = ~(fifo->mFrameCountP2 - 1);
+        int32_t genDiff = (rear & mask) - (front & mask);
+        if (genDiff != 0) {
+            ALOG_ASSERT(genDiff == (int32_t) fifo->mFrameCountP2);
+            diff -= fifo->mFudgeFactor;
+        }
+    }
+    // FIFO should not be overfull
+    ALOG_ASSERT(0 <= diff && diff <= (int32_t) fifo->mFrameCount);
+    return (size_t) diff;
+}
+
+ssize_t audio_utils_fifo_write(struct audio_utils_fifo *fifo, const void *buffer, size_t count)
+{
+    int32_t front = android_atomic_acquire_load(&fifo->mFront);
+    int32_t rear = fifo->mRear;
+    size_t availToWrite = fifo->mFrameCount - audio_utils_fifo_diff(fifo, rear, front);
+    if (availToWrite > count) {
+        availToWrite = count;
+    }
+    rear &= fifo->mFrameCountP2 - 1;
+    size_t part1 = fifo->mFrameCount - rear;
+    if (part1 > availToWrite) {
+        part1 = availToWrite;
+    }
+    if (part1 > 0) {
+        memcpy((char *) fifo->mBuffer + (rear * fifo->mFrameSize), buffer,
+                part1 * fifo->mFrameSize);
+        size_t part2 = availToWrite - part1;
+        if (part2 > 0) {
+            memcpy(fifo->mBuffer, (char *) buffer + (part1 * fifo->mFrameSize),
+                    part2 * fifo->mFrameSize);
+        }
+        android_atomic_release_store(audio_utils_fifo_sum(fifo, fifo->mRear, availToWrite),
+                &fifo->mRear);
+    }
+    return availToWrite;
+}
+
+ssize_t audio_utils_fifo_read(struct audio_utils_fifo *fifo, void *buffer, size_t count)
+{
+    int32_t rear = android_atomic_acquire_load(&fifo->mRear);
+    int32_t front = fifo->mFront;
+    size_t availToRead = audio_utils_fifo_diff(fifo, rear, front);
+    if (availToRead > count) {
+        availToRead = count;
+    }
+    front &= fifo->mFrameCountP2 - 1;
+    size_t part1 = fifo->mFrameCount - front;
+    if (part1 > availToRead) {
+        part1 = availToRead;
+    }
+    if (part1 > 0) {
+        memcpy(buffer, (char *) fifo->mBuffer + (front * fifo->mFrameSize),
+                part1 * fifo->mFrameSize);
+        size_t part2 = availToRead - part1;
+        if (part2 > 0) {
+            memcpy((char *) buffer + (part1 * fifo->mFrameSize), fifo->mBuffer,
+                    part2 * fifo->mFrameSize);
+        }
+        android_atomic_release_store(audio_utils_fifo_sum(fifo, fifo->mFront, availToRead),
+                &fifo->mFront);
+    }
+    return availToRead;
+}
diff --git a/apps/CtsVerifier/jni/audio_loopback/audio_utils/fifo.h b/apps/CtsVerifier/jni/audio_loopback/audio_utils/fifo.h
new file mode 100644
index 0000000..ba4c5c6
--- /dev/null
+++ b/apps/CtsVerifier/jni/audio_loopback/audio_utils/fifo.h
@@ -0,0 +1,86 @@
+/*
+ * Copyright (C) 2015 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.
+ */
+
+#ifndef ANDROID_AUDIO_FIFO_H
+#define ANDROID_AUDIO_FIFO_H
+
+#include <stdlib.h>
+
+// FIXME use atomic_int_least32_t and new atomic operations instead of legacy Android ones
+// #include <stdatomic.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+// Single writer, single reader non-blocking FIFO.
+// Writer and reader must be in same process.
+
+// No user-serviceable parts within.
+struct audio_utils_fifo {
+    // These fields are const after initialization
+    size_t     mFrameCount;   // max number of significant frames to be stored in the FIFO > 0
+    size_t     mFrameCountP2; // roundup(mFrameCount)
+    size_t     mFudgeFactor;  // mFrameCountP2 - mFrameCount, the number of "wasted" frames after
+                              // the end of mBuffer.  Only the indices are wasted, not any memory.
+    size_t     mFrameSize;    // size of each frame in bytes
+    void      *mBuffer;       // pointer to caller-allocated buffer of size mFrameCount frames
+
+    volatile int32_t mFront; // frame index of first frame slot available to read, or read index
+    volatile int32_t mRear;  // frame index of next frame slot available to write, or write index
+};
+
+// Initialize a FIFO object.
+// Input parameters:
+//  fifo        Pointer to the FIFO object.
+//  frameCount  Max number of significant frames to be stored in the FIFO > 0.
+//              If writes and reads always use the same count, and that count is a divisor of
+//              frameCount, then the writes and reads will never do a partial transfer.
+//  frameSize   Size of each frame in bytes.
+//  buffer      Pointer to a caller-allocated buffer of frameCount frames.
+void audio_utils_fifo_init(struct audio_utils_fifo *fifo, size_t frameCount, size_t frameSize,
+        void *buffer);
+
+// De-initialize a FIFO object.
+// Input parameters:
+//  fifo        Pointer to the FIFO object.
+void audio_utils_fifo_deinit(struct audio_utils_fifo *fifo);
+
+// Write to FIFO.
+// Input parameters:
+//  fifo        Pointer to the FIFO object.
+//  buffer      Pointer to source buffer containing 'count' frames of data.
+// Returns actual number of frames written <= count.
+// The actual transfer count may be zero if the FIFO is full,
+// or partial if the FIFO was almost full.
+// A negative return value indicates an error.  Currently there are no errors defined.
+ssize_t audio_utils_fifo_write(struct audio_utils_fifo *fifo, const void *buffer, size_t count);
+
+// Read from FIFO.
+// Input parameters:
+//  fifo        Pointer to the FIFO object.
+//  buffer      Pointer to destination buffer to be filled with up to 'count' frames of data.
+// Returns actual number of frames read <= count.
+// The actual transfer count may be zero if the FIFO is empty,
+// or partial if the FIFO was almost empty.
+// A negative return value indicates an error.  Currently there are no errors defined.
+ssize_t audio_utils_fifo_read(struct audio_utils_fifo *fifo, void *buffer, size_t count);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif  // !ANDROID_AUDIO_FIFO_H
diff --git a/apps/CtsVerifier/jni/audio_loopback/audio_utils/roundup.c b/apps/CtsVerifier/jni/audio_loopback/audio_utils/roundup.c
new file mode 100644
index 0000000..4f9af6a
--- /dev/null
+++ b/apps/CtsVerifier/jni/audio_loopback/audio_utils/roundup.c
@@ -0,0 +1,32 @@
+/*
+ * Copyright (C) 2012 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.
+ */
+
+#include "roundup.h"
+
+unsigned roundup(unsigned v)
+{
+    // __builtin_clz is undefined for zero input
+    if (v == 0) {
+        v = 1;
+    }
+    int lz = __builtin_clz((int) v);
+    unsigned rounded = ((unsigned) 0x80000000) >> lz;
+    // 0x800000001 and higher are actually rounded _down_ to prevent overflow
+    if (v > rounded && lz > 0) {
+        rounded <<= 1;
+    }
+    return rounded;
+}
diff --git a/apps/CtsVerifier/jni/audio_loopback/audio_utils/roundup.h b/apps/CtsVerifier/jni/audio_loopback/audio_utils/roundup.h
new file mode 100644
index 0000000..ad34289
--- /dev/null
+++ b/apps/CtsVerifier/jni/audio_loopback/audio_utils/roundup.h
@@ -0,0 +1,31 @@
+/*
+ * Copyright (C) 2012 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.
+ */
+
+#ifndef ANDROID_AUDIO_ROUNDUP_H
+#define ANDROID_AUDIO_ROUNDUP_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+// Round up to the next highest power of 2
+unsigned roundup(unsigned v);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif  // ANDROID_AUDIO_ROUNDUP_H
diff --git a/apps/CtsVerifier/jni/audio_loopback/jni_sles.c b/apps/CtsVerifier/jni/audio_loopback/jni_sles.c
index a865078..e8a837e 100644
--- a/apps/CtsVerifier/jni/audio_loopback/jni_sles.c
+++ b/apps/CtsVerifier/jni/audio_loopback/jni_sles.c
@@ -22,11 +22,12 @@
 
 /////
 JNIEXPORT jlong JNICALL Java_com_android_cts_verifier_audio_NativeAudioThread_slesInit
-  (JNIEnv *env __unused, jobject obj __unused, jint samplingRate, jint frameCount, jint micSource) {
+  (JNIEnv *env __unused, jobject obj __unused, jint samplingRate, jint frameCount,
+   jint micSource, jint numFramesToIgnore) {
 
     sles_data * pSles = NULL;
 
-    if (slesInit(&pSles, samplingRate, frameCount, micSource) != SLES_FAIL) {
+    if (slesInit(&pSles, samplingRate, frameCount, micSource, numFramesToIgnore) != SLES_FAIL) {
 
         return (long)pSles;
     }
diff --git a/apps/CtsVerifier/jni/audio_loopback/jni_sles.h b/apps/CtsVerifier/jni/audio_loopback/jni_sles.h
index 7bff040..d7aa625 100644
--- a/apps/CtsVerifier/jni/audio_loopback/jni_sles.h
+++ b/apps/CtsVerifier/jni/audio_loopback/jni_sles.h
@@ -25,7 +25,7 @@
 
 ////////////////////////
 JNIEXPORT jlong JNICALL Java_com_android_cts_verifier_audio_NativeAudioThread_slesInit
-  (JNIEnv *, jobject, jint, jint, jint );
+  (JNIEnv *, jobject, jint, jint, jint, jint );
 
 JNIEXPORT jint JNICALL Java_com_android_cts_verifier_audio_NativeAudioThread_slesProcessNext
   (JNIEnv *, jobject , jlong, jdoubleArray, jlong );
diff --git a/apps/CtsVerifier/jni/audio_loopback/sles.cpp b/apps/CtsVerifier/jni/audio_loopback/sles.cpp
index 7859d35..586c60f 100644
--- a/apps/CtsVerifier/jni/audio_loopback/sles.cpp
+++ b/apps/CtsVerifier/jni/audio_loopback/sles.cpp
@@ -35,19 +35,21 @@
 #include <string.h>
 #include <unistd.h>
 
-int slesInit(sles_data ** ppSles, int samplingRate, int frameCount, int micSource) {
+int slesInit(sles_data ** ppSles, int samplingRate, int frameCount, int micSource,
+             int numFramesToIgnore) {
     int status = SLES_FAIL;
     if (ppSles != NULL) {
         sles_data * pSles = (sles_data*) calloc(1, sizeof (sles_data));
 
-        SLES_PRINTF("malloc %d bytes at %p",sizeof(sles_data), pSles);
+        SLES_PRINTF("malloc %zu bytes at %p", sizeof(sles_data), pSles);
         *ppSles = pSles;
         if (pSles != NULL)
         {
             SLES_PRINTF("creating server. Sampling rate =%d, frame count = %d",samplingRate,
                     frameCount);
-            status = slesCreateServer(pSles, samplingRate, frameCount, micSource);
-            SLES_PRINTF("slesCreateServer =%d",status);
+            status = slesCreateServer(pSles, samplingRate, frameCount, micSource,
+                                      numFramesToIgnore);
+            SLES_PRINTF("slesCreateServer =%d", status);
         }
     }
     return status;
@@ -94,6 +96,17 @@
             pSles->rxFront = 0;
         }
 
+        // Throw out first frames
+        if (pSles->numFramesToIgnore) {
+            SLuint32 framesToErase = pSles->numFramesToIgnore;
+            if (framesToErase > pSles->bufSizeInFrames) {
+                framesToErase = pSles->bufSizeInFrames;
+            }
+            pSles->numFramesToIgnore -= framesToErase;
+            // FIXME: this assumes each sample is a short
+            memset(buffer, 0, framesToErase * pSles->channels * sizeof(short));
+        }
+
         ssize_t actual = audio_utils_fifo_write(&(pSles->fifo), buffer,
                 (size_t) pSles->bufSizeInFrames);
         if (actual != (ssize_t) pSles->bufSizeInFrames) {
@@ -199,7 +212,8 @@
     } //pSles not null
 }
 
-int slesCreateServer(sles_data *pSles, int samplingRate, int frameCount, int micSource) {
+int slesCreateServer(sles_data *pSles, int samplingRate, int frameCount,
+                     int micSource, int numFramesToIgnore) {
     int status = SLES_FAIL;
 
     if (pSles == NULL) {
@@ -254,12 +268,19 @@
     pSles->bufSizeInBytes = 0; // calculated
     pSles->injectImpulse = 300; // -i#i
 
+    if (numFramesToIgnore > 0) {
+        pSles->numFramesToIgnore = numFramesToIgnore;
+    } else {
+        pSles->numFramesToIgnore = 0;
+    }
+
     // Storage area for the buffer queues
     //        char **rxBuffers;
     //        char **txBuffers;
     //        char **freeBuffers;
 
     // Buffer indices
+/*
     pSles->rxFront;    // oldest recording
     pSles->rxRear;     // next to be recorded
     pSles->txFront;    // oldest playing
@@ -268,9 +289,8 @@
     pSles->freeRear;   // next to be freed
 
     pSles->fifo; //(*)
+*/
     pSles->fifo2Buffer = NULL;
-    pSles->recorderBufferQueue;
-    pSles->playerBufferQueue;
 
     // compute total free buffers as -r plus -t
     pSles->freeBufCount = pSles->rxBufCount + pSles->txBufCount;
@@ -325,7 +345,6 @@
     SLresult result;
 
     // create engine
-    pSles->engineObject;
     result = slCreateEngine(&(pSles->engineObject), 0, NULL, 0, NULL, NULL);
     ASSERT_EQ(SL_RESULT_SUCCESS, result);
     result = (*(pSles->engineObject))->Realize(pSles->engineObject, SL_BOOLEAN_FALSE);
@@ -336,7 +355,6 @@
     ASSERT_EQ(SL_RESULT_SUCCESS, result);
 
     // create output mix
-    pSles->outputmixObject;
     result = (*engineEngine)->CreateOutputMix(engineEngine, &(pSles->outputmixObject), 0, NULL,
             NULL);
     ASSERT_EQ(SL_RESULT_SUCCESS, result);
diff --git a/apps/CtsVerifier/jni/audio_loopback/sles.h b/apps/CtsVerifier/jni/audio_loopback/sles.h
index 2550b81..607f724 100644
--- a/apps/CtsVerifier/jni/audio_loopback/sles.h
+++ b/apps/CtsVerifier/jni/audio_loopback/sles.h
@@ -41,6 +41,7 @@
     SLuint32 freeBufCount;   // calculated
     SLuint32 bufSizeInBytes; // calculated
     int injectImpulse; // -i#i
+    SLuint32 numFramesToIgnore;
 
     // Storage area for the buffer queues
     char **rxBuffers;
@@ -76,7 +77,8 @@
     SLES_FAIL = 1,
 } SLES_STATUS_ENUM;
 
-int slesInit(sles_data ** ppSles, int samplingRate, int frameCount, int micSource);
+int slesInit(sles_data ** ppSles, int samplingRate, int frameCount,
+             int micSource, int numFramesToIgnore);
 
 //note the double pointer to properly free the memory of the structure
 int slesDestroy(sles_data ** ppSles);
@@ -84,7 +86,7 @@
 ///full
 int slesFull(sles_data *pSles);
 
-int slesCreateServer(sles_data *pSles, int samplingRate, int frameCount, int micSource);
+int slesCreateServer(sles_data *pSles, int samplingRate, int frameCount, int micSource, int numFramesToIgnore);
 int slesProcessNext(sles_data *pSles, double *pSamples, long maxSamples);
 int slesDestroyServer(sles_data *pSles);
 
diff --git a/apps/CtsVerifier/proguard.flags b/apps/CtsVerifier/proguard.flags
index 5a2beb5..187e8d2 100644
--- a/apps/CtsVerifier/proguard.flags
+++ b/apps/CtsVerifier/proguard.flags
@@ -14,6 +14,14 @@
     public <methods>;
 }
 
+# ensure we keep public Gnss Measurement test methods, these are needed at runtime
+-keepclassmembers class * extends com.android.cts.verifier.location.BaseGnssTestActivity {
+    public <methods>;
+}
+-keepclassmembers class * extends android.location.cts.GnssTestCase {
+    public <methods>;
+}
+
 -keepclasseswithmembers class * extends com.android.cts.verifier.location.LocationModeTestActivity
 
 # keep mockito methods
@@ -27,3 +35,11 @@
 -dontwarn java.util.concurrent.ConcurrentLinkedDeque
 -dontwarn android.cts.util.**
 -dontwarn junit.**
+
+# Jack seems less rigorous than proguard when it comes to warning about
+# transitive dependencies.
+-dontwarn com.android.org.bouncycastle.**
+-dontwarn com.android.okhttp.**
+-dontwarn org.opencv.**
+-dontwarn android.support.test.internal.runner.hidden.ExposedInstrumentationApi
+
diff --git a/apps/CtsVerifier/res/layout-land/gnss_test.xml b/apps/CtsVerifier/res/layout-land/gnss_test.xml
new file mode 100644
index 0000000..c511d40
--- /dev/null
+++ b/apps/CtsVerifier/res/layout-land/gnss_test.xml
@@ -0,0 +1,56 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2016 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.
+-->
+<com.android.cts.verifier.BoxInsetLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:app="http://schemas.android.com/apk/res-auto"
+    android:layout_width="match_parent"
+    android:layout_height="match_parent">
+    <LinearLayout app:ctsv_layout_box="all"
+        android:orientation="vertical"
+        android:layout_width="match_parent"
+        android:layout_height="match_parent"
+        >
+
+        <LinearLayout
+            android:orientation="horizontal"
+            android:layout_width="match_parent"
+            android:layout_height="0dp"
+            android:layout_weight="1">
+
+            <TextView android:id="@+id/text"
+                android:textSize="14sp"
+                android:layout_width="match_parent"
+                android:layout_height="wrap_content"/>
+
+            <ScrollView
+                android:id="@+id/log_scroll_view"
+                android:fillViewport="true"
+                android:layout_height="match_parent"
+                android:layout_width="0dp"
+                android:layout_weight="1">
+
+                <LinearLayout
+                    android:id="@+id/log_layout"
+                    android:orientation="vertical"
+                    android:layout_width="match_parent"
+                    android:layout_height="match_parent"/>
+            </ScrollView>
+
+        </LinearLayout>
+
+        <include layout="@layout/snsr_next_button" />
+
+    </LinearLayout>
+</com.android.cts.verifier.BoxInsetLayout>
diff --git a/apps/CtsVerifier/res/layout-port/gnss_test.xml b/apps/CtsVerifier/res/layout-port/gnss_test.xml
new file mode 100644
index 0000000..560133a
--- /dev/null
+++ b/apps/CtsVerifier/res/layout-port/gnss_test.xml
@@ -0,0 +1,57 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2016 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.
+-->
+<com.android.cts.verifier.BoxInsetLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:app="http://schemas.android.com/apk/res-auto"
+    android:layout_width="match_parent"
+    android:layout_height="match_parent">
+    <LinearLayout app:ctsv_layout_box="all"
+        android:orientation="vertical"
+        android:layout_width="match_parent"
+        android:layout_height="match_parent"
+        >
+
+        <LinearLayout
+            android:orientation="horizontal"
+            android:layout_width="match_parent"
+            android:layout_height="0dp"
+            android:layout_weight="1">
+
+            <TextView android:id="@+id/text"
+                android:textSize="14sp"
+                android:layout_width="match_parent"
+                android:layout_height="wrap_content"/>
+
+            <ScrollView
+                android:id="@+id/log_scroll_view"
+                android:fillViewport="true"
+                android:layout_height="match_parent"
+                android:layout_width="0dp"
+                android:layout_weight="1">
+
+                <LinearLayout
+                    android:id="@+id/log_layout"
+                    android:orientation="vertical"
+                    android:layout_width="match_parent"
+                    android:layout_height="match_parent"/>
+
+            </ScrollView>
+
+        </LinearLayout>
+
+        <include layout="@layout/snsr_next_button" />
+
+    </LinearLayout>
+</com.android.cts.verifier.BoxInsetLayout>
diff --git a/apps/CtsVerifier/res/layout-small/gnss_test.xml b/apps/CtsVerifier/res/layout-small/gnss_test.xml
new file mode 100644
index 0000000..5caea07
--- /dev/null
+++ b/apps/CtsVerifier/res/layout-small/gnss_test.xml
@@ -0,0 +1,44 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2016 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.
+-->
+<com.android.cts.verifier.BoxInsetLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:app="http://schemas.android.com/apk/res-auto"
+    android:layout_width="match_parent"
+    android:layout_height="match_parent">
+    <ScrollView android:id="@+id/log_scroll_view"
+        app:ctsv_layout_box="all"
+        android:fillViewport="true"
+        android:layout_height="match_parent"
+        android:layout_width="match_parent">
+        <LinearLayout
+            android:orientation="vertical"
+            android:layout_height="wrap_content"
+            android:layout_width="match_parent">
+
+            <TextView android:id="@+id/text"
+                android:textSize="14sp"
+                android:layout_width="match_parent"
+                android:layout_height="wrap_content"/>
+
+            <LinearLayout android:id="@+id/log_layout"
+                android:orientation="vertical"
+                android:layout_height="wrap_content"
+                android:layout_width="match_parent"/>
+
+            <include layout="@layout/snsr_next_button"/>
+        </LinearLayout>
+
+    </ScrollView>
+</com.android.cts.verifier.BoxInsetLayout>
diff --git a/apps/CtsVerifier/res/layout/audio_frequency_line_activity.xml b/apps/CtsVerifier/res/layout/audio_frequency_line_activity.xml
index c1b62af..6a755d5 100644
--- a/apps/CtsVerifier/res/layout/audio_frequency_line_activity.xml
+++ b/apps/CtsVerifier/res/layout/audio_frequency_line_activity.xml
@@ -49,13 +49,20 @@
                     android:layout_width="wrap_content"
                     android:layout_height="wrap_content"
                     android:id="@+id/audio_general_headset_no"
-                    android:text="@string/audio_general_headset_no" />
+                    android:text="@string/audio_general_headset_no"
+                    android:nextFocusForward="@+id/audio_general_headset_yes"
+                    android:nextFocusDown="@+id/audio_frequency_line_plug_ready_btn"
+                    android:nextFocusRight="@+id/audio_general_headset_yes"/>
 
                 <Button
                     android:layout_width="wrap_content"
                     android:layout_height="wrap_content"
                     android:id="@+id/audio_general_headset_yes"
-                    android:text="@string/audio_general_headset_yes" />
+                    android:text="@string/audio_general_headset_yes"
+                    android:nextFocusForward="@+id/audio_frequency_line_plug_ready_btns"
+                    android:nextFocusDown="@+id/audio_frequency_line_plug_ready_btn"
+                    android:nextFocusLeft="@+id/audio_general_headset_no"
+                    android:nextFocusRight="@+id/audio_frequency_line_plug_ready_btn" />
 
             </LinearLayout>
 
@@ -75,7 +82,12 @@
                     android:layout_width="match_parent"
                     android:layout_height="wrap_content"
                     android:id="@+id/audio_frequency_line_plug_ready_btn"
-                    android:text="@string/audio_frequency_line_plug_ready_btn" />
+                    android:text="@string/audio_frequency_line_plug_ready_btn"
+                    android:nextFocusForward="@+id/audio_frequency_line_test_btn"
+                    android:nextFocusUp="@+id/audio_general_headset_yes"
+                    android:nextFocusDown="@+id/audio_frequency_line_test_btn"
+                    android:nextFocusLeft="@+id/audio_general_headset_yes"
+                    android:nextFocusRight="@+id/audio_frequency_line_test_btn"/>
 
                 <LinearLayout
                     android:orientation="vertical"
@@ -93,7 +105,12 @@
                             android:layout_width="wrap_content"
                             android:layout_height="wrap_content"
                             android:text="@string/audio_frequency_line_test_btn"
-                            android:id="@+id/audio_frequency_line_test_btn" />
+                            android:id="@+id/audio_frequency_line_test_btn"
+                            android:nextFocusForward="@+id/pass_button"
+                            android:nextFocusUp="@+id/audio_frequency_line_plug_ready_btn"
+                            android:nextFocusDown="@+id/pass_button"
+                            android:nextFocusLeft="@+id/audio_frequency_line_plug_ready_btn"
+                            android:nextFocusRight="@+id/pass_button"/>
 
                         <ProgressBar
                             android:layout_width="wrap_content"
diff --git a/apps/CtsVerifier/res/layout/audio_frequency_mic_activity.xml b/apps/CtsVerifier/res/layout/audio_frequency_mic_activity.xml
index db52998..8722f1d 100644
--- a/apps/CtsVerifier/res/layout/audio_frequency_mic_activity.xml
+++ b/apps/CtsVerifier/res/layout/audio_frequency_mic_activity.xml
@@ -51,13 +51,20 @@
                     android:layout_width="wrap_content"
                     android:layout_height="wrap_content"
                     android:id="@+id/audio_general_headset_no"
-                    android:text="@string/audio_general_headset_no" />
+                    android:text="@string/audio_general_headset_no"
+                    android:nextFocusForward="@+id/audio_general_headset_yes"
+                    android:nextFocusDown="@+id/audio_frequency_mic_speakers_ready_btn"
+                    android:nextFocusRight="@+id/audio_general_headset_yes" />
 
                 <Button
                     android:layout_width="wrap_content"
                     android:layout_height="wrap_content"
                     android:id="@+id/audio_general_headset_yes"
-                    android:text="@string/audio_general_headset_yes" />
+                    android:text="@string/audio_general_headset_yes"
+                    android:nextFocusForward="@+id/audio_frequency_mic_speakers_ready_btn"
+                    android:nextFocusDown="@+id/audio_frequency_mic_speakers_ready_btn"
+                    android:nextFocusLeft="@+id/audio_general_headset_no"
+                    android:nextFocusRight="@+id/audio_frequency_mic_speakers_ready_btn" />
 
             </LinearLayout>
 
@@ -84,7 +91,12 @@
                 android:layout_width="match_parent"
                 android:layout_height="wrap_content"
                 android:id="@+id/audio_frequency_mic_speakers_ready_btn"
-                android:text="@string/audio_frequency_mic_speakers_ready_btn" />
+                android:text="@string/audio_frequency_mic_speakers_ready_btn"
+                android:nextFocusForward="@+id/audio_frequency_mic_test1_btn"
+                android:nextFocusUp="@+id/audio_general_headset_yes"
+                android:nextFocusDown="@+id/audio_frequency_mic_test1_btn"
+                android:nextFocusLeft="@+id/audio_general_headset_yes"
+                android:nextFocusRight="@+id/audio_frequency_mic_test1_btn" />
 
             <TextView
                 android:layout_width="match_parent"
@@ -111,7 +123,12 @@
                     android:layout_width="wrap_content"
                     android:layout_height="wrap_content"
                     android:text="@string/audio_frequency_mic_test1_btn"
-                    android:id="@+id/audio_frequency_mic_test1_btn" />
+                    android:id="@+id/audio_frequency_mic_test1_btn"
+                    android:nextFocusForward="@+id/audio_frequency_mic_mic_ready_btn"
+                    android:nextFocusUp="@+id/audio_frequency_mic_speakers_ready_btn"
+                    android:nextFocusDown="@+id/audio_frequency_mic_mic_ready_btn"
+                    android:nextFocusLeft="@+id/audio_frequency_mic_speakers_ready_btn"
+                    android:nextFocusRight="@+id/audio_frequency_mic_mic_ready_btn" />
 
                 <TextView
                     android:layout_width="wrap_content"
@@ -131,7 +148,12 @@
                     android:layout_width="match_parent"
                     android:layout_height="wrap_content"
                     android:id="@+id/audio_frequency_mic_mic_ready_btn"
-                    android:text="@string/audio_frequency_mic_mic_ready_btn" />
+                    android:text="@string/audio_frequency_mic_mic_ready_btn"
+                    android:nextFocusForward="@+id/audio_frequency_mic_test2_btn"
+                    android:nextFocusUp="@+id/audio_frequency_mic_test1_btn"
+                    android:nextFocusDown="@+id/audio_frequency_mic_test2_btn"
+                    android:nextFocusLeft="@+id/audio_frequency_mic_test1_btn"
+                    android:nextFocusRight="@+id/audio_frequency_mic_test2_btn" />
 
                 <TextView
                     android:layout_width="wrap_content"
@@ -151,7 +173,12 @@
                     android:layout_width="wrap_content"
                     android:layout_height="wrap_content"
                     android:text="@string/audio_frequency_mic_test2_btn"
-                    android:id="@+id/audio_frequency_mic_test2_btn" />
+                    android:id="@+id/audio_frequency_mic_test2_btn"
+                    android:nextFocusForward="@+id/pass_button"
+                    android:nextFocusUp="@+id/audio_frequency_mic_mic_ready_btn"
+                    android:nextFocusDown="@+id/pass_button"
+                    android:nextFocusLeft="@+id/audio_frequency_mic_mic_ready_btn"
+                    android:nextFocusRight="@+id/pass_button" />
 
                 <TextView
                     android:layout_width="wrap_content"
diff --git a/apps/CtsVerifier/res/layout/audio_frequency_speaker_activity.xml b/apps/CtsVerifier/res/layout/audio_frequency_speaker_activity.xml
index 5dd55b1..926a4c7 100644
--- a/apps/CtsVerifier/res/layout/audio_frequency_speaker_activity.xml
+++ b/apps/CtsVerifier/res/layout/audio_frequency_speaker_activity.xml
@@ -46,7 +46,10 @@
                 android:layout_width="match_parent"
                 android:layout_height="wrap_content"
                 android:id="@+id/audio_frequency_speaker_mic_ready_btn"
-                android:text="@string/audio_frequency_speaker_mic_ready_btn"/>
+                android:text="@string/audio_frequency_speaker_mic_ready_btn"
+                android:nextFocusForward="@+id/audio_frequency_speaker_test_btn"
+                android:nextFocusDown="@+id/audio_frequency_speaker_test_btn"
+                android:nextFocusRight="@+id/audio_frequency_speaker_test_btn" />
 
             <TextView
                 android:layout_width="wrap_content"
@@ -68,7 +71,12 @@
                         android:layout_width="wrap_content"
                         android:layout_height="wrap_content"
                         android:text="@string/audio_frequency_speaker_test_btn"
-                        android:id="@+id/audio_frequency_speaker_test_btn"/>
+                        android:id="@+id/audio_frequency_speaker_test_btn"
+                        android:nextFocusForward="@+id/pass_button"
+                        android:nextFocusUp="@+id/audio_frequency_speaker_mic_ready_btn"
+                        android:nextFocusDown="@+id/pass_button"
+                        android:nextFocusLeft="@+id/audio_frequency_speaker_mic_ready_btn"
+                        android:nextFocusRight="@+id/pass_button" />
 
                     <ProgressBar
                         android:layout_width="wrap_content"
diff --git a/apps/CtsVerifier/res/layout/audio_frequency_unprocessed_activity.xml b/apps/CtsVerifier/res/layout/audio_frequency_unprocessed_activity.xml
new file mode 100644
index 0000000..abc8033
--- /dev/null
+++ b/apps/CtsVerifier/res/layout/audio_frequency_unprocessed_activity.xml
@@ -0,0 +1,80 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2015 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.
+-->
+<LinearLayout
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    android:layout_width="match_parent"
+    android:layout_height="wrap_content"
+    android:padding="10dip"
+    android:orientation="vertical"
+>
+
+    <ScrollView
+        android:layout_width="match_parent"
+        android:layout_height="match_parent"
+        android:id="@+id/scrollView"
+    >
+
+        <LinearLayout
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:orientation="vertical"
+        >
+
+        <TextView
+                android:layout_width="match_parent"
+                android:layout_height="wrap_content"
+                android:scrollbars="vertical"
+                android:gravity="bottom"
+                android:id="@+id/audio_frequency_unprocessed_defined"/>
+
+                <ProgressBar
+                    android:layout_width="wrap_content"
+                    android:layout_height="wrap_content"
+                    android:layout_weight="1"
+                    android:id="@+id/audio_frequency_unprocessed_progress_bar" />
+
+            <LinearLayout
+                android:layout_width="wrap_content"
+                android:layout_height="wrap_content"
+                android:orientation="vertical"
+                android:id="@+id/audio_frequency_unprocessed_layout_test1"
+            >
+
+                <TextView
+                    android:layout_width="wrap_content"
+                    android:layout_height="wrap_content"
+                    android:text="@string/audio_frequency_unprocessed_instructions2"
+                    android:id="@+id/audio_frequency_unprocessed_instructions2" />
+
+                <Button
+                    android:layout_width="wrap_content"
+                    android:layout_height="wrap_content"
+                    android:text="@string/audio_frequency_unprocessed_test1_btn"
+                    android:id="@+id/audio_frequency_unprocessed_test1_btn" />
+
+                <TextView
+                    android:layout_width="wrap_content"
+                    android:layout_height="wrap_content"
+                    android:text="@string/audio_frequency_unprocessed_results_text"
+                    android:id="@+id/audio_frequency_unprocessed_results1_text" />
+            </LinearLayout>
+
+
+            <include layout="@layout/pass_fail_buttons" />
+        </LinearLayout>
+    </ScrollView>
+
+</LinearLayout>
\ No newline at end of file
diff --git a/apps/CtsVerifier/res/layout/audio_loopback_activity.xml b/apps/CtsVerifier/res/layout/audio_loopback_activity.xml
index 815f2bc..350f428 100644
--- a/apps/CtsVerifier/res/layout/audio_loopback_activity.xml
+++ b/apps/CtsVerifier/res/layout/audio_loopback_activity.xml
@@ -51,13 +51,20 @@
                     android:layout_width="wrap_content"
                     android:layout_height="wrap_content"
                     android:id="@+id/audio_general_headset_no"
-                    android:text="@string/audio_general_headset_no" />
+                    android:text="@string/audio_general_headset_no"
+                    android:nextFocusForward="@+id/audio_general_headset_yes"
+                    android:nextFocusDown="@+id/audio_loopback_plug_ready_btn"
+                    android:nextFocusRight="@+id/audio_general_headset_yes" />
 
                 <Button
                     android:layout_width="wrap_content"
                     android:layout_height="wrap_content"
                     android:id="@+id/audio_general_headset_yes"
-                    android:text="@string/audio_general_headset_yes" />
+                    android:text="@string/audio_general_headset_yes"
+                    android:nextFocusForward="@+id/audio_loopback_plug_ready_btn"
+                    android:nextFocusDown="@+id/audio_loopback_plug_ready_btn"
+                    android:nextFocusLeft="@+id/audio_general_headset_no"
+                    android:nextFocusRight="@+id/audio_loopback_plug_ready_btn" />
 
             </LinearLayout>
 
@@ -80,7 +87,12 @@
                     android:layout_width="match_parent"
                     android:layout_height="wrap_content"
                     android:id="@+id/audio_loopback_plug_ready_btn"
-                    android:text="@string/audio_loopback_plug_ready_btn" />
+                    android:text="@string/audio_loopback_plug_ready_btn"
+                    android:nextFocusForward="@+id/audio_loopback_level_seekbar"
+                    android:nextFocusUp="@+id/audio_general_headset_yes"
+                    android:nextFocusDown="@+id/audio_loopback_level_seekbar"
+                    android:nextFocusLeft="@+id/audio_general_headset_yes"
+                    android:nextFocusRight="@+id/audio_loopback_level_seekbar" />
 
                 <LinearLayout
                     android:orientation="vertical"
@@ -98,7 +110,12 @@
                     <SeekBar
                         android:layout_width="match_parent"
                         android:layout_height="wrap_content"
-                        android:id="@+id/audio_loopback_level_seekbar" />
+                        android:id="@+id/audio_loopback_level_seekbar"
+                        android:nextFocusForward="@+id/audio_loopback_test_btn"
+                        android:nextFocusUp="@+id/audio_loopback_plug_ready_btn"
+                        android:nextFocusDown="@+id/audio_loopback_test_btn"
+                        android:nextFocusLeft="@+id/audio_loopback_plug_ready_btn"
+                        android:nextFocusRight="@+id/audio_loopback_test_btn" />
 
                     <TextView
                         android:layout_width="wrap_content"
@@ -110,7 +127,12 @@
                         android:layout_width="wrap_content"
                         android:layout_height="wrap_content"
                         android:text="@string/audio_loopback_test_btn"
-                        android:id="@+id/audio_loopback_test_btn" />
+                        android:id="@+id/audio_loopback_test_btn"
+                        android:nextFocusForward="@+id/pass_button"
+                        android:nextFocusUp="@+id/audio_loopback_level_seekbar"
+                        android:nextFocusDown="@+id/pass_button"
+                        android:nextFocusLeft="@+id/audio_loopback_level_seekbar"
+                        android:nextFocusRight="@+id/pass_button" />
 
                     <ProgressBar
                         android:layout_width="wrap_content"
diff --git a/apps/CtsVerifier/res/layout/bua_main.xml b/apps/CtsVerifier/res/layout/bua_main.xml
new file mode 100644
index 0000000..e2d5ef1
--- /dev/null
+++ b/apps/CtsVerifier/res/layout/bua_main.xml
@@ -0,0 +1,50 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2011 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.
+-->
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+         android:orientation="vertical"
+         android:layout_width="match_parent"
+         android:layout_height="match_parent"
+         >
+
+    <ListView android:id="@+id/android:list"
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:layout_weight="1"
+            />
+
+    <TextView android:id="@id/android:empty"
+           android:gravity="center"
+           android:layout_width="match_parent"
+           android:layout_height="wrap_content"
+           android:layout_weight="1"
+           android:text="@string/bu_loading"
+           />
+
+    <Button android:id="@+id/generate_button"
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="@string/bua_read_settings"
+            />
+
+    <Button android:id="@+id/show_instructions_button"
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="@string/bua_show_instructions"
+            />
+
+    <include layout="@layout/pass_fail_buttons" />
+
+</LinearLayout>
diff --git a/apps/CtsVerifier/res/layout/camera_fov_calibration_photo_capture.xml b/apps/CtsVerifier/res/layout/camera_fov_calibration_photo_capture.xml
index c142b15..7f8efa0 100644
--- a/apps/CtsVerifier/res/layout/camera_fov_calibration_photo_capture.xml
+++ b/apps/CtsVerifier/res/layout/camera_fov_calibration_photo_capture.xml
@@ -49,6 +49,7 @@
             android:layout_alignParentBottom="true"
             android:layout_alignParentLeft="true"
             android:padding="10sp"
+            android:popupBackground="#ffffff"
             android:textSize="18sp" />
     </RelativeLayout>
 
diff --git a/apps/CtsVerifier/res/layout/fs_main.xml b/apps/CtsVerifier/res/layout/fs_main.xml
index ad46048..40b74e9 100644
--- a/apps/CtsVerifier/res/layout/fs_main.xml
+++ b/apps/CtsVerifier/res/layout/fs_main.xml
@@ -30,14 +30,12 @@
          <ListView android:id="@id/android:list"
                    android:layout_width="match_parent"
                    android:layout_height="match_parent"
-                   android:background="#000000"
                    android:layout_weight="1"
                    android:drawSelectorOnTop="false"/>
 
          <TextView android:id="@id/android:empty"
                    android:layout_width="match_parent"
                    android:layout_height="match_parent"
-                   android:background="#000000"
                    android:text="@string/fs_no_data"/>
 
         <include layout="@layout/pass_fail_buttons" />
diff --git a/apps/CtsVerifier/res/layout/list_item.xml b/apps/CtsVerifier/res/layout/list_item.xml
index 7fd9002..efa1483 100644
--- a/apps/CtsVerifier/res/layout/list_item.xml
+++ b/apps/CtsVerifier/res/layout/list_item.xml
@@ -22,4 +22,4 @@
     android:fontFamily="sans-serif-light"
     android:textSize="14dp"
     android:freezesText="true"
-    android:background="#ff1f1f1f" />
\ No newline at end of file
+    android:background="#fff" />
diff --git a/apps/CtsVerifier/res/layout/mtp_host_activity.xml b/apps/CtsVerifier/res/layout/mtp_host_activity.xml
new file mode 100644
index 0000000..f260e5d
--- /dev/null
+++ b/apps/CtsVerifier/res/layout/mtp_host_activity.xml
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2016 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.
+-->
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+        android:orientation="vertical"
+        android:layout_width="match_parent"
+        android:layout_height="match_parent">
+    <ScrollView android:layout_height="0dp"
+            android:layout_width="match_parent"
+            android:layout_weight="1" >
+        <LinearLayout android:id="@+id/mtp_host_list"
+                android:orientation="vertical"
+                android:layout_width="match_parent"
+                android:layout_height="wrap_content" />
+    </ScrollView>
+    <TextView android:id="@+id/error_text"
+              android:layout_width="match_parent"
+              android:layout_height="wrap_content" />
+    <include layout="@layout/pass_fail_buttons" />
+</LinearLayout>
diff --git a/apps/CtsVerifier/res/layout/mtp_host_item.xml b/apps/CtsVerifier/res/layout/mtp_host_item.xml
new file mode 100644
index 0000000..5268809
--- /dev/null
+++ b/apps/CtsVerifier/res/layout/mtp_host_item.xml
@@ -0,0 +1,70 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+     Copyright (C) 2013 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.
+-->
+<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    android:layout_width="match_parent"
+    android:layout_height="wrap_content"
+    android:paddingTop="8dp"
+    android:paddingBottom="8dp">
+
+    <ImageView
+        android:id="@+id/status"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:layout_alignParentLeft="true"
+        android:layout_alignParentTop="true"
+        android:contentDescription="@string/pass_button_text"
+        android:paddingTop="3dip"
+        android:paddingLeft="10dip"
+        android:paddingRight="10dip"
+        android:src="@drawable/fs_indeterminate" />
+
+    <TextView
+        android:id="@+id/instructions"
+        style="@style/InstructionsSmallFont"
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content"
+        android:layout_alignParentTop="true"
+        android:layout_toRightOf="@id/status" />
+
+    <Button
+        android:id="@+id/next_item_button"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:layout_below="@id/instructions"
+        android:layout_toRightOf="@id/status"
+        android:text="@string/next_button_text"
+        android:visibility="gone" />
+
+    <Button
+        android:id="@+id/pass_item_button"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:layout_below="@id/instructions"
+        android:layout_toRightOf="@id/next_item_button"
+        android:text="@string/pass_button_text"
+        android:visibility="gone" />
+
+    <Button
+        android:id="@+id/fail_item_button"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:layout_below="@id/instructions"
+        android:layout_toRightOf="@id/pass_item_button"
+        android:text="@string/fail_button_text"
+        android:visibility="gone" />
+
+</RelativeLayout>
diff --git a/apps/CtsVerifier/res/layout/organization_info.xml b/apps/CtsVerifier/res/layout/organization_info.xml
new file mode 100644
index 0000000..320fb8c
--- /dev/null
+++ b/apps/CtsVerifier/res/layout/organization_info.xml
@@ -0,0 +1,70 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2016 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.
+-->
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+        android:id="@+id/root_view"
+        android:orientation="vertical"
+        android:layout_width="match_parent"
+        android:layout_height="match_parent">
+
+        <TextView android:id="@+id/provisioning_byod_organization_info_instructions"
+                android:layout_width="match_parent"
+                android:layout_height="0dp"
+                android:layout_weight="1"
+                android:text="@string/provisioning_byod_organization_info_instructions"/>
+
+        <LinearLayout
+                android:layout_width="match_parent"
+                android:layout_height="wrap_content"
+                android:orientation="horizontal">
+            <EditText android:id="@+id/organization_name_edit_text"
+                    android:layout_width="0dp"
+                    android:layout_height="wrap_content"
+                    android:hint="@string/provisioning_byod_organization_name_hint"
+                    android:gravity="top|start"
+                    android:windowSoftInputMode="adjustPan"
+                    android:padding="16dp"
+                    android:layout_weight="1"/>
+            <EditText android:id="@+id/organization_color_edit_text"
+                    android:layout_width="0dp"
+                    android:layout_height="wrap_content"
+                    android:hint="@string/provisioning_byod_organization_color_hint"
+                    android:gravity="top|start"
+                    android:digits="#0123456789abcdefABCDEF"
+                    android:inputType="textCapCharacters"
+                    android:windowSoftInputMode="adjustPan"
+                    android:padding="16dp"
+                    android:layout_weight="1" />
+        </LinearLayout>
+
+        <LinearLayout
+                android:layout_width="match_parent"
+                android:layout_height="wrap_content"
+                android:orientation="horizontal">
+            <Button android:id="@+id/organization_info_set_button"
+                    android:layout_width="0dp"
+                    android:layout_height="wrap_content"
+                    android:text="@string/provisioning_byod_set_organization_info_button_text"
+                    android:layout_weight="1"/>
+            <Button android:id="@+id/go_button"
+                    android:layout_width="0dp"
+                    android:layout_height="wrap_content"
+                    android:text="@string/go_button_text"
+                    android:layout_weight="1"/>
+        </LinearLayout>
+
+        <include layout="@layout/pass_fail_buttons" />
+
+</LinearLayout>
diff --git a/apps/CtsVerifier/res/layout/policy_transparency_test.xml b/apps/CtsVerifier/res/layout/policy_transparency_test.xml
new file mode 100644
index 0000000..131ff3e
--- /dev/null
+++ b/apps/CtsVerifier/res/layout/policy_transparency_test.xml
@@ -0,0 +1,81 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2016 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.
+-->
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+        android:id="@+id/root_view"
+        android:orientation="vertical"
+        android:layout_width="match_parent"
+        android:layout_height="match_parent"
+        android:descendantFocusability="beforeDescendants"
+        android:focusableInTouchMode="true">
+    <ScrollView
+            android:layout_width="match_parent"
+            android:layout_height="0dp"
+            android:layout_weight="1"
+            android:paddingTop="4dp">
+        <TextView
+                android:id="@+id/test_instructions"
+                android:layout_width="match_parent"
+                android:layout_height="wrap_content"
+                android:textSize="16sp"
+                android:padding="10dp" />
+    </ScrollView>
+
+    <LinearLayout
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:orientation="horizontal"
+            android:paddingTop="8dp"
+            android:gravity="center_vertical">
+        <TextView android:id="@+id/widget_label"
+                android:layout_width="0dp"
+                android:layout_height="wrap_content"
+                android:textSize="18sp"
+                android:layout_weight="1"
+                android:paddingStart="16dp"
+                android:paddingEnd="8dp" />
+        <Switch android:id="@+id/switch_widget"
+                android:layout_width="wrap_content"
+                android:layout_height="wrap_content"
+                android:paddingStart="8dp"
+                android:paddingEnd="16dp"
+                android:visibility="gone" />
+        <EditText android:id="@+id/edit_text_widget"
+                android:layout_width="wrap_content"
+                android:layout_height="wrap_content"
+                android:ems="6"
+                android:singleLine="true"
+                android:gravity="center"
+                android:visibility="gone" />
+        <Button android:id="@+id/update_button"
+                android:layout_width="wrap_content"
+                android:layout_height="wrap_content"
+                android:text="@string/policy_transparency_update_button_label"
+                android:paddingStart="8dp"
+                android:paddingEnd="16dp"
+                android:visibility="gone" />
+        <Spinner android:id="@+id/spinner_widget"
+                android:layout_width="wrap_content"
+                android:layout_height="wrap_content"
+                android:visibility="gone" />
+    </LinearLayout>
+
+    <Button android:id="@+id/open_settings_button"
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="@string/policy_transparency_open_settings_label" />
+
+    <include layout="@layout/pass_fail_buttons"/>
+</LinearLayout>
\ No newline at end of file
diff --git a/apps/CtsVerifier/res/layout/policy_transparency_test_list.xml b/apps/CtsVerifier/res/layout/policy_transparency_test_list.xml
new file mode 100644
index 0000000..8358e44
--- /dev/null
+++ b/apps/CtsVerifier/res/layout/policy_transparency_test_list.xml
@@ -0,0 +1,56 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2016 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.
+-->
+<com.android.cts.verifier.BoxInsetLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:app="http://schemas.android.com/apk/res-auto"
+    android:layout_width="match_parent"
+    android:layout_height="match_parent">
+
+    <LinearLayout app:ctsv_layout_box="all"
+            android:orientation="vertical"
+            android:layout_width="match_parent"
+            android:layout_height="match_parent"
+            >
+
+        <ListView android:id="@id/android:list"
+                android:layout_width="match_parent"
+                android:layout_height="match_parent"
+                android:layout_weight="1"
+                />
+
+        <TextView android:id="@id/android:empty"
+                android:layout_width="match_parent"
+                android:layout_height="match_parent"
+                android:layout_weight="1"
+                />
+
+        <LinearLayout
+                android:layout_width="match_parent"
+                android:layout_height="wrap_content">
+            <Button android:id="@+id/short_msg_button"
+                    android:layout_width="0dp"
+                    android:layout_height="wrap_content"
+                    android:layout_weight="1"
+                    android:text="@string/policy_transparency_short_support_msg_label" />
+            <Button android:id="@+id/long_msg_button"
+                    android:layout_width="0dp"
+                    android:layout_height="wrap_content"
+                    android:layout_weight="1"
+                    android:text="@string/policy_transparency_long_support_msg_label" />
+        </LinearLayout>
+        <include layout="@layout/pass_fail_buttons" />
+
+    </LinearLayout>
+</com.android.cts.verifier.BoxInsetLayout>
\ No newline at end of file
diff --git a/apps/CtsVerifier/res/layout/positive_device_owner.xml b/apps/CtsVerifier/res/layout/positive_device_owner.xml
index f5d10e0..2ffb463 100644
--- a/apps/CtsVerifier/res/layout/positive_device_owner.xml
+++ b/apps/CtsVerifier/res/layout/positive_device_owner.xml
@@ -21,7 +21,7 @@
 
     <ScrollView
             android:layout_width="match_parent"
-            android:layout_height="320dp"
+            android:layout_height="150dp"
             android:layout_weight="2">
         <TextView
                 android:id="@+id/positive_device_owner_instructions"
diff --git a/apps/CtsVerifier/res/layout/provisioning_byod.xml b/apps/CtsVerifier/res/layout/provisioning_byod.xml
index 375c3ab..54b5121 100644
--- a/apps/CtsVerifier/res/layout/provisioning_byod.xml
+++ b/apps/CtsVerifier/res/layout/provisioning_byod.xml
@@ -21,7 +21,7 @@
 
     <ScrollView
             android:layout_width="match_parent"
-            android:layout_height="320dp"
+            android:layout_height="150dp"
             android:layout_weight="2">
         <TextView
                 android:id="@+id/test_instructions"
diff --git a/apps/CtsVerifier/res/layout/requesting_bugreport_device_owner.xml b/apps/CtsVerifier/res/layout/requesting_bugreport_device_owner.xml
new file mode 100644
index 0000000..b2955ec
--- /dev/null
+++ b/apps/CtsVerifier/res/layout/requesting_bugreport_device_owner.xml
@@ -0,0 +1,49 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2016 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.
+-->
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+        android:orientation="vertical"
+        android:layout_width="match_parent"
+        android:layout_height="match_parent"
+        >
+
+    <ScrollView
+            android:layout_width="match_parent"
+            android:layout_height="100dp"
+            android:layout_weight="2">
+        <TextView
+                android:id="@+id/requesting_bugreport_device_owner_instructions"
+                android:layout_width="match_parent"
+                android:layout_height="wrap_content"
+                android:padding="10dip"
+                android:text="@string/device_owner_requesting_bugreport_tests_info"
+                android:textSize="18dip" />
+    </ScrollView>
+
+    <Button
+        android:id="@+id/set_device_owner_button"
+        android:layout_width="204dp"
+        android:layout_height="wrap_content"
+        android:text="@string/set_device_owner_button_label" />
+
+    <ListView
+        android:id="@+id/android:list"
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content"
+        android:layout_weight="3" />
+
+    <include layout="@layout/pass_fail_buttons" />
+
+</LinearLayout>
diff --git a/apps/CtsVerifier/res/layout/set_support_message.xml b/apps/CtsVerifier/res/layout/set_support_message.xml
new file mode 100644
index 0000000..ddf8563
--- /dev/null
+++ b/apps/CtsVerifier/res/layout/set_support_message.xml
@@ -0,0 +1,53 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ Copyright 2016 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.
+-->
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+        android:layout_width="match_parent"
+        android:layout_height="match_parent"
+        android:orientation="vertical">
+    <EditText android:id="@+id/message_view"
+            android:layout_width="match_parent"
+            android:layout_height="0dp"
+            android:layout_weight="1"
+            android:scrollbars="vertical"
+            android:fadeScrollbars="false"
+            android:autoLink="phone|email"
+            android:hint="Enter the support message"
+            android:gravity="top|start"
+            android:windowSoftInputMode="adjustPan"
+            android:padding="16dp"
+            android:textColorLink="?android:attr/colorAccent"
+            android:background="@null" />
+    <Button android:id="@+id/set_default_message"
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:text="@string/policy_transparency_set_default_msg" />
+    <LinearLayout
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:orientation="horizontal">
+        <Button android:id="@+id/clear_message"
+                android:layout_width="0dp"
+                android:layout_height="wrap_content"
+                android:layout_weight="1"
+                android:text="@string/policy_transparency_clear_msg" />
+        <Button android:id="@+id/set_message"
+                android:layout_width="0dp"
+                android:layout_height="wrap_content"
+                android:layout_weight="1"
+                android:text="@string/policy_transparency_set_msg" />
+    </LinearLayout>
+</LinearLayout>
\ No newline at end of file
diff --git a/apps/CtsVerifier/res/layout/vr_item.xml b/apps/CtsVerifier/res/layout/vr_item.xml
new file mode 100644
index 0000000..b938747
--- /dev/null
+++ b/apps/CtsVerifier/res/layout/vr_item.xml
@@ -0,0 +1,54 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+     Copyright (C) 2016 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.
+-->
+<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    android:layout_width="match_parent"
+    android:layout_height="wrap_content" >
+
+    <ImageView
+        android:id="@+id/vr_status"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:layout_alignParentLeft="true"
+        android:layout_alignParentTop="true"
+        android:layout_marginTop="10dip"
+        android:contentDescription="@string/pass_button_text"
+        android:padding="10dip"
+        android:src="@drawable/fs_indeterminate" />
+
+    <TextView
+        android:id="@+id/vr_instructions"
+        style="@style/InstructionsSmallFont"
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content"
+        android:layout_alignParentRight="true"
+        android:layout_alignParentTop="true"
+        android:layout_toRightOf="@id/vr_status"
+        android:text="@string/vr_enable_service" />
+
+    <Button
+        android:id="@+id/vr_action_button"
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content"
+        android:layout_alignParentRight="true"
+        android:layout_below="@id/vr_instructions"
+        android:layout_marginLeft="20dip"
+        android:layout_marginRight="20dip"
+        android:layout_toRightOf="@id/vr_status"
+        android:onClick="actionPressed"
+        android:text="@string/vr_start_settings" />
+
+</RelativeLayout>
\ No newline at end of file
diff --git a/apps/CtsVerifier/res/layout/vr_main.xml b/apps/CtsVerifier/res/layout/vr_main.xml
new file mode 100644
index 0000000..9f6b31d
--- /dev/null
+++ b/apps/CtsVerifier/res/layout/vr_main.xml
@@ -0,0 +1,45 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+     Copyright (C) 2016 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.
+-->
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    android:orientation="vertical"
+    android:padding="10dip"
+    android:layout_width="match_parent"
+    android:layout_height="match_parent">
+
+    <ScrollView
+        android:id="@+id/vr_test_scroller"
+        android:layout_width="match_parent"
+        android:layout_height="0dp"
+        android:layout_weight="1"
+        android:orientation="vertical"
+        android:padding="10dip" >
+
+        <LinearLayout
+            android:id="@+id/vr_test_items"
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:orientation="vertical" >
+        </LinearLayout>
+    </ScrollView>
+
+    <include
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content"
+        android:layout_weight="0"
+        layout="@layout/pass_fail_buttons" />
+
+</LinearLayout>
\ No newline at end of file
diff --git a/apps/CtsVerifier/res/layout/widget_layout.xml b/apps/CtsVerifier/res/layout/widget_layout.xml
index 4e2a6b6..b0cce17 100644
--- a/apps/CtsVerifier/res/layout/widget_layout.xml
+++ b/apps/CtsVerifier/res/layout/widget_layout.xml
@@ -21,7 +21,7 @@
     android:layout_marginLeft="@dimen/widget_margin_left"
     android:layout_marginRight="@dimen/widget_margin_right"
     android:padding="1dp"
-    android:background="#2f2f2f">
+    android:background="#fff">
 
     <LinearLayout
         android:orientation="vertical"
@@ -32,7 +32,7 @@
         android:paddingBottom="12dp"
         android:paddingRight="12dp"
         android:layout_gravity="center"
-        android:background="#222">
+        android:background="#fff">
 
         <TextView
             android:id="@+id/title"
@@ -70,7 +70,7 @@
             android:layout_weight="1"
             android:layout_marginBottom="12dp"
             android:padding="1dp"
-            android:background="#333"
+            android:background="#fff"
             android:visibility="gone"/>
 
         <LinearLayout
diff --git a/apps/CtsVerifier/res/values/strings.xml b/apps/CtsVerifier/res/values/strings.xml
index 6ce5b20..52da8c4 100644
--- a/apps/CtsVerifier/res/values/strings.xml
+++ b/apps/CtsVerifier/res/values/strings.xml
@@ -13,7 +13,7 @@
      See the License for the specific language governing permissions and
      limitations under the License.
 -->
-<resources>
+<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="app_name">CTS Verifier</string>
 
     <string name="title_version">CTS Verifier %1$s</string>
@@ -52,6 +52,11 @@
     <!-- Strings for ReportViewerActivity -->
     <string name="report_viewer">Report Viewer</string>
 
+    <!-- String shared between BackupTestActivity and BackupAccessibilityTestActivity -->
+    <string name="bu_loading">Loading...</string>
+    <string name="bu_generate_error">Error occurred while generating test data...</string>
+    <string name="bu_settings">Settings</string>
+
     <!-- Strings for BackupTestActivity -->
     <string name="backup_test">Data Backup Test</string>
     <string name="backup_info">This test checks that data backup and automatic restore works
@@ -62,11 +67,9 @@
         \n\nPress the \"Generate Test Data\" to populate these values
         and then follow the on screen instructions to finish the test.
     </string>
+    <string name="bu_generate">Generate Test Data</string>
     <string name="bu_preferences">Preferences</string>
     <string name="bu_files">Files</string>
-    <string name="bu_loading">Loading...</string>
-    <string name="bu_generate">Generate Test Data</string>
-    <string name="bu_generate_error">Error occurred while generating test data...</string>
     <string name="bu_instructions">Random values for the preferences and files have been saved.
         \n\nFollow the instructions below to check that the data backup and restore works:
         \n\n1. Make sure backup and automatic restore are enabled in settings. Depending on the
@@ -79,7 +82,45 @@
         \n\n3. Uninstall the program: adb uninstall com.android.cts.verifier
         \n\n4. Reinstall the CTS Verifier and verify that the values are still the same.
     </string>
-    <string name="bu_settings">Settings</string>
+
+    <!-- Strings for BackupAccessibilityTestActivity -->
+    <string name="backup_accessibility_test">Backup Accessibility Settings Test</string>
+    <string name="backup_accessibility_info">This test checks that data backup and automatic restore
+        of Accessibility-related settings works properly. If backup and restore is working properly,
+        these values should be restored after running the backup manager, removing your Google
+        account, changing the accessibility settings values, and re-adding your Google account.
+        \n\nPress \"Generate Test Data\" to generate test values for accessibility settings and then
+        follow the on screen instructions to finish the test.
+    </string>
+    <string name="bua_settings">General Accessibility Settings</string>
+    <string name="bua_settings_color_correction">Color Correction Settings</string>
+    <string name="bua_settings_accessibility_services">Accessibility Service Settings</string>
+    <string name="bua_settings_captions">Captions Settings</string>
+    <string name="bua_settings_tts">TTS Settings</string>
+    <string name="bua_settings_system">Other System Settings</string>
+    <string name="bua_instructions">You will need two devices for this test.
+        \n\nFollow the instructions below to check that the data backup and restore of
+        accessibility-related settings works properly:
+        \n\n1. Make sure backup and automatic restore are enabled in settings. If you cannot find
+        the corresponding setting options on your device, run \"adb shell bmgr enable true\" to
+        enable the backup manager. You can check its status by executing \"adb shell bmgr enabled\".
+        You will also need to set a Google account as the backup account for the device.
+        \n\n2. Press \"Read Current Values\" and note the default values for the listed settings.
+        Values that are either \"0\" or \"null\" will appear in green. Note: Some default values are
+        neither \"0\", nor \"null\", so you still need to pay attention to the default setting
+        values that are not highlighted.
+        \n\n3. Change the values of the listed settings to something other than their default value.
+        \n\n4. Return to the CtsVerifier and press \"Read Current Values\". Make sure that you have
+        changed all of the settings.
+        \n\n5. Run the backup manager: adb shell bmgr run
+        \n\n6. Factory reset data on the second device. While going through the Setup Wizard,
+        restore all data from the account on your first device. When prompted, choose to restore all
+        settings from your first device.
+        \n\n7. Install CtsVerifier on your new device and make sure that the values read on the
+        second device match the values on your first device.
+    </string>
+    <string name="bua_show_instructions">Show Instructions</string>
+    <string name="bua_read_settings">Read Current Values</string>
 
     <!-- Strings for Device Administration tests -->
     <string name="da_policy_serialization_test">Policy Serialization Test</string>
@@ -374,6 +415,23 @@
         Make sure the device has line of sight to GPS satellites
         (for example, outside, or near a window)
         and then press OK to run the automated tests.</string>
+    <string name="location_listener_activity">Location listener</string>
+
+    <!-- Strings for Location GNSS tests -->
+    <string name="location_gnss_constellation_type_test">GNSS Measurement Constellation Test</string>
+    <string name="location_gnss_measure_no_location_test">GNSS Measurement WhenNoLocation Test</string>
+    <string name="location_gnss_reg_test">GNSS Measurement Registration Test</string>
+    <string name="location_gnss_value_test">GNSS Measurement Values Test</string>
+    <string name="location_gnss_nav_msg_test">GNSS Navigation Message Test</string>
+    <string name="location_gnss_test_info">This test verifies basic GNSS behavior.
+        Make sure the device has line of sight to GNSS satellites
+        (for example, stationary on a windowsill.  If needed, try again, outside, also with the
+        device stationary, and with at least some view of the sky.) and then press Next to run
+        the automated tests.</string>
+    <string name="location_gnss_test_retry_info">If this test fails, please make sure the device
+        has line of sight to GNSS satellites (for example, stationary on a windowsill. If needed,
+        try again, outside, also with the device stationary, with as much view of the sky as
+        possible.) </string>
 
     <!-- Strings for net.ConnectivityScreenOffTestActivity -->
     <string name="network_screen_off_test">Network Connectivity Screen Off Test</string>
@@ -467,8 +525,13 @@
     <string name="nfc_ndef_content">Id: %1$s\nMime: %2$s\nPayload: %3$s</string>
 
     <string name="nfc_hce">Host-based card emulation</string>
+    <string name="nfc_hce_f">Host-based Felica card emulation</string>
     <string name="nfc_hce_reader_tests">HCE reader tests</string>
+    <string name="nfc_hce_f_reader_tests">HCE Felica reader tests</string>
     <string name="nfc_hce_emulator_tests">HCE emulator tests</string>
+    <string name="nfc_hce_f_emulator_tests">HCE Felica emulator tests</string>
+    <string name="nfc_hce_f_emulator">HCE Felica emulator</string>
+    <string name="nfc_hce_f_reader">HCE Felica reader</string>
     <string name="nfc_hce_emulator_test_info">The host-based card emulation
         tests require two devices to be completed. The HCE emulator tests are used
         to actually test the host-based card emulation feature of the device-under-test. So the
@@ -524,7 +587,7 @@
     <string name="nfc_hce_foreground_payment_emulator">Foreground override payment services (Emulator)</string>
     <string name="nfc_hce_foreground_payment_reader">Foreground override payment services (Reader)</string>
     <string name="nfc_hce_foreground_payment_help">This test enables two payment services, and asks you to set one as the default service. It then uses Androids API to allow the foreground app to set a preference for the non-default service. This will cause the non-default payment service to be invoked.</string>
-    <string name="nfc_hce_change_favor_foreground">This test requires the "Favor foreground app" setting to be enabled. Tap OK to go to Tap and Pay settings and check the Favor foreground app option</string>
+    <string name="nfc_hce_change_favor_foreground">This test requires the \"Use default\" setting to be set to \"Except when another payment app is open\". Tap OK to go to Tap and Pay settings and make sure the \"Use default\" setting is set to \"Except when another payment app is open\".</string>
     <string name="nfc_hce_offhost_service_emulator">Off-host service (Emulator)</string>
     <string name="nfc_hce_offhost_service_reader">Off-host service (Reader)</string>
     <string name="nfc_hce_offhost_emulator_help">This tests enables a service that declares some AIDs to reside off-host. This test only needs to be passed if your device has a secure element (either embedded or UICC.). The responses from the secure element are not verified by the test - it is up to the tester to verify the responses are as expected.</string>
@@ -576,6 +639,7 @@
     <string name="transportService2">TransportService #2</string>
     <string name="accessService">AccessService</string>
     <string name="offhostService">OffhostService</string>
+    <string name="felicaservice">Felica Service</string>
 
     <!-- Strings for Sensor Test Activities -->
     <string name="snsr_device_admin_receiver">Sensor Tests Device Admin Receiver</string>
@@ -726,6 +790,9 @@
     <string name="snsr_sensor_test">CTS Sensor Test</string>
     <string name="snsr_sensor_batching_tests">CTS Sensor Batching Tests</string>
 
+    <!-- String for DynamicSensorDiscoveryTest -->
+    <string name="snsr_dynamic_sensor_discovery_test">Dynamic Sensor Discovery Test</string>
+
     <!-- Strings for Sample Test Activities -->
     <string name="share_button_text">Share</string>
     <string name="sample_framework_test">Sample Framework Test</string>
@@ -789,32 +856,32 @@
     1. Click Start Test. \n
     2. Go to home screen (HOME key). \n
     3. Launch Camera application. \n
-    4. Capture photo. \n
+    4. Capture photo within 1 minute. \n
     5. Return to CTS verifier app. \n
-    6. Pass button will light up if intent was received.\n
+    6. Pass button will light up if URI trigger was fired.\n
     7. Click "Pass" if possible.
     </string>
     <string name="ci_instruction_text_app_video_label">\n
     1. Click Start Test. \n
     2. Go to home screen (HOME key). \n
     3. Launch Camera application. \n
-    4. Capture video. \n
+    4. Capture video within 1 minute. \n
     5. Return to CTS verifier app. \n
-    6. Pass button will light up if intent was received.\n
+    6. Pass button will light up if URI trigger was fired.\n
     7. Click "Pass" if possible.
     </string>
     <string name="ci_instruction_text_intent_picture_label">\n
     1. Click Start Test.\n
     2. Camera app will launch, prompting to take photo.\n
-    3. Capture/confirm photo using camera app controls.\n
-    4. Pass button will light up if intent was NOT received.\n
+    3. Capture/confirm photo using camera app controls within 1 minute.\n
+    4. Pass button will light up if URI trigger was NOT received.\n
     5. Click "Pass" if possible.
     </string>
     <string name="ci_instruction_text_intent_video_label">\n
     1. Click Start Test.\n
     2. Camera app will launch, prompting to take video.\n
-    3. Capture/confirm video using camera app controls.\n
-    4. Pass button will light up if intent was received.\n
+    3. Capture/confirm video using camera app controls within 1 minute.\n
+    4. Pass button will light up if URI trigger was received.\n
     5. Click "Pass" if possible.
     </string>
     <string name="ci_start_test_button_caption">Start Test</string>
@@ -892,6 +959,15 @@
     <string name="usb_test_passed">Test passed, pass button enabled! You can interact with the device again.</string>
     <string name="usb_file_descriptor_error">Could not open file descriptor for USB accessory... try reconnecting and restarting the accessory?</string>
 
+    <!-- Strings for MTP host test activity -->
+    <string name="mtp_host_test">MTP Host Test</string>
+    <string name="mtp_host_test_info">The CTS-verifier tests the MTP host feature with another Android device. Please connect another Android device to this Android device by using OTG cable or USB type C cable, then follow the instructions on this screen. Note the test creates/deletes files in the connected Android device.</string>
+    <string name="mtp_host_device_lookup_message">Connect MTP device.\nPlease connect another Android device to this device by using USB OTG cable or USB type C cable.\nOpen \"Use USB for\" dialog from the notification in the other Android device and choose \"File Transfer\" option.\nThen press the next button.</string>
+    <string name="mtp_host_grant_permission_message">Grant permission.\nReply a dialog asking device permission.</string>
+    <string name="mtp_host_test_read_event_message">Test MtpDevice#readEvent.\nTake a picture at the connected device.</string>
+    <string name="mtp_host_test_send_object_message">Test MtpDevice#sendObject.</string>
+    <string name="mtp_host_test_notification_message">Test MTP notification.\nCheck if there is an notification on this device saying the other MTP device is connected to this device. Also check if it opens the UI to browse files in the connected device by tapping the notification.</string>
+
     <!-- Strings for the Camera ITS test activity -->
     <string name="camera_its_test">Camera ITS Test</string>
     <string name="camera_its_test_info">
@@ -973,23 +1049,28 @@
     <string name="p2p_service_discovery_requester">Service Discovery Requester</string>
 
     <string name="p2p_go_neg_responder_info">
-        Start the \"GO Negotiation Requester Test\" on the other device and follow
+        Go to the Wi-Fi settings and forget all remembered networks.  Then
+        start the \"GO Negotiation Requester Test\" on the other device and follow
         the instructions.</string>
     <string name="p2p_accept_client_info">
-        Start the \"Group Client Test\" on the other device and follow
+        Go to the Wi-Fi settings and forget all remembered networks.  Then
+        start the \"Group Client Test\" on the other device and follow
         the instructions.</string>
     <string name="p2p_service_discovery_responder_info">
         Start the \"Service Discovery Requester Test\" on the other device and follow
         the instructions.</string>
 
     <string name="p2p_go_neg_requester_info">
-        Start the \"GO Negotiation Responder Test\" on the other device.
+        Go to the Wi-Fi settings and forget all remembered networks.  Then
+        start the \"GO Negotiation Responder Test\" on the other device.
         Then run each test individually by clicking on it\'s name.</string>
     <string name="p2p_join_go_info">
-        Start the \"Group Owner Test\" on the other device.
+        Go to the Wi-Fi settings and forget all remembered networks.  Then
+        start the \"Group Owner Test\" on the other device.
         Then run each test individually by clicking on it\'s name.</string>
     <string name="p2p_service_discovery_requester_info">
-        Start the \"Service Discovery Responder Test\" on the other device.
+        Go to the Wi-Fi settings and forget all remembered networks.  Then
+        start the \"Service Discovery Responder Test\" on the other device.
         Then run each test individually by clicking on it\'s name.</string>
 
     <string name="p2p_not_enabled">Wi-Fi is not enabled</string>
@@ -1000,18 +1081,21 @@
     <string name="p2p_result_success">Test passed successfully.</string>
 
     <string name="p2p_go_neg_responder_ready">
-        The go negotiation responder is now ready to start. Start
-        the \"GO Negotiation Requester Test\" on the other device.
+        The go negotiation responder is now ready to start.
+        Go to the Wi-Fi settings and forget all remembered networks.  Then
+        start the \"GO Negotiation Requester Test\" on the other device.
         Keep the screen here until all tests on the other device are
         finished.</string>
     <string name="p2p_go_ready">
-        The group owner is now ready to start. Start the \"Join
-        Group Test\" on the other device.
+        The group owner is now ready to start.
+        Go to the Wi-Fi settings and forget all remembered networks.  Then
+        start the \"Join Group Test\" on the other device.
         Keep the screen here until all tests on the other device are
         finished.</string>
     <string name="p2p_service_responder_ready">
-        The service responder is now ready to start. Start the
-        \"Service Discovery Requester Test\" on the other device.
+        The service responder is now ready to start.
+        Go to the Wi-Fi settings and forget all remembered networks.  Then
+        start the \"Service Discovery Requester Test\" on the other device.
         Keep the screen here until all tests on the other device are
         finished.</string>
 
@@ -1112,8 +1196,8 @@
         user preferences about relative package priorities.
     </string>
     <string name="package_priority_bot">Verifying that the CTS Robot helper package is installed.</string>
-    <string name="package_priority_high">Find \"%s\" under \"App notifications\" in the \"Sound &amp; notifications\" settings panel, and mark it as having notification priority.</string>
-    <string name="package_priority_default">Find \"%s\" under \"App notifications\" in the \"Sound &amp; notifications\" settings panel, and make sure it has default priority.</string>
+    <string name="package_priority_high">Find \"%s\" in the \"Notifications\" settings panel, and allow it to Override Do Not Disturb.</string>
+    <string name="package_priority_default">Find \"%s\" in the \"Notifications\" settings panel, and disallow it to Override Do Not Disturb.</string>
     <string name="package_priority_user_order">Check that ranker respects user priorities.</string>
 
     <string name="attention_test">Notification Attention Management Test</string>
@@ -1136,7 +1220,7 @@
     <string name="attention_email_order">Check that ranker respects mailto URIs for contacts.</string>
     <string name="attention_phone_order">Check that ranker respects telephone URIs for contacts.</string>
     <string name="attention_interruption_order">Check that ranker temporarily boosts interruptions.
-    This test takes 15 seconds to complete.</string>
+    This test takes 30 seconds to complete.</string>
     <string name="attention_none_are_filtered">Check that \"All\" mode doesn\'t filter any notifications.</string>
     <string name="attention_some_are_filtered">Check that \"Priority\" mode doesn\'t filter priority notifications.</string>
     <string name="attention_all_are_filtered">Check that \"None\" mode filters all notifications.</string>
@@ -1146,10 +1230,27 @@
         and disabled, and that once enabled the service is able to receive notifications and
         dismiss them.
     </string>
+    <string name="vr_tests">VR Tests</string>
+    <string name="test_category_vr">VR</string>
+    <string name="vr_test_title">VR Listener Test</string>
+    <string name="vr_service_name">VR Listener for CTS Verifier</string>
+    <string name="vr_info">This test checks that a VrListenerService can be enabled and disabled, and
+        and that it receives the correct lifecycle callbacks when entering and exiting VR mode.
+    </string>
+    <string name="vr_start_settings">Launch Settings</string>
+    <string name="vr_start_vr_activity">Launch VR mode activity</string>
+    <string name="vr_start_double_vr_activity">Launch Two VR mode activities</string>
+    <string name="vr_start_vr_activity_desc">Click the button to launch the VR mode activity.</string>
+    <string name="vr_start_vr_double_activity_desc">Click the button to launch two consecutive VR mode activities.</string>
+    <string name="vr_check_disabled">Check that the CTS VR helper service is disabled by default.</string>
+    <string name="vr_enable_service">Please enable \"VR Listener for CTS Verifier\"
+        under Apps > Gear Icon > Special Access > VR Helper Services and return here.</string>
+        <string name="vr_disable_service">Please disable \"VR Listener for CTS Verifier\"
+        under Apps > Gear Icon > Special Access > VR Helper Services and return here.</string>
     <string name="nls_enable_service">Please enable \"Notification Listener for CTS Verifier\"
-        under Security > Notification Access and return here.</string>
+        under Apps > Gear Icon > Special Access > Notification Access and return here.</string>
     <string name="nls_disable_service">Please disable \"Notification Listener for CTS Verifier\"
-        under Security > Notification Access and return here.</string>
+        under Apps > Gear Icon > Special Access > Notification Access and return here.</string>
     <string name="nls_start_settings">Launch Settings</string>
     <string name="nls_service_started">Service should start once enabled.</string>
     <string name="nls_note_received">Check that notification was received.</string>
@@ -1158,6 +1259,23 @@
     <string name="nls_clear_all">Check that service can clear all notifications.</string>
     <string name="nls_service_stopped">Service should stop once disabled.</string>
     <string name="nls_note_missed">Check that notification was not received.</string>
+    <string name="cp_test">Condition Provider test</string>
+    <string name="cp_service_name">Condition Provider for CTS Verifier</string>
+    <string name="cp_info">This test checks that a ConditionProviderService can be enabled
+        and disabled, and that once enabled the service is able to create, query, edit, and delete
+        automatic zen rules.
+    </string>
+    <string name="cp_enable_service">Please enable \"CTS Verifier\" under Do Not Disturb access and return here.</string>
+    <string name="cp_disable_service">Please disable \"CTS Verifier\" under Do Not Disturb access and return here.</string>
+    <string name="cp_start_settings">Launch Settings</string>
+    <string name="cp_create_rule">Creating Automatic Zen Rule</string>
+    <string name="cp_subscribe_rule">Subscribing to Automatic Zen Rule</string>
+    <string name="cp_service_started">Service should start once enabled.</string>
+    <string name="cp_service_stopped">Service should stop once disabled.</string>
+    <string name="cp_unsubscribe_rule">Unsubscribing to Automatic Zen Rule</string>
+    <string name="cp_delete_rule">Deleting Automatic Zen Rule</string>
+    <string name="cp_get_rules">Retrieving Automatic Zen Rules</string>
+    <string name="cp_get_rule">Retrieving Automatic Zen Rule</string>
 
     <string name="location_mode_high_accuracy_test">High Accuracy Mode Test</string>
     <string name="location_mode_high_accuracy_info">
@@ -1216,7 +1334,11 @@
     <string name="cacert_done">Done</string>
     <string name="cacert_install_cert">Use the CertInstaller to install the certificate. When it opens, just tap "Okay". If this button does nothing, pass the test and move on.</string>
     <string name="cacert_check_cert_in_settings">Visit the user-installed trusted credentials page and confirm that the "Internet Widgits Pty Ltd" cert appears in the list.</string>
-    <string name="cacert_check_notification">Please look at the new notification and confirm: It say the network may be monitored. Tapping it brings up a more detailed explanation and a button to check trusted credentials. Tapping that button brings up the Trusted Credentials page you just visited.</string>
+    <string name="cacert_remove_screen_lock">You may have been prompted to set a screen lock when installing the certificate. If so, remove it. If not, you may skip this step.</string>
+    <string name="cacert_check_notification">Look at the system notifications. Confirm that:\n
+1. There is a notification saying a certificate authority is installed.\n
+2. Tapping that notification brings up a more detailed explanation and a button to check trusted credentials.\n
+3. Tapping that button brings up the Trusted Credentials page you just visited.</string>
     <string name="cacert_dismiss_notification">Dismiss the notification. If it cannot be dismissed, fail the test.</string>
 
     <string name="caboot_test">CA Cert Notification on Boot test</string>
@@ -1234,14 +1356,14 @@
     <string name="keychain_reset">Reset</string>
     <string name="keychain_skip">Skip</string>
     <string name="keychain_setup_desc">The first step sets up an internal KeyStore and generates credentials to use for the remainder of the test.\n\n
- Touch \'Next\' to begin.</string>
-    <string name="keychain_install_desc">Credentials generated. Touch \'Next\' to install them to the system keychain.\n\n
+ Tap \'Next\' to begin.</string>
+    <string name="keychain_install_desc">Credentials generated. Tap \'Next\' to install them to the system keychain.\n\n
 The container for the credentials will not be protected with a password; if prompted for one, leave that field blank.\n\n
 During installation you may be prompted for a name - accept the default suggestion.\n\n
 In the case that these credentials were already installed, you may skip this step.</string>
     <string name="keychain_https_desc">The last test involves setting up an HTTPS connection using credentials from the KeyChain.\n\n
 You should be prompted to select credentials; choose the ones you just installed in the previous step.</string>
-    <string name="keychain_reset_desc">Before marking this test as passed, touch \'Next\' to open security settings and reset the following items:\n
+    <string name="keychain_reset_desc">Before marking this test as passed, tap \'Next\' to open security settings and reset the following items:\n
  1. Clear device credentials.\n
  2. Change the lock screen type to \'None\'.</string>
 
@@ -1321,6 +1443,29 @@
     <string name="provisioning_byod_lockscreen_bound_key">Lockscreen-bound key test</string>
     <string name="provisioning_byod_fingerprint_bound_key">Fingerprint-bound key test</string>
     <string name="provisioning_byod_vpn">Vpn test</string>
+    <string name="provisioning_byod_select_work_challenge">Select work lock test</string>
+    <string name="provisioning_byod_select_work_challenge_description">
+        This test verifies that a work lock can be chosen.\n
+
+        1. Verify that you get sent to the page for Choosing a new work lock.\n
+        2. Set a new work lock.
+    </string>
+    <string name="provisioning_byod_confirm_work_credentials">Confirm work lock test</string>
+    <string name="provisioning_byod_confirm_work_credentials_description">
+        This test verifies that work lock is shown when opening a work app,
+        the work lock was set correctly and it is customized according to
+        the policies set. You can only do this test after you have done the previous test.\n
+
+        1. Open a work app.\n
+        2. Verify that a screen asking you for your work credentials is shown.\n
+        3. Verify that the background image contains an orange suitcase.\n
+        4. Verify that the background color of the remaining image is blue.\n
+        5. Verify that the header text says \"CtsVerifier\".\n
+        6. Confirm your credentials and verify that the credentials you entered previously work.
+    </string>
+    <string name="provisioning_byod_confirm_work_credentials_header">
+        CtsVerifier
+    </string>
     <!-- Strings for DeskClock -->
     <string name="deskclock_tests">Alarms and Timers Tests</string>
     <string name="deskclock_tests_info">
@@ -1417,12 +1562,10 @@
     <string name="pwa_info">This tests whether or displaying widets and keyfocus navigation works.\n
         You should see four buttons on the bottom of the screen.\n
         Pressing the "up" and "down" buttons should highlight different buttons.\n
-        Further, you should also be able to touch them and they should highlight as usual.</string>
+        Furthermore, the highlight should disappear when any button is touched, and the touched button should behave as usual.\n</string>
     <string name="pwa_test">Projection Widget Test</string>
     <string name="pwa_button_up">Up</string>
     <string name="pwa_button_down">Down</string>
-    <string name="pwa_button_left">Left</string>
-    <string name="pwa_button_right">Right</string>
     <string name="pwa_button">Button</string>
     <string name="pla_test">Projection Scrolling List Test</string>
     <string name="pla_info">This tests whether a projected list view will scroll properly\n
@@ -1473,7 +1616,22 @@
     <!-- Strings common for BYOD and DO managed provisioning tests. -->
     <string name="afw_device_admin">CTS Verifier</string>
 
-    <!-- Strings for BYOD managed provisioning tests (ByodFlowTestActivity) -->
+    <string name="provisioning_tests_byod">BYOD Provisioning tests</string>
+
+    <string name="provisioning_tests_byod_custom_color"> Custom provisioning color </string>
+    <string name="provisioning_tests_byod_custom_color_info">
+        Please press the Go button to start the provisioning.
+        Check that provisioning is colorized in green.
+        Then hit back and stop the provisioning.
+    </string>
+    <string name="provisioning_tests_byod_custom_image"> Custom provisioning image </string>
+    <string name="provisioning_tests_byod_custom_image_info">
+        Please press the Go button to start the provisioning.
+        Check that the CtsVerifier logo is displayed at the top of the page.
+        Then hit back and stop the provisioning.
+    </string>
+
+    <!-- Strings for BYOD managed provisioning (ByodFlowTestActivity) -->
     <string name="test_category_managed_provisioning">Managed Provisioning</string>
     <string name="provisioning_byod">BYOD Managed Provisioning</string>
     <string name="provisioning_byod_info">
@@ -1540,10 +1698,13 @@
     <string name="provisioning_byod_keyguard_disabled_features_instruction">
         Please go to Settings &gt; Security &gt; Device administrators and set
         \"CTS Verifier\" as active admin.\n
-        After that please press the \"Prepare test\" button to disable trust agents.\n
+        After that please go to Settings &gt; Security &gt; Screen lock and set
+        your screen lock password to \"testpassword\".\n
+        Then please press the \"Prepare test\" button to disable trust agents.\n
         Then please press through the following verification steps.\n
-        Note: Device password will be set to \"testpassword\". After leaving the screen device
-        password and active admin status will be cleared.
+        Note: After leaving the screen active admin status will be cleared.
+        Please go to Settings &gt; Security &gt; Screen lock and set your
+        password type to \"None\".
     </string>
     <string name="provisioning_byod_keyguard_disabled_features_prepare_button">Prepare test</string>
     <string name="provisioning_byod_keyguard_disabled_features_not_admin">CtsVerifier is not active admin. Please follow instructions.</string>
@@ -1570,7 +1731,7 @@
     <string name="provisioning_byod_disable_unredacted_notifications_instruction">
         Please press the Go button to lock the screen. Wait a couple of seconds and look out for a
         notification from CtsVerifier.\n
-        Expected result is the notification is shown as \"Contents hidden\", you can not see the contents
+        Expected result is the notification is shown as \"Contents hidden by policy\", you can not see the contents
         (Which would read \"This is a notification\"). You should be seeing a work badge.\n
         After you log back in, please navigate back to CtsVerifier and mark the test as \"Pass\" or \"Fail\".
     </string>
@@ -1594,20 +1755,17 @@
     <string name="provisioning_byod_disallow_apps_control_prepare_button">Prepare test</string>
     <string name="provisioning_byod_disabled_uninstall_button">Disabled uninstall button</string>
     <string name="provisioning_byod_disabled_uninstall_button_instruction">
-        Please press the Go button to go to Settings > Apps. Choose a managed app. Check if the button that says
-        either \"Uninstall\" or \"Disable\" is greyed out and disabled, i.e. nothing happens when you tap on it.
+        Please press the Go button to go to Settings > Apps. Choose a managed app. Check that performing either \"Uninstall\" or \"Disable\" is not possible and triggers a support message when trying to do so.
         Then please press Back and mark the test as \"Pass\" or \"Fail\".
     </string>
     <string name="provisioning_byod_disabled_force_stop_button">Disabled force stop button</string>
     <string name="provisioning_byod_disabled_force_stop_button_instruction">
-        Please press the Go button to go to Settings > Apps. Choose a managed app. Check if the button that says
-        \"Force stop\" is greyed out and disabled, i.e. nothing happens when you tap on it.
+        Please press the Go button to go to Settings > Apps. Choose a managed app. Check that performing \"Force stop\" is not possible and triggers a support message when trying to do so.
         Then please press Back and mark the test as \"Pass\" or \"Fail\".
     </string>
     <string name="provisioning_byod_disabled_app_storage_buttons">Disabled app storage buttons</string>
     <string name="provisioning_byod_disabled_app_storage_buttons_instruction">
-        Please press the Go button to go to Settings > Apps. Choose a managed (badged) app. Select \"Storage\". Check that the buttons
-        \"Clear Data\" and \"Clear Cache\" are disabled, i.e. nothing happens when you tap on them.
+        Please press the Go button to go to Settings > Apps. Choose a managed (badged) app. Select \"Storage\". Check that performing \"Clear Data\" and \"Clear Cache\" is not possible and triggers a support message when trying to do so.
         Note: if an app has no data then tapping the clear data button has no effect anyway. Make sure you have selected
         the badged version of app with non-zero app data. Badged \"Settings\" may be a good candidate.
         Then please press Back and mark the test as \"Pass\" or \"Fail\".
@@ -1657,8 +1815,8 @@
         Navigate to Device administrators and confirm that:\n
         \n
         - Device administrators outside of the work profile (if any) appear in the list, and the managed profile administrators are badged correctly.\n
-        - \"CTS Verifier\" exists under the Work category, and is activated.\n
-        - Attempting to uncheck badged \"CTS Verifier\" shows an alert dialog informing you that this admin can be deactivated only if you remove the managed profile.\n
+        - A badged \"CTS Verifier\" exists, and is activated.\n
+        - Attempting to uncheck the badged \"CTS Verifier\" shows a page allowing the user to remove the managed profile.\n
         \n
         Use the Back button to return to this page.
     </string>
@@ -1686,30 +1844,35 @@
     <string name="provisioning_byod_location_settings_instruction">
         Please press the Go button to open Location page in settings.\n
         \n
-        Verify that work profile entry exists in the page.\n
+        Verify that work profile entry exists in the page and it has a toggleable switch.\n
+        Switch the main location switch at the top of the screen off. You should see the work profile location switch go disabled and into \'off\' state.\n
+        Then switch the main location switch on again. You should see the work profile location switch go enabled and into its previous state.\n
         \n
         Then use the Back button to return to this test and mark accordingly.
     </string>
 
-    <string name="provisioning_byod_battery_settings">Profile-aware battery settings</string>
-    <string name="provisioning_byod_battery_settings_instruction">
-        Please press the Go button to open Battery page in settings.\n
-        \n
-        Verify that Battery page shows both badged and unbadged apps in the usage list.\n
-        \n
-        Note that the usage list only displays usage since last charge,
-        so you may need to unplug your device and use a badged and unbadged app
-        for a little while before they will appear in the list.\n
-        \n
-        Then use the Back button to return to this test and mark accordingly.
-    </string>
-
-    <string name="provisioning_byod_data_usage_settings">Profile-aware data usage settings</string>
-    <string name="provisioning_byod_data_usage_settings_instruction">
+    <string name="provisioning_byod_wifi_data_usage_settings">Profile-aware data usage settings (Wi-Fi)</string>
+    <string name="provisioning_byod_wifi_data_usage_settings_instruction">
         Please press the Go button to open the Settings page.\n
         \n
-        Navigate to Data usage page and confirm that it includes a Work profile section,
-        and that tapping it shows just work profile data usage.\n
+        Navigate to \"Data usage\" page and then into the \"Wi-Fi data usage\" category.\n
+        Confirm that \"All work apps\" section is present and that the list includes badged apps.\n
+        Confirm that tapping on \"All work apps\" section shows a list of only work profile apps data usage.\n
+        \n
+        Then use the Back button to return to this test and mark accordingly.
+    </string>
+
+    <string name="provisioning_byod_cellular_data_usage_settings">Profile-aware data usage settings (Cellular)</string>
+    <string name="provisioning_byod_cellular_data_usage_settings_instruction">
+        Please disable Wi-Fi connection on your device.\n
+        Please make sure you have added a SIM card with data plan to your phone, have enabled data over cellular and in case of dual SIM devices, have selected the right SIM for data connection.\n
+        Please carry out operations that will use mobile data using both badged and unbadged apps (e.g. visit a page in a browser).\n
+        \n
+        Please press the Go button to open the Settings page.\n
+        \n
+        Navigate to \"Data usage\" page and then into the \"Cellular data usage\" category.\n
+        Confirm that \"All work apps\" section is present and that the list includes badged apps.\n
+        Confirm that tapping on \"All work apps\" section shows a list of only work profile apps data usage.\n
         \n
         Then use the Back button to return to this test and mark accordingly.
     </string>
@@ -1771,7 +1934,7 @@
     <string name="provisioning_byod_location_mode_enable_toast_location_change">Location changed</string>
     <string name="provisioning_byod_location_mode_enable_instruction">
         This test verifies that the location updates can be enabled for the managed profile apps.\n
-        1. Press the go button to go to the location settings page, set the location switch enabled.\n
+        1. Press the go button to go to the location settings page, set both the main location switch and the work profile location switch enabled.\n
         2. Move your position a little bit, verify that location updates toast comes up.\n
         Please wait until the location updates or timeout toast message shows up before going back to the cts-verifier tests.\n
         3. Go back to the cts-verifier tests using the back button, then mark the test accordingly.\n
@@ -1780,13 +1943,104 @@
     <string name="provisioning_byod_location_mode_disable">Disable location</string>
     <string name="provisioning_byod_location_mode_time_out_toast">Timeout waiting for gps location change</string>
     <string name="provisioning_byod_location_mode_disable_instruction">
-        This test verifies that the location updates can be disabled for the managed profile apps.\n
-        1. Press the go button to go to the location settings page, set the location switch disabled.\n
+        This test verifies that the location updates can be disabled for the managed profile apps through the main location switch.\n
+        1. Press the go button to go to the location settings page, set the main location switch disabled.\n
         2. Move your position a little bit, verify that no location updates toast come up and that the timeout message show up after around 15 seconds.
         Please wait until the timeout or location updates toast message shows up before going back to the cts-verifier tests.\n
         3. Go back to the cts-verifier tests using the back button, then mark the test accordingly.\n
     </string>
 
+    <string name="provisioning_byod_work_location_mode_disable">Disable location for work profile</string>
+    <string name="provisioning_byod_work_location_mode_disable_instruction">
+        This test verifies that the location updates can be disabled for the managed profile apps through work profile location switch.\n
+        1. Press the go button to go to the location settings page, set the work location switch disabled while the main location switch is still enabled.\n
+        2. Move your position a little bit, verify that no location updates toast come up and that the timeout message show up after around 15 seconds.
+        Please wait until the timeout or location updates toast message shows up before going back to the cts-verifier tests.\n
+        3. Go back to the cts-verifier tests using the back button, then mark the test accordingly.\n
+    </string>
+    <string name="provisioning_byod_primary_location_when_work_disabled">Primary receives updates while work location is disabled</string>
+    <string name="provisioning_byod_primary_location_when_work_disabled_instruction">
+        This test verifies that location updates are still received by primary profile when location updates are disabled for managed profile apps through work profile location switch.\n
+        1. Press the go button to go to the location settings page, set the work location switch disabled while the main location switch is still enabled.\n
+        2. Move your position a little bit, verify that location updates toast comes up.\n
+        Please wait until the location updates or timeout toast message shows up before going back to the cts-verifier tests.\n
+        3. Go back to the cts-verifier tests using the back button, then mark the test accordingly.\n
+    </string>
+
+    <string name="provisioning_byod_turn_off_work">Turn off work mode</string>
+    <string name="provisioning_byod_turn_off_work_info">This test verifes device behaviours when turning off work mode.</string>
+    <string name="provisioning_byod_turn_off_work_instructions">
+        This test verifies the device behaviour when work profile is turned off.\n
+        Please exercise the following tests in sequence.\n
+        The button below can be used to open the Settings page where you can toggle work mode.
+    </string>
+    <string name="provisioning_byod_turn_off_work_prepare_button">Open Settings to toggle work mode</string>
+
+    <string name="provisioning_byod_turn_off_work_prepare_notifications">Prepare a work notification</string>
+    <string name="provisioning_byod_turn_off_work_prepare_notifications_instruction">
+        This is a test setup step.\n
+        1. Press the go button to send a work notification.\n
+        2. Verify that the notification is displayed and mark this test as passed.\n
+        (Note: in the following test, you will be asked to verify the notification disappears after work mode is turned off.)
+    </string>
+
+    <string name="provisioning_byod_turn_off_work_turned_off">Please turn off work mode</string>
+    <string name="provisioning_byod_turn_off_work_turned_off_toast">Open settings to turn off work mode, using the button above.</string>
+
+    <string name="provisioning_byod_turn_off_work_notifications">Notifications when work mode is off</string>
+    <string name="provisioning_byod_turn_off_work_notifications_instruction">
+        Verify that the previously-shown work notification has now disappeared.
+    </string>
+
+    <string name="provisioning_byod_turn_off_work_icon">Status bar icon when work mode is off</string>
+    <string name="provisioning_byod_turn_off_work_icon_instruction">
+        Now that work mode is off, please verify that the status bar shows an icon indicating that work mode is off.\n
+    </string>
+
+    <string name="provisioning_byod_turn_off_work_launcher">Starting work apps when work mode is off</string>
+    <string name="provisioning_byod_turn_off_work_launcher_instruction">
+        This test verifies that work applications cannot be started if work mode is off.\n
+        1. Press home to go to the launcher.\n
+        2. Verify that work applications are greyed out.\n
+        3. Tap on a work application.\n
+        4. Verify that the application does not start.\n
+    </string>
+
+    <string name="provisioning_byod_turn_off_work_turned_on">Please turn work mode back on</string>
+    <string name="provisioning_byod_turn_off_work_turned_on_toast">Open settings to turn work mode back on, using the button above.</string>
+
+    <string name="provisioning_byod_turn_on_work_icon">Status bar icon when work mode is on</string>
+    <string name="provisioning_byod_turn_on_work_icon_instruction">
+        Now that work mode is back on, please verify that the status bar icon for work mode off is no longer visible.
+    </string>
+
+    <string name="provisioning_byod_turn_on_work_launcher">Starting work apps when work mode is on</string>
+    <string name="provisioning_byod_turn_on_work_launcher_instruction">
+        Now that work mode is back on, please go to the launcher and verify that you can start a work application.
+    </string>
+
+    <string name="provisioning_byod_organization_info">Organization Info</string>
+    <string name="provisioning_byod_organization_name_hint">Name</string>
+    <string name="provisioning_byod_organization_color_hint">#FF00FF</string>
+    <string name="provisioning_byod_set_organization_info_button_text">Set</string>
+    <string name="provisioning_byod_organization_info_instructions">
+    This test verifies that the Organization Info was set correctly.
+    You can only do this test after you have done "select work lock" test.\n
+        1. Enter your organization name.\n
+        2. Enter a valid color code.\n
+        3. Press the Set button to set organization Info.\n
+        4. Press the Go button to open a dialog to confirm work credentials.\n
+        5. Verify that the background color of the resulting dialog is as set by you.\n
+        6. Verify that the header text has organization name as set by you.\n
+    </string>
+    <string name="provisioning_byod_parent_profile_password">Personal password test</string>
+    <string name="provisioning_byod_parent_profile_password_description">
+        This test verifies that the password on the personal side can be chosen from within a managed profile.\n
+
+        1. Press the Go button to set a new password for the personal side.\n
+        2. Lock and unlock the screen to verify that the personal side password was set correctly.\n
+    </string>
+
     <!-- Strings for DeviceOwnerProvisioningTest -->
     <string name="provisioning_device_owner">Device Owner Provisioning</string>
     <string name="device_owner_provisioning_tests">Device Owner provisioning tests</string>
@@ -1897,9 +2151,9 @@
     <string name="device_profile_owner_permission_lockdown_test_instructions">
             Select each of the three grant states for the permission shown below in turn.\n
             Now open application settings, select Permissions, and verify if the following behaviour is observed.\n
-            <b>Allow:</b> Permission is granted to the app and cannot be changed through the settings UI.\n
+            <b>Allow:</b> Permission is granted to the app and cannot be changed through the settings UI. Trying to change it triggers a support message.\n
             <b>Let user decide:</b> Permission state can be changed through the settings UI.\n
-            <b>Deny:</b> Permission is denied to the app and cannot be changed through the settings UI.\n
+            <b>Deny:</b> Permission is denied to the app and cannot be changed through the settings UI. Trying to change it triggers a support message.\n
             Please mark the test accordingly.
     </string>
     <string name="device_owner_permission_lockdown_test_info">
@@ -1907,13 +2161,22 @@
     </string>
     <string name="device_owner_disallow_usb_file_transfer_test">Disallow USB file transfer</string>
     <string name="device_owner_disallow_usb_file_transfer_test_info">
-            Please press below button to set the \"disallow USB file transfer\" restriction.
+            Please press below button to set the \"disallow USB file transfer\" restriction.\n
             Next, connect your device to your desktop computer through USB, open the USB notification from the status bar
-            and check that the \"Transfer files (MTP)\" and \"Transfer photos (PTP)\" options are not present. Also, check
-            that you can download files from your phone to the desktop computer. The test is successful if the files from
-            your phone are not and cannot be downloaded through USB.\n
+            and check that the \"Transfer files (MTP)\" and \"Transfer photos (PTP)\" cannot be selected and triggers a support message when trying to select them.\n
+            Also, check that if you can download files from your phone to the desktop computer. The test is successful if the files from your phone are not and cannot be downloaded through USB.\n
             Please mark the test accordingly.
     </string>
+    <string name="device_owner_set_user_icon">Setting the user icon</string>
+    <string name="device_owner_set_user_icon_instruction">
+        This test verifies that the user icon can be set.\n
+        1. Press the set user icon button.\n
+        2. Press the go button to go to Settings.\n
+        3a. If there is a \"users\" section in Settings, check that the icon of the user \"owner\" is the CtsVerifier one and mark this test accordingly.\n
+        3b. If there is no \"users\" section, mark this test as passed.\n
+    </string>
+    <string name="device_owner_set_user_icon_button">Set user icon</string>
+
     <string name="profile_owner_permission_lockdown_test_info">
         <b>
         Before proceeding, check if com.android.cts.permissionapp (aka CtsPermissionApp) is installed in work profile by going to Settings &gt; Apps. If not, please install the app before proceeding.\n\n
@@ -1946,7 +2209,7 @@
         Confirm that:\n
         \n
         - You cannot view Bluetooth devices in range.\n
-        - You cannot edit, add or remove any already paired devices.\n
+        - Trying to edit, add or remove any already paired devices triggers a support message.\n
         \n
         Use the Back button to return to this page.
     </string>
@@ -1957,7 +2220,19 @@
         Confirm that:\n
         \n
         - You cannot view WiFi networks in range.\n
-        - You cannot edit, add or remove any existing WiFi configs.\n
+        - Trying to edit, add or remove any existing WiFi configs triggers a support message.\n
+        \n
+        Use the Back button to return to this page.
+    </string>
+    <string name="device_owner_disallow_data_roaming">Disallow data roaming</string>
+    <string name="device_owner_disallow_data_roaming_info">
+        Device should have a sim card to perform this test.
+        Please press the Set restriction button to set the user restriction.
+        Then press Go to open the Cellular network page in Settings.
+        Confirm that:\n
+        \n
+        - Data roaming is disabled.\n
+        - Enabling data roaming is not possible and triggers a support message.\n
         \n
         Use the Back button to return to this page.
     </string>
@@ -1993,13 +2268,229 @@
         1. Press Go to open the Vpn settings page.\n
         Confirm that:\n
         - You cannot add a new VPN network.\n
-        - You cannot edit, add or remove any existing VPNs.\n\n
+        - You cannot edit, add or remove any existing VPNs.\n
+        - Trying to perform any of the above actions will trigger a support message.\n\n
         2. Press Check VPN to check programmatic Vpn test.\n
         - Check Vpn setup\n\n
         Use the Back button to return to this page.
     </string>
     <string name="device_owner_user_vpn_restriction_set">Set VPN restriction</string>
 
+    <!-- Strings for DeviceOwnerBugreportTest -->
+    <string name="device_owner_requesting_bugreport_tests">Device Owner Requesting Bugreport Tests</string>
+    <string name="device_owner_requesting_bugreport_category">Device Owner Requesting Bugreport Tests</string>
+    <string name="device_owner_requesting_bugreport_tests_info">
+            The device owner requesting bugreport tests verify that a bugreport can be requested on a corporate owned device.\n
+            Press below button first, follow steps described in the dialog that pops up,
+            then proceed to the test cases.\n
+            Pressing \'back\', \'pass\' or \'fail\' on this test page will remove the device owner.\n
+            Alternatively, you can run the \'Remove device owner\' test. Ideally, that test should
+            be run last so that it does not interfere with other tests.
+    </string>
+    <string name="device_owner_request_bugreport">Request bugreport</string>
+    <string name="bugreport_sharing_declined">Bugreport sharing declined</string>
+    <string name="bugreport_shared_successfully">Bugreport shared successfully</string>
+    <string name="bugreport_already_in_progress">Bugreport is already being collected on this device</string>
+    <string name="bugreport_failed_completing">Bugreport collection operation failed</string>
+    <string name="device_owner_bugreport_sharing_declined_while_being_taken">Sharing of requested bugreport declined while being taken</string>
+    <string name="device_owner_bugreport_sharing_declined_while_being_taken_info">
+        Please press the \"Request bugreport\" button to invoke the bugreport sharing operation.
+        Open the notifications panel and verify that:\n
+        \n
+        - Notification titled \"Taking bugreport...\" with an indefinite progress bar is present.\n
+        \n
+        Press the \"Request bugreport\" button again to try to invoke a second bugreport sharing operation.
+        Open the notifications panel and verify that:\n
+        \n
+        - Notification titled \"Device Owner Requesting Bugreport Tests\" with message \"Bugreport is already being collected on this device\" is present. Dismiss that notification.\n
+        - Tapping on the \"Taking bugreport...\" notification opens a dialog titled \"Share bug report?\", that contains a message \"Your IT admin requested a bug report to help troubleshoot this device. Apps and data may be shared, and your device may temporarily slow down.\" and two buttons - \"DECLINE\" and \"SHARE\".\n
+        \n
+        Tap the \"DECLINE\" button and verify that:\n
+        \n
+        - \"Taking bugreport...\" notification with an indefinite progress bar is no longer present.\n
+        - Notification titled \"Device Owner Requesting Bugreport Tests\" with message \"Bugreport sharing declined\" is present.\n
+        \n
+        Dismiss the notifications and mark test as passed or failed.
+    </string>
+    <string name="device_owner_bugreport_sharing_accepted_while_being_taken">Sharing of requested bugreport accepted while being taken</string>
+    <string name="device_owner_bugreport_sharing_accepted_while_being_taken_info">
+        Please press the \"Request bugreport\" button to invoke the bugreport sharing operation.
+        Open the notifications panel and verify that:\n
+        \n
+        - Notification titled \"Taking bugreport...\" with an indefinite progress bar is present.\n
+        - Tapping on the \"Taking bugreport...\" notification opens a dialog titled \"Share bug report?\", that contains a message \"Your IT admin requested a bug report to help troubleshoot this device. Apps and data may be shared, and your device may temporarily slow down.\" and two buttons - \"DECLINE\" and \"SHARE\".\n
+        \n
+        Tap the \"SHARE\" button and verify that:\n
+        \n
+        - \"Taking bugreport...\" notification with an indefinite progress bar is no longer present.\n
+        - Notification titled \"Sharing bugreport...\" with an indefinite progress bar is present.\n
+        - After a few minutes (time necessary to wait for bugreport being collected) notification titled \"Sharing bugreport...\" is automatically dismissed and notification titled \"Device Owner Requesting Bugreport Tests\" with message \"Bugreport shared successfully\" is present.\n
+        \n
+        Dismiss the notifications and mark test as passed or failed.
+    </string>
+    <string name="device_owner_bugreport_sharing_declined_after_having_been_taken">Sharing of requested bugreport declined after having been taken</string>
+    <string name="device_owner_bugreport_sharing_declined_after_having_been_taken_info">
+        Please press the \"Request bugreport\" button to invoke the bugreport sharing operation.
+        Open the notifications panel and verify that:\n
+        \n
+        - Notification titled \"Taking bugreport...\" with an indefinite progress bar is present.\n
+        \n
+        Wait for a few minutes (time necessary for bugreport to be collected) and verify that:\n
+        \n
+        - \"Taking bugreport...\" notification with an indefinite progress bar is dismissed.\n
+        - Notification titled \"Share bug report?\", that contains a message \"Your IT admin requested a bug report to help troubleshoot this device. Apps and data may be shared.\" and two buttons - \"DECLINE\" and \"SHARE\" is shown.\n
+        \n
+        Tap the \"DECLINE\" button and verify that:\n
+        \n
+        - Notification titled \"Share bug report?\" is dismissed.\n
+        - Notification titled \"Device Owner Requesting Bugreport Tests\" with message \"Bugreport sharing declined\" is present.\n
+        \n
+        Dismiss the notifications and mark test as passed or failed.
+    </string>
+    <string name="device_owner_bugreport_sharing_accepted_after_having_been_taken">Sharing of requested bugreport accepted after having been taken</string>
+    <string name="device_owner_bugreport_sharing_accepted_after_having_been_taken_info">
+        Please press the \"Request bugreport\" button to invoke the bugreport sharing operation.
+        Open the notifications panel and verify that:\n
+        \n
+        - Notification titled \"Taking bugreport...\" with an indefinite progress bar is present.\n
+        \n
+        Wait for a few minutes (time necessary for bugreport to be collected) and verify that:\n
+        \n
+        - \"Taking bugreport...\" notification with an indefinite progress bar is dismissed.\n
+        - Notification titled \"Share bug report?\", that contains a message \"Your IT admin requested a bug report to help troubleshoot this device. Apps and data may be shared.\" and two buttons - \"DECLINE\" and \"SHARE\" is shown.\n
+        \n
+        Tap the \"SHARE\" button and verify that:\n
+        \n
+        - Notification titled \"Share bug report?\" is dismissed.\n
+        - Notification titled \"Device Owner Requesting Bugreport Tests\" with message \"Bugreport shared successfully\" is present.\n
+        \n
+        Dismiss the notifications and mark test as passed or failed.
+    </string>
+
+    <!-- Strings used for policy transparency test -->
+    <string name="device_profile_owner_policy_transparency_test">Policy transparency test</string>
+    <string name="device_profile_owner_policy_transparency_test_info">
+        This test checks that if an admin has enforced a policy, we let the user know about this.\nSet the short and long support messages before proceeding with the tests.
+    </string>
+    <string name="policy_transparency_open_settings_label">Open settings</string>
+    <string name="policy_transparency_short_support_msg_label">Set short support message</string>
+    <string name="policy_transparency_long_support_msg_label">Set long support message</string>
+    <string name="policy_transparency_set_msg">Set message</string>
+    <string name="policy_transparency_clear_msg">Clear message</string>
+    <string name="policy_transparency_set_default_msg">Set default message</string>
+    <string name="policy_transparency_default_short_msg">
+        This action is disabled by your administrator. Contact someone@example.com for support.
+    </string>
+    <string name="policy_transparency_default_long_msg">
+        This profile or device is managed by CtsVerifier. You can contact tech
+        support on:\n\n
+        America: +1 555-0100\n\n
+        APAC: +1 555-0100\n\n
+        Europe: +1 555-0100\n\n
+        Email: someone@example.com
+    </string>
+    <string name="policy_transparency_update_button_label">Update</string>
+    <string name="dummy_input_method_label">Dummy input method</string>
+    <string name="dummy_accessibility_service_label">Dummy accessibility service</string>
+    <string name="policy_transparency_test_instructions">
+        1. <xliff:g id="set_step" example="Set policy by turning the switch on">%1$s</xliff:g>\n
+        2. Open Settings app by clicking the "Open settings" button below.\n
+        3. Verify that performing the following action will trigger a support dialog:\n
+           <xliff:g id="user_action" example="Adding an account">%2$s</xliff:g>.\n
+        4. Verify that the support dialog displays the short support message set earlier.\n
+        5. Verify that clicking the "More details" link will redirect to Device administrators
+           page in Settings app which displays the long support message set earlier.\n
+    </string>
+    <string name="user_restriction_set_step">
+        Set \'%s\' user restriction by turning on the switch below.
+    </string>
+    <string name="disallow_add_user">Disallow add user</string>
+    <string name="disallow_add_user_action">Adding a new user</string>
+    <string name="disallow_adjust_volume">Disallow adjust volume</string>
+    <string name="disallow_adjust_volume_action">Adjusting the volume</string>
+    <string name="disallow_apps_control">Disallow controlling apps</string>
+    <string name="disallow_apps_control_action">DISABLE/UNINSTALL/FORCE STOP-ing any app in the managed device/profile other than CtsVerifier</string>
+    <string name="disallow_config_cell_broadcasts">Disallow config cell broadcasts</string>
+    <string name="disallow_config_cell_broadcasts_action">Configuring cell broadcasts</string>
+    <string name="disallow_config_credentials">Disallow config credentials</string>
+    <string name="disallow_config_credentials_action">Configuring user credentials</string>
+    <string name="disallow_config_mobile_networks">Disallow config mobile networks</string>
+    <string name="disallow_config_mobile_networks_action">Configuring mobile networks</string>
+    <string name="disallow_config_tethering">Disallow config tethering</string>
+    <string name="disallow_config_tethering_action">Configuring tethering and portable hotspots</string>
+    <string name="disallow_config_wifi">Disallow config Wi-Fi</string>
+    <string name="disallow_config_wifi_action">Modifying Wi-Fi configuration</string>
+    <string name="disallow_debugging_features">Disallow debugging features</string>
+    <string name="disallow_debugging_features_action">Enabling developer options</string>
+    <string name="disallow_factory_reset">Disallow factory reset</string>
+    <string name="disallow_factory_reset_action">Factory resetting the device</string>
+    <string name="disallow_fun">Disallow fun</string>
+    <string name="disallow_fun_action">Opening android easter egg game by tapping repeatedly on the \'Android version\' option</string>
+    <string name="disallow_install_unknown_sources">Disallow install unknown sources</string>
+    <string name="disallow_install_unknown_sources_action">Enabling \'Unknown sources\' setting</string>
+    <string name="disallow_modify_accounts">Disallow modify accounts</string>
+    <string name="disallow_modify_accounts_action">Adding an account or removing an account (if you have already added one)</string>
+    <string name="disallow_network_reset">Disallow network reset</string>
+    <string name="disallow_network_reset_action">Resetting network settings</string>
+    <string name="disallow_outgoing_beam">Disallow outgoing beam</string>
+    <string name="disallow_outgoing_beam_action">Switching on android beam</string>
+    <string name="disallow_remove_user">Disallow remove user</string>
+    <string name="disallow_remove_user_action">Removing other users</string>
+    <string name="disallow_share_location">Disallow share location</string>
+    <string name="disallow_share_location_action">Turning on location sharing</string>
+    <string name="disallow_uninstall_apps">Disallow uninstall apps</string>
+    <string name="disallow_uninstall_apps_action">Uninstalling applications other CtsVerifier</string>
+    <string name="disallow_keyguard_unredacted_notifications">Disallow lockscreen unredacted notification</string>
+    <string name="disallow_keyguard_unredacted_notifications_set_step">Disallow unredacted notifications when device is locked by turning on the switch below</string>
+    <string name="disallow_keyguard_unredacted_notifications_action">Selecting show all notification content when device is locked</string>
+    <string name="disallow_keyguard_unredacted_notifications_widget_label">@string/disallow_keyguard_unredacted_notifications</string>
+    <string name="set_auto_time_required">Set auto (network) time required</string>
+    <string name="auto_time_required_set_step">Set auto time required policy by turning on the switch below</string>
+    <string name="set_auto_time_required_action">Modifying date and time</string>
+    <string name="set_auto_time_required_widget_label">@string/set_auto_time_required</string>
+    <string name="set_lock_screen_info">Set lock screen info</string>
+    <string name="lock_screen_info_set_step">Select a lock screen info by setting a non-empty message in the edittext below.</string>
+    <string name="set_lock_screen_info_action">Modifying lock screen message</string>
+    <string name="set_lock_screen_info_widget_label">@string/set_lock_screen_info</string>
+    <string name="set_maximum_time_to_lock">Set maximum time to lock</string>
+    <string name="maximum_time_to_lock_set_step">
+        Select a non-zero maximum time to lock value by setting a value in the edittext box below.
+    </string>
+    <string name="set_maximum_time_to_lock_action">Selecting maximum time to lock greater than the set value below</string>
+    <string name="set_maximum_time_to_lock_widget_label">Set maximum time to lock (in Sec):</string>
+    <string name="set_password_quality">Set password quality</string>
+    <string name="password_quality_set_step">Set minimum password quality by selecting an option in the spinner below.</string>
+    <string name="set_password_quality_action">Setting a password which does not meet the requirements of the password quality selected</string>
+    <string name="set_password_quality_widget_label">@string/set_password_quality</string>
+    <string name="password_quality_unspecified">Unspecified</string>
+    <string name="password_quality_something">Something</string>
+    <string name="password_quality_numeric">Numeric</string>
+    <string name="password_quality_numeric_complex">Numeric (Complex)</string>
+    <string name="password_quality_alphabetic">Alphabetic</string>
+    <string name="password_quality_alphanumeric">Alphanumeric</string>
+    <string name="password_quality_complex">Complex</string>
+    <string name="set_permitted_accessibility_services">Set permitted accessibility services</string>
+    <string name="permitted_accessibility_services_set_step">
+        Disallow \'Dummy Accessibility service\' from permitted accessibility services by turning on
+        the switch below.
+    </string>
+    <string name="set_permitted_accessibility_services_action">
+        Enabling \'Dummy Accessibility service\' in the list of accessibility services
+    </string>
+    <string name="set_permitted_accessibility_services_widget_label">
+        Allow only system accessibility services:
+    </string>
+    <string name="set_permitted_input_methods">Set permitted input methods</string>
+    <string name="permitted_input_methods_set_step">
+        Disallow \'Dummy Input method\' from permitted input methods by turning on the switch below.
+    </string>
+    <string name="set_permitted_input_methods_action">
+        Enabling \'Dummy Input Method\' in the list of accessibility services
+    </string>
+    <string name="set_permitted_input_methods_widget_label">
+        Allow only system input methods:
+    </string>
+
     <!-- Strings for JobScheduler Tests -->
     <string name="js_test_description">This test is mostly automated, but requires some user interaction. You can pass this test once the list items below are checked.</string>
 
@@ -2069,6 +2560,13 @@
     Do you see the programs named \"Dummy Program\" and their descriptions
     "Dummy Program Description" in the EPG?
     </string>
+    <string name="tv_input_discover_test_trigger_setup">
+    Select the \"Launch setup\" button and verify if the bundled TV app shows the list of installed
+    TV inputs for setup.
+    </string>
+    <string name="tv_input_discover_test_verify_trigger_setup">
+    Do you see the \"CTS Verifier\" input in the list?
+    </string>
 
     <string name="tv_parental_control_test">TV app parental controls test</string>
     <string name="tv_parental_control_test_info">
@@ -2101,6 +2599,7 @@
     <string name="tv_parental_control_turn_off_enabled">Yes</string>
     <string name="tv_launch_tv_app">Launch TV app</string>
     <string name="tv_launch_epg">Launch EPG</string>
+    <string name="tv_launch_setup">Launch setup</string>
     <string name="tv_channel_not_found">
     CtsVerifier channel is not set up. Please set up before proceeding.
     </string>
@@ -2245,7 +2744,13 @@
     <string name="audio_general_deficiency_found">WARNING: Some results show potential deficiencies on the system.
     Please consider addressing them for a future release.</string>
     <string name="audio_general_test_passed">Test Successful</string>
-    <string name="audio_general_test_failed">Test Failed</string>
+    <string name="audio_general_test_failed">Test Result: Not Optimal</string>
+    <string name="audio_general_default_false_string">false</string>
+    <string name="audio_general_default_true_string">true</string>
+    <string name="audio_general_warning">Warning</string>
+    <string name="audio_general_ok">Ok</string>
+    <string name="audio_general_level_not_max">Audio Level is not maximum. Please check your device
+          is set to max level for audio playback.</string>
 
     <!-- Audio Loopback Latency Test -->
     <string name="audio_loopback_test">Audio Loopback Latency Test</string>
@@ -2329,4 +2834,20 @@
     <string name="audio_frequency_mic_test2_btn">Test 2</string>
     <string name="audio_frequency_mic_results_text">Results...</string>
 
+     <!-- Audio Frequency Unprocessed Test -->
+    <string name="audio_frequency_unprocessed_test">Audio Frequency Unprocessed Test</string>
+    <string name="audio_frequency_unprocessed_info">
+   This test requires an external broadband noise source (or click/impulse).
+   Please be prepared to activate the noise source when asked to.
+   The system will measure frequency response of the built in microphone using the UNPROCESSED
+   audio source.
+       </string>
+    <string name="audio_frequency_unprocessed_defined">Audio Frequency Unprocessed feature is defined. Test is mandatory</string>
+    <string name="audio_frequency_unprocessed_not_defined">Audio Frequency Unprocessed feature is NOT defined. Test is optional</string>
+     <string name="audio_frequency_unprocessed_instructions2">
+          Once you press the [TEST] button, you have 5 seconds to play a broadband sound (click or white noise).
+    </string>
+    <string name="audio_frequency_unprocessed_test1_btn">Test 1</string>
+    <string name="audio_frequency_unprocessed_results_text">Results...</string>
+
 </resources>
diff --git a/apps/CtsVerifier/res/xml/device_admin_byod.xml b/apps/CtsVerifier/res/xml/device_admin_byod.xml
index ff1eb95..b1ba372 100644
--- a/apps/CtsVerifier/res/xml/device_admin_byod.xml
+++ b/apps/CtsVerifier/res/xml/device_admin_byod.xml
@@ -24,6 +24,7 @@
         <reset-password />
         <disable-keyguard-features />
         <force-lock />
+        <limit-password />
     </uses-policies>
 </device-admin>
 <!-- END_INCLUDE(meta_data) -->
diff --git a/apps/CtsVerifier/res/xml/dummy_method.xml b/apps/CtsVerifier/res/xml/dummy_method.xml
new file mode 100644
index 0000000..03d555e
--- /dev/null
+++ b/apps/CtsVerifier/res/xml/dummy_method.xml
@@ -0,0 +1,18 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright 2016 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.
+-->
+
+<!-- Configuration info for the Dummy input method -->
+<input-method xmlns:android="http://schemas.android.com/apk/res/android" />
\ No newline at end of file
diff --git a/apps/CtsVerifier/res/xml/felicaservice.xml b/apps/CtsVerifier/res/xml/felicaservice.xml
new file mode 100644
index 0000000..7d1b164
--- /dev/null
+++ b/apps/CtsVerifier/res/xml/felicaservice.xml
@@ -0,0 +1,5 @@
+<host-nfcf-service xmlns:android="http://schemas.android.com/apk/res/android"
+    android:description="@string/felicaservice">
+    <system-code-filter android:name="4001" />
+    <nfcid2-filter android:name="02FE000000001481" />
+</host-nfcf-service>
diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/TestResultsReport.java b/apps/CtsVerifier/src/com/android/cts/verifier/TestResultsReport.java
index dc2502c..76eb8a1 100644
--- a/apps/CtsVerifier/src/com/android/cts/verifier/TestResultsReport.java
+++ b/apps/CtsVerifier/src/com/android/cts/verifier/TestResultsReport.java
@@ -16,17 +16,17 @@
 
 package com.android.cts.verifier;
 
+import android.content.Context;
+import android.os.Build;
+import android.text.TextUtils;
+import android.util.Xml;
+
 import com.android.compatibility.common.util.MetricsXmlSerializer;
 import com.android.compatibility.common.util.ReportLog;
 import com.android.cts.verifier.TestListAdapter.TestListItem;
 
 import org.xmlpull.v1.XmlSerializer;
 
-import android.content.Context;
-import android.os.Build;
-import android.text.TextUtils;
-import android.util.Xml;
-
 import java.io.ByteArrayOutputStream;
 import java.io.IOException;
 import java.text.DateFormat;
@@ -130,6 +130,7 @@
                     xml.endTag(null, TEST_DETAILS_TAG);
                 }
 
+                // TODO(stuartscott): For v2: ReportLog.serialize(xml, mAdapter.getReportLog(i));
                 ReportLog reportLog = mAdapter.getReportLog(i);
                 if (reportLog != null) {
                     MetricsXmlSerializer metricsXmlSerializer = new MetricsXmlSerializer(xml);
diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/audio/AudioFrequencyActivity.java b/apps/CtsVerifier/src/com/android/cts/verifier/audio/AudioFrequencyActivity.java
new file mode 100644
index 0000000..1893ac2
--- /dev/null
+++ b/apps/CtsVerifier/src/com/android/cts/verifier/audio/AudioFrequencyActivity.java
@@ -0,0 +1,80 @@
+/*
+ * Copyright (C) 2015 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.verifier.audio;
+
+import com.android.cts.verifier.PassFailButtons;
+import com.android.cts.verifier.R;
+import com.android.cts.verifier.audio.wavelib.*;
+import com.android.compatibility.common.util.ReportLog;
+import com.android.compatibility.common.util.ResultType;
+import com.android.compatibility.common.util.ResultUnit;
+
+import android.app.AlertDialog;
+import android.content.Context;
+import android.media.AudioDeviceCallback;
+import android.media.AudioDeviceInfo;
+import android.media.AudioFormat;
+import android.media.AudioManager;
+import android.media.AudioTrack;
+import android.media.AudioRecord;
+import android.media.MediaRecorder;
+import android.os.Bundle;
+import android.os.Handler;
+import android.os.Message;
+import android.os.SystemClock;
+import android.util.Log;
+import android.view.View;
+import android.view.View.OnClickListener;
+import android.widget.Button;
+import android.widget.TextView;
+import android.widget.SeekBar;
+import android.widget.LinearLayout;
+import android.widget.ProgressBar;
+
+/**
+ * Audio Frequency Test base activity
+ */
+public class AudioFrequencyActivity extends PassFailButtons.Activity {
+    private static final String TAG = "AudioFrequencyActivity";
+
+    public int mMaxLevel = 0;
+
+    public void setMaxLevel() {
+        AudioManager am = (AudioManager) getSystemService(Context.AUDIO_SERVICE);
+        mMaxLevel = am.getStreamMaxVolume(AudioManager.STREAM_MUSIC);
+        am.setStreamVolume(AudioManager.STREAM_MUSIC, (int)(mMaxLevel), 0);
+    }
+
+    public void setMinLevel() {
+        AudioManager am = (AudioManager) getSystemService(Context.AUDIO_SERVICE);
+        am.setStreamVolume(AudioManager.STREAM_MUSIC, 0, 0);
+    }
+
+    public void testMaxLevel() {
+        AudioManager am = (AudioManager) getSystemService(Context.AUDIO_SERVICE);
+        int currentLevel =  am.getStreamVolume(AudioManager.STREAM_MUSIC);
+        Log.i(TAG, String.format("Max level: %d curLevel: %d", mMaxLevel, currentLevel));
+        if (currentLevel != mMaxLevel) {
+            new AlertDialog.Builder(this)
+                .setTitle(R.string.audio_general_warning)
+                .setMessage(R.string.audio_general_level_not_max)
+                .setPositiveButton(R.string.audio_general_ok, null)
+                .show();
+        }
+    }
+
+}
diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/audio/AudioFrequencyLineActivity.java b/apps/CtsVerifier/src/com/android/cts/verifier/audio/AudioFrequencyLineActivity.java
index edb3bf0..944f7bf 100644
--- a/apps/CtsVerifier/src/com/android/cts/verifier/audio/AudioFrequencyLineActivity.java
+++ b/apps/CtsVerifier/src/com/android/cts/verifier/audio/AudioFrequencyLineActivity.java
@@ -23,6 +23,7 @@
 import com.android.compatibility.common.util.ResultType;
 import com.android.compatibility.common.util.ResultUnit;
 
+import android.app.AlertDialog;
 import android.content.Context;
 import android.media.AudioDeviceCallback;
 import android.media.AudioDeviceInfo;
@@ -47,7 +48,7 @@
 /**
  * Tests Audio Device roundtrip latency by using a loopback plug.
  */
-public class AudioFrequencyLineActivity extends PassFailButtons.Activity implements Runnable,
+public class AudioFrequencyLineActivity extends AudioFrequencyActivity implements Runnable,
     AudioRecord.OnRecordPositionUpdateListener {
     private static final String TAG = "AudioFrequencyLineActivity";
 
@@ -78,7 +79,7 @@
 
     private final int mBlockSizeSamples = 1024;
     private final int mSamplingRate = 48000;
-    private final int mSelectedRecordSource = MediaRecorder.AudioSource.VOICE_RECOGNITION;
+    private final int mSelectedRecordSource = MediaRecorder.AudioSource.UNPROCESSED;
     private final int mChannelConfig = AudioFormat.CHANNEL_IN_MONO;
     private final int mAudioFormat = AudioFormat.ENCODING_PCM_16BIT;
     private volatile Thread mRecordThread;
@@ -101,7 +102,6 @@
     int mBands = 4;
     AudioBandSpecs[] bandSpecsArray = new AudioBandSpecs[mBands];
 
-    int mMaxLevel;
     private class OnBtnClickListener implements OnClickListener {
         @Override
         public void onClick(View v) {
@@ -110,6 +110,8 @@
                     Log.i(TAG, "audio loopback plug ready");
                     //enable all the other views.
                     enableLayout(true);
+                    setMaxLevel();
+                    testMaxLevel();
                     break;
                 case R.id.audio_frequency_line_test_btn:
                     Log.i(TAG, "audio loopback test");
@@ -178,7 +180,7 @@
         //Init bands
         bandSpecsArray[0] = new AudioBandSpecs(
                 50, 500,        /* frequency start,stop */
-                -20.0, -50,     /* start top,bottom value */
+                4.0, -50,     /* start top,bottom value */
                 4.0, -4.0       /* stop top,bottom value */);
 
         bandSpecsArray[1] = new AudioBandSpecs(
@@ -218,12 +220,6 @@
         }
     }
 
-    private void setMaxLevel() {
-        AudioManager am = (AudioManager) getSystemService(Context.AUDIO_SERVICE);
-        mMaxLevel = am.getStreamMaxVolume(AudioManager.STREAM_MUSIC);
-        am.setStreamVolume(AudioManager.STREAM_MUSIC, (int)(mMaxLevel), 0);
-    }
-
     /**
      *  Start the loopback audio test
      */
@@ -250,7 +246,6 @@
             Message msg = Message.obtain();
             msg.what = TEST_STARTED;
             mMessageHandler.sendMessage(msg);
-            setMaxLevel();
 
             sendMessage("Testing Left Capture");
             mCurrentTest = 0;
@@ -332,7 +327,7 @@
         public String toString() {
             StringBuilder sb = new StringBuilder();
             sb.append(String.format("Channel %s\n", mLabel));
-            sb.append("Level in Band 1 : " + (testLevel() ? "OK" :"FAILED") +"\n");
+            sb.append("Level in Band 1 : " + (testLevel() ? "OK" :"Not Optimal") +"\n");
             for (int b = 0; b < mBands; b++) {
                 double percent = 0;
                 if (mPointsPerBand[b] > 0) {
@@ -344,7 +339,7 @@
                         mInBoundPointsPerBand[b],
                         mPointsPerBand[b],
                         percent,
-                        (testInBand(b) ? "OK" : "FAILED")));
+                        (testInBand(b) ? "OK" : "Not Optimal")));
             }
             return sb.toString();
         }
@@ -601,11 +596,13 @@
             mRecorder = new AudioRecord(mSelectedRecordSource, mSamplingRate,
                     mChannelConfig, mAudioFormat, 2 * minRecordBuffSizeInBytes);
         } catch (IllegalArgumentException e) {
+            Log.v(TAG, "Error: " + e.toString());
             return false;
         }
         if (mRecorder.getState() != AudioRecord.STATE_INITIALIZED) {
             mRecorder.release();
             mRecorder = null;
+            Log.v(TAG, "Error: mRecorder not initialized");
             return false;
         }
         mRecorder.setRecordPositionUpdateListener(this);
diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/audio/AudioFrequencyMicActivity.java b/apps/CtsVerifier/src/com/android/cts/verifier/audio/AudioFrequencyMicActivity.java
index 03d84e1..ce7eb3f 100644
--- a/apps/CtsVerifier/src/com/android/cts/verifier/audio/AudioFrequencyMicActivity.java
+++ b/apps/CtsVerifier/src/com/android/cts/verifier/audio/AudioFrequencyMicActivity.java
@@ -54,7 +54,7 @@
 /**
  * Tests Audio built in Microphone response using external speakers and USB reference microphone.
  */
-public class AudioFrequencyMicActivity extends PassFailButtons.Activity implements Runnable,
+public class AudioFrequencyMicActivity extends AudioFrequencyActivity implements Runnable,
     AudioRecord.OnRecordPositionUpdateListener {
     private static final String TAG = "AudioFrequencyMicActivity";
 
@@ -123,13 +123,14 @@
     AudioBandSpecs[] bandSpecsArray = new AudioBandSpecs[mBands];
     AudioBandSpecs[] baseBandSpecsArray = new AudioBandSpecs[mBands];
 
-    int mMaxLevel;
     private class OnBtnClickListener implements OnClickListener {
         @Override
         public void onClick(View v) {
             switch (v.getId()) {
             case R.id.audio_frequency_mic_speakers_ready_btn:
                 testSpeakersReady();
+                setMaxLevel();
+                testMaxLevel();
                 break;
             case R.id.audio_frequency_mic_test1_btn:
                 startTest1();
@@ -215,7 +216,7 @@
         //Init bands for BuiltIn/Reference test
         bandSpecsArray[0] = new AudioBandSpecs(
                 50, 500,        /* frequency start,stop */
-                -20.0, -50,     /* start top,bottom value */
+                4.0, -50,     /* start top,bottom value */
                 4.0, -4.0       /* stop top,bottom value */);
 
         bandSpecsArray[1] = new AudioBandSpecs(
@@ -277,17 +278,6 @@
         }
     }
 
-    private void setMaxLevel() {
-        AudioManager am = (AudioManager) getSystemService(Context.AUDIO_SERVICE);
-        mMaxLevel = am.getStreamMaxVolume(AudioManager.STREAM_MUSIC);
-        am.setStreamVolume(AudioManager.STREAM_MUSIC, (int)(mMaxLevel), 0);
-    }
-
-    private void setMinLevel() {
-        AudioManager am = (AudioManager) getSystemService(Context.AUDIO_SERVICE);
-        am.setStreamVolume(AudioManager.STREAM_MUSIC, 0, 0);
-    }
-
     /**
      *  Start the loopback audio test
      */
@@ -476,7 +466,7 @@
         public String toString() {
             StringBuilder sb = new StringBuilder();
             sb.append(String.format("Channel %s\n", mLabel));
-            sb.append("Level in Band 1 : " + (testLevel() ? "OK" :"FAILED") +
+            sb.append("Level in Band 1 : " + (testLevel() ? "OK" :"Not Optimal") +
                     (mIsBaseMeasurement ? " (Base Meas.)" : "") + "\n");
             for (int b = 0; b < mBands; b++) {
                 double percent = 0;
@@ -489,7 +479,7 @@
                         mInBoundPointsPerBand[b],
                         mPointsPerBand[b],
                         percent,
-                        (testInBand(b) ? "OK" : "FAILED")));
+                        (testInBand(b) ? "OK" : "Not Optimal")));
             }
             return sb.toString();
         }
diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/audio/AudioFrequencySpeakerActivity.java b/apps/CtsVerifier/src/com/android/cts/verifier/audio/AudioFrequencySpeakerActivity.java
index ba7b86d..294e48d 100644
--- a/apps/CtsVerifier/src/com/android/cts/verifier/audio/AudioFrequencySpeakerActivity.java
+++ b/apps/CtsVerifier/src/com/android/cts/verifier/audio/AudioFrequencySpeakerActivity.java
@@ -54,7 +54,7 @@
 /**
  * Tests Audio Device roundtrip latency by using a loopback plug.
  */
-public class AudioFrequencySpeakerActivity extends PassFailButtons.Activity implements Runnable,
+public class AudioFrequencySpeakerActivity extends AudioFrequencyActivity implements Runnable,
     AudioRecord.OnRecordPositionUpdateListener {
     private static final String TAG = "AudioFrequencySpeakerActivity";
 
@@ -110,13 +110,14 @@
     AudioBandSpecs[] bandSpecsArray = new AudioBandSpecs[mBands];
     AudioBandSpecs[] baseBandSpecsArray = new AudioBandSpecs[mBands];
 
-    int mMaxLevel;
     private class OnBtnClickListener implements OnClickListener {
         @Override
         public void onClick(View v) {
             switch (v.getId()) {
             case R.id.audio_frequency_speaker_mic_ready_btn:
                 testUSB();
+                setMaxLevel();
+                testMaxLevel();
                 break;
             case R.id.audio_frequency_speaker_test_btn:
                 startAudioTest();
@@ -165,7 +166,7 @@
         //Init bands for Left/Right test
         bandSpecsArray[0] = new AudioBandSpecs(
                 50, 500,        /* frequency start,stop */
-                -20.0, -50,     /* start top,bottom value */
+                4.0, -50,     /* start top,bottom value */
                 4.0, -4.0       /* stop top,bottom value */);
 
         bandSpecsArray[1] = new AudioBandSpecs(
@@ -227,17 +228,6 @@
         }
     }
 
-    private void setMaxLevel() {
-        AudioManager am = (AudioManager) getSystemService(Context.AUDIO_SERVICE);
-        mMaxLevel = am.getStreamMaxVolume(AudioManager.STREAM_MUSIC);
-        am.setStreamVolume(AudioManager.STREAM_MUSIC, (int)(mMaxLevel), 0);
-    }
-
-    private void setMinLevel() {
-        AudioManager am = (AudioManager) getSystemService(Context.AUDIO_SERVICE);
-        am.setStreamVolume(AudioManager.STREAM_MUSIC, 0, 0);
-    }
-
     /**
      *  Start the loopback audio test
      */
@@ -354,7 +344,7 @@
         public String toString() {
             StringBuilder sb = new StringBuilder();
             sb.append(String.format("Channel %s\n", mLabel));
-            sb.append("Level in Band 1 : " + (testLevel() ? "OK" :"FAILED") +
+            sb.append("Level in Band 1 : " + (testLevel() ? "OK" :"Not Optimal") +
                     (mIsBaseMeasurement ? " (Base Meas.)" : "") + "\n");
             for (int b = 0; b < mBands; b++) {
                 double percent = 0;
@@ -367,7 +357,7 @@
                         mInBoundPointsPerBand[b],
                         mPointsPerBand[b],
                         percent,
-                        (testInBand(b) ? "OK" : "FAILED")));
+                        (testInBand(b) ? "OK" : "Not Optimal")));
             }
             return sb.toString();
         }
diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/audio/AudioFrequencyUnprocessedActivity.java b/apps/CtsVerifier/src/com/android/cts/verifier/audio/AudioFrequencyUnprocessedActivity.java
new file mode 100644
index 0000000..56275c5
--- /dev/null
+++ b/apps/CtsVerifier/src/com/android/cts/verifier/audio/AudioFrequencyUnprocessedActivity.java
@@ -0,0 +1,684 @@
+/*
+ * Copyright (C) 2015 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.verifier.audio;
+
+import com.android.cts.verifier.PassFailButtons;
+import com.android.cts.verifier.R;
+import com.android.cts.verifier.audio.wavelib.*;
+import com.android.compatibility.common.util.ReportLog;
+import com.android.compatibility.common.util.ResultType;
+import com.android.compatibility.common.util.ResultUnit;
+import android.content.Context;
+import android.content.BroadcastReceiver;
+import android.content.Intent;
+import android.content.IntentFilter;
+
+import android.media.AudioDeviceCallback;
+import android.media.AudioDeviceInfo;
+import android.media.AudioFormat;
+import android.media.AudioManager;
+import android.media.AudioTrack;
+import android.media.AudioRecord;
+import android.media.MediaRecorder;
+
+import android.os.Bundle;
+import android.os.Handler;
+import android.os.Message;
+import android.os.SystemClock;
+
+import android.util.Log;
+
+import android.view.View;
+import android.view.View.OnClickListener;
+
+import android.widget.Button;
+import android.widget.TextView;
+import android.widget.SeekBar;
+import android.widget.LinearLayout;
+import android.widget.ProgressBar;
+
+/**
+ * Tests Audio built in Microphone response for Unprocessed audio source feature.
+ */
+public class AudioFrequencyUnprocessedActivity extends AudioFrequencyActivity implements Runnable,
+    AudioRecord.OnRecordPositionUpdateListener {
+    private static final String TAG = "AudioFrequencyUnprocessedActivity";
+
+    private static final int TEST_STARTED = 900;
+    private static final int TEST_ENDED = 901;
+    private static final int TEST_MESSAGE = 902;
+    private static final int TEST1_MESSAGE = 903;
+    private static final int TEST1_ENDED = 904;
+    private static final double MIN_ENERGY_BAND_1 = -50.0;          //dB Full Scale
+    private static final double MAX_ENERGY_BAND_1_BASE = -60.0;     //dB Full Scale
+    private static final double MIN_FRACTION_POINTS_IN_BAND = 0.3;
+    private static final double MAX_VAL = Math.pow(2, 15);
+    private static final double CLIP_LEVEL = (MAX_VAL-10) / MAX_VAL;
+
+    final OnBtnClickListener mBtnClickListener = new OnBtnClickListener();
+    Context mContext;
+
+    Button mTest1Button;                //execute test 1
+    Button mTest2Button;                 //user to start test
+    String mUsbDevicesInfo;             //usb device info for report
+    LinearLayout mLayoutTest1;
+    TextView mTest1Result;
+    ProgressBar mProgressBar;
+
+    private boolean mIsRecording = false;
+    private final Object mRecordingLock = new Object();
+    private AudioRecord mRecorder;
+    private int mMinRecordBufferSizeInSamples = 0;
+    private short[] mAudioShortArray;
+    private short[] mAudioShortArray2;
+
+    private final int mBlockSizeSamples = 4096;
+    private final int mSamplingRate = 48000;
+    private final int mSelectedRecordSource = MediaRecorder.AudioSource.UNPROCESSED;
+    private final int mChannelConfig = AudioFormat.CHANNEL_IN_MONO;
+    private final int mAudioFormat = AudioFormat.ENCODING_PCM_16BIT;
+    private Thread mRecordThread;
+
+    PipeShort mPipe = new PipeShort(65536);
+
+    private boolean mSupportsUnprocessed = false;
+
+    private DspBufferComplex mC;
+    private DspBufferDouble mData;
+
+    private DspWindow mWindow;
+    private DspFftServer mFftServer;
+    private VectorAverage mFreqAverageMain = new VectorAverage();
+    private VectorAverage mFreqAverageBuiltIn = new VectorAverage();
+
+    int mBands = 4;
+    AudioBandSpecs[] bandSpecsArray = new AudioBandSpecs[mBands];
+    private TextView mTextViewUnprocessedStatus;
+
+    private class OnBtnClickListener implements OnClickListener {
+        @Override
+        public void onClick(View v) {
+            switch (v.getId()) {
+            case R.id.audio_frequency_unprocessed_test1_btn:
+                setMaxLevel();
+                testMaxLevel();
+                startTest1();
+                break;
+            }
+        }
+    }
+
+    @Override
+    protected void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+        setContentView(R.layout.audio_frequency_unprocessed_activity);
+        mContext = this;
+        mTextViewUnprocessedStatus = (TextView) findViewById(
+                R.id.audio_frequency_unprocessed_defined);
+        //unprocessed test
+        mSupportsUnprocessed = supportsUnprocessed();
+        if (mSupportsUnprocessed) {
+            mTextViewUnprocessedStatus.setText(
+                    getResources().getText(R.string.audio_frequency_unprocessed_defined));
+        } else {
+            mTextViewUnprocessedStatus.setText(
+                    getResources().getText(R.string.audio_frequency_unprocessed_not_defined));
+        }
+
+        mTest1Button = (Button)findViewById(R.id.audio_frequency_unprocessed_test1_btn);
+        mTest1Button.setOnClickListener(mBtnClickListener);
+        mTest1Result = (TextView)findViewById(R.id.audio_frequency_unprocessed_results1_text);
+        mLayoutTest1 = (LinearLayout) findViewById(R.id.audio_frequency_unprocessed_layout_test1);
+        mProgressBar = (ProgressBar)findViewById(R.id.audio_frequency_unprocessed_progress_bar);
+        showWait(false);
+        enableLayout(mLayoutTest1, true);
+
+        //Init FFT stuff
+        mAudioShortArray2 = new short[mBlockSizeSamples*2];
+        mData = new DspBufferDouble(mBlockSizeSamples);
+        mC = new DspBufferComplex(mBlockSizeSamples);
+        mFftServer = new DspFftServer(mBlockSizeSamples);
+
+        int overlap = mBlockSizeSamples / 2;
+
+        mWindow = new DspWindow(DspWindow.WINDOW_HANNING, mBlockSizeSamples, overlap);
+
+        setPassFailButtonClickListeners();
+        getPassButton().setEnabled(false);
+        setInfoResources(R.string.audio_frequency_unprocessed_test,
+                R.string.audio_frequency_unprocessed_info, -1);
+
+        //Init bands for BuiltIn/Reference test
+        bandSpecsArray[0] = new AudioBandSpecs(
+                2, 500,         /* frequency start,stop */
+                30.0, -50,     /* start top,bottom value */
+                30.0, -4.0       /* stop top,bottom value */);
+
+        bandSpecsArray[1] = new AudioBandSpecs(
+                500,4000,       /* frequency start,stop */
+                4.0, -4.0,      /* start top,bottom value */
+                4.0, -4.0        /* stop top,bottom value */);
+
+        bandSpecsArray[2] = new AudioBandSpecs(
+                4000, 12000,    /* frequency start,stop */
+                4.0, -4.0,      /* start top,bottom value */
+                5.0, -5.0       /* stop top,bottom value */);
+
+        bandSpecsArray[3] = new AudioBandSpecs(
+                12000, 20000,   /* frequency start,stop */
+                5.0, -5.0,      /* start top,bottom value */
+                5.0, -30.0      /* stop top,bottom value */);
+
+        mSupportsUnprocessed = supportsUnprocessed();
+        Log.v(TAG, "Supports unprocessed: " + mSupportsUnprocessed);
+    }
+
+    /**
+     * enable test ui elements
+     */
+    private void enableLayout(LinearLayout layout, boolean enable) {
+        for (int i = 0; i < layout.getChildCount(); i++) {
+            View view = layout.getChildAt(i);
+            view.setEnabled(enable);
+        }
+    }
+
+    /**
+     * show active progress bar
+     */
+    private void showWait(boolean show) {
+        if (show) {
+            mProgressBar.setVisibility(View.VISIBLE);
+        } else {
+            mProgressBar.setVisibility(View.INVISIBLE);
+        }
+    }
+
+    private boolean supportsUnprocessed() {
+        boolean unprocessedSupport = false;
+        AudioManager am = (AudioManager) getSystemService(Context.AUDIO_SERVICE);
+        String unprocessedSupportString = am.getProperty(
+                AudioManager.PROPERTY_SUPPORT_AUDIO_SOURCE_UNPROCESSED);
+        Log.v(TAG,"unprocessed support: " + unprocessedSupportString);
+        if (unprocessedSupportString == null ||
+                unprocessedSupportString.equalsIgnoreCase(getResources().getString(
+                        R.string.audio_general_default_false_string))) {
+            unprocessedSupport = false;
+        } else {
+            unprocessedSupport = true;
+        }
+        return unprocessedSupport;
+    }
+
+    /**
+     *  Start the loopback audio test
+     */
+    private void startTest1() {
+        if (mTestThread != null && !mTestThread.isAlive()) {
+            mTestThread = null; //kill it.
+        }
+
+        if (mTestThread == null) {
+            Log.v(TAG,"Executing test Thread");
+            mTestThread = new Thread(mTest1Runnable);
+            mTestThread.start();
+        } else {
+            Log.v(TAG,"test Thread already running.");
+        }
+    }
+
+    Thread mTestThread;
+    Runnable mTest1Runnable = new Runnable() {
+        public void run() {
+            Message msg = Message.obtain();
+            msg.what = TEST_STARTED;
+            mMessageHandler.sendMessage(msg);
+
+            sendMessage("Testing Built in Microphone");
+            mFreqAverageBuiltIn.reset();
+            mFreqAverageBuiltIn.setCaptureType(VectorAverage.CAPTURE_TYPE_MAX);
+            play();
+
+            sendMessage("Testing Completed");
+
+            Message msg2 = Message.obtain();
+            msg2.what = TEST1_ENDED;
+            mMessageHandler.sendMessage(msg2);
+        }
+
+        private void play() {
+            startRecording();
+
+            try {
+                Thread.sleep(5000);
+            } catch (InterruptedException e) {
+                e.printStackTrace();
+                //restore interrupted status
+                Thread.currentThread().interrupt();
+            }
+            stopRecording();
+        }
+
+        private void sendMessage(String str) {
+            Message msg = Message.obtain();
+            msg.what = TEST1_MESSAGE;
+            msg.obj = str;
+            mMessageHandler.sendMessage(msg);
+        }
+    };
+
+    private Handler mMessageHandler = new Handler() {
+        public void handleMessage(Message msg) {
+            super.handleMessage(msg);
+            switch (msg.what) {
+            case TEST_STARTED:
+                showWait(true);
+                getPassButton().setEnabled(false);
+                break;
+            case TEST_ENDED:
+                showWait(false);
+//                computeTest2Results();
+                break;
+            case TEST1_MESSAGE: {
+                    String str = (String)msg.obj;
+                    if (str != null) {
+                        mTest1Result.setText(str);
+                    }
+                }
+                break;
+            case TEST1_ENDED:
+                showWait(false);
+                computeTest1Results();
+                break;
+            case TEST_MESSAGE: {
+                }
+                break;
+            default:
+                Log.e(TAG, String.format("Unknown message: %d", msg.what));
+            }
+        }
+    };
+
+    private class Results {
+        private String mLabel;
+        public double[] mValuesLog;
+        int[] mPointsPerBand = new int[mBands];
+        double[] mAverageEnergyPerBand = new double[mBands];
+        int[] mInBoundPointsPerBand = new int[mBands];
+        public Results(String label) {
+            mLabel = label;
+        }
+
+        //append results
+        public String toString() {
+            StringBuilder sb = new StringBuilder();
+            sb.append(String.format("Channel %s\n", mLabel));
+            sb.append("Level in Band 1 : " + (testLevel() ? "OK" :"Not Optimal") + "\n");
+            for (int b = 0; b < mBands; b++) {
+                double percent = 0;
+                if (mPointsPerBand[b] > 0) {
+                    percent = 100.0 * (double) mInBoundPointsPerBand[b] / mPointsPerBand[b];
+                }
+                sb.append(String.format(
+                        " Band %d: Av. Level: %.1f dB InBand: %d/%d (%.1f%%) %s\n",
+                        b, mAverageEnergyPerBand[b],
+                        mInBoundPointsPerBand[b],
+                        mPointsPerBand[b],
+                        percent,
+                        (testInBand(b) ? "OK" : "Not Optimal")));
+            }
+            return sb.toString();
+        }
+
+        public boolean testLevel() {
+            if (mAverageEnergyPerBand[1] >= MIN_ENERGY_BAND_1) {
+                return true;
+            }
+            return false;
+        }
+
+        public boolean testInBand(int b) {
+            if (b >= 0 && b < mBands && mPointsPerBand[b] > 0) {
+                if ((double) mInBoundPointsPerBand[b] / mPointsPerBand[b] >
+                    MIN_FRACTION_POINTS_IN_BAND) {
+                        return true;
+                }
+            }
+            return false;
+        }
+
+        public boolean testAll() {
+            if (!testLevel()) {
+                return false;
+            }
+            for (int b = 0; b < mBands; b++) {
+                if (!testInBand(b)) {
+                    return false;
+                }
+            }
+            return true;
+        }
+    }
+
+
+    /**
+     * compute test1 results
+     */
+    private void computeTest1Results() {
+        Results resultsBuiltIn = new Results("BuiltIn");
+        if (computeResultsForVector(mFreqAverageBuiltIn, resultsBuiltIn, bandSpecsArray)) {
+            appendResultsToScreen(resultsBuiltIn.toString(), mTest1Result);
+            recordTestResults(resultsBuiltIn);
+        }
+        if (mSupportsUnprocessed) { //test is mandatory
+            appendResultsToScreen(getResources().getText(
+                    R.string.audio_frequency_unprocessed_defined).toString(), mTest1Result);
+            if (resultsBuiltIn.testAll()) {
+                //tst passed
+                getPassButton().setEnabled(true);
+                String strSuccess = getResources().getString(R.string.audio_general_test_passed);
+                appendResultsToScreen(strSuccess, mTest1Result);
+            } else {
+                getPassButton().setEnabled(false);
+                String strFailed = getResources().getString(R.string.audio_general_test_failed);
+                appendResultsToScreen(strFailed, mTest1Result);
+            }
+        } else {
+            //test optional
+            appendResultsToScreen(getResources().getText(
+                    R.string.audio_frequency_unprocessed_not_defined).toString(), mTest1Result);
+            getPassButton().setEnabled(true);
+        }
+    }
+
+    private boolean computeResultsForVector(VectorAverage freqAverage, Results results,
+            AudioBandSpecs[] bandSpecs) {
+
+        int points = freqAverage.getSize();
+        if (points > 0) {
+            //compute vector in db
+            double[] values = new double[points];
+            freqAverage.getData(values, false);
+            results.mValuesLog = new double[points];
+            for (int i = 0; i < points; i++) {
+                results.mValuesLog[i] = 20 * Math.log10(values[i]);
+            }
+
+            int currentBand = 0;
+            for (int i = 0; i < points; i++) {
+                double freq = (double)mSamplingRate * i / (double)mBlockSizeSamples;
+                if (freq > bandSpecs[currentBand].mFreqStop) {
+                    currentBand++;
+                    if (currentBand >= mBands)
+                        break;
+                }
+
+                if (freq >= bandSpecs[currentBand].mFreqStart) {
+                    results.mAverageEnergyPerBand[currentBand] += results.mValuesLog[i];
+                    results.mPointsPerBand[currentBand]++;
+                }
+            }
+
+            for (int b = 0; b < mBands; b++) {
+                if (results.mPointsPerBand[b] > 0) {
+                    results.mAverageEnergyPerBand[b] =
+                            results.mAverageEnergyPerBand[b] / results.mPointsPerBand[b];
+                }
+            }
+
+            //set offset relative to band 1 level
+            for (int b = 0; b < mBands; b++) {
+                bandSpecs[b].setOffset(results.mAverageEnergyPerBand[1]);
+            }
+
+            //test points in band.
+            currentBand = 0;
+            for (int i = 0; i < points; i++) {
+                double freq = (double)mSamplingRate * i / (double)mBlockSizeSamples;
+                if (freq >  bandSpecs[currentBand].mFreqStop) {
+                    currentBand++;
+                    if (currentBand >= mBands)
+                        break;
+                }
+
+                if (freq >= bandSpecs[currentBand].mFreqStart) {
+                    double value = results.mValuesLog[i];
+                    if (bandSpecs[currentBand].isInBounds(freq, value)) {
+                        results.mInBoundPointsPerBand[currentBand]++;
+                    }
+                }
+            }
+            return true;
+        } else {
+            return false;
+        }
+    }
+
+    //append results
+    private void appendResultsToScreen(String str, TextView text) {
+        String currentText = text.getText().toString();
+        text.setText(currentText + "\n" + str);
+    }
+
+    /**
+     * Store test results in log
+     */
+    private void recordTestResults(Results results) {
+        String channelLabel = "channel_" + results.mLabel;
+
+        for (int b = 0; b < mBands; b++) {
+            String bandLabel = String.format(channelLabel + "_%d", b);
+            getReportLog().addValue(
+                    bandLabel + "_Level",
+                    results.mAverageEnergyPerBand[b],
+                    ResultType.HIGHER_BETTER,
+                    ResultUnit.NONE);
+
+            getReportLog().addValue(
+                    bandLabel + "_pointsinbound",
+                    results.mInBoundPointsPerBand[b],
+                    ResultType.HIGHER_BETTER,
+                    ResultUnit.COUNT);
+
+            getReportLog().addValue(
+                    bandLabel + "_pointstotal",
+                    results.mPointsPerBand[b],
+                    ResultType.NEUTRAL,
+                    ResultUnit.COUNT);
+        }
+
+        getReportLog().addValues(channelLabel + "_magnitudeSpectrumLog",
+                results.mValuesLog,
+                ResultType.NEUTRAL,
+                ResultUnit.NONE);
+
+        Log.v(TAG, "Results Recorded");
+    }
+
+    private void recordHeasetPortFound(boolean found) {
+        getReportLog().addValue(
+                "User Reported Headset Port",
+                found ? 1.0 : 0,
+                ResultType.NEUTRAL,
+                ResultUnit.NONE);
+    }
+
+    private void startRecording() {
+        synchronized (mRecordingLock) {
+            mIsRecording = true;
+        }
+
+        boolean successful = initRecord();
+        if (successful) {
+            startRecordingForReal();
+        } else {
+            Log.v(TAG, "Recorder initialization error.");
+            synchronized (mRecordingLock) {
+                mIsRecording = false;
+            }
+        }
+    }
+
+    private void startRecordingForReal() {
+        // start streaming
+        if (mRecordThread == null) {
+            mRecordThread = new Thread(AudioFrequencyUnprocessedActivity.this);
+            mRecordThread.setName("FrequencyAnalyzerThread");
+        }
+        if (!mRecordThread.isAlive()) {
+            mRecordThread.start();
+        }
+
+        mPipe.flush();
+
+        long startTime = SystemClock.uptimeMillis();
+        mRecorder.startRecording();
+        if (mRecorder.getRecordingState() != AudioRecord.RECORDSTATE_RECORDING) {
+            stopRecording();
+            return;
+        }
+        Log.v(TAG, "Start time: " + (long) (SystemClock.uptimeMillis() - startTime) + " ms");
+    }
+
+    private void stopRecording() {
+        synchronized (mRecordingLock) {
+            stopRecordingForReal();
+            mIsRecording = false;
+        }
+    }
+
+    private void stopRecordingForReal() {
+
+        // stop streaming
+        Thread zeThread = mRecordThread;
+        mRecordThread = null;
+        if (zeThread != null) {
+            zeThread.interrupt();
+            try {
+                zeThread.join();
+            } catch(InterruptedException e) {
+                //restore interrupted status of recording thread
+                zeThread.interrupt();
+            }
+        }
+         // release recording resources
+        if (mRecorder != null) {
+            mRecorder.stop();
+            mRecorder.release();
+            mRecorder = null;
+        }
+    }
+
+    private boolean initRecord() {
+        int minRecordBuffSizeInBytes = AudioRecord.getMinBufferSize(mSamplingRate,
+                mChannelConfig, mAudioFormat);
+        Log.v(TAG,"FrequencyAnalyzer: min buff size = " + minRecordBuffSizeInBytes + " bytes");
+        if (minRecordBuffSizeInBytes <= 0) {
+            return false;
+        }
+
+        mMinRecordBufferSizeInSamples = minRecordBuffSizeInBytes / 2;
+        // allocate the byte array to read the audio data
+
+        mAudioShortArray = new short[mMinRecordBufferSizeInSamples];
+
+        Log.v(TAG, "Initiating record:");
+        Log.v(TAG, "      using source " + mSelectedRecordSource);
+        Log.v(TAG, "      at " + mSamplingRate + "Hz");
+
+        try {
+            mRecorder = new AudioRecord(mSelectedRecordSource, mSamplingRate,
+                    mChannelConfig, mAudioFormat, 2 * minRecordBuffSizeInBytes);
+        } catch (IllegalArgumentException e) {
+            return false;
+        }
+        if (mRecorder.getState() != AudioRecord.STATE_INITIALIZED) {
+            mRecorder.release();
+            mRecorder = null;
+            return false;
+        }
+        mRecorder.setRecordPositionUpdateListener(this);
+        mRecorder.setPositionNotificationPeriod(mBlockSizeSamples / 2);
+        return true;
+    }
+
+    // ---------------------------------------------------------
+    // Implementation of AudioRecord.OnPeriodicNotificationListener
+    // --------------------
+    public void onPeriodicNotification(AudioRecord recorder) {
+        int samplesAvailable = mPipe.availableToRead();
+        int samplesNeeded = mBlockSizeSamples;
+        if (samplesAvailable >= samplesNeeded) {
+            mPipe.read(mAudioShortArray2, 0, samplesNeeded);
+
+            //compute stuff.
+            int clipcount = 0;
+            double sum = 0;
+            double maxabs = 0;
+            int i;
+
+            for (i = 0; i < samplesNeeded; i++) {
+                double value = mAudioShortArray2[i] / MAX_VAL;
+                double valueabs = Math.abs(value);
+
+                if (valueabs > maxabs) {
+                    maxabs = valueabs;
+                }
+
+                if (valueabs > CLIP_LEVEL) {
+                    clipcount++;
+                }
+
+                sum += value * value;
+                //fft stuff
+                mData.mData[i] = value;
+            }
+
+            //for the current frame, compute FFT and send to the viewer.
+
+            //apply window and pack as complex for now.
+            DspBufferMath.mult(mData, mData, mWindow.mBuffer);
+            DspBufferMath.set(mC, mData);
+            mFftServer.fft(mC, 1);
+
+            double[] halfMagnitude = new double[mBlockSizeSamples / 2];
+            for (i = 0; i < mBlockSizeSamples / 2; i++) {
+                halfMagnitude[i] = Math.sqrt(mC.mReal[i] * mC.mReal[i] + mC.mImag[i] * mC.mImag[i]);
+            }
+
+            mFreqAverageMain.setData(halfMagnitude, false); //average all of them!
+            mFreqAverageBuiltIn.setData(halfMagnitude, false);
+        }
+    }
+
+    public void onMarkerReached(AudioRecord track) {
+    }
+
+    // ---------------------------------------------------------
+    // Implementation of Runnable for the audio recording + playback
+    // --------------------
+    public void run() {
+        Thread thisThread = Thread.currentThread();
+        while (!thisThread.isInterrupted()) {
+            // read from native recorder
+            int nSamplesRead = mRecorder.read(mAudioShortArray, 0, mMinRecordBufferSizeInSamples);
+            if (nSamplesRead > 0) {
+                mPipe.write(mAudioShortArray, 0, nSamplesRead);
+            }
+        }
+    }
+}
diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/audio/AudioLoopbackActivity.java b/apps/CtsVerifier/src/com/android/cts/verifier/audio/AudioLoopbackActivity.java
index fbec57a..9e52d95 100644
--- a/apps/CtsVerifier/src/com/android/cts/verifier/audio/AudioLoopbackActivity.java
+++ b/apps/CtsVerifier/src/com/android/cts/verifier/audio/AudioLoopbackActivity.java
@@ -58,6 +58,9 @@
     private static final double CONFIDENCE_THRESHOLD = 0.6;
     private Correlation mCorrelation = new Correlation();
 
+    // TODO: remove this when no longer necessary
+    private int mNumFramesToIgnore = mSamplingRate / 10; // ignore first 100 ms
+
     OnBtnClickListener mBtnClickListener = new OnBtnClickListener();
     Context mContext;
 
@@ -221,7 +224,8 @@
             nativeAudioThread.setParams(mSamplingRate,
                     minBufferSizeInBytes,
                     minBufferSizeInBytes,
-                    0x03 /*voice recognition*/);
+                    0x03 /*voice recognition*/,
+                    mNumFramesToIgnore);
             nativeAudioThread.start();
 
             try {
diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/audio/NativeAudioThread.java b/apps/CtsVerifier/src/com/android/cts/verifier/audio/NativeAudioThread.java
index 224d4c8..0bb1298 100644
--- a/apps/CtsVerifier/src/com/android/cts/verifier/audio/NativeAudioThread.java
+++ b/apps/CtsVerifier/src/com/android/cts/verifier/audio/NativeAudioThread.java
@@ -53,6 +53,8 @@
 
     int mMicSource = 0;
 
+    int mNumFramesToIgnore;
+
 //    private double [] samples = new double[50000];
 
     boolean isPlaying = false;
@@ -66,11 +68,12 @@
     static final int NATIVE_AUDIO_THREAD_MESSAGE_REC_COMPLETE_ERRORS = 895;
 
     public void setParams(int samplingRate, int playBufferInBytes, int recBufferInBytes,
-            int micSource) {
+                          int micSource, int numFramesToIgnore) {
         mSamplingRate = samplingRate;
         mMinPlayBufferSizeInBytes = playBufferInBytes;
         mMinRecordBuffSizeInBytes = recBufferInBytes;
         mMicSource = micSource;
+        mNumFramesToIgnore = numFramesToIgnore;
     }
 
     //JNI load
@@ -86,7 +89,8 @@
     }
 
     //jni calls
-    public native long slesInit(int samplingRate, int frameCount, int micSource);
+    public native long slesInit(int samplingRate, int frameCount, int micSource,
+                                int numFramesToIgnore);
     public native int slesProcessNext(long sles_data, double[] samples, long offset);
     public native int slesDestroy(long sles_data);
 
@@ -124,7 +128,8 @@
 
         log(String.format("about to init, sampling rate: %d, buffer:%d", mSamplingRate,
                 mMinPlayBufferSizeInBytes/2 ));
-        long sles_data = slesInit(mSamplingRate, mMinPlayBufferSizeInBytes/2, mMicSource);
+        long sles_data = slesInit(mSamplingRate, mMinPlayBufferSizeInBytes/2, mMicSource,
+                                  mNumFramesToIgnore);
         log(String.format("sles_data = 0x%X",sles_data));
 
         if (sles_data == 0 ) {
diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/audio/wavelib/VectorAverage.java b/apps/CtsVerifier/src/com/android/cts/verifier/audio/wavelib/VectorAverage.java
index 41f0411..8783cbb 100644
--- a/apps/CtsVerifier/src/com/android/cts/verifier/audio/wavelib/VectorAverage.java
+++ b/apps/CtsVerifier/src/com/android/cts/verifier/audio/wavelib/VectorAverage.java
@@ -24,6 +24,12 @@
     private double[] mData;
     private int mValueCount = 0;
 
+    public static final int CAPTURE_TYPE_AVERAGE = 0;
+    public static final int CAPTURE_TYPE_MAX     = 1;
+    public static final int CAPTURE_TYPE_MIN     = 2;
+
+    private int mCaptureType = CAPTURE_TYPE_AVERAGE;
+
     public void setData(double[] data, boolean replace) {
         int size = data.length;
         if (mData == null || mData.length != size) {
@@ -34,10 +40,34 @@
             System.arraycopy(data, 0, mData, 0, size);
             mValueCount = 1;
         } else {
-            for (int i = 0; i < size; i++) {
-                mData[i] += data[i];
+            switch(mCaptureType) {
+                default:
+                case CAPTURE_TYPE_AVERAGE: {
+                    for (int i = 0; i < size; i++) {
+                        mData[i] += data[i];
+                    }
+                    mValueCount++;
+                }
+                break;
+                case CAPTURE_TYPE_MAX: {
+                    for (int i = 0; i < size; i++) {
+                        if (data[i] > mData[i]) {
+                            mData[i] = data[i];
+                        }
+                    }
+                    mValueCount = 1;
+                }
+                break;
+                case CAPTURE_TYPE_MIN: {
+                    for (int i = 0; i < size; i++) {
+                        if (data[i] < mData[i]) {
+                            mData[i] = data[i];
+                        }
+                    }
+                    mValueCount = 1;
+                }
+                break;
             }
-            mValueCount++;
         }
     }
 
@@ -77,6 +107,22 @@
         mValueCount = 0;
     }
 
+    public void setCaptureType(int type) {
+        switch(type) {
+            case CAPTURE_TYPE_AVERAGE:
+            case CAPTURE_TYPE_MAX:
+            case CAPTURE_TYPE_MIN:
+                mCaptureType = type;
+                break;
+            default:
+                mCaptureType = CAPTURE_TYPE_AVERAGE;
+        }
+    }
+
+    public int getCaptureType() {
+        return mCaptureType;
+    }
+
     private final String SERIALIZED_VERSION = "VECTOR_AVERAGE_VERSION";
     private final String SERIALIZED_COUNT = "COUNT";
 
diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/backup/BackupAccessibilityTestActivity.java b/apps/CtsVerifier/src/com/android/cts/verifier/backup/BackupAccessibilityTestActivity.java
new file mode 100644
index 0000000..157a71c
--- /dev/null
+++ b/apps/CtsVerifier/src/com/android/cts/verifier/backup/BackupAccessibilityTestActivity.java
@@ -0,0 +1,342 @@
+/*
+ * Copyright (C) 2011 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.verifier.backup;
+
+import com.android.cts.verifier.PassFailButtons;
+import com.android.cts.verifier.R;
+
+import android.app.AlertDialog;
+import android.app.Dialog;
+import android.app.backup.BackupManager;
+import android.app.backup.FileBackupHelper;
+import android.content.Context;
+import android.content.DialogInterface;
+import android.content.Intent;
+import android.graphics.Color;
+import android.os.AsyncTask;
+import android.os.Bundle;
+import android.provider.Settings;
+import android.util.Log;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.View.OnClickListener;
+import android.view.ViewGroup;
+import android.view.Window;
+import android.widget.BaseAdapter;
+import android.widget.TextView;
+import android.widget.Toast;
+
+import java.io.File;
+import java.io.FileNotFoundException;
+import java.io.PrintWriter;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Random;
+import java.util.Scanner;
+
+/**
+ * Test for checking whether Accessibility Settings are being backed up properly. It lists the
+ * values of the accessibility preferences that should get backed up and restored after running the
+ * backup manager and reinstalling the CTS verifier.
+ */
+public class BackupAccessibilityTestActivity extends PassFailButtons.ListActivity {
+
+    private static final String TAG = BackupAccessibilityTestActivity.class.getSimpleName();
+
+    private static final int INSTRUCTIONS_DIALOG_ID = 1;
+
+    private static final List<String> ACCESSIBILITY_SETTINGS = new ArrayList();
+    private static final List<String> COLOR_CORRECTION_SETTINGS = new ArrayList();
+    private static final List<String> ACCESSIBILITY_SERVICE_SETTINGS = new ArrayList();
+    private static final List<String> CAPTIONS_SETTINGS = new ArrayList();
+    private static final List<String> TTS_SETTINGS = new ArrayList();
+    private static final List<String> SYSTEM_SETTINGS = new ArrayList();
+
+    static {
+        ACCESSIBILITY_SETTINGS.add("accessibility_display_magnification_enabled");
+        ACCESSIBILITY_SETTINGS.add("accessibility_autoclick_enabled");
+        ACCESSIBILITY_SETTINGS.add("accessibility_autoclick_delay");
+        ACCESSIBILITY_SETTINGS.add("high_text_contrast_enabled");
+        ACCESSIBILITY_SETTINGS.add("incall_power_button_behavior");
+        ACCESSIBILITY_SETTINGS.add(Settings.Secure.ACCESSIBILITY_SPEAK_PASSWORD);
+        ACCESSIBILITY_SETTINGS.add("accessibility_large_pointer_icon");
+        ACCESSIBILITY_SETTINGS.add("long_press_timeout");
+        ACCESSIBILITY_SETTINGS.add(Settings.Secure.ACCESSIBILITY_DISPLAY_INVERSION_ENABLED);
+
+        COLOR_CORRECTION_SETTINGS.add("accessibility_display_daltonizer");
+        COLOR_CORRECTION_SETTINGS.add("accessibility_display_daltonizer_enabled");
+
+        CAPTIONS_SETTINGS.add("accessibility_captioning_preset");
+        CAPTIONS_SETTINGS.add("accessibility_captioning_enabled");
+        CAPTIONS_SETTINGS.add("accessibility_captioning_locale");
+        CAPTIONS_SETTINGS.add("accessibility_captioning_background_color");
+        CAPTIONS_SETTINGS.add("accessibility_captioning_foreground_color");
+        CAPTIONS_SETTINGS.add("accessibility_captioning_edge_type");
+        CAPTIONS_SETTINGS.add("accessibility_captioning_edge_color");
+        CAPTIONS_SETTINGS.add("accessibility_captioning_typeface");
+        CAPTIONS_SETTINGS.add("accessibility_captioning_font_scale");
+        CAPTIONS_SETTINGS.add("accessibility_captioning_window_color");
+
+        TTS_SETTINGS.add(Settings.Secure.TTS_DEFAULT_RATE);
+        TTS_SETTINGS.add("tts_default_locale");
+
+        ACCESSIBILITY_SERVICE_SETTINGS.add(Settings.Secure.ENABLED_ACCESSIBILITY_SERVICES);
+        ACCESSIBILITY_SERVICE_SETTINGS.add("touch_exploration_granted_accessibility_services");
+        ACCESSIBILITY_SERVICE_SETTINGS.add(Settings.Secure.TOUCH_EXPLORATION_ENABLED);
+
+        SYSTEM_SETTINGS.add(Settings.System.FONT_SCALE);
+        SYSTEM_SETTINGS.add(Settings.System.STAY_ON_WHILE_PLUGGED_IN);
+        SYSTEM_SETTINGS.add(Settings.System.SCREEN_OFF_TIMEOUT);
+        SYSTEM_SETTINGS.add(Settings.System.SCREEN_BRIGHTNESS);
+        SYSTEM_SETTINGS.add(Settings.System.SCREEN_BRIGHTNESS_MODE);
+        SYSTEM_SETTINGS.add(Settings.System.TEXT_SHOW_PASSWORD);
+        SYSTEM_SETTINGS.add(Settings.System.HAPTIC_FEEDBACK_ENABLED);
+        SYSTEM_SETTINGS.add("power_sounds_enabled");
+        SYSTEM_SETTINGS.add("lockscreen_sounds_enabled");
+        SYSTEM_SETTINGS.add("pointer_speed");
+        SYSTEM_SETTINGS.add(Settings.System.VIBRATE_WHEN_RINGING);
+        SYSTEM_SETTINGS.add(Settings.System.ACCELEROMETER_ROTATION);
+    }
+
+    private BackupAdapter mAdapter;
+
+    @Override
+    protected void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+        requestWindowFeature(Window.FEATURE_INDETERMINATE_PROGRESS);
+        setContentView(R.layout.bua_main);
+        setPassFailButtonClickListeners();
+        setInfoResources(R.string.backup_accessibility_test, R.string.backup_accessibility_info, 0);
+
+        mAdapter = new BackupAdapter(this);
+        setListAdapter(mAdapter);
+
+        new ReadCurrentSettingsValuesTask().execute();
+
+        findViewById(R.id.generate_button).setOnClickListener(new OnClickListener() {
+            @Override
+            public void onClick(View v) {
+                new ReadCurrentSettingsValuesTask().execute();
+            }
+        });
+
+        findViewById(R.id.show_instructions_button).setOnClickListener(new OnClickListener() {
+            @Override
+            public void onClick(View v) {
+                showDialog(INSTRUCTIONS_DIALOG_ID);
+            }
+        });
+    }
+
+    class ReadCurrentSettingsValuesTask extends AsyncTask<Void, Void, List<BackupItem>> {
+
+        @Override
+        protected void onPreExecute() {
+            super.onPreExecute();
+            setProgressBarIndeterminateVisibility(true);
+        }
+
+        @Override
+        protected List<BackupItem> doInBackground(Void... params) {
+            List<BackupItem> items = new ArrayList<BackupItem>();
+
+            items.add(new CategoryBackupItem(R.string.bua_settings));
+            addSecureSettings(items, ACCESSIBILITY_SETTINGS);
+
+            items.add(new CategoryBackupItem(R.string.bua_settings_color_correction));
+            addSecureSettings(items, COLOR_CORRECTION_SETTINGS);
+
+            items.add(new CategoryBackupItem(R.string.bua_settings_captions));
+            addSecureSettings(items, CAPTIONS_SETTINGS);
+
+            items.add(new CategoryBackupItem(R.string.bua_settings_tts));
+            addSecureSettings(items, TTS_SETTINGS);
+
+            items.add(new CategoryBackupItem(R.string.bua_settings_accessibility_services));
+            addSecureSettings(items, ACCESSIBILITY_SERVICE_SETTINGS);
+
+            items.add(new CategoryBackupItem(R.string.bua_settings_system));
+            addSystemSettings(items, SYSTEM_SETTINGS);
+
+            return items;
+        }
+
+        private void addSecureSettings(List<BackupItem> items, List<String> settings) {
+            for (String setting : settings) {
+                String value = Settings.Secure.getString(getContentResolver(), setting);
+                items.add(new PreferenceBackupItem(setting, value));
+            }
+        }
+
+        private void addSystemSettings(List<BackupItem> items, List<String> settings) {
+            for (String setting : settings) {
+                String value = Settings.System.getString(getContentResolver(), setting);
+                items.add(new PreferenceBackupItem(setting, value));
+            }
+        }
+
+        @Override
+        protected void onPostExecute(List<BackupItem> result) {
+            super.onPostExecute(result);
+            setProgressBarIndeterminateVisibility(false);
+            mAdapter.clear();
+            mAdapter.addAll(result);
+        }
+    }
+
+    @Override
+    public Dialog onCreateDialog(int id, Bundle args) {
+        switch (id) {
+            case INSTRUCTIONS_DIALOG_ID:
+                return new AlertDialog.Builder(this)
+                    .setIcon(android.R.drawable.ic_dialog_info)
+                    .setTitle(R.string.backup_accessibility_test)
+                    .setMessage(R.string.bua_instructions)
+                    .setPositiveButton(android.R.string.ok, null)
+                    .setNeutralButton(R.string.bu_settings, new DialogInterface.OnClickListener() {
+                        @Override
+                        public void onClick(DialogInterface dialog, int which) {
+                            startActivity(new Intent(Settings.ACTION_PRIVACY_SETTINGS));
+                        }
+                    }).create();
+
+            default:
+                return super.onCreateDialog(id, args);
+        }
+    }
+
+    interface BackupItem {
+        int getViewType();
+        View getView(LayoutInflater inflater, int position, View convertView, ViewGroup parent);
+    }
+
+    static class CategoryBackupItem implements BackupItem {
+
+        private final int mTitleResId;
+
+        CategoryBackupItem(int titleResId) {
+            mTitleResId = titleResId;
+        }
+
+        @Override
+        public int getViewType() {
+            return 0;
+        }
+
+        @Override
+        public View getView(LayoutInflater inflater, int position, View convertView,
+                ViewGroup parent) {
+            TextView view = (TextView) convertView;
+            if (convertView == null) {
+                view = (TextView) inflater.inflate(R.layout.test_category_row, parent, false);
+            }
+            view.setText(mTitleResId);
+            view.setAllCaps(true);
+            view.setTextAppearance(1);  // Bold
+            return view;
+        }
+    }
+
+    static class PreferenceBackupItem implements BackupItem {
+
+        private final String mName;
+        private final String mValue;
+
+        PreferenceBackupItem(String name, String value) {
+            mName = name;
+            mValue = value;
+        }
+
+        @Override
+        public int getViewType() {
+            if (mValue == null || mValue.equals("0")) {
+                return 1;
+            } else {
+                return 2;
+            }
+        }
+
+        @Override
+        public View getView(LayoutInflater inflater, int position, View convertView,
+                ViewGroup parent) {
+            TextView view = (TextView) convertView;
+            if (convertView == null) {
+                view = (TextView) inflater.inflate(R.layout.bu_preference_row, parent, false);
+            }
+            view.setText(mName + " : " + mValue);
+            if (mValue == null || mValue.equals("0")) {
+                view.setTextColor(Color.GREEN);
+            }
+            return view;
+        }
+    }
+
+    class BackupAdapter extends BaseAdapter {
+
+        private final LayoutInflater mLayoutInflater;
+
+        private final List<BackupItem> mItems = new ArrayList<BackupItem>();
+
+        public BackupAdapter(Context context) {
+            mLayoutInflater = (LayoutInflater) context.getSystemService(LAYOUT_INFLATER_SERVICE);
+        }
+
+        public void clear() {
+            mItems.clear();
+        }
+
+        public void addAll(List<BackupItem> items) {
+            mItems.addAll(items);
+            notifyDataSetChanged();
+        }
+
+        @Override
+        public int getCount() {
+            return mItems.size();
+        }
+
+        @Override
+        public BackupItem getItem(int position) {
+            return mItems.get(position);
+        }
+
+        @Override
+        public long getItemId(int position) {
+            return position;
+        }
+
+        @Override
+        public boolean isEnabled(int position) {
+            return false;
+        }
+
+        @Override
+        public int getViewTypeCount() {
+            return 3;
+        }
+
+        @Override
+        public int getItemViewType(int position) {
+            return getItem(position).getViewType();
+        }
+
+        @Override
+        public View getView(int position, View convertView, ViewGroup parent) {
+            return getItem(position).getView(mLayoutInflater, position, convertView, parent);
+        }
+    }
+}
diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/camera/intents/CameraContentJobService.java b/apps/CtsVerifier/src/com/android/cts/verifier/camera/intents/CameraContentJobService.java
new file mode 100644
index 0000000..9e92163
--- /dev/null
+++ b/apps/CtsVerifier/src/com/android/cts/verifier/camera/intents/CameraContentJobService.java
@@ -0,0 +1,115 @@
+/*
+ * Copyright (C) 2016 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.verifier.camera.intents;
+
+import android.annotation.TargetApi;
+import android.app.job.JobInfo;
+import android.app.job.JobParameters;
+import android.app.job.JobScheduler;
+import android.app.job.JobService;
+import android.content.Context;
+import android.os.ConditionVariable;
+import android.os.Handler;
+import android.util.Log;
+
+/**
+ * Handles callback from the framework {@link android.app.job.JobScheduler}. The behaviour of this
+ * class is configured through the static
+ * {@link TestEnvironment}.
+ */
+@TargetApi(21)
+public class CameraContentJobService extends JobService {
+    private static final String TAG = "CameraContentJobService";
+
+    /** Wait this long before timing out the test. */
+    private static final long DEFAULT_TIMEOUT_MILLIS = 60000L; // 60 seconds.
+
+    @Override
+    public void onCreate() {
+        super.onCreate();
+        Log.i(TAG, "Created test service.");
+    }
+
+    @Override
+    public boolean onStartJob(JobParameters params) {
+        Log.i(TAG, "Test job executing: " + params.getJobId());
+        TestEnvironment.getTestEnvironment().notifyExecution(params);
+        return false;  // No work to do.
+    }
+
+    @Override
+    public boolean onStopJob(JobParameters params) {
+        return false;
+    }
+
+    /**
+     * Configures the expected behaviour for each test. This object is shared across consecutive
+     * tests, so to clear state each test is responsible for calling
+     * {@link TestEnvironment#setUp()}.
+     */
+    public static final class TestEnvironment {
+
+        private static TestEnvironment kTestEnvironment;
+
+        private ConditionVariable mCondition = new ConditionVariable();
+        private JobParameters mExecutedJobParameters;
+        private boolean mCancelled = false;
+
+        public static TestEnvironment getTestEnvironment() {
+            if (kTestEnvironment == null) {
+                kTestEnvironment = new TestEnvironment();
+            }
+            return kTestEnvironment;
+        }
+
+        public JobParameters getLastJobParameters() {
+            return mExecutedJobParameters;
+        }
+
+        /**
+         * Block the test thread, waiting on the JobScheduler to execute some previously scheduled
+         * job on this service.
+         */
+        public boolean awaitExecution() throws InterruptedException {
+            final boolean executed = mCondition.block(DEFAULT_TIMEOUT_MILLIS);
+            if (mCancelled) {
+                return false;
+            }
+            return executed;
+        }
+
+        private void notifyExecution(JobParameters params) {
+            Log.d(TAG, "Job executed:" + params.getJobId());
+            mExecutedJobParameters = params;
+            mCondition.open();
+        }
+
+        // Cancel any ongoing wait. Will cause awaitExecution to return false (timeout)
+        public void cancelWait() {
+            mCancelled = true;
+            mCondition.open();
+        }
+
+        /** Called before starting a new test */
+        public void setUp() {
+            mCondition.close();
+            mExecutedJobParameters = null;
+            mCancelled = false;
+        }
+
+    }
+}
diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/camera/intents/CameraIntentsActivity.java b/apps/CtsVerifier/src/com/android/cts/verifier/camera/intents/CameraIntentsActivity.java
index 9204de3..161cceb 100644
--- a/apps/CtsVerifier/src/com/android/cts/verifier/camera/intents/CameraIntentsActivity.java
+++ b/apps/CtsVerifier/src/com/android/cts/verifier/camera/intents/CameraIntentsActivity.java
@@ -15,12 +15,18 @@
  */
 package com.android.cts.verifier.camera.intents;
 
-import android.content.BroadcastReceiver;
+import android.app.job.JobInfo;
+import android.app.job.JobParameters;
+import android.app.job.JobScheduler;
+import android.content.ComponentName;
 import android.content.Context;
 import android.content.Intent;
 import android.content.IntentFilter;
 import android.hardware.Camera;
+import android.net.Uri;
+import android.os.AsyncTask;
 import android.os.Bundle;
+import android.provider.MediaStore;
 import android.util.Log;
 import android.view.SurfaceHolder;
 import android.view.View;
@@ -29,6 +35,7 @@
 import android.widget.ImageButton;
 import android.widget.TextView;
 
+import com.android.cts.verifier.camera.intents.CameraContentJobService;
 import com.android.cts.verifier.PassFailButtons;
 import com.android.cts.verifier.R;
 import com.android.cts.verifier.TestResult;
@@ -36,12 +43,12 @@
 import java.util.TreeSet;
 
 /**
- * Tests for manual verification of camera intents being fired.
+ * Tests for manual verification of uri trigger being fired.
  *
- * android.hardware.Camera.ACTION_NEW_PICTURE - this should fire
+ * MediaStore.Images.Media.EXTERNAL_CONTENT_URI - this should fire
  *  when a new picture was captured by the camera app, and it has been
  *  added to the media store.
- * android.hardware.Camera.ACTION_NEW_VIDEO - this should fire when a new
+ * MediaStore.Video.Media.EXTERNAL_CONTENT_URI - this should fire when a new
  *  video has been captured by the camera app, and it has been added
  *  to the media store.
  *
@@ -70,21 +77,12 @@
     private static final int STAGE_INTENT_PICTURE = 2;
     private static final int STAGE_INTENT_VIDEO = 3;
 
-    private static String[]  EXPECTED_INTENTS = new String[] {
-        Camera.ACTION_NEW_PICTURE,
-        Camera.ACTION_NEW_VIDEO,
-        null,
-        Camera.ACTION_NEW_VIDEO
-    };
-
     private ImageButton mPassButton;
     private ImageButton mFailButton;
     private Button mStartTestButton;
 
     private int mState = STATE_OFF;
 
-    private BroadcastReceiver mReceiver;
-    private IntentFilter mFilterPicture;
     private boolean mActivityResult = false;
     private boolean mDetectCheating = false;
 
@@ -92,45 +90,41 @@
     private final TreeSet<String> mTestedCombinations = new TreeSet<String>();
     private final TreeSet<String> mUntestedCombinations = new TreeSet<String>();
 
-    /* Callback from mReceiver#onReceive */
-    public void onReceivedIntent(Intent intent) {
-        Log.v(TAG, "Received intent " + intent.toString());
-        if (mState == STATE_STARTED) {
+    private CameraContentJobService.TestEnvironment mTestEnv;
+    private static final int CAMERA_JOB_ID = CameraIntentsActivity.class.hashCode();
+    private static final int JOB_TYPE_IMAGE = 0;
+    private static final int JOB_TYPE_VIDEO = 1;
 
-            /* this can happen if..
-              the camera apps intent finishes,
-              user returns to cts verifier,
-              user leaves cts verifier and tries to fake receiver intents
-              */
-            if (mDetectCheating) {
-                Log.w(TAG, "Cheating attempt suppressed");
+    private static int[] TEST_JOB_TYPES = new int[] {
+        JOB_TYPE_IMAGE,
+        JOB_TYPE_VIDEO,
+        JOB_TYPE_IMAGE,
+        JOB_TYPE_VIDEO
+    };
 
-                mState = STATE_FAILED;
-            }
-
-            String expectedIntent = EXPECTED_INTENTS[getStageIndex()];
-            if (expectedIntent != intent.getAction()) {
-                Log.e(TAG, "FAIL: Test # " + getStageIndex()
-                    + " must not broadcast "
-                    + intent.getAction()
-                    + ", expected: "
-                    + (expectedIntent != null ? expectedIntent : "no intent"));
-
-                mState = STATE_FAILED;
-            }
-
-            if (mState != STATE_FAILED) {
-                mState = STATE_SUCCESSFUL;
-
-                mPassButton.setEnabled(true);
-                mFailButton.setEnabled(false);
-            }
-            else {
-                mPassButton.setEnabled(false);
-                mFailButton.setEnabled(true);
-            }
-
+    private JobInfo makeJobInfo(int jobType) {
+        JobInfo.Builder builder = new JobInfo.Builder(CAMERA_JOB_ID,
+                new ComponentName(this, CameraContentJobService.class));
+        // Look for specific changes to images in the provider.
+        Uri uriToTrigger = null;
+        switch (jobType) {
+            case JOB_TYPE_IMAGE:
+                uriToTrigger = MediaStore.Images.Media.EXTERNAL_CONTENT_URI;
+                break;
+            case JOB_TYPE_VIDEO:
+                uriToTrigger = MediaStore.Video.Media.EXTERNAL_CONTENT_URI;
+                break;
+            default:
+                Log.e(TAG, "Unknown jobType" + jobType);
+                return null;
         }
+        builder.addTriggerContentUri(new JobInfo.TriggerContentUri(
+                uriToTrigger,
+                JobInfo.TriggerContentUri.FLAG_NOTIFY_FOR_DESCENDANTS));
+        // For testing purposes, react quickly.
+        builder.setTriggerContentUpdateDelay(100);
+        builder.setTriggerContentMaxDelay(100);
+        return builder.build();
     }
 
     private int getStageIndex()
@@ -236,41 +230,18 @@
                 (TextView) findViewById(R.id.instruction_text);
         instructionLabel.setText(R.string.ci_instruction_text_photo_label);
 
-        /* Display the instructions to launch camera app and take a photo
-        */
+        /* Display the instructions to launch camera app and take a photo */
         TextView cameraExtraLabel =
                 (TextView) findViewById(R.id.instruction_extra_text);
         cameraExtraLabel.setText(getStageInstructionLabel(getStageIndex()));
 
         mStartTestButton.setEnabled(true);
-
-        mReceiver = new BroadcastReceiver() {
-            @Override
-            public void onReceive(Context context, Intent intent) {
-                onReceivedIntent(intent);
-            }
-        };
-
-        mFilterPicture = new IntentFilter();
-        mFilterPicture.addAction(Camera.ACTION_NEW_PICTURE);
-        mFilterPicture.addAction(Camera.ACTION_NEW_VIDEO);
-
-        try {
-            mFilterPicture.addDataType("video/*");
-            mFilterPicture.addDataType("image/*");
-        }
-        catch(IntentFilter.MalformedMimeTypeException e) {
-            Log.e(TAG, "Caught exceptione e " + e.toString());
-        }
-        registerReceiver(mReceiver, mFilterPicture);
     }
 
     @Override
     public void onDestroy() {
         super.onDestroy();
-
         Log.v(TAG, "onDestroy");
-        this.unregisterReceiver(mReceiver);
     }
 
     @Override
@@ -281,7 +252,6 @@
     @Override
     public void onPause() {
         super.onPause();
-
         /*
         When testing INTENT_PICTURE, INTENT_VIDEO,
         do not allow user to cheat by going to camera app and re-firing
@@ -307,12 +277,11 @@
 
             if (mState != STATE_FAILED
                 && getStageIndex() == STAGE_INTENT_PICTURE) {
-
                 mPassButton.setEnabled(true);
                 mFailButton.setEnabled(false);
 
                 mState = STATE_SUCCESSFUL;
-                /* successful, unless we get the mediastore intent back
+                /* successful, unless we get the URI trigger back
                  at some point later on */
             }
         }
@@ -323,16 +292,85 @@
         return mReportBuilder.toString();
     }
 
+    private class WaitForTriggerTask extends AsyncTask<Void, Void, Boolean> {
+        protected Boolean doInBackground(Void... param) {
+            try {
+                boolean executed = mTestEnv.awaitExecution();
+                // Check latest test param
+                if (executed && mState == STATE_STARTED) {
+
+                    // this can happen if..
+                    //  the camera apps intent finishes,
+                    //  user returns to cts verifier,
+                    //  user leaves cts verifier and tries to fake receiver intents
+                    if (mDetectCheating) {
+                        Log.w(TAG, "Cheating attempt suppressed");
+                        mState = STATE_FAILED;
+                    }
+
+                    // For STAGE_INTENT_PICTURE test, if EXTRA_OUTPUT is not assigned in intent,
+                    // file should NOT be saved so triggering this is a test failure.
+                    if (getStageIndex() == STAGE_INTENT_PICTURE) {
+                        Log.e(TAG, "FAIL: STAGE_INTENT_PICTURE test should not create file");
+                        mState = STATE_FAILED;
+                    }
+
+                    if (mState != STATE_FAILED) {
+                        mState = STATE_SUCCESSFUL;
+                        return true;
+                    } else {
+                        return false;
+                    }
+                }
+            } catch (InterruptedException e) {
+                e.printStackTrace();
+            }
+
+            if (getStageIndex() == STAGE_INTENT_PICTURE) {
+                // STAGE_INTENT_PICTURE should timeout
+                return true;
+            } else {
+                Log.e(TAG, "FAIL: timeout waiting for URI trigger");
+                return false;
+            }
+        }
+
+        protected void onPostExecute(Boolean pass) {
+            if (pass) {
+                mPassButton.setEnabled(true);
+                mFailButton.setEnabled(false);
+            } else {
+                mPassButton.setEnabled(false);
+                mFailButton.setEnabled(true);
+            }
+        }
+    }
+
     @Override
     public void onClick(View view) {
         Log.v(TAG, "Click detected");
 
+        final int stageIndex = getStageIndex();
+
         if (view == mStartTestButton) {
             Log.v(TAG, "Starting testing... ");
 
 
             mState = STATE_STARTED;
 
+            JobScheduler jobScheduler = (JobScheduler) getSystemService(
+                    Context.JOB_SCHEDULER_SERVICE);
+            jobScheduler.cancelAll();
+
+            mTestEnv = CameraContentJobService.TestEnvironment.getTestEnvironment();
+
+            mTestEnv.setUp();
+
+            JobInfo job = makeJobInfo(TEST_JOB_TYPES[stageIndex]);
+            jobScheduler.schedule(job);
+
+            new WaitForTriggerTask().execute();
+
             /* we can allow user to fail immediately */
             mFailButton.setEnabled(true);
 
@@ -340,10 +378,10 @@
                 which will run the camera app itself */
             String intentStr = null;
             Intent cameraIntent = null;
-            if (getStageIndex() == STAGE_INTENT_PICTURE) {
+            if (stageIndex == STAGE_INTENT_PICTURE) {
                 intentStr = android.provider.MediaStore.ACTION_IMAGE_CAPTURE;
             }
-            else if (getStageIndex() == STAGE_INTENT_VIDEO) {
+            else if (stageIndex == STAGE_INTENT_VIDEO) {
                 intentStr = android.provider.MediaStore.ACTION_VIDEO_CAPTURE;
             }
 
@@ -353,11 +391,12 @@
             }
 
             mStartTestButton.setEnabled(false);
-
         }
 
         if(view == mPassButton || view == mFailButton) {
-            final int stageIndex = getStageIndex();
+            // Stop any running wait
+            mTestEnv.cancelWait();
+
             for (int counter = 0; counter < NUM_STAGES; counter++) {
                 String combination = getStageString(counter) + "\n";
 
diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/camera/its/ItsService.java b/apps/CtsVerifier/src/com/android/cts/verifier/camera/its/ItsService.java
index 9a1b89e..0960d89 100644
--- a/apps/CtsVerifier/src/com/android/cts/verifier/camera/its/ItsService.java
+++ b/apps/CtsVerifier/src/com/android/cts/verifier/camera/its/ItsService.java
@@ -564,6 +564,7 @@
             // Each command is a serialized JSON object.
             try {
                 JSONObject cmdObj = new JSONObject(cmd);
+                Logt.i(TAG, "Start processing command" + cmdObj.getString("cmdName"));
                 if ("open".equals(cmdObj.getString("cmdName"))) {
                     int cameraId = cmdObj.getInt("cameraId");
                     openCameraDevice(cameraId);
@@ -588,6 +589,7 @@
                 } else {
                     throw new ItsException("Unknown command: " + cmd);
                 }
+                Logt.i(TAG, "Finish processing command" + cmdObj.getString("cmdName"));
             } catch (org.json.JSONException e) {
                 Logt.e(TAG, "Invalid command: ", e);
             }
@@ -642,6 +644,7 @@
 
         public void sendResponse(LinkedList<MySensorEvent> events)
                 throws ItsException {
+            Logt.i(TAG, "Sending " + events.size() + " sensor events");
             try {
                 JSONArray accels = new JSONArray();
                 JSONArray mags = new JSONArray();
@@ -668,6 +671,7 @@
             } catch (org.json.JSONException e) {
                 throw new ItsException("JSON error: ", e);
             }
+            Logt.i(TAG, "Sent sensor events");
         }
 
         public void sendResponse(CameraCharacteristics props)
diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/features/FeatureSummaryActivity.java b/apps/CtsVerifier/src/com/android/cts/verifier/features/FeatureSummaryActivity.java
index 285c8da..af34931 100644
--- a/apps/CtsVerifier/src/com/android/cts/verifier/features/FeatureSummaryActivity.java
+++ b/apps/CtsVerifier/src/com/android/cts/verifier/features/FeatureSummaryActivity.java
@@ -238,6 +238,15 @@
             new Feature(PackageManager.FEATURE_FINGERPRINT, false),
     };
 
+    public static final Feature[] ALL_NYC_FEATURES = {
+            new Feature(PackageManager.FEATURE_VR_MODE, false),
+            new Feature(PackageManager.FEATURE_VR_MODE_HIGH_PERFORMANCE, false),
+            new Feature(PackageManager.FEATURE_VULKAN_HARDWARE_VERSION, false),
+            new Feature(PackageManager.FEATURE_VULKAN_HARDWARE_LEVEL, false),
+            new Feature(PackageManager.FEATURE_NFC_HOST_CARD_EMULATION_NFCF, false),
+            new Feature(PackageManager.FEATURE_PICTURE_IN_PICTURE, false),
+    };
+
     @Override
     public void onCreate(Bundle savedInstanceState) {
         super.onCreate(savedInstanceState);
@@ -269,6 +278,9 @@
 
         // add features from latest to last so that the latest requirements are put in the set first
         int apiVersion = Build.VERSION.SDK_INT;
+        if (apiVersion >= Build.VERSION_CODES.N) {
+            Collections.addAll(features, ALL_NYC_FEATURES);
+        }
         if (apiVersion >= Build.VERSION_CODES.M) {
             Collections.addAll(features, ALL_MNC_FEATURES);
         }
diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/location/GnssMeasurementRegistrationTestsActivity.java b/apps/CtsVerifier/src/com/android/cts/verifier/location/GnssMeasurementRegistrationTestsActivity.java
new file mode 100644
index 0000000..56755cc
--- /dev/null
+++ b/apps/CtsVerifier/src/com/android/cts/verifier/location/GnssMeasurementRegistrationTestsActivity.java
@@ -0,0 +1,30 @@
+/*
+ * Copyright (C) 2016 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.verifier.location;
+
+import android.location.cts.GnssMeasurementRegistrationTest;
+import com.android.cts.verifier.location.base.GnssCtsTestActivity;
+
+/**
+ * Activity to execute CTS Gnss Measurement tests.
+ * It is a wrapper for {@link GnssMeasurementValuesTest} running with AndroidJUnitRunner.
+ */
+public class GnssMeasurementRegistrationTestsActivity extends GnssCtsTestActivity {
+    public GnssMeasurementRegistrationTestsActivity() {
+        super(GnssMeasurementRegistrationTest.class);
+    }
+}
diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/location/GnssMeasurementValuesTestsActivity.java b/apps/CtsVerifier/src/com/android/cts/verifier/location/GnssMeasurementValuesTestsActivity.java
new file mode 100644
index 0000000..4bdbddf
--- /dev/null
+++ b/apps/CtsVerifier/src/com/android/cts/verifier/location/GnssMeasurementValuesTestsActivity.java
@@ -0,0 +1,30 @@
+/*
+ * Copyright (C) 2016 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.verifier.location;
+
+import android.location.cts.GnssMeasurementValuesTest;
+import com.android.cts.verifier.location.base.GnssCtsTestActivity;
+
+/**
+ * Activity to execute CTS Gnss Measurement tests.
+ * It is a wrapper for {@link GnssMeasurementValuesTest} running with AndroidJUnitRunner.
+ */
+public class GnssMeasurementValuesTestsActivity extends GnssCtsTestActivity {
+    public GnssMeasurementValuesTestsActivity() {
+        super(GnssMeasurementValuesTest.class);
+    }
+}
diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/location/GnssMeasurementWhenNoLocationTestsActivity.java b/apps/CtsVerifier/src/com/android/cts/verifier/location/GnssMeasurementWhenNoLocationTestsActivity.java
new file mode 100644
index 0000000..1ee74c5
--- /dev/null
+++ b/apps/CtsVerifier/src/com/android/cts/verifier/location/GnssMeasurementWhenNoLocationTestsActivity.java
@@ -0,0 +1,30 @@
+/*
+ * Copyright (C) 2016 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.verifier.location;
+
+import android.location.cts.GnssMeasurementWhenNoLocationTest;
+import com.android.cts.verifier.location.base.GnssCtsTestActivity;
+
+/**
+ * Activity to execute CTS GnssMeasurementWhenNoLocationTest.
+ * It is a wrapper for {@link GnssMeasurementValuesTest} running with AndroidJUnitRunner.
+ */
+public class GnssMeasurementWhenNoLocationTestsActivity extends GnssCtsTestActivity {
+    public GnssMeasurementWhenNoLocationTestsActivity() {
+        super(GnssMeasurementWhenNoLocationTest.class);
+    }
+}
diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/location/GnssMeasurementsConstellationTestsActivity.java b/apps/CtsVerifier/src/com/android/cts/verifier/location/GnssMeasurementsConstellationTestsActivity.java
new file mode 100644
index 0000000..c59346a1
--- /dev/null
+++ b/apps/CtsVerifier/src/com/android/cts/verifier/location/GnssMeasurementsConstellationTestsActivity.java
@@ -0,0 +1,30 @@
+/*
+ * Copyright (C) 2016 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.verifier.location;
+
+import android.location.cts.GnssMeasurementsConstellationTest;
+import com.android.cts.verifier.location.base.GnssCtsTestActivity;
+
+/**
+ * Activity to execute CTS Gnss ConstellationType tests.
+ * It is a wrapper for {@link GnssConstellationTypeTest} running with AndroidJUnitRunner.
+ */
+public class GnssMeasurementsConstellationTestsActivity extends GnssCtsTestActivity {
+    public GnssMeasurementsConstellationTestsActivity() {
+        super(GnssMeasurementsConstellationTest.class);
+    }
+}
diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/location/GnssNavigationMessageTestsActivity.java b/apps/CtsVerifier/src/com/android/cts/verifier/location/GnssNavigationMessageTestsActivity.java
new file mode 100644
index 0000000..a4c9c93
--- /dev/null
+++ b/apps/CtsVerifier/src/com/android/cts/verifier/location/GnssNavigationMessageTestsActivity.java
@@ -0,0 +1,30 @@
+/*
+ * Copyright (C) 2016 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.verifier.location;
+
+import android.location.cts.GnssNavigationMessageTest;
+import com.android.cts.verifier.location.base.GnssCtsTestActivity;
+
+/**
+ * Activity to execute CTS GnssNavigationMessageTest.
+ * It is a wrapper for {@link GnssMeasurementValuesTest} running with AndroidJUnitRunner.
+ */
+public class GnssNavigationMessageTestsActivity extends GnssCtsTestActivity {
+    public GnssNavigationMessageTestsActivity() {
+        super(GnssNavigationMessageTest.class);
+    }
+}
\ No newline at end of file
diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/location/LocationListenerActivity.java b/apps/CtsVerifier/src/com/android/cts/verifier/location/LocationListenerActivity.java
new file mode 100644
index 0000000..8140b3f
--- /dev/null
+++ b/apps/CtsVerifier/src/com/android/cts/verifier/location/LocationListenerActivity.java
@@ -0,0 +1,126 @@
+package com.android.cts.verifier.location;
+
+import android.app.Activity;
+import android.content.Intent;
+import android.location.Location;
+import android.location.LocationListener;
+import android.location.LocationManager;
+import android.os.Bundle;
+import android.os.Handler;
+import android.os.Message;
+import android.os.Process;
+import android.provider.Settings;
+import android.util.Log;
+import android.widget.Toast;
+
+import com.android.cts.verifier.R;
+
+public class LocationListenerActivity extends Activity implements Handler.Callback {
+    // Primary -> managed intent: request to goto the location settings page and listen to updates.
+    public static final String ACTION_SET_LOCATION_AND_CHECK_UPDATES =
+            "com.android.cts.verifier.location.SET_LOCATION_AND_CHECK";
+    private static final int REQUEST_LOCATION_UPDATE = 1;
+
+    private static final int MSG_TIMEOUT_ID = 1;
+
+    private static final long MSG_TIMEOUT_MILLISEC = 15000; // 15 seconds.
+
+    private LocationManager mLocationManager;
+    private Handler mHandler;
+    private boolean mIsLocationUpdated;
+
+    @Override
+    protected void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+        mLocationManager = (LocationManager) getSystemService(LOCATION_SERVICE);
+        mHandler = new Handler(this);
+        mIsLocationUpdated = false;
+        Intent intent = getIntent();
+        if (intent != null) {
+            String action = intent.getAction();
+            if (ACTION_SET_LOCATION_AND_CHECK_UPDATES.equals(action)) {
+                Log.d(getLogTag(), "ACTION_SET_LOCATION_AND_CHECK_UPDATES received in uid "
+                        + Process.myUid());
+                handleLocationAction();
+            }
+        }
+    }
+
+    @Override
+    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
+        switch (requestCode) {
+            case REQUEST_LOCATION_UPDATE: {
+                Log.d(getLogTag(), "Exit location settings:OK");
+                mLocationManager.removeUpdates(mLocationListener);
+                mHandler.removeMessages(MSG_TIMEOUT_ID);
+                finish();
+                break;
+            }
+            default: {
+                Log.wtf(getLogTag(), "Unknown requestCode " + requestCode + "; data = " + data);
+                break;
+            }
+        }
+    }
+
+    protected void handleLocationAction() {
+        Intent locationSettingsIntent = new Intent(Settings.ACTION_LOCATION_SOURCE_SETTINGS);
+        if (locationSettingsIntent.resolveActivity(getPackageManager()) != null) {
+            startActivityForResult(locationSettingsIntent, REQUEST_LOCATION_UPDATE);
+            scheduleTimeout();
+        } else {
+            Log.e(getLogTag(), "Settings.ACTION_LOCATION_SOURCE_SETTINGS could not be resolved");
+            finish();
+        }
+        mLocationManager.requestLocationUpdates(
+                LocationManager.GPS_PROVIDER, 0, 0, mLocationListener);
+    }
+
+    private final LocationListener mLocationListener = new LocationListener() {
+        @Override
+        public void onLocationChanged(Location location) {
+            synchronized (LocationListenerActivity.this) {
+                if (mIsLocationUpdated) return;
+                showToast(R.string.provisioning_byod_location_mode_enable_toast_location_change);
+                mIsLocationUpdated = true;
+            }
+        }
+
+        @Override
+        public void onProviderDisabled(String provider) {
+        }
+
+        @Override
+        public void onProviderEnabled(String provider) {
+        }
+
+        @Override
+        public void onStatusChanged(String provider, int status, Bundle extras) {
+        }
+    };
+
+    private void scheduleTimeout() {
+        mHandler.removeMessages(MSG_TIMEOUT_ID);
+        mHandler.sendMessageDelayed(mHandler.obtainMessage(MSG_TIMEOUT_ID), MSG_TIMEOUT_MILLISEC);
+    }
+
+    @Override
+    public boolean handleMessage(Message msg) {
+        if (msg.what == MSG_TIMEOUT_ID) {
+            synchronized (this) {
+                if (mIsLocationUpdated) return true;
+                showToast(R.string.provisioning_byod_location_mode_time_out_toast);
+            }
+        }
+        return true;
+    }
+
+    protected String getLogTag() {
+        return "LocationListenerActivity";
+    }
+
+    protected void showToast(int messageId) {
+        String message = getString(messageId);
+        Toast.makeText(this, message, Toast.LENGTH_SHORT).show();
+    }
+}
diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/location/base/BaseGnssTestActivity.java b/apps/CtsVerifier/src/com/android/cts/verifier/location/base/BaseGnssTestActivity.java
new file mode 100644
index 0000000..5da985d
--- /dev/null
+++ b/apps/CtsVerifier/src/com/android/cts/verifier/location/base/BaseGnssTestActivity.java
@@ -0,0 +1,447 @@
+/*
+ * Copyright (C) 2016 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.verifier.location.base;
+
+import com.android.cts.verifier.R;
+import com.android.cts.verifier.TestResult;
+import com.android.cts.verifier.location.reporting.GnssTestDetails;
+
+import junit.framework.Assert;
+
+import com.android.cts.verifier.PassFailButtons;
+
+import android.content.Context;
+import android.content.Intent;
+import android.hardware.cts.helpers.ActivityResultMultiplexedLatch;
+import android.media.MediaPlayer;
+import android.os.Bundle;
+import android.os.SystemClock;
+import android.os.Vibrator;
+import android.provider.Settings;
+import android.text.TextUtils;
+import android.text.format.DateUtils;
+import android.util.Log;
+import android.view.View;
+import android.widget.Button;
+import android.widget.LinearLayout;
+import android.widget.ScrollView;
+import android.widget.TextView;
+
+import java.util.ArrayList;
+import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Executors;
+import java.util.concurrent.TimeUnit;
+
+import android.test.AndroidTestCase;
+
+/**
+ * A base Activity that is used to build different methods to execute tests inside CtsVerifier.
+ * i.e. CTS tests, and semi-automated CtsVerifier tests.
+ *
+ * This class provides access to the following flow:
+ *      Activity set up
+ *          Execute tests (implemented by sub-classes)
+ *      Activity clean up
+ *
+ * Currently the following class structure is available:
+ * - BaseGnssTestActivity                 : provides the platform to execute Gnss tests inside
+ *      |                                     CtsVerifier.
+ *      |
+ *      -- GnssCtsTestActivity            : an activity that can be inherited from to wrap a CTS
+ *      |                                     Gnss test, and execute it inside CtsVerifier
+ *      |                                     these tests do not require any operator interaction
+ */
+public abstract class BaseGnssTestActivity extends PassFailButtons.Activity
+        implements View.OnClickListener, Runnable, IGnssTestStateContainer {
+    @Deprecated
+    protected static final String LOG_TAG = "GnssTest";
+
+    protected final Class mTestClass;
+
+    private final int mLayoutId;
+
+    private final ExecutorService mExecutorService = Executors.newSingleThreadExecutor();
+    private final ActivityResultMultiplexedLatch mActivityResultMultiplexedLatch =
+            new ActivityResultMultiplexedLatch();
+    private final ArrayList<CountDownLatch> mWaitForUserLatches = new ArrayList<CountDownLatch>();
+
+    private ScrollView mLogScrollView;
+    private LinearLayout mLogLayout;
+    private Button mNextButton;
+    protected TextView mTextView;
+
+    /**
+     * Constructor to be used by subclasses.
+     *
+     * @param testClass The class that contains the tests. It is dependant on test executor
+     *                  implemented by subclasses.
+     */
+    protected BaseGnssTestActivity(Class<? extends AndroidTestCase> testClass) {
+        this(testClass, R.layout.gnss_test);
+    }
+
+    /**
+     * Constructor to be used by subclasses. It allows to provide a custom layout for the test UI.
+     *
+     * @param testClass The class that contains the tests. It is dependant on test executor
+     *                  implemented by subclasses.
+     * @param layoutId The Id of the layout to use for the test UI. The layout must contain all the
+     *                 elements in the base layout {@code R.layout.gnss_test}.
+     */
+    protected BaseGnssTestActivity(Class testClass, int layoutId) {
+        mTestClass = testClass;
+        mLayoutId = layoutId;
+    }
+
+    @Override
+    protected void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+        setContentView(mLayoutId);
+
+        mLogScrollView = (ScrollView) findViewById(R.id.log_scroll_view);
+        mLogLayout = (LinearLayout) findViewById(R.id.log_layout);
+        mNextButton = (Button) findViewById(R.id.next_button);
+        mNextButton.setOnClickListener(this);
+        mTextView = (TextView) findViewById(R.id.text);
+
+        mTextView.setText(R.string.location_gnss_test_info);
+
+        updateNextButton(false /*not enabled*/);
+        mExecutorService.execute(this);
+    }
+
+    @Override
+    protected void onDestroy() {
+        super.onDestroy();
+        mExecutorService.shutdownNow();
+    }
+
+    @Override
+    protected void onPause() {
+        super.onPause();
+    }
+
+    @Override
+    protected void onResume() {
+        super.onResume();
+    }
+
+    @Override
+    public void onClick(View target) {
+        synchronized (mWaitForUserLatches) {
+            for (CountDownLatch latch : mWaitForUserLatches) {
+                latch.countDown();
+            }
+            mWaitForUserLatches.clear();
+        }
+    }
+
+    @Override
+    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
+        mActivityResultMultiplexedLatch.onActivityResult(requestCode, resultCode);
+    }
+
+    /**
+     * The main execution {@link Thread}.
+     *
+     * This function executes in a background thread, allowing the test run freely behind the
+     * scenes. It provides the following execution hooks:
+     *  - Activity SetUp/CleanUp (not available in JUnit)
+     *  - executeTests: to implement several execution engines
+     */
+    @Override
+    public void run() {
+        long startTimeNs = SystemClock.elapsedRealtimeNanos();
+        String testName = getTestClassName();
+
+        GnssTestDetails testDetails;
+        try {
+            testDetails = new GnssTestDetails(testName, GnssTestDetails.ResultCode.PASS);
+        } catch (Throwable e) {
+            testDetails = new GnssTestDetails(testName, "DeactivateFeatures", e);
+        }
+
+        GnssTestDetails.ResultCode resultCode = testDetails.getResultCode();
+        if (resultCode == GnssTestDetails.ResultCode.SKIPPED) {
+            // this is an invalid state at this point of the test setup
+            throw new IllegalStateException("Deactivation of features cannot skip the test.");
+        }
+        if (resultCode == GnssTestDetails.ResultCode.PASS) {
+            testDetails = executeActivityTests(testName);
+        }
+
+        // This set the test UI so the operator can report the result of the test
+        updateResult(testDetails);
+    }
+
+    /**
+     * A general set up routine. It executes only once before the first test case.
+     *
+     * NOTE: implementers must be aware of the interrupted status of the worker thread, and let
+     * {@link InterruptedException} propagate.
+     *
+     * @throws Throwable An exception that denotes the failure of set up. No tests will be executed.
+     */
+    protected void activitySetUp() throws Throwable {}
+
+    /**
+     * A general clean up routine. It executes upon successful execution of {@link #activitySetUp()}
+     * and after all the test cases.
+     *
+     * NOTE: implementers must be aware of the interrupted status of the worker thread, and handle
+     * it in two cases:
+     * - let {@link InterruptedException} propagate
+     * - if it is invoked with the interrupted status, prevent from showing any UI
+
+     * @throws Throwable An exception that will be logged and ignored, for ease of implementation
+     *                   by subclasses.
+     */
+    protected void activityCleanUp() throws Throwable {}
+
+    /**
+     * Performs the work of executing the tests.
+     * Sub-classes implementing different execution methods implement this method.
+     *
+     * @return A {@link GnssTestDetails} object containing information about the executed tests.
+     */
+    protected abstract GnssTestDetails executeTests() throws InterruptedException;
+
+    @Deprecated
+    protected void appendText(String text) {
+        TextAppender textAppender = new TextAppender(R.layout.snsr_instruction);
+        textAppender.setText(text);
+        textAppender.append();
+    }
+
+    @Deprecated
+    protected void clearText() {
+        this.runOnUiThread(new Runnable() {
+            @Override
+            public void run() {
+                mLogLayout.removeAllViews();
+            }
+        });
+    }
+
+    /**
+     * Waits for the operator to acknowledge a requested action.
+     *
+     * @param waitMessageResId The action requested to the operator.
+     */
+    protected void waitForUser(int waitMessageResId) throws InterruptedException {
+        CountDownLatch latch = new CountDownLatch(1);
+        synchronized (mWaitForUserLatches) {
+            mWaitForUserLatches.add(latch);
+        }
+
+        updateNextButton(true);
+        latch.await();
+        updateNextButton(false);
+    }
+
+    /**
+     * Waits for the operator to acknowledge to begin execution.
+     */
+    protected void waitForUserToBegin() throws InterruptedException {
+        waitForUser(R.string.snsr_wait_to_begin);
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public void waitForUserToContinue() throws InterruptedException {
+        waitForUser(R.string.snsr_wait_for_user);
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public int executeActivity(String action) throws InterruptedException {
+        return executeActivity(new Intent(action));
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public int executeActivity(Intent intent) throws InterruptedException {
+        ActivityResultMultiplexedLatch.Latch latch = mActivityResultMultiplexedLatch.bindThread();
+        startActivityForResult(intent, latch.getRequestCode());
+        return latch.await();
+    }
+
+    /**
+     * Plays a (default) sound as a notification for the operator.
+     */
+    protected void playSound() throws InterruptedException {
+        MediaPlayer player = MediaPlayer.create(this, Settings.System.DEFAULT_NOTIFICATION_URI);
+        if (player == null) {
+            Log.e(LOG_TAG, "MediaPlayer unavailable.");
+            return;
+        }
+        player.start();
+        try {
+            Thread.sleep(500);
+        } finally {
+            player.stop();
+        }
+    }
+
+    /**
+     * Makes the device vibrate for the given amount of time.
+     */
+    protected void vibrate(int timeInMs) {
+        Vibrator vibrator = (Vibrator) getSystemService(Context.VIBRATOR_SERVICE);
+        vibrator.vibrate(timeInMs);
+    }
+
+    /**
+     * Makes the device vibrate following the given pattern.
+     * See {@link Vibrator#vibrate(long[], int)} for more information.
+     */
+    protected void vibrate(long[] pattern) {
+        Vibrator vibrator = (Vibrator) getSystemService(Context.VIBRATOR_SERVICE);
+        vibrator.vibrate(pattern, -1);
+    }
+
+    protected String getTestClassName() {
+        if (mTestClass == null) {
+            return "<unknown>";
+        }
+        return mTestClass.getName();
+    }
+
+    protected void setLogScrollViewListener(View.OnTouchListener listener) {
+        mLogScrollView.setOnTouchListener(listener);
+    }
+
+    private void setTestResult(GnssTestDetails testDetails) {
+        // the name here, must be the Activity's name because it is what CtsVerifier expects
+        String name = super.getClass().getName();
+        GnssTestDetails.ResultCode resultCode = testDetails.getResultCode();
+        switch(resultCode) {
+            case SKIPPED:
+                TestResult.setPassedResult(this, name, "");
+                break;
+            case PASS:
+                TestResult.setPassedResult(this, name, "");
+                break;
+            case FAIL:
+                TestResult.setFailedResult(this, name, "");
+                break;
+            case INTERRUPTED:
+                // do not set a result, just return so the test can complete
+                break;
+            default:
+                throw new IllegalStateException("Unknown ResultCode: " + resultCode);
+        }
+    }
+
+    private GnssTestDetails executeActivityTests(String testName) {
+        GnssTestDetails testDetails;
+        try {
+            activitySetUp();
+            testDetails = new GnssTestDetails(testName, GnssTestDetails.ResultCode.PASS);
+        } catch (Throwable e) {
+            testDetails = new GnssTestDetails(testName, "ActivitySetUp", e);
+        }
+
+        GnssTestDetails.ResultCode resultCode = testDetails.getResultCode();
+        if (resultCode == GnssTestDetails.ResultCode.PASS) {
+            // TODO: implement execution filters:
+            //      - execute all tests and report results officially
+            //      - execute single test or failed tests only
+            try {
+                testDetails = executeTests();
+            } catch (Throwable e) {
+                // we catch and continue because we have to guarantee a proper clean-up sequence
+                testDetails = new GnssTestDetails(testName, "TestExecution", e);
+            }
+        }
+
+        // clean-up executes for all states, even on SKIPPED and INTERRUPTED there might be some
+        // intermediate state that needs to be taken care of
+        try {
+            activityCleanUp();
+        } catch (Throwable e) {
+            testDetails = new GnssTestDetails(testName, "ActivityCleanUp", e);
+        }
+
+        return testDetails;
+    }
+
+    private void updateResult(final GnssTestDetails testDetails) {
+        runOnUiThread(new Runnable() {
+            @Override
+            public void run() {
+                setTestResult(testDetails);
+            }
+        });
+    }
+
+    private void updateNextButton(final boolean enabled) {
+        runOnUiThread(new Runnable() {
+            @Override
+            public void run() {
+                mNextButton.setEnabled(enabled);
+            }
+        });
+    }
+
+    private class ViewAppender {
+        protected final View mView;
+
+        public ViewAppender(View view) {
+            mView = view;
+        }
+
+        public void append() {
+            runOnUiThread(new Runnable() {
+                @Override
+                public void run() {
+                    mLogLayout.addView(mView);
+                    mLogScrollView.post(new Runnable() {
+                        @Override
+                        public void run() {
+                            mLogScrollView.fullScroll(View.FOCUS_DOWN);
+                        }
+                    });
+                }
+            });
+        }
+    }
+
+    private class TextAppender extends ViewAppender{
+        private final TextView mTextView;
+
+        public TextAppender(int textViewResId) {
+            super(getLayoutInflater().inflate(textViewResId, null /* viewGroup */));
+            mTextView = (TextView) mView;
+        }
+
+        public void setText(String text) {
+            mTextView.setText(text);
+        }
+
+        public void setText(int textResId) {
+            mTextView.setText(textResId);
+        }
+    }
+}
\ No newline at end of file
diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/location/base/GnssCtsTestActivity.java b/apps/CtsVerifier/src/com/android/cts/verifier/location/base/GnssCtsTestActivity.java
new file mode 100644
index 0000000..1e7e481
--- /dev/null
+++ b/apps/CtsVerifier/src/com/android/cts/verifier/location/base/GnssCtsTestActivity.java
@@ -0,0 +1,248 @@
+/*
+ * Copyright (C) 2016 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.verifier.location.base;
+
+import android.location.cts.GnssTestCase;
+import android.location.cts.MultiConstellationNotSupportedException;
+import android.view.WindowManager;
+
+import com.android.cts.verifier.R;
+import com.android.cts.verifier.location.reporting.GnssTestDetails;
+
+import junit.framework.Test;
+import junit.framework.TestSuite;
+
+import org.junit.internal.runners.JUnit38ClassRunner;
+import org.junit.internal.runners.SuiteMethod;
+import org.junit.runner.Computer;
+import org.junit.runner.Description;
+import org.junit.runner.JUnitCore;
+import org.junit.runner.Request;
+import org.junit.runner.Result;
+import org.junit.runner.Runner;
+import org.junit.runner.notification.Failure;
+import org.junit.runner.notification.RunListener;
+import org.junit.runners.model.RunnerBuilder;
+
+import java.util.List;
+import java.util.concurrent.TimeUnit;
+
+/**
+ * An Activity that allows Gnss CTS tests to be executed inside CtsVerifier.
+ *
+ * Sub-classes pass the test class as part of construction.
+ * One JUnit test class is executed per Activity, the test class can still be executed outside
+ * CtsVerifier.
+ */
+public class GnssCtsTestActivity extends BaseGnssTestActivity {
+
+    /**
+     * Constructor for a CTS test executor. It will execute a standalone CTS test class.
+     *
+     * @param testClass The test class to execute, it must be a subclass of {@link AndroidTestCase}.
+     */
+    protected GnssCtsTestActivity(Class<? extends GnssTestCase> testClass) {
+        super(testClass);
+    }
+
+    @Override
+    protected void activitySetUp() throws InterruptedException {
+        waitForUserToBegin();
+        runOnUiThread(new Runnable() {
+            @Override
+            public void run() {
+                mTextView.setText("");
+            }
+        });
+    }
+
+    @Override
+    protected void activityCleanUp() {
+        runOnUiThread(new Runnable() {
+            @Override
+            public void run() {
+                getWindow().addFlags(WindowManager.LayoutParams.FLAG_DISMISS_KEYGUARD);
+            }
+        });
+    }
+
+    @Override
+    protected void onDestroy() {
+        super.onDestroy();
+    }
+
+    /**
+     * For reference on the implementation of this test executor see:
+     *      android.support.test.runner.AndroidJUnitRunner
+     */
+    @Override
+    protected GnssTestDetails executeTests() {
+        JUnitCore testRunner = new JUnitCore();
+        testRunner.addListener(new GnssRunListener());
+
+        Computer computer = new Computer();
+        RunnerBuilder runnerBuilder = new GnssRunnerBuilder();
+
+        Runner runner;
+        try {
+            runner = computer.getSuite(runnerBuilder, new Class[]{ mTestClass });
+        } catch (Exception e) {
+            return new GnssTestDetails(
+                    getTestClassName(),
+                    GnssTestDetails.ResultCode.FAIL,
+                    "[JUnit Initialization]" + e.getMessage());
+        }
+
+        Request request = Request.runner(runner);
+        Result result = testRunner.run(request);
+        // Handle MultiConstellationNotSupportedException warning: If there is a
+        // "MultiConstellationNotSupportedException" then it will just print the warning and
+        // mark test as pass.
+        int failureCount = result.getFailureCount();
+        List<Failure> failures = result.getFailures();
+        for (Failure f: failures) {
+            // TODO: Refactor this to use a more general exception instead of 
+            // MultiConstellationNotSupportedException.
+            if (f.getException() instanceof MultiConstellationNotSupportedException) {
+                failureCount = failureCount - 1;
+                int passCount = result.getRunCount() - failureCount - result.getIgnoreCount();
+                return new GnssTestDetails(
+                        getApplicationContext(), getClass().getName(), passCount,
+                        result.getIgnoreCount(), failureCount);
+            }
+        }
+
+        return new GnssTestDetails(getApplicationContext(), getClass().getName(), result);
+    }
+
+    /**
+     * A {@link RunnerBuilder} that is used to inject during execution a {@link GnssCtsTestSuite}.
+     */
+    private class GnssRunnerBuilder extends RunnerBuilder {
+        @Override
+        public Runner runnerForClass(Class<?> testClass) throws Throwable {
+            TestSuite testSuite;
+            if (hasSuiteMethod(testClass)) {
+                Test test = SuiteMethod.testFromSuiteMethod(testClass);
+                if (test instanceof TestSuite) {
+                    testSuite = (TestSuite) test;
+                } else {
+                    throw new IllegalArgumentException(
+                            testClass.getName() + "#suite() did not return a TestSuite.");
+                }
+            } else {
+                testSuite = new TestSuite(testClass);
+            }
+            GnssCtsTestSuite gnssTestSuite =
+                    new GnssCtsTestSuite(getApplicationContext(), testSuite);
+            return new JUnit38ClassRunner(gnssTestSuite);
+        }
+
+        private boolean hasSuiteMethod(Class<?> testClass) {
+            try {
+                testClass.getMethod("suite");
+                return true;
+            } catch (NoSuchMethodException e) {
+                return false;
+            }
+        }
+    }
+
+    /**
+     * Dummy {@link RunListener}.
+     * It is only used to handle logging into the UI.
+     */
+    private class GnssRunListener extends RunListener {
+        private volatile boolean mCurrentTestReported;
+        private StringBuilder mTestsResults = new StringBuilder("Test summary:\n");
+        private int mPassTestCase = 0;
+        private int mFailTestCase = 0;
+
+        public void testRunStarted(Description description) throws Exception {
+            // nothing to log
+        }
+
+        public void testRunFinished(Result result) throws Exception {
+            // nothing to log
+            runOnUiThread(new Runnable() {
+                @Override
+                public void run() {
+                    int totalTestCase = mPassTestCase + mFailTestCase;
+                    mTestsResults.append(String.format("\n\n %d/%d verification passed.",
+                            mPassTestCase, totalTestCase));
+                    if (mFailTestCase == 0) {
+                        mTestsResults.append(" All test pass!");
+                    } else {
+                        mTestsResults.append("\n\n" + mTextView.getResources().getString(
+                                R.string.location_gnss_test_retry_info) + "\n");
+                    }
+                    mTextView.setText(mTestsResults);
+                }
+            });
+            vibrate((int)TimeUnit.SECONDS.toMillis(2));
+            playSound();
+        }
+
+        public void testStarted(Description description) throws Exception {
+            mCurrentTestReported = false;
+            runOnUiThread(new Runnable() {
+                @Override
+                public void run() {
+                    mTextView.append("\n Running test: " + description.getMethodName());
+                }
+            });
+        }
+
+        public void testFinished(Description description) throws Exception {
+            if (!mCurrentTestReported) {
+                mPassTestCase++;
+                appendTestDetail("\n Test passed: " + description.getMethodName());
+                mTestsResults.append("\n Test passed: " + description.getMethodName());
+            }
+        }
+
+        public void testFailure(Failure failure) throws Exception {
+            mCurrentTestReported = true;
+            if (failure.getException() instanceof MultiConstellationNotSupportedException) {
+                // append warning for MultiConstellationNotSupportedException's.
+                mTestsResults.append(failure.getException());
+            } else {
+                mFailTestCase++;
+                mTestsResults.append("\n Test failed: "
+                        + failure.getDescription().getMethodName()
+                        + "\n\n Error: " + failure.toString() + "\n");
+            }
+        }
+
+        public void testAssumptionFailure(Failure failure) {
+            mCurrentTestReported = true;
+        }
+
+        public void testIgnored(Description description) throws Exception {
+            mCurrentTestReported = true;
+        }
+
+        private void appendTestDetail(final String testDetail) {
+            runOnUiThread(new Runnable() {
+                @Override
+                public void run() {
+                    mTextView.append(testDetail);
+                }
+            });
+        }
+    }
+}
diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/location/base/GnssCtsTestResult.java b/apps/CtsVerifier/src/com/android/cts/verifier/location/base/GnssCtsTestResult.java
new file mode 100644
index 0000000..fb33a63
--- /dev/null
+++ b/apps/CtsVerifier/src/com/android/cts/verifier/location/base/GnssCtsTestResult.java
@@ -0,0 +1,146 @@
+/*
+ * Copyright (C) 2016 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.verifier.location.base;
+
+import junit.framework.AssertionFailedError;
+import junit.framework.Protectable;
+import junit.framework.Test;
+import junit.framework.TestCase;
+import junit.framework.TestFailure;
+import junit.framework.TestListener;
+import junit.framework.TestResult;
+
+import android.content.Context;
+import android.location.cts.GnssTestCase;
+
+import java.util.Enumeration;
+
+/**
+ * A wrapper class for a {@link TestResult}.
+ *
+ * It provides a way to inject augmented data and helper objects during the execution of tests.
+ * i.e. inject a Context object for use by tests.
+ */
+public class GnssCtsTestResult extends TestResult {
+    private final Context mContext;
+    private final TestResult mWrappedTestResult;
+
+    private volatile boolean mInterrupted;
+
+    public GnssCtsTestResult(Context context, TestResult testResult) {
+        mContext = context;
+        mWrappedTestResult = testResult;
+    }
+
+    @Override
+    public void addError(Test test, Throwable throwable) {
+        mWrappedTestResult.addError(test, throwable);
+    }
+
+    @Override
+    public void addFailure(Test test, AssertionFailedError assertionFailedError) {
+        mWrappedTestResult.addFailure(test, assertionFailedError);
+    }
+
+    @Override
+    public void addListener(TestListener testListener) {
+        mWrappedTestResult.addListener(testListener);
+    }
+
+    @Override
+    public void removeListener(TestListener testListener) {
+        mWrappedTestResult.removeListener(testListener);
+    }
+
+    @Override
+    public void endTest(Test test) {
+        mWrappedTestResult.endTest(test);
+    }
+
+    @Override
+    public int errorCount() {
+        return mWrappedTestResult.errorCount();
+    }
+
+    @Override
+    public Enumeration<TestFailure> errors() {
+        return mWrappedTestResult.errors();
+    }
+
+    @Override
+    public int failureCount() {
+        return mWrappedTestResult.failureCount();
+    }
+
+    @Override
+    public Enumeration<TestFailure> failures() {
+        return mWrappedTestResult.failures();
+    }
+
+    @Override
+    public int runCount() {
+        return mWrappedTestResult.runCount();
+    }
+
+    @Override
+    public void runProtected(Test test, Protectable protectable) {
+        try {
+            protectable.protect();
+        } catch (AssertionFailedError e) {
+            addFailure(test, e);
+        } catch (ThreadDeath e) {
+            throw e;
+        } catch (InterruptedException e) {
+            mInterrupted = true;
+            addError(test, e);
+        } catch (Throwable e) {
+            addError(test, e);
+        }
+    }
+
+    @Override
+    public boolean shouldStop() {
+        return mInterrupted || mWrappedTestResult.shouldStop();
+    }
+
+    @Override
+    public void startTest(Test test) {
+        mWrappedTestResult.startTest(test);
+    }
+
+    @Override
+    public void stop() {
+        mWrappedTestResult.stop();
+    }
+
+    @Override
+    public boolean wasSuccessful() {
+        return mWrappedTestResult.wasSuccessful();
+    }
+
+    @Override
+    protected void run(TestCase testCase) {
+        if (testCase instanceof GnssTestCase) {
+            GnssTestCase gnssTestCase = (GnssTestCase) testCase;
+            gnssTestCase.setContext(mContext);
+            gnssTestCase.setTestAsCtsVerifierTest(true);
+        } else {
+            throw new IllegalStateException("TestCase invalid.");
+        }
+        super.run(testCase);
+    }
+}
\ No newline at end of file
diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/location/base/GnssCtsTestSuite.java b/apps/CtsVerifier/src/com/android/cts/verifier/location/base/GnssCtsTestSuite.java
new file mode 100644
index 0000000..0a724b6
--- /dev/null
+++ b/apps/CtsVerifier/src/com/android/cts/verifier/location/base/GnssCtsTestSuite.java
@@ -0,0 +1,90 @@
+/*
+ * Copyright (C) 2016 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.verifier.location.base;
+
+import junit.framework.Test;
+import junit.framework.TestResult;
+import junit.framework.TestSuite;
+
+import android.content.Context;
+
+import java.util.Enumeration;
+
+/**
+ * A wrapper class for a {@link TestSuite}.
+ *
+ * It provides a way to inject a {@link GnssCtsTestResult} during execution.
+ */
+public class GnssCtsTestSuite extends TestSuite {
+    private final Context mContext;
+    private final TestSuite mWrappedTestSuite;
+
+    public GnssCtsTestSuite(Context context, TestSuite testSuite) {
+        mContext = context;
+        mWrappedTestSuite = testSuite;
+    }
+
+    @Override
+    public void run(TestResult testResult) {
+        mWrappedTestSuite.run(new GnssCtsTestResult(mContext, testResult));
+    }
+
+    @Override
+    public void addTest(Test test) {
+        mWrappedTestSuite.addTest(test);
+    }
+
+    @Override
+    public int countTestCases() {
+        return mWrappedTestSuite.countTestCases();
+    }
+
+    @Override
+    public String getName() {
+        return mWrappedTestSuite.getName();
+    }
+
+    @Override
+    public void runTest(Test test, TestResult testResult) {
+        mWrappedTestSuite.runTest(test, testResult);
+    }
+
+    @Override
+    public void setName(String name) {
+        mWrappedTestSuite.setName(name);
+    }
+
+    @Override
+    public Test testAt(int index) {
+        return mWrappedTestSuite.testAt(index);
+    }
+
+    @Override
+    public int testCount() {
+        return mWrappedTestSuite.testCount();
+    }
+
+    @Override
+    public Enumeration<Test> tests() {
+        return mWrappedTestSuite.tests();
+    }
+
+    @Override
+    public String toString() {
+        return mWrappedTestSuite.toString();
+    }
+}
diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/location/base/IGnssTestStateContainer.java b/apps/CtsVerifier/src/com/android/cts/verifier/location/base/IGnssTestStateContainer.java
new file mode 100644
index 0000000..498c599
--- /dev/null
+++ b/apps/CtsVerifier/src/com/android/cts/verifier/location/base/IGnssTestStateContainer.java
@@ -0,0 +1,68 @@
+/*
+ * Copyright (C) 2016 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.verifier.location.base;
+
+import android.content.ContentResolver;
+import android.content.Intent;
+
+/**
+ * An interface that defines a facade for {@link BaseGnssTestActivity}, so it can be consumed by
+ * other CtsVerifier Sensor Test Framework helper components.
+ */
+public interface IGnssTestStateContainer {
+
+    /**
+     * Waits for the operator to acknowledge to continue execution.
+     */
+    void waitForUserToContinue() throws InterruptedException;
+
+    /**
+     * @param resId The resource Id to extract.
+     * @return The extracted string.
+     */
+    String getString(int resId);
+
+    /**
+     * @param resId  The resource Id to extract.
+     * @param params The parameters to format the string represented by the resource contents.
+     * @return The formatted extracted string.
+     */
+    String getString(int resId, Object... params);
+
+    /**
+     * Starts an Activity and blocks until it completes, then it returns its result back to the
+     * client.
+     *
+     * @param action The action to start the Activity.
+     * @return The Activity's result code.
+     */
+    int executeActivity(String action) throws InterruptedException;
+
+    /**
+     * Starts an Activity and blocks until it completes, then it returns its result back to the
+     * client.
+     *
+     * @param intent The intent to start the Activity.
+     * @return The Activity's result code.
+     */
+    int executeActivity(Intent intent) throws InterruptedException;
+
+    /**
+     * @return The {@link ContentResolver} associated with the test.
+     */
+    ContentResolver getContentResolver();
+}
diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/location/reporting/GnssTestDetails.java b/apps/CtsVerifier/src/com/android/cts/verifier/location/reporting/GnssTestDetails.java
new file mode 100644
index 0000000..ea04123
--- /dev/null
+++ b/apps/CtsVerifier/src/com/android/cts/verifier/location/reporting/GnssTestDetails.java
@@ -0,0 +1,109 @@
+/*
+ * Copyright (C) 2016 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.verifier.location.reporting;
+
+import com.android.cts.verifier.R;
+
+import org.junit.runner.Result;
+
+import android.content.Context;
+
+/**
+ * A class that holds the result of a Gnss test execution.
+ */
+public class GnssTestDetails {
+    private final String mName;
+    private final ResultCode mResultCode;
+    private final String mSummary;
+
+    public enum ResultCode {
+        SKIPPED,
+        PASS,
+        FAIL,
+        INTERRUPTED
+    }
+
+    public GnssTestDetails(String name, ResultCode resultCode) {
+        this(name, resultCode, null /* summary */);
+    }
+
+    public GnssTestDetails(String name, ResultCode resultCode, String summary) {
+        mName = name;
+        mResultCode = resultCode;
+        mSummary = summary;
+    }
+
+    public GnssTestDetails(
+            Context context,
+            String name,
+            int passCount,
+            int skipCount,
+            int failCount) {
+        ResultCode resultCode = ResultCode.PASS;
+        if (failCount > 0) {
+            resultCode = ResultCode.FAIL;
+        } else if (skipCount > 0) {
+            resultCode = ResultCode.SKIPPED;
+        }
+
+        mName = name;
+        mResultCode = resultCode;
+        mSummary = context.getString(R.string.snsr_test_summary, passCount, skipCount, failCount);
+    }
+
+    public GnssTestDetails(Context context, String name, Result result) {
+        this(context,
+                name,
+                result.getRunCount() - result.getFailureCount() - result.getIgnoreCount(),
+                result.getIgnoreCount(),
+                result.getFailureCount());
+    }
+
+    public GnssTestDetails(String name, String tag, Throwable cause) {
+        ResultCode resultCode = ResultCode.FAIL;
+        if (cause instanceof InterruptedException) {
+            resultCode = ResultCode.INTERRUPTED;
+            // the interrupted status must be restored, so other routines can consume it
+            Thread.currentThread().interrupt();
+        }
+        mName = name;
+        mResultCode = resultCode;
+        mSummary = String.format("[%s] %s", tag, cause.getMessage());
+    }
+
+    public String getName() {
+        return mName;
+    }
+
+    public ResultCode getResultCode() {
+        return mResultCode;
+    }
+
+    public String getSummary() {
+        return mSummary;
+    }
+
+    public GnssTestDetails cloneAndChangeResultCode(ResultCode resultCode) {
+        return new GnssTestDetails(mName, resultCode, mSummary);
+    }
+
+    @Override
+    public String toString() {
+        return String.format("%s|%s|%s", mName, mResultCode.name(), mSummary);
+    }
+}
+
diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/managedprovisioning/ByodFlowTestActivity.java b/apps/CtsVerifier/src/com/android/cts/verifier/managedprovisioning/ByodFlowTestActivity.java
index 7a51cb9..6aacea8 100644
--- a/apps/CtsVerifier/src/com/android/cts/verifier/managedprovisioning/ByodFlowTestActivity.java
+++ b/apps/CtsVerifier/src/com/android/cts/verifier/managedprovisioning/ByodFlowTestActivity.java
@@ -35,6 +35,7 @@
 import com.android.cts.verifier.TestListActivity;
 import com.android.cts.verifier.TestListAdapter.TestListItem;
 import com.android.cts.verifier.TestResult;
+import com.android.cts.verifier.location.LocationListenerActivity;
 
 /**
  * CTS verifier test for BYOD managed provisioning flow.
@@ -70,8 +71,8 @@
     private DialogTestListItem mWorkStatusBarToastTest;
     private DialogTestListItem mAppSettingsVisibleTest;
     private DialogTestListItem mLocationSettingsVisibleTest;
-    private DialogTestListItem mBatterySettingsVisibleTest;
-    private DialogTestListItem mDataUsageSettingsVisibleTest;
+    private DialogTestListItem mWiFiDataUsageSettingsVisibleTest;
+    private DialogTestListItem mCellularDataUsageSettingsVisibleTest;
     private DialogTestListItem mCredSettingsVisibleTest;
     private DialogTestListItem mPrintSettingsVisibleTest;
     private DialogTestListItem mIntentFiltersTest;
@@ -84,9 +85,17 @@
     private DialogTestListItem mDisableNfcBeamTest;
     private TestListItem mAuthenticationBoundKeyTest;
     private DialogTestListItem mEnableLocationModeTest;
-    private DialogTestListItem mDisableLocationModeTest;
+    private DialogTestListItem mDisableLocationModeThroughMainSwitchTest;
+    private DialogTestListItem mDisableLocationModeThroughWorkSwitchTest;
+    private DialogTestListItem mPrimaryLocationWhenWorkDisabledTest;
+    private DialogTestListItem mSelectWorkChallenge;
+    private DialogTestListItem mConfirmWorkCredentials;
+    private DialogTestListItem mParentProfilePassword;
     private TestListItem mVpnTest;
     private TestListItem mDisallowAppsControlTest;
+    private TestListItem mOrganizationInfoTest;
+    private TestListItem mPolicyTransparencyTest;
+    private TestListItem mTurnOffWorkFeaturesTest;
 
     public ByodFlowTestActivity() {
         super(R.layout.provisioning_byod,
@@ -161,7 +170,7 @@
     public void finish() {
         // Pass and fail buttons are known to call finish() when clicked, and this is when we want to
         // clean up the provisioned profile.
-        requestDeleteProfileOwner();
+        Utils.requestDeleteManagedProfile(this);
         enableComponent(PackageManager.COMPONENT_ENABLED_STATE_DEFAULT);
         super.finish();
     }
@@ -256,16 +265,16 @@
                 R.string.provisioning_byod_location_settings_instruction,
                 new Intent(Settings.ACTION_LOCATION_SOURCE_SETTINGS));
 
-        mBatterySettingsVisibleTest = new DialogTestListItem(this,
-                R.string.provisioning_byod_battery_settings,
-                "BYOD_BatterySettingsVisibleTest",
-                R.string.provisioning_byod_battery_settings_instruction,
-                new Intent(Intent.ACTION_POWER_USAGE_SUMMARY));
+        mWiFiDataUsageSettingsVisibleTest = new DialogTestListItem(this,
+                R.string.provisioning_byod_wifi_data_usage_settings,
+                "BYOD_WiFiDataUsageSettingsVisibleTest",
+                R.string.provisioning_byod_wifi_data_usage_settings_instruction,
+                new Intent(Settings.ACTION_SETTINGS));
 
-        mDataUsageSettingsVisibleTest = new DialogTestListItem(this,
-                R.string.provisioning_byod_data_usage_settings,
-                "BYOD_DataUsageSettingsVisibleTest",
-                R.string.provisioning_byod_data_usage_settings_instruction,
+        mCellularDataUsageSettingsVisibleTest = new DialogTestListItem(this,
+                R.string.provisioning_byod_cellular_data_usage_settings,
+                "BYOD_CellularDataUsageSettingsVisibleTest",
+                R.string.provisioning_byod_cellular_data_usage_settings_instruction,
                 new Intent(Settings.ACTION_SETTINGS));
 
         mPrintSettingsVisibleTest = new DialogTestListItem(this,
@@ -328,6 +337,11 @@
             }
         };
 
+        mTurnOffWorkFeaturesTest = TestListItem.newTest(this,
+                R.string.provisioning_byod_turn_off_work,
+                TurnOffWorkActivity.class.getName(),
+                new Intent(this, TurnOffWorkActivity.class), null);
+
         Intent permissionCheckIntent = new Intent(
                 PermissionLockdownTestActivity.ACTION_MANAGED_PROFILE_CHECK_PERMISSION_LOCKDOWN);
         mPermissionLockdownTest = new DialogTestListItem(this,
@@ -336,6 +350,41 @@
                 R.string.profile_owner_permission_lockdown_test_info,
                 permissionCheckIntent);
 
+        mSelectWorkChallenge = new DialogTestListItem(this,
+                R.string.provisioning_byod_select_work_challenge,
+                "BYOD_SelectWorkChallenge",
+                R.string.provisioning_byod_select_work_challenge_description,
+                new Intent(ByodHelperActivity.ACTION_TEST_SELECT_WORK_CHALLENGE));
+
+        mConfirmWorkCredentials = new DialogTestListItem(this,
+                R.string.provisioning_byod_confirm_work_credentials,
+                "BYOD_ConfirmWorkCredentials",
+                R.string.provisioning_byod_confirm_work_credentials_description,
+                new Intent(Intent.ACTION_MAIN).addCategory(Intent.CATEGORY_HOME));
+
+        mOrganizationInfoTest = TestListItem.newTest(this,
+                R.string.provisioning_byod_organization_info,
+                OrganizationInfoTestActivity.class.getName(),
+                new Intent(this, OrganizationInfoTestActivity.class),
+                null);
+
+        mParentProfilePassword = new DialogTestListItem(this,
+                R.string.provisioning_byod_parent_profile_password,
+                "BYOD_ParentProfilePasswordTest",
+                R.string.provisioning_byod_parent_profile_password_description,
+                new Intent(ByodHelperActivity.ACTION_TEST_PARENT_PROFILE_PASSWORD));
+
+        final Intent policyTransparencyTestIntent = new Intent(this,
+                PolicyTransparencyTestListActivity.class);
+        policyTransparencyTestIntent.putExtra(
+                PolicyTransparencyTestListActivity.EXTRA_IS_DEVICE_OWNER, false);
+        policyTransparencyTestIntent.putExtra(
+                PolicyTransparencyTestActivity.EXTRA_TEST_ID, "BYOD_PolicyTransparency");
+        mPolicyTransparencyTest = TestListItem.newTest(this,
+                R.string.device_profile_owner_policy_transparency_test,
+                "BYOD_PolicyTransparency",
+                policyTransparencyTestIntent, null);
+
         adapter.add(mProfileOwnerInstalled);
 
         // Badge related tests
@@ -350,8 +399,8 @@
         adapter.add(mCredSettingsVisibleTest);
         adapter.add(mAppSettingsVisibleTest);
         adapter.add(mLocationSettingsVisibleTest);
-        adapter.add(mBatterySettingsVisibleTest);
-        adapter.add(mDataUsageSettingsVisibleTest);
+        adapter.add(mWiFiDataUsageSettingsVisibleTest);
+        adapter.add(mCellularDataUsageSettingsVisibleTest);
         adapter.add(mPrintSettingsVisibleTest);
 
         adapter.add(mCrossProfileIntentFiltersTestFromPersonal);
@@ -364,6 +413,13 @@
         adapter.add(mKeyguardDisabledFeaturesTest);
         adapter.add(mAuthenticationBoundKeyTest);
         adapter.add(mVpnTest);
+        adapter.add(mTurnOffWorkFeaturesTest);
+        adapter.add(mSelectWorkChallenge);
+        adapter.add(mConfirmWorkCredentials);
+        adapter.add(mOrganizationInfoTest);
+        adapter.add(mParentProfilePassword);
+        adapter.add(mPolicyTransparencyTest);
+
         if (canResolveIntent(new Intent(Settings.ACTION_APPLICATION_SETTINGS))) {
             adapter.add(mDisallowAppsControlTest);
         }
@@ -465,15 +521,26 @@
                     R.string.provisioning_byod_location_mode_enable,
                     "BYOD_LocationModeEnableTest",
                     R.string.provisioning_byod_location_mode_enable_instruction,
-                    new Intent(ByodHelperActivity.ACTION_SET_LOCATION_AND_CHECK_UPDATES));
-            mDisableLocationModeTest = new DialogTestListItem(this,
+                    new Intent(ByodHelperActivity.ACTION_BYOD_SET_LOCATION_AND_CHECK_UPDATES));
+            mDisableLocationModeThroughMainSwitchTest = new DialogTestListItem(this,
                     R.string.provisioning_byod_location_mode_disable,
-                    "BYOD_LocationModeDisableTest",
+                    "BYOD_LocationModeDisableMainTest",
                     R.string.provisioning_byod_location_mode_disable_instruction,
-                    new Intent(ByodHelperActivity.ACTION_SET_LOCATION_AND_CHECK_UPDATES));
-
+                    new Intent(ByodHelperActivity.ACTION_BYOD_SET_LOCATION_AND_CHECK_UPDATES));
+            mDisableLocationModeThroughWorkSwitchTest = new DialogTestListItem(this,
+                    R.string.provisioning_byod_work_location_mode_disable,
+                    "BYOD_LocationModeDisableWorkTest",
+                    R.string.provisioning_byod_work_location_mode_disable_instruction,
+                    new Intent(ByodHelperActivity.ACTION_BYOD_SET_LOCATION_AND_CHECK_UPDATES));
+            mPrimaryLocationWhenWorkDisabledTest = new DialogTestListItem(this,
+                    R.string.provisioning_byod_primary_location_when_work_disabled,
+                    "BYOD_PrimaryLocationWhenWorkDisabled",
+                    R.string.provisioning_byod_primary_location_when_work_disabled_instruction,
+                    new Intent(LocationListenerActivity.ACTION_SET_LOCATION_AND_CHECK_UPDATES));
             adapter.add(mEnableLocationModeTest);
-            adapter.add(mDisableLocationModeTest);
+            adapter.add(mDisableLocationModeThroughMainSwitchTest);
+            adapter.add(mDisableLocationModeThroughWorkSwitchTest);
+            adapter.add(mPrimaryLocationWhenWorkDisabledTest);
         } else {
             // The system does not support GPS feature, so skip test.
             Toast.makeText(ByodFlowTestActivity.this,
@@ -507,8 +574,6 @@
                 mAdminReceiverComponent);
 
         if (sending.resolveActivity(getPackageManager()) != null) {
-            // ManagedProvisioning must be started with startActivityForResult, but we don't
-            // care about the result, so passing 0 as a requestCode
             startActivityForResult(sending, REQUEST_MANAGED_PROVISIONING);
         } else {
             showToast(R.string.provisioning_byod_disabled);
@@ -529,17 +594,6 @@
         }
     }
 
-    private void requestDeleteProfileOwner() {
-        try {
-            Intent intent = new Intent(ByodHelperActivity.ACTION_REMOVE_PROFILE_OWNER);
-            startActivity(intent);
-            showToast(R.string.provisioning_byod_delete_profile);
-        }
-        catch (ActivityNotFoundException e) {
-            Log.d(TAG, "requestDeleteProfileOwner: ActivityNotFoundException", e);
-        }
-    }
-
     private void checkIntentFilters() {
         try {
             // Enable component HandleIntentActivity before intent filters are checked.
@@ -587,7 +641,9 @@
             WorkStatusTestActivity.class.getName(),
             PermissionLockdownTestActivity.ACTIVITY_ALIAS,
             AuthenticationBoundKeyTestActivity.class.getName(),
-            VpnTestActivity.class.getName()
+            VpnTestActivity.class.getName(),
+            CommandReceiverActivity.class.getName(),
+            SetSupportMessageActivity.class.getName()
         };
         for (String component : components) {
             getPackageManager().setComponentEnabledSetting(new ComponentName(this, component),
diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/managedprovisioning/ByodHelperActivity.java b/apps/CtsVerifier/src/com/android/cts/verifier/managedprovisioning/ByodHelperActivity.java
index 0cd674a..b4f9724 100644
--- a/apps/CtsVerifier/src/com/android/cts/verifier/managedprovisioning/ByodHelperActivity.java
+++ b/apps/CtsVerifier/src/com/android/cts/verifier/managedprovisioning/ByodHelperActivity.java
@@ -19,6 +19,7 @@
 import android.app.Activity;
 import android.app.admin.DevicePolicyManager;
 import android.app.Dialog;
+import android.app.KeyguardManager;
 import android.app.Notification;
 import android.app.NotificationManager;
 import android.content.BroadcastReceiver;
@@ -27,6 +28,7 @@
 import android.content.Intent;
 import android.content.IntentFilter;
 import android.content.pm.PackageManager;
+import android.graphics.Color;
 import android.location.Location;
 import android.location.LocationListener;
 import android.location.LocationManager;
@@ -47,6 +49,7 @@
 import java.io.File;
 import java.util.ArrayList;
 
+import com.android.cts.verifier.location.LocationListenerActivity;
 import com.android.cts.verifier.R;
 import com.android.cts.verifier.managedprovisioning.ByodPresentMediaDialog.DialogCallback;
 
@@ -59,7 +62,8 @@
  *
  * Note: We have to use a dummy activity because cross-profile intents only work for activities.
  */
-public class ByodHelperActivity extends Activity implements DialogCallback, Handler.Callback {
+public class ByodHelperActivity extends LocationListenerActivity
+        implements DialogCallback {
     static final String TAG = "ByodHelperActivity";
 
     // Primary -> managed intent: query if the profile owner has been set up.
@@ -67,7 +71,7 @@
     // Managed -> primary intent: update profile owner test status in primary's CtsVerifer
     public static final String ACTION_PROFILE_OWNER_STATUS = "com.android.cts.verifier.managedprovisioning.BYOD_STATUS";
     // Primary -> managed intent: request to delete the current profile
-    public static final String ACTION_REMOVE_PROFILE_OWNER = "com.android.cts.verifier.managedprovisioning.BYOD_REMOVE";
+    public static final String ACTION_REMOVE_MANAGED_PROFILE = "com.android.cts.verifier.managedprovisioning.BYOD_REMOVE";
     // Managed -> managed intent: provisioning completed successfully
     public static final String ACTION_PROFILE_PROVISIONED = "com.android.cts.verifier.managedprovisioning.BYOD_PROVISIONED";
     // Primary -> managed intent: request to capture and check an image
@@ -108,7 +112,7 @@
             "com.android.cts.verifier.managedprovisioning.action.TEST_APP_LINKING_DIALOG";
 
     // Primary -> managed intent: request to goto the location settings page and listen to updates.
-    public static final String ACTION_SET_LOCATION_AND_CHECK_UPDATES =
+    public static final String ACTION_BYOD_SET_LOCATION_AND_CHECK_UPDATES =
             "com.android.cts.verifier.managedprovisioning.BYOD_SET_LOCATION_AND_CHECK";
     public static final String ACTION_NOTIFICATION =
             "com.android.cts.verifier.managedprovisioning.NOTIFICATION";
@@ -125,14 +129,29 @@
     public static final String ACTION_CLEAR_USER_RESTRICTION =
             "com.android.cts.verifier.managedprovisioning.BYOD_CLEAR_USER_RESTRICTION";
 
+    // Primary -> managed intent: Start the selection of a work challenge
+    public static final String ACTION_TEST_SELECT_WORK_CHALLENGE =
+            "com.android.cts.verifier.managedprovisioning.TEST_SELECT_WORK_CHALLENGE";
+
+    // Primary -> managed intent: Start the selection of a parent profile password.
+    public static final String ACTION_TEST_PARENT_PROFILE_PASSWORD =
+            "com.android.cts.verifier.managedprovisioning.TEST_PARENT_PROFILE_PASSWORD";
+
+    // Primary -> managed intent: Start the confirm credentials screen for the managed profile
+    public static final String ACTION_LAUNCH_CONFIRM_WORK_CREDENTIALS =
+            "com.android.cts.verifier.managedprovisioning.LAUNCH_CONFIRM_WORK_CREDENTIALS";
+
+    public static final String ACTION_SET_ORGANIZATION_INFO =
+            "com.android.cts.verifier.managedprovisioning.TEST_ORGANIZATION_INFO";
+
     public static final int RESULT_FAILED = RESULT_FIRST_USER;
 
-    private static final int REQUEST_INSTALL_PACKAGE = 1;
-    private static final int REQUEST_IMAGE_CAPTURE = 2;
-    private static final int REQUEST_VIDEO_CAPTURE_WITH_EXTRA_OUTPUT = 3;
-    private static final int REQUEST_VIDEO_CAPTURE_WITHOUT_EXTRA_OUTPUT = 4;
-    private static final int REQUEST_AUDIO_CAPTURE = 5;
-    private static final int REQUEST_LOCATION_UPDATE = 6;
+    private static final int REQUEST_INSTALL_PACKAGE = 2;
+    private static final int REQUEST_IMAGE_CAPTURE = 3;
+    private static final int REQUEST_VIDEO_CAPTURE_WITH_EXTRA_OUTPUT = 4;
+    private static final int REQUEST_VIDEO_CAPTURE_WITHOUT_EXTRA_OUTPUT = 5;
+    private static final int REQUEST_AUDIO_CAPTURE = 6;
+    private static final int REQUEST_LOCATION_UPDATE = 7;
 
     private static final String ORIGINAL_SETTINGS_NAME = "original settings";
 
@@ -141,15 +160,8 @@
     private NotificationManager mNotificationManager;
     private Bundle mOriginalSettings;
 
-    private static final int MSG_TIMEOUT = 1;
-
-    private static final long MSG_TIMEOUT_MILLISEC = 15 * 1000;
-
     private ComponentName mAdminReceiverComponent;
     private DevicePolicyManager mDevicePolicyManager;
-    private LocationManager mLocationManager;
-    private Handler mHandler;
-    private boolean mIsLocationUpdated;
 
     private Uri mImageUri;
     private Uri mVideoUri;
@@ -181,9 +193,6 @@
         mAdminReceiverComponent = new ComponentName(this, DeviceAdminTestReceiver.class.getName());
         mDevicePolicyManager = (DevicePolicyManager) getSystemService(
                 Context.DEVICE_POLICY_SERVICE);
-        mLocationManager = (LocationManager) getSystemService(LOCATION_SERVICE);
-        mHandler = new Handler(this);
-        mIsLocationUpdated = false;
         mNotificationManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
         Intent intent = getIntent();
         String action = intent.getAction();
@@ -201,7 +210,7 @@
             response.putExtra(EXTRA_PROVISIONED, isProfileOwner());
             setResult(RESULT_OK, response);
             // Request to delete work profile.
-        } else if (action.equals(ACTION_REMOVE_PROFILE_OWNER)) {
+        } else if (action.equals(ACTION_REMOVE_MANAGED_PROFILE)) {
             if (isProfileOwner()) {
                 Log.d(TAG, "Clearing cross profile intents");
                 mDevicePolicyManager.clearCrossProfileIntentFilters(mAdminReceiverComponent);
@@ -281,8 +290,7 @@
         } else if (ACTION_KEYGUARD_DISABLED_FEATURES.equals(action)) {
             final int value = intent.getIntExtra(EXTRA_PARAMETER_1,
                     DevicePolicyManager.KEYGUARD_DISABLE_FEATURES_NONE);
-            ComponentName admin = DeviceAdminTestReceiver.getReceiverComponentName();
-            mDevicePolicyManager.setKeyguardDisabledFeatures(admin, value);
+            mDevicePolicyManager.setKeyguardDisabledFeatures(mAdminReceiverComponent, value);
         } else if (ACTION_LOCKNOW.equals(action)) {
             mDevicePolicyManager.lockNow();
             setResult(RESULT_OK);
@@ -314,31 +322,38 @@
                 mDevicePolicyManager.clearUserRestriction(
                         DeviceAdminTestReceiver.getReceiverComponentName(), restriction);
             }
-        } else if (action.equals(ACTION_SET_LOCATION_AND_CHECK_UPDATES)) {
-            // Grant the locaiton permission to the provile owner on cts-verifier.
-            // The permission state does not have to be reverted at the end since the profile onwer
-            // is going to be deleted when BYOD tests ends.
-            grantLocationPermissionToSelf();
-            Intent locationSettingsIntent = getLocationSettingsIntent();
-            if (locationSettingsIntent.resolveActivity(getPackageManager()) != null) {
-                startActivityForResult(locationSettingsIntent, REQUEST_LOCATION_UPDATE);
-                scheduleTimeout();
-            } else {
-                Log.e(TAG, "BYOD settings could not be resolved in managed profile");
-                finish();
-            }
-            mLocationManager.requestLocationUpdates(
-                    LocationManager.GPS_PROVIDER, 0, 0, mLocationListener);
+        } else if (action.equals(ACTION_BYOD_SET_LOCATION_AND_CHECK_UPDATES)) {
+            handleLocationAction();
             return;
         } else if (action.equals(ACTION_NOTIFICATION)) {
             showNotification(Notification.VISIBILITY_PUBLIC);
         } else if (ACTION_NOTIFICATION_ON_LOCKSCREEN.equals(action)) {
-            DevicePolicyManager dpm = (DevicePolicyManager) getSystemService(
-                    Context.DEVICE_POLICY_SERVICE);
-            dpm.lockNow();
+            mDevicePolicyManager.lockNow();
             showNotification(Notification.VISIBILITY_PRIVATE);
         } else if (ACTION_CLEAR_NOTIFICATION.equals(action)) {
             mNotificationManager.cancel(NOTIFICATION_ID);
+        } else if (ACTION_TEST_SELECT_WORK_CHALLENGE.equals(action)) {
+            mDevicePolicyManager.setOrganizationColor(mAdminReceiverComponent, Color.BLUE);
+            mDevicePolicyManager.setOrganizationName(mAdminReceiverComponent, getResources()
+                    .getString(R.string.provisioning_byod_confirm_work_credentials_header));
+            startActivity(new Intent(DevicePolicyManager.ACTION_SET_NEW_PASSWORD));
+        } else if (ACTION_LAUNCH_CONFIRM_WORK_CREDENTIALS.equals(action)) {
+            KeyguardManager keyguardManager =
+                    (KeyguardManager) getSystemService(Context.KEYGUARD_SERVICE);
+            Intent launchIntent = keyguardManager.createConfirmDeviceCredentialIntent(null, null);
+            startActivity(launchIntent);
+        } else if (ACTION_SET_ORGANIZATION_INFO.equals(action)) {
+            if(intent.hasExtra(OrganizationInfoTestActivity.EXTRA_ORGANIZATION_NAME)) {
+                final String organizationName = intent
+                        .getStringExtra(OrganizationInfoTestActivity.EXTRA_ORGANIZATION_NAME);
+                mDevicePolicyManager.setOrganizationName(mAdminReceiverComponent, organizationName);
+            }
+            final int organizationColor = intent.getIntExtra(
+                    OrganizationInfoTestActivity.EXTRA_ORGANIZATION_COLOR,
+                    mDevicePolicyManager.getOrganizationColor(mAdminReceiverComponent));
+            mDevicePolicyManager.setOrganizationColor(mAdminReceiverComponent, organizationColor);
+        } else if (ACTION_TEST_PARENT_PROFILE_PASSWORD.equals(action)) {
+            startActivity(new Intent(DevicePolicyManager.ACTION_SET_NEW_PARENT_PROFILE_PASSWORD));
         }
         // This activity has no UI and is only used to respond to CtsVerifier in the primary side.
         finish();
@@ -404,15 +419,8 @@
                 }
                 break;
             }
-            case REQUEST_LOCATION_UPDATE: {
-                Log.d(TAG, "BYOD exit location settings:OK");
-                mLocationManager.removeUpdates(mLocationListener);
-                mHandler.removeMessages(MSG_TIMEOUT);
-                finish();
-                break;
-            }
             default: {
-                Log.wtf(TAG, "Unknown requestCode " + requestCode + "; data = " + data);
+                super.onActivityResult(requestCode, resultCode, data);
                 break;
             }
         }
@@ -436,10 +444,6 @@
         return new Intent(MediaStore.Audio.Media.RECORD_SOUND_ACTION);
     }
 
-    public static Intent getLocationSettingsIntent() {
-        return new Intent(Settings.ACTION_LOCATION_SOURCE_SETTINGS);
-    }
-
     public static Intent createLockIntent() {
         return new Intent(ACTION_LOCKNOW);
     }
@@ -484,11 +488,6 @@
         startActivity(intent);
     }
 
-    private void showToast(int messageId) {
-        String message = getString(messageId);
-        Toast.makeText(this, message, Toast.LENGTH_SHORT).show();
-    }
-
     private void grantCameraPermissionToSelf() {
         mDevicePolicyManager.setPermissionGrantState(mAdminReceiverComponent, getPackageName(),
                 android.Manifest.permission.CAMERA,
@@ -502,49 +501,28 @@
         startActivity(chooser);
     }
 
+    @Override
+    protected void handleLocationAction() {
+        // Grant the locaiton permission to the provile owner on cts-verifier.
+        // The permission state does not have to be reverted at the end since the profile onwer
+        // is going to be deleted when BYOD tests ends.
+        grantLocationPermissionToSelf();
+        super.handleLocationAction();
+    }
+
     private void grantLocationPermissionToSelf() {
         mDevicePolicyManager.setPermissionGrantState(mAdminReceiverComponent, getPackageName(),
                 android.Manifest.permission.ACCESS_FINE_LOCATION,
                 DevicePolicyManager.PERMISSION_GRANT_STATE_GRANTED);
     }
 
-    private final LocationListener mLocationListener = new LocationListener() {
-        @Override
-        public void onLocationChanged(Location location) {
-            if (mIsLocationUpdated) return;
-            showToast(R.string.provisioning_byod_location_mode_enable_toast_location_change);
-            mIsLocationUpdated = true;
-        }
-
-        @Override
-        public void onProviderDisabled(String provider) {
-        }
-
-        @Override
-        public void onProviderEnabled(String provider) {
-        }
-
-        @Override
-        public void onStatusChanged(String provider, int status, Bundle extras) {
-        }
-    };
-
-    private void scheduleTimeout() {
-        mHandler.removeMessages(MSG_TIMEOUT);
-        mHandler.sendMessageDelayed(mHandler.obtainMessage(MSG_TIMEOUT), MSG_TIMEOUT_MILLISEC);
-    }
-
     @Override
     public void onDialogClose() {
         finish();
     }
 
     @Override
-    public boolean handleMessage(Message msg) {
-        if (msg.what == MSG_TIMEOUT) {
-            if (mIsLocationUpdated) return true;
-            showToast(R.string.provisioning_byod_location_mode_time_out_toast);
-        }
-        return true;
+    protected String getLogTag() {
+        return TAG;
     }
 }
diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/managedprovisioning/ByodProvisioningTestActivity.java b/apps/CtsVerifier/src/com/android/cts/verifier/managedprovisioning/ByodProvisioningTestActivity.java
new file mode 100644
index 0000000..dfbbb31
--- /dev/null
+++ b/apps/CtsVerifier/src/com/android/cts/verifier/managedprovisioning/ByodProvisioningTestActivity.java
@@ -0,0 +1,84 @@
+/*
+ * Copyright (C) 2015 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.verifier.managedprovisioning;
+
+import android.app.admin.DevicePolicyManager;
+import android.app.Activity;
+import android.content.ComponentName;
+import android.content.ContentResolver;
+import android.content.Intent;
+import android.graphics.Color;
+import android.net.Uri;
+import android.os.Bundle;
+
+import com.android.cts.verifier.ArrayTestListAdapter;
+import com.android.cts.verifier.IntentDrivenTestActivity.ButtonInfo;
+import com.android.cts.verifier.PassFailButtons;
+import com.android.cts.verifier.R;
+
+public class ByodProvisioningTestActivity extends PassFailButtons.TestListActivity {
+    @Override
+    protected void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+        setContentView(R.layout.pass_fail_list);
+        setPassFailButtonClickListeners();
+
+        final ArrayTestListAdapter adapter = new ArrayTestListAdapter(this);
+
+        Intent colorIntent = new Intent(this, ProvisioningStartingActivity.class)
+                .putExtra(DevicePolicyManager.EXTRA_PROVISIONING_MAIN_COLOR, Color.GREEN);
+        adapter.add(Utils.createInteractiveTestItem(this, "BYOD_CustomColor",
+                        R.string.provisioning_tests_byod_custom_color,
+                        R.string.provisioning_tests_byod_custom_color_info,
+                        new ButtonInfo(R.string.go_button_text, colorIntent)));
+        Uri logoUri = Uri.parse(ContentResolver.SCHEME_ANDROID_RESOURCE + "://" + getPackageName()
+                + "/" + R.drawable.icon);
+        Intent imageIntent = new Intent(this, ProvisioningStartingActivity.class)
+                .putExtra(DevicePolicyManager.EXTRA_PROVISIONING_LOGO_URI, logoUri);
+        adapter.add(Utils.createInteractiveTestItem(this, "BYOD_CustomImage",
+                        R.string.provisioning_tests_byod_custom_image,
+                        R.string.provisioning_tests_byod_custom_image_info,
+                        new ButtonInfo(R.string.go_button_text, imageIntent)));
+
+        setTestListAdapter(adapter);
+    }
+
+    @Override
+    public void finish() {
+        // Pass and fail buttons are known to call finish() when clicked, and this is when we want
+        // to clean up the provisioned profile in case the user has added one.
+        Utils.requestDeleteManagedProfile(this);
+        super.finish();
+    }
+
+    // We need this activity because the provisioning needs to be started with
+    // startActivityForResult
+    public static class ProvisioningStartingActivity extends Activity {
+        @Override
+        protected void onCreate(Bundle savedInstanceState) {
+            super.onCreate(savedInstanceState);
+            Intent provisioningIntent = new Intent(
+                    DevicePolicyManager.ACTION_PROVISION_MANAGED_PROFILE);
+            // forward all the extras we received.
+            provisioningIntent.putExtras(getIntent().getExtras());
+            provisioningIntent.putExtra(
+                    DevicePolicyManager.EXTRA_PROVISIONING_DEVICE_ADMIN_COMPONENT_NAME,
+                    new ComponentName(this, DeviceAdminTestReceiver.class.getName()));
+            startActivityForResult(provisioningIntent, 0);
+            finish();
+        }
+    }
+}
diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/managedprovisioning/CommandReceiverActivity.java b/apps/CtsVerifier/src/com/android/cts/verifier/managedprovisioning/CommandReceiverActivity.java
new file mode 100644
index 0000000..1349694
--- /dev/null
+++ b/apps/CtsVerifier/src/com/android/cts/verifier/managedprovisioning/CommandReceiverActivity.java
@@ -0,0 +1,228 @@
+/*
+ * Copyright (C) 2016 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.verifier.managedprovisioning;
+
+import android.app.Activity;
+import android.app.admin.DevicePolicyManager;
+import android.content.ComponentName;
+import android.content.Context;
+import android.content.Intent;
+import android.graphics.BitmapFactory;
+import android.os.Bundle;
+import android.os.UserManager;
+import android.util.Log;
+
+import com.android.cts.verifier.R;
+import com.android.cts.verifier.managedprovisioning.Utils;
+
+import java.util.ArrayList;
+import java.util.concurrent.TimeUnit;
+
+public class CommandReceiverActivity extends Activity {
+    private static final String TAG = "CommandReceiverActivity";
+
+    public static final String ACTION_EXECUTE_COMMAND =
+            "com.android.cts.verifier.managedprovisioning.action.EXECUTE_COMMAND";
+    public static final String EXTRA_COMMAND =
+            "com.android.cts.verifier.managedprovisioning.extra.COMMAND";
+
+    public static final String COMMAND_SET_USER_RESTRICTION = "set-user_restriction";
+    public static final String COMMAND_DISALLOW_KEYGUARD_UNREDACTED_NOTIFICATIONS =
+            "disallow-keyguard-unredacted-notifications";
+    public static final String COMMAND_SET_AUTO_TIME_REQUIRED = "set-auto-time-required";
+    public static final String COMMAND_SET_GLOBAL_SETTING =
+            "set-global-setting";
+    public static final String COMMAND_SET_MAXIMUM_TO_LOCK = "set-maximum-time-to-lock";
+    public static final String COMMAND_SET_PASSWORD_QUALITY = "set-password-quality";
+    public static final String COMMAND_SET_KEYGUARD_DISABLED = "set-keyguard-disabled";
+    public static final String COMMAND_SET_LOCK_SCREEN_INFO = "set-lock-screen-info";
+    public static final String COMMAND_SET_STATUSBAR_DISABLED = "set-statusbar-disabled";
+    public static final String COMMAND_ALLOW_ONLY_SYSTEM_INPUT_METHODS =
+            "allow-only-system-input-methods";
+    public static final String COMMAND_ALLOW_ONLY_SYSTEM_ACCESSIBILITY_SERVICES =
+            "allow-only-system-accessibility-services";
+    public static final String COMMAND_DEVICE_OWNER_CLEAR_POLICIES = "do-clear-policies";
+    public static final String COMMAND_PROFILE_OWNER_CLEAR_POLICIES = "po-clear-policies";
+    public static final String COMMAND_REMOVE_DEVICE_OWNER = "remove-device-owner";
+    public static final String COMMAND_REQUEST_BUGREPORT = "request-bugreport";
+    public static final String COMMAND_SET_USER_ICON = "set-user-icon";
+
+    public static final String EXTRA_USER_RESTRICTION =
+            "com.android.cts.verifier.managedprovisioning.extra.USER_RESTRICTION";
+    public static final String EXTRA_SETTING =
+            "com.android.cts.verifier.managedprovisioning.extra.SETTING";
+    // This extra can be used along with a command extra to set policy to
+    // specify if that policy is enforced or not.
+    public static final String EXTRA_ENFORCED =
+            "com.android.cts.verifier.managedprovisioning.extra.ENFORCED";
+    public static final String EXTRA_VALUE =
+            "com.android.cts.verifier.managedprovisioning.extra.VALUE";
+
+    private ComponentName mAdmin;
+    private DevicePolicyManager mDpm;
+
+    @Override
+    public void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+        final Intent intent = getIntent();
+        try {
+            mDpm = (DevicePolicyManager) getSystemService(
+                    Context.DEVICE_POLICY_SERVICE);
+            mAdmin = DeviceAdminTestReceiver.getReceiverComponentName();
+            Log.i(TAG, "Command: " + intent);
+
+            final String command = getIntent().getStringExtra(EXTRA_COMMAND);
+            switch (command) {
+                case COMMAND_SET_USER_RESTRICTION: {
+                    String restrictionKey = intent.getStringExtra(EXTRA_USER_RESTRICTION);
+                    boolean enforced = intent.getBooleanExtra(EXTRA_ENFORCED, false);
+                    if (enforced) {
+                        mDpm.addUserRestriction(mAdmin, restrictionKey);
+                    } else {
+                        mDpm.clearUserRestriction(mAdmin, restrictionKey);
+                    }
+                } break;
+                case COMMAND_DISALLOW_KEYGUARD_UNREDACTED_NOTIFICATIONS: {
+                    mDpm.setKeyguardDisabledFeatures(mAdmin,
+                            DevicePolicyManager.KEYGUARD_DISABLE_UNREDACTED_NOTIFICATIONS);
+                } break;
+                case COMMAND_SET_AUTO_TIME_REQUIRED: {
+                    mDpm.setAutoTimeRequired(mAdmin,
+                            intent.getBooleanExtra(EXTRA_ENFORCED, false));
+                }
+                case COMMAND_SET_LOCK_SCREEN_INFO: {
+                    mDpm.setDeviceOwnerLockScreenInfo(mAdmin, intent.getStringExtra(EXTRA_VALUE));
+                }
+                case COMMAND_SET_MAXIMUM_TO_LOCK: {
+                    final long timeInSeconds = Long.parseLong(intent.getStringExtra(EXTRA_VALUE));
+                    mDpm.setMaximumTimeToLock(mAdmin,
+                            TimeUnit.SECONDS.toMillis(timeInSeconds) /* in milliseconds */);
+                } break;
+                case COMMAND_SET_PASSWORD_QUALITY: {
+                    int quality = intent.getIntExtra(EXTRA_VALUE, 0);
+                    mDpm.setPasswordQuality(mAdmin, quality);
+                } break;
+                case COMMAND_SET_KEYGUARD_DISABLED: {
+                    boolean enforced = intent.getBooleanExtra(EXTRA_ENFORCED, false);
+                    if (enforced) {
+                        mDpm.resetPassword(null, 0);
+                    }
+                    mDpm.setKeyguardDisabled(mAdmin, enforced);
+                } break;
+                case COMMAND_SET_STATUSBAR_DISABLED: {
+                    boolean enforced = intent.getBooleanExtra(EXTRA_ENFORCED, false);
+                    mDpm.setStatusBarDisabled(mAdmin, enforced);
+                } break;
+                case COMMAND_ALLOW_ONLY_SYSTEM_INPUT_METHODS: {
+                    boolean enforced = intent.getBooleanExtra(EXTRA_ENFORCED, false);
+                    mDpm.setPermittedInputMethods(mAdmin, enforced ? new ArrayList() : null);
+                } break;
+                case COMMAND_ALLOW_ONLY_SYSTEM_ACCESSIBILITY_SERVICES: {
+                    boolean enforced = intent.getBooleanExtra(EXTRA_ENFORCED, false);
+                    mDpm.setPermittedAccessibilityServices(mAdmin,
+                            enforced ? new ArrayList() : null);
+                } break;
+                case COMMAND_SET_GLOBAL_SETTING: {
+                    final String setting = intent.getStringExtra(EXTRA_SETTING);
+                    final String value = intent.getStringExtra(EXTRA_VALUE);
+                    mDpm.setGlobalSetting(mAdmin, setting, value);
+                } break;
+                case COMMAND_REMOVE_DEVICE_OWNER: {
+                    if (!mDpm.isDeviceOwnerApp(getPackageName())) {
+                        return;
+                    }
+                    clearAllPolicies();
+                    mDpm.clearDeviceOwnerApp(getPackageName());
+                } break;
+                case COMMAND_REQUEST_BUGREPORT: {
+                    if (!mDpm.isDeviceOwnerApp(getPackageName())) {
+                        return;
+                    }
+                    final boolean bugreportStarted = mDpm.requestBugreport(mAdmin);
+                    if (!bugreportStarted) {
+                        Utils.showBugreportNotification(this, getString(
+                                R.string.bugreport_already_in_progress),
+                                Utils.BUGREPORT_NOTIFICATION_ID);
+                    }
+                } break;
+                case COMMAND_DEVICE_OWNER_CLEAR_POLICIES: {
+                    if (!mDpm.isDeviceOwnerApp(getPackageName())) {
+                        return;
+                    }
+                    clearAllPolicies();
+                } break;
+                case COMMAND_PROFILE_OWNER_CLEAR_POLICIES: {
+                    if (!mDpm.isProfileOwnerApp(getPackageName())) {
+                        return;
+                    }
+                    clearProfileOwnerRelatedPolicies();
+                } break;
+                case COMMAND_SET_USER_ICON: {
+                    if (!mDpm.isDeviceOwnerApp(getPackageName())) {
+                        return;
+                    }
+                    mDpm.setUserIcon(mAdmin, BitmapFactory.decodeResource(getResources(),
+                            com.android.cts.verifier.R.drawable.icon));
+                } break;
+            }
+        } catch (Exception e) {
+            Log.e(TAG, "Failed to execute command: " + intent, e);
+        } finally {
+            finish();
+        }
+    }
+
+    private void clearAllPolicies() {
+        clearProfileOwnerRelatedPolicies();
+
+        mDpm.clearUserRestriction(mAdmin, UserManager.DISALLOW_ADD_USER);
+        mDpm.clearUserRestriction(mAdmin, UserManager.DISALLOW_ADJUST_VOLUME);
+        mDpm.clearUserRestriction(mAdmin, UserManager.DISALLOW_CONFIG_BLUETOOTH);
+        mDpm.clearUserRestriction(mAdmin, UserManager.DISALLOW_CONFIG_CELL_BROADCASTS);
+        mDpm.clearUserRestriction(mAdmin, UserManager.DISALLOW_CONFIG_MOBILE_NETWORKS);
+        mDpm.clearUserRestriction(mAdmin, UserManager.DISALLOW_CONFIG_TETHERING);
+        mDpm.clearUserRestriction(mAdmin, UserManager.DISALLOW_CONFIG_VPN);
+        mDpm.clearUserRestriction(mAdmin, UserManager.DISALLOW_CONFIG_WIFI);
+        mDpm.clearUserRestriction(mAdmin, UserManager.DISALLOW_DATA_ROAMING);
+        mDpm.clearUserRestriction(mAdmin, UserManager.DISALLOW_DEBUGGING_FEATURES);
+        mDpm.clearUserRestriction(mAdmin, UserManager.DISALLOW_FACTORY_RESET);
+        mDpm.clearUserRestriction(mAdmin, UserManager.DISALLOW_FUN);
+        mDpm.clearUserRestriction(mAdmin, UserManager.DISALLOW_INSTALL_UNKNOWN_SOURCES);
+        mDpm.clearUserRestriction(mAdmin, UserManager.DISALLOW_NETWORK_RESET);
+        mDpm.clearUserRestriction(mAdmin, UserManager.DISALLOW_OUTGOING_BEAM);
+        mDpm.clearUserRestriction(mAdmin, UserManager.DISALLOW_REMOVE_USER);
+
+        mDpm.setDeviceOwnerLockScreenInfo(mAdmin, null);
+        mDpm.setKeyguardDisabled(mAdmin, false);
+        mDpm.setAutoTimeRequired(mAdmin, false);
+        mDpm.setStatusBarDisabled(mAdmin, false);
+    }
+
+    private void clearProfileOwnerRelatedPolicies() {
+        mDpm.clearUserRestriction(mAdmin, UserManager.DISALLOW_APPS_CONTROL);
+        mDpm.clearUserRestriction(mAdmin, UserManager.DISALLOW_CONFIG_CREDENTIALS);
+        mDpm.clearUserRestriction(mAdmin, UserManager.DISALLOW_MODIFY_ACCOUNTS);
+        mDpm.clearUserRestriction(mAdmin, UserManager.DISALLOW_SHARE_LOCATION);
+        mDpm.clearUserRestriction(mAdmin, UserManager.DISALLOW_UNINSTALL_APPS);
+
+        mDpm.setKeyguardDisabledFeatures(mAdmin, 0);
+        mDpm.setPasswordQuality(mAdmin, 0);
+        mDpm.setMaximumTimeToLock(mAdmin, 0);
+        mDpm.setPermittedAccessibilityServices(mAdmin, null);
+        mDpm.setPermittedInputMethods(mAdmin, null);
+    }
+}
diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/managedprovisioning/DeviceAdminTestReceiver.java b/apps/CtsVerifier/src/com/android/cts/verifier/managedprovisioning/DeviceAdminTestReceiver.java
index 34166e0..e6ba855 100644
--- a/apps/CtsVerifier/src/com/android/cts/verifier/managedprovisioning/DeviceAdminTestReceiver.java
+++ b/apps/CtsVerifier/src/com/android/cts/verifier/managedprovisioning/DeviceAdminTestReceiver.java
@@ -25,6 +25,10 @@
 import android.provider.Settings;
 import android.util.Log;
 
+import com.android.cts.verifier.R;
+import com.android.cts.verifier.location.LocationListenerActivity;
+import com.android.cts.verifier.managedprovisioning.Utils;
+
 /**
  * Profile owner receiver for BYOD flow test.
  * Setup cross-profile intent filter after successful provisioning.
@@ -48,6 +52,27 @@
             setupProfile(context);
         }
 
+        @Override
+        public void onBugreportSharingDeclined(Context context, Intent intent) {
+            Log.i(TAG, "Bugreport sharing declined");
+            Utils.showBugreportNotification(context, context.getString(
+                    R.string.bugreport_sharing_declined), Utils.BUGREPORT_NOTIFICATION_ID);
+        }
+
+        @Override
+        public void onBugreportShared(Context context, Intent intent, String bugreportFileHash) {
+            Log.i(TAG, "Bugreport shared");
+            Utils.showBugreportNotification(context, context.getString(
+                    R.string.bugreport_shared_successfully), Utils.BUGREPORT_NOTIFICATION_ID);
+        }
+
+        @Override
+        public void onBugreportFailed(Context context, Intent intent, int failureCode) {
+            Log.i(TAG, "Bugreport collection operation failed, code: " + failureCode);
+            Utils.showBugreportNotification(context, context.getString(
+                    R.string.bugreport_failed_completing), Utils.BUGREPORT_NOTIFICATION_ID);
+        }
+
         private void setupProfile(Context context) {
             DevicePolicyManager dpm = (DevicePolicyManager) context.getSystemService(Context.DEVICE_POLICY_SERVICE);
             dpm.setProfileEnabled(new ComponentName(context.getApplicationContext(), getClass()));
@@ -56,7 +81,7 @@
             // Primary -> work direction
             IntentFilter filter = new IntentFilter();
             filter.addAction(ByodHelperActivity.ACTION_QUERY_PROFILE_OWNER);
-            filter.addAction(ByodHelperActivity.ACTION_REMOVE_PROFILE_OWNER);
+            filter.addAction(ByodHelperActivity.ACTION_REMOVE_MANAGED_PROFILE);
             filter.addAction(ByodHelperActivity.ACTION_INSTALL_APK);
             filter.addAction(ByodHelperActivity.ACTION_CHECK_INTENT_FILTERS);
             filter.addAction(ByodHelperActivity.ACTION_CAPTURE_AND_CHECK_IMAGE);
@@ -79,8 +104,14 @@
             filter.addAction(
                     PermissionLockdownTestActivity.ACTION_MANAGED_PROFILE_CHECK_PERMISSION_LOCKDOWN);
             filter.addAction(AuthenticationBoundKeyTestActivity.ACTION_AUTH_BOUND_KEY_TEST);
-            filter.addAction(ByodHelperActivity.ACTION_SET_LOCATION_AND_CHECK_UPDATES);
+            filter.addAction(ByodHelperActivity.ACTION_BYOD_SET_LOCATION_AND_CHECK_UPDATES);
             filter.addAction(VpnTestActivity.ACTION_VPN);
+            filter.addAction(ByodHelperActivity.ACTION_TEST_SELECT_WORK_CHALLENGE);
+            filter.addAction(ByodHelperActivity.ACTION_LAUNCH_CONFIRM_WORK_CREDENTIALS);
+            filter.addAction(ByodHelperActivity.ACTION_SET_ORGANIZATION_INFO);
+            filter.addAction(ByodHelperActivity.ACTION_TEST_PARENT_PROFILE_PASSWORD);
+            filter.addAction(SetSupportMessageActivity.ACTION_SET_SUPPORT_MSG);
+            filter.addAction(CommandReceiverActivity.ACTION_EXECUTE_COMMAND);
             dpm.addCrossProfileIntentFilter(getWho(context), filter,
                     DevicePolicyManager.FLAG_MANAGED_CAN_ACCESS_PARENT);
 
@@ -88,6 +119,7 @@
             filter = new IntentFilter();
             filter.addAction(ByodHelperActivity.ACTION_PROFILE_OWNER_STATUS);
             filter.addAction(CrossProfileTestActivity.ACTION_CROSS_PROFILE_TO_PERSONAL);
+            filter.addAction(LocationListenerActivity.ACTION_SET_LOCATION_AND_CHECK_UPDATES);
             dpm.addCrossProfileIntentFilter(getWho(context), filter,
                     DevicePolicyManager.FLAG_PARENT_CAN_ACCESS_MANAGED);
 
@@ -96,4 +128,5 @@
             intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
             context.startActivity(intent);
         }
+
 }
diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/managedprovisioning/DeviceOwnerNegativeTestActivity.java b/apps/CtsVerifier/src/com/android/cts/verifier/managedprovisioning/DeviceOwnerNegativeTestActivity.java
index 3c0955d..5b43f6a 100644
--- a/apps/CtsVerifier/src/com/android/cts/verifier/managedprovisioning/DeviceOwnerNegativeTestActivity.java
+++ b/apps/CtsVerifier/src/com/android/cts/verifier/managedprovisioning/DeviceOwnerNegativeTestActivity.java
@@ -16,6 +16,9 @@
 
 package com.android.cts.verifier.managedprovisioning;
 
+import android.app.Activity;
+import android.app.admin.DevicePolicyManager;
+import android.content.ComponentName;
 import android.content.Intent;
 import android.database.DataSetObserver;
 import android.os.Bundle;
@@ -33,20 +36,7 @@
  */
 public class DeviceOwnerNegativeTestActivity extends PassFailButtons.TestListActivity {
 
-    private static final String ACTION_PROVISION_MANAGED_DEVICE
-        = "com.android.managedprovisioning.ACTION_PROVISION_MANAGED_DEVICE";
-    private static final Intent PROVISION_DEVICE_INTENT =
-            new Intent(ACTION_PROVISION_MANAGED_DEVICE);
-
     private static final String DEVICE_OWNER_NEGATIVE_TEST = "DEVICE_OWNER_PROVISIONING_NEGATIVE";
-    private static final TestInfo DEVICE_OWNER_NEGATIVE_TEST_INFO = new TestInfo(
-                    DEVICE_OWNER_NEGATIVE_TEST,
-                    R.string.device_owner_negative_test,
-                    R.string.device_owner_negative_test_info,
-                    new ButtonInfo(
-                            R.string.start_device_owner_provisioning_button,
-                            PROVISION_DEVICE_INTENT));
-
     @Override
     protected void onCreate(Bundle savedInstanceState) {
         super.onCreate(savedInstanceState);
@@ -55,22 +45,29 @@
                 R.string.device_owner_provisioning_tests_info, 0);
         setPassFailButtonClickListeners();
 
+        TestInfo deviceOwnerNegativeTestInfo = new TestInfo(
+                DEVICE_OWNER_NEGATIVE_TEST,
+                R.string.device_owner_negative_test,
+                R.string.device_owner_negative_test_info,
+                new ButtonInfo(
+                        R.string.start_device_owner_provisioning_button,
+                        new Intent(this, TrampolineActivity.class)));
+
         final ArrayTestListAdapter adapter = new ArrayTestListAdapter(this);
         adapter.add(TestListItem.newCategory(this, R.string.device_owner_provisioning_category));
 
         Intent startTestIntent = new Intent(this, IntentDrivenTestActivity.class)
                     .putExtra(IntentDrivenTestActivity.EXTRA_ID,
-                            DEVICE_OWNER_NEGATIVE_TEST_INFO.getTestId())
+                            deviceOwnerNegativeTestInfo.getTestId())
                     .putExtra(IntentDrivenTestActivity.EXTRA_TITLE,
-                            DEVICE_OWNER_NEGATIVE_TEST_INFO.getTitle())
+                            deviceOwnerNegativeTestInfo.getTitle())
                     .putExtra(IntentDrivenTestActivity.EXTRA_INFO,
-                            DEVICE_OWNER_NEGATIVE_TEST_INFO.getInfoText())
+                            deviceOwnerNegativeTestInfo.getInfoText())
                     .putExtra(IntentDrivenTestActivity.EXTRA_BUTTONS,
-                            DEVICE_OWNER_NEGATIVE_TEST_INFO.getButtons());
+                            deviceOwnerNegativeTestInfo.getButtons());
 
-
-        adapter.add(TestListItem.newTest(this, DEVICE_OWNER_NEGATIVE_TEST_INFO.getTitle(),
-                DEVICE_OWNER_NEGATIVE_TEST_INFO.getTestId(), startTestIntent, null));
+        adapter.add(TestListItem.newTest(this, deviceOwnerNegativeTestInfo.getTitle(),
+                deviceOwnerNegativeTestInfo.getTestId(), startTestIntent, null));
 
         adapter.registerDataSetObserver(new DataSetObserver() {
             @Override
@@ -81,5 +78,29 @@
 
         setTestListAdapter(adapter);
     }
+
+    /**
+     * This is needed because IntentDrivenTestActivity fires the intent by startActivity when
+     * a button is clicked, but ACTION_PROVISION_MANAGED_DEVICE requires to be fired by
+     * startActivityForResult.
+     */
+    public static class TrampolineActivity extends Activity {
+        @Override
+        protected void onCreate(Bundle savedInstanceState) {
+            super.onCreate(savedInstanceState);
+            Intent provisionDeviceIntent = new Intent(
+                    DevicePolicyManager.ACTION_PROVISION_MANAGED_DEVICE);
+            provisionDeviceIntent.putExtra(
+                    DevicePolicyManager.EXTRA_PROVISIONING_DEVICE_ADMIN_COMPONENT_NAME,
+                    new ComponentName(this, DeviceAdminTestReceiver.class.getName()));
+            startActivityForResult(provisionDeviceIntent, 0);
+        }
+
+        @Override
+        protected void onActivityResult(int requestCode, int resultCode, Intent data) {
+            super.onActivityResult(requestCode, resultCode, data);
+            finish();
+        }
+    }
 }
 
diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/managedprovisioning/DeviceOwnerPositiveTestActivity.java b/apps/CtsVerifier/src/com/android/cts/verifier/managedprovisioning/DeviceOwnerPositiveTestActivity.java
index b6e3b2c..724f03d 100644
--- a/apps/CtsVerifier/src/com/android/cts/verifier/managedprovisioning/DeviceOwnerPositiveTestActivity.java
+++ b/apps/CtsVerifier/src/com/android/cts/verifier/managedprovisioning/DeviceOwnerPositiveTestActivity.java
@@ -16,6 +16,8 @@
 
 package com.android.cts.verifier.managedprovisioning;
 
+import static com.android.cts.verifier.managedprovisioning.Utils.createInteractiveTestItem;
+
 import android.app.Activity;
 import android.app.AlertDialog;
 import android.app.admin.DevicePolicyManager;
@@ -49,22 +51,9 @@
 public class DeviceOwnerPositiveTestActivity extends PassFailButtons.TestListActivity {
     private static final String TAG = "DeviceOwnerPositiveTestActivity";
 
-    static final String EXTRA_COMMAND = "extra-command";
+    private static final String ACTION_CHECK_DEVICE_OWNER =
+            "com.android.cts.verifier.managedprovisioning.action.CHECK_DEVICE_OWNER";
     static final String EXTRA_TEST_ID = "extra-test-id";
-    static final String COMMAND_SET_POLICY = "set-policy";
-    static final String EXTRA_POLICY = "extra-policy";
-    static final String EXTRA_PARAMETER_1 = "extra_parameter_1";
-    static final String EXTRA_PARAMETER_2 = "extra_parameter_2";
-    static final String COMMAND_ADD_USER_RESTRICTION = "add-user-restriction";
-    static final String COMMAND_CLEAR_USER_RESTRICTION = "clear-user-restriction";
-    static final String EXTRA_RESTRICTION = "extra-restriction";
-    static final String COMMAND_TEAR_DOWN = "tear-down";
-    static final String COMMAND_CHECK_DEVICE_OWNER = "check-device-owner";
-    static final String COMMAND_SET_GLOBAL_SETTING = "set-global-setting";
-    static final String COMMAND_SET_STATUSBAR_DISABLED = "set-statusbar-disabled";
-    static final String COMMAND_SET_KEYGUARD_DISABLED = "set-keyguard-disabled";
-    static final String COMMAND_CHECK_PERMISSION_LOCKDOWN = "check-permission-lockdown";
-    static final String EXTRA_SETTING = "extra-setting";
 
     private static final String CHECK_DEVICE_OWNER_TEST_ID = "CHECK_DEVICE_OWNER";
     private static final String DEVICE_ADMIN_SETTINGS_ID = "DEVICE_ADMIN_SETTINGS";
@@ -77,13 +66,28 @@
     private static final String DISALLOW_CONFIG_WIFI_ID = "DISALLOW_CONFIG_WIFI";
     private static final String DISALLOW_CONFIG_VPN_ID = "DISALLOW_CONFIG_VPN";
     private static final String DISALLOW_USB_FILE_TRANSFER_ID = "DISALLOW_USB_FILE_TRANSFER";
-    //TODO(rgl): This symbol should be available in android.provider.settings
-    private static final String ACTION_VPN_SETTINGS = "android.net.vpn.SETTINGS";
+    private static final String SET_USER_ICON_TEST_ID = "SET_USER_ICON";
+    private static final String DISALLOW_DATA_ROAMING_ID = "DISALLOW_DATA_ROAMING";
+    private static final String POLICY_TRANSPARENCY_TEST_ID = "POLICY_TRANSPARENCY";
     private static final String REMOVE_DEVICE_OWNER_TEST_ID = "REMOVE_DEVICE_OWNER";
 
     @Override
     protected void onCreate(Bundle savedInstanceState) {
         super.onCreate(savedInstanceState);
+        if (ACTION_CHECK_DEVICE_OWNER.equals(getIntent().getAction())) {
+            DevicePolicyManager dpm = (DevicePolicyManager) getSystemService(
+                    Context.DEVICE_POLICY_SERVICE);
+            if (dpm.isDeviceOwnerApp(getPackageName())) {
+                TestResult.setPassedResult(this, getIntent().getStringExtra(EXTRA_TEST_ID),
+                        null, null);
+            } else {
+                TestResult.setFailedResult(this, getIntent().getStringExtra(EXTRA_TEST_ID),
+                        getString(R.string.device_owner_incorrect_device_owner), null);
+            }
+            finish();
+            return;
+        }
+
         setContentView(R.layout.positive_device_owner);
         setInfoResources(R.string.device_owner_positive_tests,
                 R.string.device_owner_positive_tests_info, 0);
@@ -121,18 +125,21 @@
 
     @Override
     public void finish() {
-        // Pass and fail buttons are known to call finish() when clicked, and this is when we want
-        // to remove the device owner.
-        startActivity(createTearDownIntent());
+        // If this activity was started for checking device owner status, then no need to do any
+        // tear down.
+        if (!ACTION_CHECK_DEVICE_OWNER.equals(getIntent().getAction())) {
+            // Pass and fail buttons are known to call finish() when clicked,
+            // and this is when we want to remove the device owner.
+            startActivity(createTearDownIntent());
+        }
         super.finish();
     }
 
     private void addTestsToAdapter(final ArrayTestListAdapter adapter) {
         adapter.add(createTestItem(this, CHECK_DEVICE_OWNER_TEST_ID,
                 R.string.device_owner_check_device_owner_test,
-                new Intent(this, CommandReceiver.class)
-                        .putExtra(EXTRA_COMMAND, COMMAND_CHECK_DEVICE_OWNER)
-                        ));
+                new Intent(ACTION_CHECK_DEVICE_OWNER)
+                        .putExtra(EXTRA_TEST_ID, getIntent().getStringExtra(EXTRA_TEST_ID))));
 
         // device admin settings
         adapter.add(createInteractiveTestItem(this, DEVICE_ADMIN_SETTINGS_ID,
@@ -174,11 +181,26 @@
                                         UserManager.DISALLOW_CONFIG_VPN)),
                         new ButtonInfo(
                                 R.string.device_owner_settings_go,
-                                new Intent(ACTION_VPN_SETTINGS)),
+                                new Intent(Settings.ACTION_VPN_SETTINGS)),
                         new ButtonInfo(
                                 R.string.device_owner_vpn_test,
                                 new Intent(this, VpnTestActivity.class))}));
 
+        // DISALLOW_DATA_ROAMING
+        if(packageManager.hasSystemFeature(PackageManager.FEATURE_TELEPHONY)) {
+            adapter.add(createInteractiveTestItem(this, DISALLOW_DATA_ROAMING_ID,
+                    R.string.device_owner_disallow_data_roaming,
+                    R.string.device_owner_disallow_data_roaming_info,
+                    new ButtonInfo[] {
+                            new ButtonInfo(
+                                    R.string.device_owner_user_restriction_set,
+                                    createSetUserRestrictionIntent(
+                                            UserManager.DISALLOW_DATA_ROAMING)),
+                            new ButtonInfo(
+                                    R.string.device_owner_settings_go,
+                                    new Intent(Settings.ACTION_DATA_ROAMING_SETTINGS))}));
+        }
+
         // DISALLOW_CONFIG_BLUETOOTH
         if (packageManager.hasSystemFeature(PackageManager.FEATURE_BLUETOOTH)) {
             adapter.add(createInteractiveTestItem(this, DISALLOW_CONFIG_BT_ID,
@@ -213,11 +235,13 @@
                         new ButtonInfo(
                                 R.string.device_owner_disable_statusbar_button,
                                 createDeviceOwnerIntentWithBooleanParameter(
-                                        COMMAND_SET_STATUSBAR_DISABLED, true)),
+                                        CommandReceiverActivity.COMMAND_SET_STATUSBAR_DISABLED,
+                                                true)),
                         new ButtonInfo(
                                 R.string.device_owner_reenable_statusbar_button,
                                 createDeviceOwnerIntentWithBooleanParameter(
-                                        COMMAND_SET_STATUSBAR_DISABLED, false))}));
+                                        CommandReceiverActivity.COMMAND_SET_STATUSBAR_DISABLED,
+                                                false))}));
 
         // setKeyguardDisabled
         adapter.add(createInteractiveTestItem(this, DISABLE_KEYGUARD_TEST_ID,
@@ -227,17 +251,41 @@
                         new ButtonInfo(
                                 R.string.device_owner_disable_keyguard_button,
                                 createDeviceOwnerIntentWithBooleanParameter(
-                                        COMMAND_SET_KEYGUARD_DISABLED, true)),
+                                        CommandReceiverActivity.COMMAND_SET_KEYGUARD_DISABLED,
+                                                true)),
                         new ButtonInfo(
                                 R.string.device_owner_reenable_keyguard_button,
                                 createDeviceOwnerIntentWithBooleanParameter(
-                                        COMMAND_SET_KEYGUARD_DISABLED, false))}));
+                                        CommandReceiverActivity.COMMAND_SET_KEYGUARD_DISABLED,
+                                                false))}));
+
+        adapter.add(createInteractiveTestItem(this, SET_USER_ICON_TEST_ID,
+                R.string.device_owner_set_user_icon,
+                R.string.device_owner_set_user_icon_instruction,
+                new ButtonInfo[] {
+                        new ButtonInfo(
+                                R.string.device_owner_set_user_icon_button,
+                                createSetUserIconIntent()),
+                        new ButtonInfo(
+                                R.string.device_owner_settings_go,
+                                new Intent(Settings.ACTION_SETTINGS))}));
 
         // setPermissionGrantState
         adapter.add(createTestItem(this, CHECK_PERMISSION_LOCKDOWN_TEST_ID,
                 R.string.device_profile_owner_permission_lockdown_test,
                 new Intent(PermissionLockdownTestActivity.ACTION_CHECK_PERMISSION_LOCKDOWN)));
 
+        // Policy Transparency
+        final Intent policyTransparencyTestIntent = new Intent(this,
+                PolicyTransparencyTestListActivity.class);
+        policyTransparencyTestIntent.putExtra(
+                PolicyTransparencyTestListActivity.EXTRA_IS_DEVICE_OWNER, true);
+        policyTransparencyTestIntent.putExtra(
+                PolicyTransparencyTestActivity.EXTRA_TEST_ID, POLICY_TRANSPARENCY_TEST_ID);
+        adapter.add(createTestItem(this, POLICY_TRANSPARENCY_TEST_ID,
+                R.string.device_profile_owner_policy_transparency_test,
+                policyTransparencyTestIntent));
+
         // removeDeviceOwner
         adapter.add(createInteractiveTestItem(this, REMOVE_DEVICE_OWNER_TEST_ID,
                 R.string.device_owner_remove_device_owner_test,
@@ -247,112 +295,36 @@
                         createTearDownIntent())));
     }
 
-    static TestListItem createInteractiveTestItem(Activity activity, String id, int titleRes,
-            int infoRes, ButtonInfo buttonInfo) {
-        return createInteractiveTestItem(activity, id, titleRes, infoRes,
-                new ButtonInfo[] { buttonInfo });
-    }
-
-    static TestListItem createInteractiveTestItem(Activity activity, String id, int titleRes,
-            int infoRes, ButtonInfo[] buttonInfos) {
-        return TestListItem.newTest(activity, titleRes,
-                id, new Intent(activity, IntentDrivenTestActivity.class)
-                .putExtra(IntentDrivenTestActivity.EXTRA_ID, id)
-                .putExtra(IntentDrivenTestActivity.EXTRA_TITLE, titleRes)
-                .putExtra(IntentDrivenTestActivity.EXTRA_INFO, infoRes)
-                .putExtra(IntentDrivenTestActivity.EXTRA_BUTTONS, buttonInfos),
-                null);
-    }
 
     static TestListItem createTestItem(Activity activity, String id, int titleRes,
             Intent intent) {
-        return TestListItem.newTest(activity, titleRes, id, intent.putExtra(EXTRA_TEST_ID, id),
-                null);
+        intent.putExtra(EXTRA_TEST_ID, id);
+        return TestListItem.newTest(activity, titleRes, id, intent, null);
     }
 
     private Intent createTearDownIntent() {
-        return new Intent(this, CommandReceiver.class)
-                .putExtra(EXTRA_COMMAND, COMMAND_TEAR_DOWN);
+        return new Intent(this, CommandReceiverActivity.class)
+                .putExtra(CommandReceiverActivity.EXTRA_COMMAND,
+                        CommandReceiverActivity.COMMAND_REMOVE_DEVICE_OWNER);
     }
 
     private Intent createDeviceOwnerIntentWithBooleanParameter(String command, boolean value) {
-        return new Intent(this, CommandReceiver.class)
-                .putExtra(EXTRA_COMMAND, command)
-                .putExtra(EXTRA_PARAMETER_1, value);
+        return new Intent(this, CommandReceiverActivity.class)
+                .putExtra(CommandReceiverActivity.EXTRA_COMMAND, command)
+                .putExtra(CommandReceiverActivity.EXTRA_ENFORCED, value);
     }
 
     private Intent createSetUserRestrictionIntent(String restriction) {
-        return new Intent(this, CommandReceiver.class)
-                .putExtra(EXTRA_COMMAND, COMMAND_ADD_USER_RESTRICTION)
-                .putExtra(EXTRA_RESTRICTION, restriction);
+        return new Intent(this, CommandReceiverActivity.class)
+                .putExtra(CommandReceiverActivity.EXTRA_COMMAND,
+                        CommandReceiverActivity.COMMAND_SET_USER_RESTRICTION)
+                .putExtra(CommandReceiverActivity.EXTRA_USER_RESTRICTION, restriction)
+                .putExtra(CommandReceiverActivity.EXTRA_ENFORCED, true);
     }
 
-    public static class CommandReceiver extends Activity {
-        @Override
-        public void onCreate(Bundle savedInstanceState) {
-            super.onCreate(savedInstanceState);
-            Intent intent = getIntent();
-            String command = intent.getStringExtra(EXTRA_COMMAND);
-            try {
-                DevicePolicyManager dpm = (DevicePolicyManager)
-                        getSystemService(Context.DEVICE_POLICY_SERVICE);
-                ComponentName admin = DeviceAdminTestReceiver.getReceiverComponentName();
-                Log.i(TAG, "Command: " + command);
-
-                if (COMMAND_ADD_USER_RESTRICTION.equals(command)) {
-                    String restrictionKey = intent.getStringExtra(EXTRA_RESTRICTION);
-                    dpm.addUserRestriction(admin, restrictionKey);
-                    Log.i(TAG, "Added user restriction " + restrictionKey);
-                } else if (COMMAND_CLEAR_USER_RESTRICTION.equals(command)) {
-                    String restrictionKey = intent.getStringExtra(EXTRA_RESTRICTION);
-                    dpm.clearUserRestriction(admin, restrictionKey);
-                    Log.i(TAG, "Cleared user restriction " + restrictionKey);
-                } else if (COMMAND_TEAR_DOWN.equals(command)) {
-                    tearDown(dpm, admin);
-                } else if (COMMAND_SET_GLOBAL_SETTING.equals(command)) {
-                    final String setting = intent.getStringExtra(EXTRA_SETTING);
-                    final String value = intent.getStringExtra(EXTRA_PARAMETER_1);
-                    dpm.setGlobalSetting(admin, setting, value);
-                } else if (COMMAND_SET_STATUSBAR_DISABLED.equals(command)) {
-                    final boolean value = intent.getBooleanExtra(EXTRA_PARAMETER_1, false);
-                    dpm.setStatusBarDisabled(admin, value);
-                } else if (COMMAND_SET_KEYGUARD_DISABLED.equals(command)) {
-                    final boolean value = intent.getBooleanExtra(EXTRA_PARAMETER_1, false);
-                    if (value) {
-                        dpm.resetPassword(null, 0);
-                    }
-                    dpm.setKeyguardDisabled(admin, value);
-                } else if (COMMAND_CHECK_DEVICE_OWNER.equals(command)) {
-                    if (dpm.isDeviceOwnerApp(getPackageName())) {
-                        TestResult.setPassedResult(this, intent.getStringExtra(EXTRA_TEST_ID),
-                                null, null);
-                    } else {
-                        TestResult.setFailedResult(this, intent.getStringExtra(EXTRA_TEST_ID),
-                                getString(R.string.device_owner_incorrect_device_owner), null);
-                    }
-                } else {
-                    Log.e(TAG, "Invalid command: " + command);
-                }
-            } catch (Exception e) {
-                Log.e(TAG, "Command " + command + " failed with exception " + e);
-            } finally {
-                // No matter what happened, don't let the activity run
-                finish();
-            }
-        }
-
-        private void tearDown(DevicePolicyManager dpm, ComponentName admin) {
-            if (dpm == null || !dpm.isDeviceOwnerApp(getPackageName())) {
-                return;
-            }
-
-            dpm.setStatusBarDisabled(admin, false);
-            dpm.setKeyguardDisabled(admin, false);
-            dpm.clearUserRestriction(admin, UserManager.DISALLOW_CONFIG_BLUETOOTH);
-            dpm.clearUserRestriction(admin, UserManager.DISALLOW_CONFIG_WIFI);
-            dpm.clearUserRestriction(admin, UserManager.DISALLOW_CONFIG_VPN);
-            dpm.clearDeviceOwnerApp(getPackageName());
-        }
+    private Intent createSetUserIconIntent() {
+        return new Intent(this, CommandReceiverActivity.class)
+                .putExtra(CommandReceiverActivity.EXTRA_COMMAND,
+                        CommandReceiverActivity.COMMAND_SET_USER_ICON);
     }
 }
-
diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/managedprovisioning/DeviceOwnerRequestingBugreportTestActivity.java b/apps/CtsVerifier/src/com/android/cts/verifier/managedprovisioning/DeviceOwnerRequestingBugreportTestActivity.java
new file mode 100644
index 0000000..1d23175
--- /dev/null
+++ b/apps/CtsVerifier/src/com/android/cts/verifier/managedprovisioning/DeviceOwnerRequestingBugreportTestActivity.java
@@ -0,0 +1,196 @@
+/*
+ * Copyright (C) 2016 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.verifier.managedprovisioning;
+
+import static com.android.cts.verifier.managedprovisioning.Utils.createInteractiveTestItem;
+
+import android.app.Activity;
+import android.app.AlertDialog;
+import android.app.admin.DevicePolicyManager;
+import android.content.ComponentName;
+import android.content.Context;
+import android.content.Intent;
+import android.database.DataSetObserver;
+import android.os.Bundle;
+import android.view.View;
+import android.view.View.OnClickListener;
+
+import com.android.cts.verifier.ArrayTestListAdapter;
+import com.android.cts.verifier.IntentDrivenTestActivity.ButtonInfo;
+import com.android.cts.verifier.PassFailButtons;
+import com.android.cts.verifier.R;
+import com.android.cts.verifier.TestListAdapter.TestListItem;
+import com.android.cts.verifier.TestResult;
+
+/**
+ * Activity that lists all requesting bugreport device owner tests. Requires the following
+ * adb command be issued by the user prior to starting the tests:
+ *
+ * adb shell dpm set-device-owner
+ *  'com.android.cts.verifier/com.android.cts.verifier.managedprovisioning.DeviceAdminTestReceiver'
+ */
+public class DeviceOwnerRequestingBugreportTestActivity extends PassFailButtons.TestListActivity {
+    private static final String TAG = "DeviceOwnerRequestingBugreportTestActivity";
+
+    private static final String ACTION_CHECK_DEVICE_OWNER_FOR_REQUESTING_BUGREPORT =
+            "com.android.cts.verifier.managedprovisioning.action" +
+            ".CHECK_DEVICE_OWNER_FOR_REQUESTING_BUGREPORT";
+    static final String EXTRA_TEST_ID = "extra-test-id";
+
+    private static final String CHECK_DEVICE_OWNER_TEST_ID = "CHECK_DEVICE_OWNER";
+    private static final String DEVICE_ADMIN_SETTINGS_ID = "DEVICE_ADMIN_SETTINGS";
+    private static final String BUGREPORT_SHARING_DECLINED_WHILE_BEING_TAKEN =
+            "BUGREPORT_SHARING_DECLINED_WHILE_RUNNING";
+    private static final String BUGREPORT_SHARING_ACCEPTED_WHILE_BEING_TAKEN =
+            "BUGREPORT_SHARING_ACCEPTED_WHILE_RUNNING";
+    private static final String BUGREPORT_SHARING_DECLINED_AFTER_HAVING_BEEN_TAKEN =
+            "BUGREPORT_SHARING_DECLINED_AFTER_HAVING_BEEN_TAKEN";
+    private static final String BUGREPORT_SHARING_ACCEPTED_AFTER_HAVING_BEEN_TAKEN =
+            "BUGREPORT_SHARING_ACCEPTED_AFTER_HAVING_BEEN_TAKEN";
+    private static final String REMOVE_DEVICE_OWNER_TEST_ID = "REMOVE_DEVICE_OWNER";
+
+    @Override
+    protected void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+        if (ACTION_CHECK_DEVICE_OWNER_FOR_REQUESTING_BUGREPORT.equals(getIntent().getAction())) {
+            DevicePolicyManager dpm = (DevicePolicyManager) getSystemService(
+                    Context.DEVICE_POLICY_SERVICE);
+            if (dpm.isDeviceOwnerApp(getPackageName())) {
+                TestResult.setPassedResult(this, getIntent().getStringExtra(EXTRA_TEST_ID),
+                        null, null);
+            } else {
+                TestResult.setFailedResult(this, getIntent().getStringExtra(EXTRA_TEST_ID),
+                        getString(R.string.device_owner_incorrect_device_owner), null);
+            }
+            finish();
+            return;
+        }
+
+        setContentView(R.layout.requesting_bugreport_device_owner);
+        setInfoResources(R.string.device_owner_requesting_bugreport_tests,
+                R.string.device_owner_requesting_bugreport_tests_info, 0);
+        setPassFailButtonClickListeners();
+
+        final ArrayTestListAdapter adapter = new ArrayTestListAdapter(this);
+        adapter.add(TestListItem.newCategory(this,
+                R.string.device_owner_requesting_bugreport_category));
+
+        addTestsToAdapter(adapter);
+
+        adapter.registerDataSetObserver(new DataSetObserver() {
+            @Override
+            public void onChanged() {
+                updatePassButton();
+            }
+        });
+
+        setTestListAdapter(adapter);
+
+        View setDeviceOwnerButton = findViewById(R.id.set_device_owner_button);
+        setDeviceOwnerButton.setOnClickListener(new OnClickListener() {
+            @Override
+            public void onClick(View v) {
+                new AlertDialog.Builder(
+                        DeviceOwnerRequestingBugreportTestActivity.this)
+                        .setIcon(android.R.drawable.ic_dialog_info)
+                        .setTitle(R.string.set_device_owner_dialog_title)
+                        .setMessage(R.string.set_device_owner_dialog_text)
+                        .setPositiveButton(android.R.string.ok, null)
+                        .show();
+            }
+        });
+    }
+
+    @Override
+    public void finish() {
+        // If this activity was started for checking device owner status, then no need to do any
+        // tear down.
+        if (!ACTION_CHECK_DEVICE_OWNER_FOR_REQUESTING_BUGREPORT.equals(getIntent().getAction())) {
+            // Pass and fail buttons are known to call finish() when clicked,
+            // and this is when we want to remove the device owner.
+            startActivity(createTearDownIntent());
+        }
+        super.finish();
+    }
+
+    private void addTestsToAdapter(final ArrayTestListAdapter adapter) {
+        adapter.add(createTestItem(this, CHECK_DEVICE_OWNER_TEST_ID,
+                R.string.device_owner_check_device_owner_test,
+                new Intent(ACTION_CHECK_DEVICE_OWNER_FOR_REQUESTING_BUGREPORT)
+                        .putExtra(EXTRA_TEST_ID, getIntent().getStringExtra(EXTRA_TEST_ID))));
+
+        // bugreport sharing declined while running test
+        adapter.add(createInteractiveTestItem(this, BUGREPORT_SHARING_DECLINED_WHILE_BEING_TAKEN,
+                R.string.device_owner_bugreport_sharing_declined_while_being_taken,
+                R.string.device_owner_bugreport_sharing_declined_while_being_taken_info,
+                new ButtonInfo(
+                        R.string.device_owner_request_bugreport,
+                        createRequestBugreportIntent())));
+
+        // bugreport sharing accepted while running test
+        adapter.add(createInteractiveTestItem(this, BUGREPORT_SHARING_ACCEPTED_WHILE_BEING_TAKEN,
+                R.string.device_owner_bugreport_sharing_accepted_while_being_taken,
+                R.string.device_owner_bugreport_sharing_accepted_while_being_taken_info,
+                new ButtonInfo(
+                        R.string.device_owner_request_bugreport,
+                        createRequestBugreportIntent())));
+
+        // bugreport sharing declined after having been taken test
+        adapter.add(createInteractiveTestItem(this,
+                BUGREPORT_SHARING_DECLINED_AFTER_HAVING_BEEN_TAKEN,
+                R.string.device_owner_bugreport_sharing_declined_after_having_been_taken,
+                R.string.device_owner_bugreport_sharing_declined_after_having_been_taken_info,
+                new ButtonInfo(
+                        R.string.device_owner_request_bugreport,
+                        createRequestBugreportIntent())));
+
+        // bugreport sharing accepted after having been taken test
+        adapter.add(createInteractiveTestItem(this,
+                BUGREPORT_SHARING_ACCEPTED_AFTER_HAVING_BEEN_TAKEN,
+                R.string.device_owner_bugreport_sharing_accepted_after_having_been_taken,
+                R.string.device_owner_bugreport_sharing_accepted_after_having_been_taken_info,
+                new ButtonInfo(
+                        R.string.device_owner_request_bugreport,
+                        createRequestBugreportIntent())));
+
+        // removeDeviceOwner
+        adapter.add(createInteractiveTestItem(this, REMOVE_DEVICE_OWNER_TEST_ID,
+                R.string.device_owner_remove_device_owner_test,
+                R.string.device_owner_remove_device_owner_test_info,
+                new ButtonInfo(
+                        R.string.remove_device_owner_button,
+                        createTearDownIntent())));
+    }
+
+    static TestListItem createTestItem(Activity activity, String id, int titleRes,
+            Intent intent) {
+        intent.putExtra(EXTRA_TEST_ID, id);
+        return TestListItem.newTest(activity, titleRes, id, intent, null);
+    }
+
+    private Intent createTearDownIntent() {
+        return new Intent(this, CommandReceiverActivity.class)
+                .putExtra(CommandReceiverActivity.EXTRA_COMMAND,
+                        CommandReceiverActivity.COMMAND_REMOVE_DEVICE_OWNER);
+    }
+
+    private Intent createRequestBugreportIntent() {
+        return new Intent(this, CommandReceiverActivity.class)
+                .putExtra(CommandReceiverActivity.EXTRA_COMMAND,
+                        CommandReceiverActivity.COMMAND_REQUEST_BUGREPORT);
+    }
+}
diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/managedprovisioning/IntentFiltersTestHelper.java b/apps/CtsVerifier/src/com/android/cts/verifier/managedprovisioning/IntentFiltersTestHelper.java
index 24a6c79..b162b58 100644
--- a/apps/CtsVerifier/src/com/android/cts/verifier/managedprovisioning/IntentFiltersTestHelper.java
+++ b/apps/CtsVerifier/src/com/android/cts/verifier/managedprovisioning/IntentFiltersTestHelper.java
@@ -77,6 +77,7 @@
                 new Intent(Settings.ACTION_WIRELESS_SETTINGS),
                 new Intent(DevicePolicyManager.ACTION_SET_NEW_PASSWORD),
                 new Intent("android.net.vpn.SETTINGS"),
+                new Intent(Settings.ACTION_VPN_SETTINGS),
                 new Intent("android.settings.ACCOUNT_SYNC_SETTINGS"),
                 new Intent(Settings.ACTION_BATTERY_SAVER_SETTINGS),
                 new Intent("android.settings.LICENSE"),
@@ -148,7 +149,6 @@
         if (pm.hasSystemFeature(PackageManager.FEATURE_TELEPHONY)) {
             forwardedIntentsFromManaged.addAll(Arrays.asList(
                     new Intent(Intent.ACTION_DIAL).setData(Uri.parse("tel:123")),
-                    new Intent(Intent.ACTION_CALL).setData(Uri.parse("tel:123")),
                     new Intent("android.intent.action.CALL_EMERGENCY").setData(
                             Uri.parse("tel:123")),
                     new Intent("android.intent.action.CALL_PRIVILEGED").setData(
@@ -174,6 +174,8 @@
                             Uri.parse("mmsto:07700900100?body=Hello%20world")).addCategory(
                             Intent.CATEGORY_BROWSABLE),
                     new Intent(Settings.ACTION_APN_SETTINGS)));
+            notForwardedIntentsFromManaged
+                    .add(new Intent(Intent.ACTION_CALL).setData(Uri.parse("tel:123")));
         }
 
         if (pm.hasSystemFeature(PackageManager.FEATURE_NFC)) {
@@ -282,15 +284,9 @@
         }
 
         // Check for intents which can be forwarded to the managed profile.
-        Intent intent = checkForIntentsNotHandled(forwardedIntentsFromPrimary,
-                forwarderActivityInfo, true);
-        if (intent != null) {
-            Log.d(TAG, intent + " from primary profile should be forwarded to the " +
-                    "managed profile but is not.");
-            return false;
-        }
-
-        return true;
+        return checkForIntentsNotHandled(forwardedIntentsFromPrimary,
+                forwarderActivityInfo, "from primary profile should be forwarded to the " +
+                "managed profile but is not.", true);
     }
 
     /**
@@ -306,25 +302,17 @@
             return false;
         }
 
+        boolean success = true;
         // Check for intents which can be forwarded to the primary profile.
-        Intent intent = checkForIntentsNotHandled(forwardedIntentsFromManaged,
-                forwarderActivityInfo, true);
-        if (intent != null) {
-            Log.d(TAG, intent + " from managed profile should be forwarded to the " +
-                    "primary profile but is not.");
-            return false;
-        }
+        success &= checkForIntentsNotHandled(forwardedIntentsFromManaged,
+                forwarderActivityInfo, " from managed profile should be forwarded to the " +
+                "primary profile but is not.", true);
 
         // Check for intents which cannot be forwarded to the primary profile.
-        intent = checkForIntentsNotHandled(notForwardedIntentsFromManaged,
-                forwarderActivityInfo, false);
-        if (intent != null) {
-            Log.d(TAG, intent + " from managed profile should not be forwarded to the " +
-                    "primary profile but it is.");
-            return false;
-        }
-
-        return true;
+        success &= checkForIntentsNotHandled(notForwardedIntentsFromManaged,
+                forwarderActivityInfo, "from managed profile should not be forwarded to the " +
+                "primary profile but it is.", false);
+        return success;
     }
 
     /**
@@ -364,17 +352,18 @@
 
     /**
      * Checks if the intents passed are correctly handled.
-     * @return {@code null} if all the intents are correctly handled
-     *         otherwise, the first intent in the list which is not handled correctly.
+     * @return {@code false} if at least one intent is not handled correctly.
      */
-    private Intent checkForIntentsNotHandled(ArrayList<Intent> intentList,
-            ActivityInfo expectedForwarderActivityInfo, boolean canResolve) {
+    private boolean checkForIntentsNotHandled(ArrayList<Intent> intentList,
+            ActivityInfo expectedForwarderActivityInfo, String errorMessage, boolean canResolve) {
+        boolean success = true;
         for (Intent intent : intentList) {
             if (canForwarderActivityHandleIntent(intent,
                     expectedForwarderActivityInfo) != canResolve) {
-                return intent;
+                Log.e(TAG, intent + " " + errorMessage);
+                success = false;
             }
         }
-        return null;
+        return success;
     }
 }
diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/managedprovisioning/KeyguardDisabledFeaturesActivity.java b/apps/CtsVerifier/src/com/android/cts/verifier/managedprovisioning/KeyguardDisabledFeaturesActivity.java
index 66507b4..5585cbc 100644
--- a/apps/CtsVerifier/src/com/android/cts/verifier/managedprovisioning/KeyguardDisabledFeaturesActivity.java
+++ b/apps/CtsVerifier/src/com/android/cts/verifier/managedprovisioning/KeyguardDisabledFeaturesActivity.java
@@ -67,7 +67,6 @@
                         return;
                     }
                     setKeyguardDisabledFeatures();
-                    mDpm.resetPassword("testpassword", 0);
                 }
             });
     }
@@ -86,7 +85,6 @@
         // clear the password.
         final ComponentName adminComponent = getAdminComponent();
         if (mDpm.isAdminActive(adminComponent)) {
-            mDpm.resetPassword(null, 0);
             mDpm.removeActiveAdmin(adminComponent);
         }
         super.finish();
diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/managedprovisioning/OrganizationInfoTestActivity.java b/apps/CtsVerifier/src/com/android/cts/verifier/managedprovisioning/OrganizationInfoTestActivity.java
new file mode 100644
index 0000000..7c5f374
--- /dev/null
+++ b/apps/CtsVerifier/src/com/android/cts/verifier/managedprovisioning/OrganizationInfoTestActivity.java
@@ -0,0 +1,81 @@
+/*
+ * Copyright (C) 2016 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.verifier.managedprovisioning;
+
+import android.content.Intent;
+import android.graphics.Color;
+import android.os.Bundle;
+import android.view.View;
+import android.widget.EditText;
+import android.widget.Toast;
+
+import com.android.cts.verifier.PassFailButtons;
+import com.android.cts.verifier.R;
+
+/**
+ * Test class to verify Organization Info.
+ */
+public class OrganizationInfoTestActivity extends PassFailButtons.Activity
+        implements View.OnClickListener {
+
+    public static final String EXTRA_ORGANIZATION_NAME = "extra_organization_name";
+    public static final String EXTRA_ORGANIZATION_COLOR = "extra_organization_color";
+
+    private int mOrganizationColor;
+
+    @Override
+    protected void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+        setContentView(R.layout.organization_info);
+        setPassFailButtonClickListeners();
+        setButtonClickListeners();
+    }
+
+    private void setButtonClickListeners() {
+        findViewById(R.id.organization_info_set_button).setOnClickListener(this);
+        findViewById(R.id.go_button).setOnClickListener(this);
+    }
+
+    @Override
+    public void onClick(View view) {
+        if (view.getId() == R.id.organization_info_set_button) {
+            EditText organizationNameEditText = (EditText) findViewById(
+                    R.id.organization_name_edit_text);
+            Intent intent = new Intent(ByodHelperActivity.ACTION_SET_ORGANIZATION_INFO);
+            intent.putExtra(EXTRA_ORGANIZATION_NAME, organizationNameEditText.getText().toString());
+            if (isOrganizationColorSet()) {
+                intent.putExtra(EXTRA_ORGANIZATION_COLOR, mOrganizationColor);
+            }
+            startActivity(intent);
+        } else if (view.getId() == R.id.go_button) {
+            Intent intent = new Intent(ByodHelperActivity.ACTION_LAUNCH_CONFIRM_WORK_CREDENTIALS);
+            startActivity(intent);
+        }
+    }
+
+    private boolean isOrganizationColorSet() {
+        EditText organizationColorEditText = (EditText) findViewById(
+                R.id.organization_color_edit_text);
+        try {
+            mOrganizationColor = Color.parseColor(organizationColorEditText.getText().toString());
+        } catch (Exception e) {
+            Toast.makeText(this, "Not a valid Color value", Toast.LENGTH_SHORT).show();
+            return false;
+        }
+        return true;
+    }
+}
diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/managedprovisioning/PolicyTransparencyTestActivity.java b/apps/CtsVerifier/src/com/android/cts/verifier/managedprovisioning/PolicyTransparencyTestActivity.java
new file mode 100644
index 0000000..9261284
--- /dev/null
+++ b/apps/CtsVerifier/src/com/android/cts/verifier/managedprovisioning/PolicyTransparencyTestActivity.java
@@ -0,0 +1,309 @@
+/*
+ * Copyright (C) 2016 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.verifier.managedprovisioning;
+
+import android.accessibilityservice.AccessibilityService;
+import android.app.admin.DevicePolicyManager;
+import android.content.Intent;
+import android.inputmethodservice.InputMethodService;
+import android.os.Bundle;
+import android.os.UserManager;
+import android.util.ArrayMap;
+import android.view.accessibility.AccessibilityEvent;
+import android.view.View;
+import android.widget.AdapterView;
+import android.widget.ArrayAdapter;
+import android.widget.Button;
+import android.widget.CompoundButton;
+import android.widget.EditText;
+import android.widget.Spinner;
+import android.widget.Switch;
+import android.widget.TextView;
+
+import com.android.cts.verifier.PassFailButtons;
+import com.android.cts.verifier.R;
+
+import java.util.ArrayList;
+import java.util.Map;
+
+public class PolicyTransparencyTestActivity extends PassFailButtons.Activity implements
+        View.OnClickListener, CompoundButton.OnCheckedChangeListener,
+        AdapterView.OnItemSelectedListener {
+    public static final String ACTION_SHOW_POLICY_TRANSPARENCY_TEST =
+            "com.android.cts.verifier.managedprovisioning.action.SHOW_POLICY_TRANSPARENCY_TEST";
+    public static final String EXTRA_TEST =
+            "com.android.cts.verifier.managedprovisioning.extra.TEST";
+
+    public static final String TEST_CHECK_USER_RESTRICTION = "check-user-restriction";
+    public static final String TEST_CHECK_AUTO_TIME_REQUIRED = "check-auto-time-required";
+    public static final String TEST_CHECK_KEYGURAD_UNREDACTED_NOTIFICATION =
+            "check-keyguard-unredacted-notification";
+    public static final String TEST_CHECK_LOCK_SCREEN_INFO = "check-lock-screen-info";
+    public static final String TEST_CHECK_MAXIMUM_TIME_TO_LOCK = "check-maximum-time-to-lock";
+    public static final String TEST_CHECK_PASSWORD_QUALITY = "check-password-quality";
+    public static final String TEST_CHECK_PERMITTED_ACCESSIBILITY_SERVICE =
+            "check-permitted-accessibility-service";
+    public static final String TEST_CHECK_PERMITTED_INPUT_METHOD = "check-permitted-input-method";
+
+    public static final String EXTRA_SETTINGS_INTENT_ACTION =
+            "com.android.cts.verifier.managedprovisioning.extra.SETTINGS_INTENT_ACTION";
+    public static final String EXTRA_TITLE =
+            "com.android.cts.verifier.managedprovisioning.extra.TITLE";
+    public static final String EXTRA_TEST_ID =
+            "com.android.cts.verifier.managedprovisioning.extra.TEST_ID";
+
+    private static final Map<String, PolicyTestItem> POLICY_TEST_ITEMS = new ArrayMap<>();
+    static {
+        POLICY_TEST_ITEMS.put(TEST_CHECK_AUTO_TIME_REQUIRED, new PolicyTestItem(
+                R.string.auto_time_required_set_step,
+                R.string.set_auto_time_required_action,
+                R.string.set_auto_time_required_widget_label,
+                R.id.switch_widget,
+                CommandReceiverActivity.COMMAND_SET_AUTO_TIME_REQUIRED));
+        POLICY_TEST_ITEMS.put(TEST_CHECK_KEYGURAD_UNREDACTED_NOTIFICATION, new PolicyTestItem(
+                R.string.disallow_keyguard_unredacted_notifications_set_step,
+                R.string.disallow_keyguard_unredacted_notifications_action,
+                R.string.disallow_keyguard_unredacted_notifications_widget_label,
+                R.id.switch_widget,
+                CommandReceiverActivity.COMMAND_DISALLOW_KEYGUARD_UNREDACTED_NOTIFICATIONS));
+        POLICY_TEST_ITEMS.put(TEST_CHECK_LOCK_SCREEN_INFO, new PolicyTestItem(
+                R.string.lock_screen_info_set_step,
+                R.string.set_lock_screen_info_action,
+                R.string.set_lock_screen_info_widget_label,
+                R.id.edit_text_widget,
+                CommandReceiverActivity.COMMAND_SET_LOCK_SCREEN_INFO));
+        POLICY_TEST_ITEMS.put(TEST_CHECK_MAXIMUM_TIME_TO_LOCK, new PolicyTestItem(
+                R.string.maximum_time_to_lock_set_step,
+                R.string.set_maximum_time_to_lock_action,
+                R.string.set_maximum_time_to_lock_widget_label,
+                R.id.edit_text_widget,
+                CommandReceiverActivity.COMMAND_SET_MAXIMUM_TO_LOCK));
+        POLICY_TEST_ITEMS.put(TEST_CHECK_PASSWORD_QUALITY, new PolicyTestItem(
+                R.string.password_quality_set_step,
+                R.string.set_password_quality_action,
+                R.string.set_password_quality_widget_label,
+                R.id.spinner_widget,
+                CommandReceiverActivity.COMMAND_SET_PASSWORD_QUALITY));
+        POLICY_TEST_ITEMS.put(TEST_CHECK_PERMITTED_ACCESSIBILITY_SERVICE, new PolicyTestItem(
+                R.string.permitted_accessibility_services_set_step,
+                R.string.set_permitted_accessibility_services_action,
+                R.string.set_permitted_accessibility_services_widget_label,
+                R.id.switch_widget,
+                CommandReceiverActivity.COMMAND_ALLOW_ONLY_SYSTEM_ACCESSIBILITY_SERVICES));
+        POLICY_TEST_ITEMS.put(TEST_CHECK_PERMITTED_INPUT_METHOD, new PolicyTestItem(
+                R.string.permitted_input_methods_set_step,
+                R.string.set_permitted_input_methods_action,
+                R.string.set_permitted_input_methods_widget_label,
+                R.id.switch_widget,
+                CommandReceiverActivity.COMMAND_ALLOW_ONLY_SYSTEM_INPUT_METHODS));
+    }
+
+    // IDs of settings for {@link DevicePolicyManager#setPasswordQuality(ComponentName, int)}.
+    private final int[] passwordQualityIds = new int[] {
+        DevicePolicyManager.PASSWORD_QUALITY_UNSPECIFIED,
+        DevicePolicyManager.PASSWORD_QUALITY_SOMETHING,
+        DevicePolicyManager.PASSWORD_QUALITY_NUMERIC,
+        DevicePolicyManager.PASSWORD_QUALITY_NUMERIC_COMPLEX,
+        DevicePolicyManager.PASSWORD_QUALITY_ALPHABETIC,
+        DevicePolicyManager.PASSWORD_QUALITY_ALPHANUMERIC,
+        DevicePolicyManager.PASSWORD_QUALITY_COMPLEX
+    };
+    // Strings to show for each password quality setting.
+    private final int[] passwordQualityLabelResIds = new int[] {
+        R.string.password_quality_unspecified,
+        R.string.password_quality_something,
+        R.string.password_quality_numeric,
+        R.string.password_quality_numeric_complex,
+        R.string.password_quality_alphabetic,
+        R.string.password_quality_alphanumeric,
+        R.string.password_quality_complex
+    };
+
+    private String mSettingsIntentAction;
+    private String mTestId;
+    private String mTitle;
+    private String mTest;
+
+    @Override
+    public void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+        setContentView(R.layout.policy_transparency_test);
+        setPassFailButtonClickListeners();
+
+        mTitle = getIntent().getStringExtra(EXTRA_TITLE);
+        mTestId = getIntent().getStringExtra(EXTRA_TEST_ID);
+        mSettingsIntentAction = getIntent().getStringExtra(EXTRA_SETTINGS_INTENT_ACTION);
+        mTest = getIntent().getStringExtra(EXTRA_TEST);
+
+        setTitle(mTitle);
+        findViewById(R.id.open_settings_button).setOnClickListener(this);
+        updateTestInstructions();
+    }
+
+    private void updateTestInstructions() {
+        String setStep = null;
+        String userAction = null;
+        String widgetLabel = null;
+        int widgetId = 0;
+        if (TEST_CHECK_USER_RESTRICTION.equals(mTest)) {
+            setStep = getString(R.string.user_restriction_set_step, mTitle);
+            final String userRestriction = getIntent().getStringExtra(
+                    CommandReceiverActivity.EXTRA_USER_RESTRICTION);
+            userAction = UserRestrictions.getUserAction(this, userRestriction);
+            widgetLabel = mTitle;
+            widgetId = R.id.switch_widget;
+        } else {
+            final PolicyTestItem testItem = POLICY_TEST_ITEMS.get(mTest);
+            setStep = getString(testItem.setStep);
+            userAction = getString(testItem.userAction);
+            widgetLabel = getString(testItem.widgetLabel);
+            widgetId = testItem.widgetId;
+        }
+        ((TextView) findViewById(R.id.widget_label)).setText(widgetLabel);
+        ((TextView) findViewById(R.id.test_instructions)).setText(
+                getString(R.string.policy_transparency_test_instructions, setStep, userAction));
+        updateWidget(widgetId);
+    }
+
+    private void updateWidget(int widgetId) {
+        switch (widgetId) {
+            case R.id.switch_widget: {
+                Switch switchWidget = (Switch) findViewById(R.id.switch_widget);
+                switchWidget.setOnCheckedChangeListener(this);
+                switchWidget.setVisibility(View.VISIBLE);
+            } break;
+            case R.id.edit_text_widget: {
+                findViewById(R.id.edit_text_widget).setVisibility(View.VISIBLE);
+                Button updateButton = (Button) findViewById(R.id.update_button);
+                updateButton.setOnClickListener(this);
+                updateButton.setVisibility(View.VISIBLE);
+            } break;
+            case R.id.spinner_widget: {
+                if (TEST_CHECK_PASSWORD_QUALITY.equals(mTest)) {
+                    Spinner spinner = (Spinner) findViewById(R.id.spinner_widget);
+                    spinner.setVisibility(View.VISIBLE);
+                    spinner.setOnItemSelectedListener(this);
+                    final ArrayList<String> passwordQualityLabels = new ArrayList<String>();
+                    for (int resId : passwordQualityLabelResIds) {
+                        passwordQualityLabels.add(getString(resId));
+                    }
+                    ArrayAdapter<String> adapter = new ArrayAdapter(this,
+                            android.R.layout.simple_spinner_item, passwordQualityLabels);
+                    adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
+                    spinner.setAdapter(adapter);
+                }
+            } break;
+            default: {
+                throw new IllegalArgumentException("Unknown widgetId: " + widgetId);
+            }
+        }
+    }
+
+    @Override
+    public void onClick(View view) {
+        if (view.getId() == R.id.open_settings_button) {
+            startActivity(new Intent(mSettingsIntentAction));
+        } else if (view.getId() == R.id.update_button) {
+            final PolicyTestItem testItem = POLICY_TEST_ITEMS.get(mTest);
+            final Intent intent = new Intent(CommandReceiverActivity.ACTION_EXECUTE_COMMAND);
+            intent.putExtra(CommandReceiverActivity.EXTRA_COMMAND, testItem.command);
+            final EditText editText = (EditText) findViewById(R.id.edit_text_widget);
+            intent.putExtra(CommandReceiverActivity.EXTRA_VALUE, editText.getText().toString());
+            startActivity(intent);
+        }
+    }
+
+    @Override
+    public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
+        final Intent intent = new Intent(CommandReceiverActivity.ACTION_EXECUTE_COMMAND);
+        if (TEST_CHECK_USER_RESTRICTION.equals(mTest)) {
+            final String userRestriction = getIntent().getStringExtra(
+                    CommandReceiverActivity.EXTRA_USER_RESTRICTION);
+            intent.putExtra(CommandReceiverActivity.EXTRA_COMMAND,
+                    CommandReceiverActivity.COMMAND_SET_USER_RESTRICTION);
+            intent.putExtra(CommandReceiverActivity.EXTRA_USER_RESTRICTION, userRestriction);
+            intent.putExtra(CommandReceiverActivity.EXTRA_ENFORCED, isChecked);
+        } else {
+            final PolicyTestItem testItem = POLICY_TEST_ITEMS.get(mTest);
+            intent.putExtra(CommandReceiverActivity.EXTRA_COMMAND, testItem.command);
+            intent.putExtra(CommandReceiverActivity.EXTRA_ENFORCED, isChecked);
+        }
+        startActivity(intent);
+    }
+
+    @Override
+    public void onItemSelected(AdapterView<?> parent, View view, int pos, long id) {
+        final PolicyTestItem testItem = POLICY_TEST_ITEMS.get(mTest);
+        final Intent intent = new Intent(CommandReceiverActivity.ACTION_EXECUTE_COMMAND);
+        intent.putExtra(CommandReceiverActivity.EXTRA_COMMAND, testItem.command);
+        if (TEST_CHECK_PASSWORD_QUALITY.equals(mTest)) {
+            intent.putExtra(CommandReceiverActivity.EXTRA_VALUE, passwordQualityIds[(int) id]);
+        }
+        startActivity(intent);
+    }
+
+    @Override
+    public void onNothingSelected(AdapterView<?> parent) {
+        // Do nothing.
+    }
+
+    @Override
+    public String getTestId() {
+        return mTestId;
+    }
+
+    public class DummyAccessibilityService extends AccessibilityService {
+        @Override
+        public void onAccessibilityEvent(AccessibilityEvent event) {
+            // Do nothing
+        }
+
+        @Override
+        public void onInterrupt() {
+            // Do nothing
+        }
+    }
+
+    public class DummyInputMethod extends InputMethodService {
+        @Override
+        public boolean onEvaluateFullscreenMode() {
+            return false;
+        }
+
+        @Override
+        public boolean onEvaluateInputViewShown() {
+            return false;
+        }
+    }
+
+    private static class PolicyTestItem {
+        public final int setStep;
+        public final int userAction;
+        public final int widgetLabel;
+        public final int widgetId;
+        public final String command;
+
+        public PolicyTestItem(int setStep, int userAction, int widgetLabel, int widgetId,
+                String command) {
+            this.setStep = setStep;
+            this.userAction = userAction;
+            this.widgetLabel = widgetLabel;
+            this.widgetId = widgetId;
+            this.command = command;
+        }
+    }
+}
\ No newline at end of file
diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/managedprovisioning/PolicyTransparencyTestListActivity.java b/apps/CtsVerifier/src/com/android/cts/verifier/managedprovisioning/PolicyTransparencyTestListActivity.java
new file mode 100644
index 0000000..88f4f18
--- /dev/null
+++ b/apps/CtsVerifier/src/com/android/cts/verifier/managedprovisioning/PolicyTransparencyTestListActivity.java
@@ -0,0 +1,181 @@
+/*
+ * Copyright (C) 2016 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.verifier.managedprovisioning;
+
+import android.app.admin.DevicePolicyManager;
+import android.content.Intent;
+import android.database.DataSetObserver;
+import android.os.Bundle;
+import android.provider.Settings;
+import android.util.Pair;
+import android.view.View;
+
+import com.android.cts.verifier.ArrayTestListAdapter;
+import com.android.cts.verifier.PassFailButtons;
+import com.android.cts.verifier.R;
+import com.android.cts.verifier.TestListAdapter.TestListItem;
+
+import java.util.ArrayList;
+
+/**
+ * Test class to verify transparency for policies enforced by device/profile owner.
+ */
+public class PolicyTransparencyTestListActivity extends PassFailButtons.TestListActivity
+        implements View.OnClickListener {
+    public static final String ACTION_CHECK_POLICY_TRANSPARENCY =
+            "com.android.cts.verifier.managedprovisioning.action.CHECK_POLICY_TRANSPARENCY";
+    public static final String EXTRA_IS_DEVICE_OWNER =
+            "com.android.cts.verifier.managedprovisioning.extra.IS_DEVICE_OWNER";
+
+    private static final Pair<Intent, Integer>[] POLICIES;
+    static {
+        final String[] policyTests = new String[] {
+            PolicyTransparencyTestActivity.TEST_CHECK_AUTO_TIME_REQUIRED,
+            PolicyTransparencyTestActivity.TEST_CHECK_KEYGURAD_UNREDACTED_NOTIFICATION,
+            PolicyTransparencyTestActivity.TEST_CHECK_LOCK_SCREEN_INFO,
+            PolicyTransparencyTestActivity.TEST_CHECK_MAXIMUM_TIME_TO_LOCK,
+            PolicyTransparencyTestActivity.TEST_CHECK_PASSWORD_QUALITY,
+            PolicyTransparencyTestActivity.TEST_CHECK_PERMITTED_ACCESSIBILITY_SERVICE,
+            PolicyTransparencyTestActivity.TEST_CHECK_PERMITTED_INPUT_METHOD
+        };
+        final String[] settingsIntentActions = new String[] {
+            Settings.ACTION_DATE_SETTINGS,
+            Settings.ACTION_SETTINGS,
+            Settings.ACTION_SECURITY_SETTINGS,
+            Settings.ACTION_DISPLAY_SETTINGS,
+            DevicePolicyManager.ACTION_SET_NEW_PASSWORD,
+            Settings.ACTION_ACCESSIBILITY_SETTINGS,
+            Settings.ACTION_INPUT_METHOD_SETTINGS
+        };
+        final int[] policyLabels = new int[] {
+            R.string.set_auto_time_required,
+            R.string.disallow_keyguard_unredacted_notifications,
+            R.string.set_lock_screen_info,
+            R.string.set_maximum_time_to_lock,
+            R.string.set_password_quality,
+            R.string.set_permitted_accessibility_services,
+            R.string.set_permitted_input_methods
+        };
+        if (policyTests.length != settingsIntentActions.length ||
+                policyTests.length != policyLabels.length) {
+            throw new AssertionError("Number of items in policyTests, "
+                    + " settingsIntentActions and policyLabels do not match");
+        }
+        POLICIES = new Pair[policyTests.length];
+        for (int i = 0; i < policyTests.length; ++i) {
+            final Intent intent =
+                    new Intent(PolicyTransparencyTestActivity.ACTION_SHOW_POLICY_TRANSPARENCY_TEST)
+                            .putExtra(PolicyTransparencyTestActivity.EXTRA_TEST, policyTests[i])
+                            .putExtra(PolicyTransparencyTestActivity.EXTRA_SETTINGS_INTENT_ACTION,
+                                    settingsIntentActions[i]);
+            POLICIES[i] = Pair.create(intent, policyLabels[i]);
+        }
+    }
+
+    private static final ArrayList<String> ALSO_VALID_FOR_PO = new ArrayList<String>();
+    static {
+        ALSO_VALID_FOR_PO.add(
+                PolicyTransparencyTestActivity.TEST_CHECK_PERMITTED_ACCESSIBILITY_SERVICE);
+        ALSO_VALID_FOR_PO.add(PolicyTransparencyTestActivity.TEST_CHECK_PERMITTED_INPUT_METHOD);
+    }
+
+    private boolean mIsDeviceOwner;
+
+    @Override
+    protected void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+        setContentView(R.layout.policy_transparency_test_list);
+        setInfoResources(R.string.device_profile_owner_policy_transparency_test,
+                R.string.device_profile_owner_policy_transparency_test_info, 0);
+        setPassFailButtonClickListeners();
+        setSupportMsgButtonClickListeners();
+
+        mIsDeviceOwner = getIntent().getBooleanExtra(EXTRA_IS_DEVICE_OWNER, false);
+
+        final ArrayTestListAdapter adapter = new ArrayTestListAdapter(this);
+        addTestsToAdapter(adapter);
+        adapter.registerDataSetObserver(new DataSetObserver() {
+            @Override
+            public void onChanged() {
+                updatePassButton();
+            }
+        });
+
+        setTestListAdapter(adapter);
+    }
+
+    private void addTestsToAdapter(final ArrayTestListAdapter adapter) {
+        for (String restriction : UserRestrictions.getUserRestrictions()) {
+            final Intent intent = UserRestrictions.getUserRestrictionTestIntent(this, restriction);
+            if (!mIsDeviceOwner && !UserRestrictions.isValidForPO(restriction)) {
+                continue;
+            }
+            final String title = UserRestrictions.getRestrictionLabel(this, restriction);
+            String testId = (mIsDeviceOwner ? "DO_" : "PO_") + title;
+            intent.putExtra(PolicyTransparencyTestActivity.EXTRA_TEST_ID, testId);
+            adapter.add(TestListItem.newTest(title, testId, intent, null));
+        }
+
+        for (Pair<Intent, Integer> policy : POLICIES) {
+            final Intent intent = policy.first;
+            String test = intent.getStringExtra(PolicyTransparencyTestActivity.EXTRA_TEST);
+            if (!mIsDeviceOwner && !ALSO_VALID_FOR_PO.contains(test)) {
+                continue;
+            }
+            final String title = getString(policy.second);
+            String testId = (mIsDeviceOwner ? "DO_" : "PO_") + title;
+            intent.putExtra(PolicyTransparencyTestActivity.EXTRA_TITLE, title);
+            intent.putExtra(PolicyTransparencyTestActivity.EXTRA_TEST_ID, testId);
+            adapter.add(TestListItem.newTest(title, testId, intent, null));
+        }
+    }
+
+    private void setSupportMsgButtonClickListeners() {
+        findViewById(R.id.short_msg_button).setOnClickListener(this);
+        findViewById(R.id.long_msg_button).setOnClickListener(this);
+    }
+
+    @Override
+    public void onClick(View view) {
+        if (view.getId() == R.id.short_msg_button) {
+            final Intent intent = new Intent(SetSupportMessageActivity.ACTION_SET_SUPPORT_MSG);
+            intent.putExtra(SetSupportMessageActivity.EXTRA_SUPPORT_MSG_TYPE,
+                    SetSupportMessageActivity.TYPE_SHORT_MSG);
+            startActivity(intent);
+        } else if (view.getId() == R.id.long_msg_button) {
+            final Intent intent = new Intent(SetSupportMessageActivity.ACTION_SET_SUPPORT_MSG);
+            intent.putExtra(SetSupportMessageActivity.EXTRA_SUPPORT_MSG_TYPE,
+                    SetSupportMessageActivity.TYPE_LONG_MSG);
+            startActivity(intent);
+        }
+    }
+
+    @Override
+    public String getTestId() {
+        return getIntent().getStringExtra(PolicyTransparencyTestActivity.EXTRA_TEST_ID);
+    }
+
+    @Override
+    public void finish() {
+        super.finish();
+        final Intent intent = new Intent(CommandReceiverActivity.ACTION_EXECUTE_COMMAND);
+        intent.putExtra(CommandReceiverActivity.EXTRA_COMMAND, mIsDeviceOwner
+                ? CommandReceiverActivity.COMMAND_DEVICE_OWNER_CLEAR_POLICIES
+                : CommandReceiverActivity.COMMAND_PROFILE_OWNER_CLEAR_POLICIES);
+        startActivity(intent);
+    }
+}
\ No newline at end of file
diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/managedprovisioning/SetSupportMessageActivity.java b/apps/CtsVerifier/src/com/android/cts/verifier/managedprovisioning/SetSupportMessageActivity.java
new file mode 100644
index 0000000..9aa71a8
--- /dev/null
+++ b/apps/CtsVerifier/src/com/android/cts/verifier/managedprovisioning/SetSupportMessageActivity.java
@@ -0,0 +1,86 @@
+/*
+ * Copyright (C) 2016 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.verifier.managedprovisioning;
+
+import android.app.Activity;
+import android.app.admin.DevicePolicyManager;
+import android.content.ComponentName;
+import android.content.Context;
+import android.os.Bundle;
+import android.view.View;
+import android.widget.EditText;
+
+import com.android.cts.verifier.R;
+
+public class SetSupportMessageActivity extends Activity implements View.OnClickListener {
+    public static final String ACTION_SET_SUPPORT_MSG =
+            "com.android.cts.verifier.managedprovisioning.action.SET_SUPPORT_MSG";
+    public static final String EXTRA_SUPPORT_MSG_TYPE =
+            "com.android.cts.verifier.managedprovisioning.extra.SUPPORT_MSG_TYPE";
+
+    public static final String TYPE_SHORT_MSG = "short-msg";
+    public static final String TYPE_LONG_MSG = "long-msg";
+
+    private String mType;
+    private EditText mSupportMessage;
+    private DevicePolicyManager mDpm;
+    private ComponentName mAdmin;
+
+    public void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+        setContentView(R.layout.set_support_message);
+        findViewById(R.id.set_default_message).setOnClickListener(this);
+        findViewById(R.id.set_message).setOnClickListener(this);
+        findViewById(R.id.clear_message).setOnClickListener(this);
+        mSupportMessage = (EditText) findViewById(R.id.message_view);
+
+        mType = getIntent().getStringExtra(EXTRA_SUPPORT_MSG_TYPE);
+        setTitle(TYPE_SHORT_MSG.equals(mType)
+                ? R.string.policy_transparency_short_support_msg_label
+                : R.string.policy_transparency_long_support_msg_label);
+        mDpm = (DevicePolicyManager) getSystemService(Context.DEVICE_POLICY_SERVICE);
+        mAdmin = DeviceAdminTestReceiver.getReceiverComponentName();
+
+        mSupportMessage.setText(TYPE_SHORT_MSG.equals(mType)
+                ? mDpm.getShortSupportMessage(mAdmin)
+                : mDpm.getLongSupportMessage(mAdmin));
+    }
+
+    @Override
+    public void onClick(View view) {
+        String message = null;
+        switch (view.getId()) {
+            case R.id.set_default_message: {
+                message = getString(TYPE_SHORT_MSG.equals(mType)
+                        ? R.string.policy_transparency_default_short_msg
+                        : R.string.policy_transparency_default_long_msg);
+            } break;
+            case R.id.set_message: {
+                message = mSupportMessage.getText().toString();
+            } break;
+            case R.id.clear_message: {
+                message = null;
+            } break;
+        }
+        if (TYPE_SHORT_MSG.equals(mType)) {
+            mDpm.setShortSupportMessage(mAdmin, message);
+        } else {
+            mDpm.setLongSupportMessage(mAdmin, message);
+        }
+        mSupportMessage.setText(message);
+    }
+}
\ No newline at end of file
diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/managedprovisioning/TurnOffWorkActivity.java b/apps/CtsVerifier/src/com/android/cts/verifier/managedprovisioning/TurnOffWorkActivity.java
new file mode 100644
index 0000000..719f1db
--- /dev/null
+++ b/apps/CtsVerifier/src/com/android/cts/verifier/managedprovisioning/TurnOffWorkActivity.java
@@ -0,0 +1,154 @@
+/*
+ * Copyright (C) 2016 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.verifier.managedprovisioning;
+
+import android.app.admin.DevicePolicyManager;
+import android.content.ActivityNotFoundException;
+import android.content.BroadcastReceiver;
+import android.content.ComponentName;
+import android.content.Context;
+import android.content.Intent;
+import android.content.IntentFilter;
+import android.hardware.fingerprint.FingerprintManager;
+import android.os.Bundle;
+import android.provider.Settings;
+import android.util.Log;
+import android.view.View;
+import android.view.View.OnClickListener;
+import android.widget.Toast;
+
+import com.android.cts.verifier.ArrayTestListAdapter;
+import com.android.cts.verifier.DialogTestListActivity;
+import com.android.cts.verifier.R;
+import com.android.cts.verifier.TestResult;
+
+public class TurnOffWorkActivity extends DialogTestListActivity {
+
+    private static final String TAG = "TurnOffWorkActivity";
+    private DialogTestListItem mTurnOffWorkTest;
+    private DialogTestListItem mTurnOnWorkTest;
+
+    private BroadcastReceiver mReceiver = new BroadcastReceiver() {
+        @Override
+        public void onReceive(Context content, Intent intent) {
+            if (Intent.ACTION_MANAGED_PROFILE_UNAVAILABLE.equals(intent.getAction())) {
+                setTestResult(mTurnOffWorkTest, TestResult.TEST_RESULT_PASSED);
+            } else if (Intent.ACTION_MANAGED_PROFILE_AVAILABLE.equals(intent.getAction())) {
+                setTestResult(mTurnOnWorkTest, TestResult.TEST_RESULT_PASSED);
+            }
+        }
+    };
+
+    public TurnOffWorkActivity() {
+        super(R.layout.provisioning_byod,
+                R.string.provisioning_byod_turn_off_work,
+                R.string.provisioning_byod_turn_off_work_info,
+                R.string.provisioning_byod_turn_off_work_instructions);
+    }
+
+    @Override
+    protected void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+
+        mPrepareTestButton.setText(R.string.provisioning_byod_turn_off_work_prepare_button);
+        mPrepareTestButton.setOnClickListener(new OnClickListener() {
+            @Override
+            public void onClick(View v) {
+                try {
+                    startActivity(new Intent(Settings.ACTION_SYNC_SETTINGS));
+                } catch (ActivityNotFoundException e) {
+                    Log.w(TAG, "Cannot start activity.", e);
+                    Toast.makeText(TurnOffWorkActivity.this,
+                            "Cannot start settings", Toast.LENGTH_SHORT).show();
+                }
+            }
+        });
+        setTestResult(mTurnOffWorkTest, TestResult.TEST_RESULT_NOT_EXECUTED);
+        setTestResult(mTurnOnWorkTest, TestResult.TEST_RESULT_NOT_EXECUTED);
+        IntentFilter filter = new IntentFilter();
+        filter.addAction(Intent.ACTION_MANAGED_PROFILE_AVAILABLE);
+        filter.addAction(Intent.ACTION_MANAGED_PROFILE_UNAVAILABLE);
+        registerReceiver(mReceiver, filter);
+    }
+
+    @Override
+    protected void onDestroy() {
+        super.onDestroy();
+        unregisterReceiver(mReceiver);
+    }
+
+    @Override
+    protected void setupTests(ArrayTestListAdapter adapter) {
+        final Intent homeIntent = new Intent(Intent.ACTION_MAIN).addCategory(Intent.CATEGORY_HOME);
+
+        adapter.add(new DialogTestListItem(this,
+                R.string.provisioning_byod_turn_off_work_prepare_notifications,
+                "BYOD_TurnOffWorkCreateNotification",
+                R.string.provisioning_byod_turn_off_work_prepare_notifications_instruction,
+                new Intent(ByodHelperActivity.ACTION_NOTIFICATION)));
+
+        mTurnOffWorkTest = new DialogTestListItem(this,
+                R.string.provisioning_byod_turn_off_work_turned_off,
+                "BYOD_WorkTurnedOff") {
+            @Override
+            public void performTest(DialogTestListActivity activity) {
+                Toast.makeText(TurnOffWorkActivity.this,
+                        R.string.provisioning_byod_turn_off_work_turned_off_toast,
+                        Toast.LENGTH_SHORT).show();
+            }
+        };
+        adapter.add(mTurnOffWorkTest);
+
+        adapter.add(new DialogTestListItem(this,
+                R.string.provisioning_byod_turn_off_work_notifications,
+                "BYOD_TurnOffWorkNotifications",
+                R.string.provisioning_byod_turn_off_work_notifications_instruction,
+                new Intent(ByodHelperActivity.ACTION_NOTIFICATION)));
+
+        adapter.add(new DialogTestListItem(this, R.string.provisioning_byod_turn_off_work_icon,
+                "BYOD_TurnOffWorkIcon",
+                R.string.provisioning_byod_turn_off_work_icon_instruction,
+                new Intent(Settings.ACTION_SETTINGS)));
+
+        adapter.add(new DialogTestListItem(this, R.string.provisioning_byod_turn_off_work_launcher,
+                "BYOD_TurnOffWorkStartApps",
+                R.string.provisioning_byod_turn_off_work_launcher_instruction,
+                homeIntent));
+
+        mTurnOnWorkTest = new DialogTestListItem(this,
+                R.string.provisioning_byod_turn_off_work_turned_on,
+                "BYOD_WorkTurnedOn") {
+            @Override
+            public void performTest(DialogTestListActivity activity) {
+                Toast.makeText(TurnOffWorkActivity.this,
+                        R.string.provisioning_byod_turn_off_work_turned_on_toast,
+                        Toast.LENGTH_SHORT).show();
+            }
+        };
+        adapter.add(mTurnOnWorkTest);
+
+        adapter.add(new DialogTestListItem(this, R.string.provisioning_byod_turn_on_work_icon,
+                "BYOD_TurnOnWorkIcon",
+                R.string.provisioning_byod_turn_on_work_icon_instruction,
+                new Intent(Settings.ACTION_SETTINGS)));
+
+        adapter.add(new DialogTestListItem(this, R.string.provisioning_byod_turn_on_work_launcher,
+                "BYOD_TurnOnWorkStartApps",
+                R.string.provisioning_byod_turn_on_work_launcher_instruction,
+                homeIntent));
+    }
+}
diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/managedprovisioning/UserRestrictions.java b/apps/CtsVerifier/src/com/android/cts/verifier/managedprovisioning/UserRestrictions.java
new file mode 100644
index 0000000..06d0381
--- /dev/null
+++ b/apps/CtsVerifier/src/com/android/cts/verifier/managedprovisioning/UserRestrictions.java
@@ -0,0 +1,187 @@
+/*
+ * Copyright (C) 2016 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.verifier.managedprovisioning;
+
+import android.content.Context;
+import android.content.Intent;
+import android.os.UserManager;
+import android.provider.Settings;
+import android.util.ArrayMap;
+
+import java.util.ArrayList;
+
+import com.android.cts.verifier.R;
+
+public class UserRestrictions {
+    private static final String[] RESTRICTION_IDS = new String[] {
+        UserManager.DISALLOW_ADD_USER,
+        UserManager.DISALLOW_ADJUST_VOLUME,
+        UserManager.DISALLOW_APPS_CONTROL,
+        UserManager.DISALLOW_CONFIG_CELL_BROADCASTS,
+        UserManager.DISALLOW_CONFIG_CREDENTIALS,
+        UserManager.DISALLOW_CONFIG_MOBILE_NETWORKS,
+        UserManager.DISALLOW_CONFIG_TETHERING,
+        UserManager.DISALLOW_CONFIG_WIFI,
+        UserManager.DISALLOW_DEBUGGING_FEATURES,
+        UserManager.DISALLOW_FACTORY_RESET,
+        UserManager.DISALLOW_FUN,
+        UserManager.DISALLOW_INSTALL_UNKNOWN_SOURCES,
+        UserManager.DISALLOW_MODIFY_ACCOUNTS,
+        UserManager.DISALLOW_NETWORK_RESET,
+        UserManager.DISALLOW_OUTGOING_BEAM,
+        UserManager.DISALLOW_REMOVE_USER,
+        UserManager.DISALLOW_SHARE_LOCATION,
+        UserManager.DISALLOW_UNINSTALL_APPS
+    };
+
+    private static final ArrayMap<String, UserRestrictionItem> USER_RESTRICTION_ITEMS;
+    static {
+        final int[] restrictionLabels = new int[] {
+            R.string.disallow_add_user,
+            R.string.disallow_adjust_volume,
+            R.string.disallow_apps_control,
+            R.string.disallow_config_cell_broadcasts,
+            R.string.disallow_config_credentials,
+            R.string.disallow_config_mobile_networks,
+            R.string.disallow_config_tethering,
+            R.string.disallow_config_wifi,
+            R.string.disallow_debugging_features,
+            R.string.disallow_factory_reset,
+            R.string.disallow_fun,
+            R.string.disallow_install_unknown_sources,
+            R.string.disallow_modify_accounts,
+            R.string.disallow_network_reset,
+            R.string.disallow_outgoing_beam,
+            R.string.disallow_remove_user,
+            R.string.disallow_share_location,
+            R.string.disallow_uninstall_apps
+        };
+
+        final int[] restrictionActions = new int[] {
+            R.string.disallow_add_user_action,
+            R.string.disallow_adjust_volume_action,
+            R.string.disallow_apps_control_action,
+            R.string.disallow_config_cell_broadcasts_action,
+            R.string.disallow_config_credentials_action,
+            R.string.disallow_config_mobile_networks_action,
+            R.string.disallow_config_tethering_action,
+            R.string.disallow_config_wifi_action,
+            R.string.disallow_debugging_features_action,
+            R.string.disallow_factory_reset_action,
+            R.string.disallow_fun_action,
+            R.string.disallow_install_unknown_sources_action,
+            R.string.disallow_modify_accounts_action,
+            R.string.disallow_network_reset_action,
+            R.string.disallow_outgoing_beam_action,
+            R.string.disallow_remove_user_action,
+            R.string.disallow_share_location_action,
+            R.string.disallow_uninstall_apps_action
+        };
+
+        final String[] settingsIntentActions = new String[] {
+            Settings.ACTION_SETTINGS,
+            Settings.ACTION_SOUND_SETTINGS,
+            Settings.ACTION_APPLICATION_SETTINGS,
+            Settings.ACTION_SOUND_SETTINGS,
+            Settings.ACTION_SECURITY_SETTINGS,
+            Settings.ACTION_WIRELESS_SETTINGS,
+            Settings.ACTION_WIRELESS_SETTINGS,
+            Settings.ACTION_WIFI_SETTINGS,
+            Settings.ACTION_DEVICE_INFO_SETTINGS,
+            Settings.ACTION_PRIVACY_SETTINGS,
+            Settings.ACTION_DEVICE_INFO_SETTINGS,
+            Settings.ACTION_SECURITY_SETTINGS,
+            Settings.ACTION_SYNC_SETTINGS,
+            Settings.ACTION_PRIVACY_SETTINGS,
+            Settings.ACTION_WIRELESS_SETTINGS,
+            Settings.ACTION_SETTINGS,
+            Settings.ACTION_LOCATION_SOURCE_SETTINGS,
+            Settings.ACTION_APPLICATION_SETTINGS,
+        };
+
+        if (RESTRICTION_IDS.length != restrictionLabels.length
+                || RESTRICTION_IDS.length != restrictionActions.length
+                || RESTRICTION_IDS.length != settingsIntentActions.length) {
+            throw new AssertionError("Number of items in restrictionIds, restrictionLabels, "
+                    + "restrictionActions, and settingsIntentActions do not match");
+        }
+        USER_RESTRICTION_ITEMS = new ArrayMap<>(RESTRICTION_IDS.length);
+        for (int i = 0; i < RESTRICTION_IDS.length; ++i) {
+            USER_RESTRICTION_ITEMS.put(RESTRICTION_IDS[i], new UserRestrictionItem(
+                    restrictionLabels[i],
+                    restrictionActions[i],
+                    settingsIntentActions[i]));
+        }
+    }
+
+    private static final ArrayList<String> ALSO_VALID_FOR_PO =
+            new ArrayList<String>();
+    static {
+        ALSO_VALID_FOR_PO.add(UserManager.DISALLOW_APPS_CONTROL);
+        ALSO_VALID_FOR_PO.add(UserManager.DISALLOW_UNINSTALL_APPS);
+        ALSO_VALID_FOR_PO.add(UserManager.DISALLOW_MODIFY_ACCOUNTS);
+        ALSO_VALID_FOR_PO.add(UserManager.DISALLOW_SHARE_LOCATION);
+    }
+
+    public static String getRestrictionLabel(Context context, String restriction) {
+        final UserRestrictionItem item = findRestrictionItem(restriction);
+        return context.getString(item.label);
+    }
+
+    public static String getUserAction(Context context, String restriction) {
+        final UserRestrictionItem item = findRestrictionItem(restriction);
+        return context.getString(item.userAction);
+    }
+
+    private static UserRestrictionItem findRestrictionItem(String restriction) {
+        final UserRestrictionItem item = USER_RESTRICTION_ITEMS.get(restriction);
+        if (item == null) {
+            throw new IllegalArgumentException("Unknown restriction: " + restriction);
+        }
+        return item;
+    }
+
+    public static boolean isValidForPO(String restriction) {
+        return ALSO_VALID_FOR_PO.contains(restriction);
+    }
+
+    public static String[] getUserRestrictions() {
+        return RESTRICTION_IDS;
+    }
+
+    public static Intent getUserRestrictionTestIntent(Context context, String restriction) {
+        final UserRestrictionItem item = USER_RESTRICTION_ITEMS.get(restriction);
+        return new Intent(PolicyTransparencyTestActivity.ACTION_SHOW_POLICY_TRANSPARENCY_TEST)
+                .putExtra(PolicyTransparencyTestActivity.EXTRA_TEST,
+                        PolicyTransparencyTestActivity.TEST_CHECK_USER_RESTRICTION)
+                .putExtra(CommandReceiverActivity.EXTRA_USER_RESTRICTION, restriction)
+                .putExtra(PolicyTransparencyTestActivity.EXTRA_TITLE, context.getString(item.label))
+                .putExtra(PolicyTransparencyTestActivity.EXTRA_SETTINGS_INTENT_ACTION,
+                        item.intentAction);
+    }
+
+    private static class UserRestrictionItem {
+        final int label;
+        final int userAction;
+        final String intentAction;
+        public UserRestrictionItem(int label, int userAction, String intentAction) {
+            this.label = label;
+            this.userAction = userAction;
+            this.intentAction = intentAction;
+        }
+    }
+}
\ No newline at end of file
diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/managedprovisioning/Utils.java b/apps/CtsVerifier/src/com/android/cts/verifier/managedprovisioning/Utils.java
new file mode 100644
index 0000000..17e83c1
--- /dev/null
+++ b/apps/CtsVerifier/src/com/android/cts/verifier/managedprovisioning/Utils.java
@@ -0,0 +1,80 @@
+/*
+ * Copyright (C) 2015 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.verifier.managedprovisioning;
+
+import android.app.Activity;
+import android.app.Notification;
+import android.app.NotificationManager;
+import android.widget.Toast;
+import android.content.ActivityNotFoundException;
+import android.content.Context;
+import android.content.Intent;
+import android.util.Log;
+
+import com.android.cts.verifier.IntentDrivenTestActivity;
+import com.android.cts.verifier.IntentDrivenTestActivity.ButtonInfo;
+import com.android.cts.verifier.managedprovisioning.ByodHelperActivity;
+import com.android.cts.verifier.R;
+import com.android.cts.verifier.TestListAdapter.TestListItem;
+
+public class Utils {
+
+    private static final String TAG = "CtsVerifierByodUtils";
+    static final int BUGREPORT_NOTIFICATION_ID = 12345;
+
+    static TestListItem createInteractiveTestItem(Activity activity, String id, int titleRes,
+            int infoRes, ButtonInfo[] buttonInfos) {
+        return TestListItem.newTest(activity, titleRes,
+                id, new Intent(activity, IntentDrivenTestActivity.class)
+                .putExtra(IntentDrivenTestActivity.EXTRA_ID, id)
+                .putExtra(IntentDrivenTestActivity.EXTRA_TITLE, titleRes)
+                .putExtra(IntentDrivenTestActivity.EXTRA_INFO, infoRes)
+                .putExtra(IntentDrivenTestActivity.EXTRA_BUTTONS, buttonInfos),
+                null);
+    }
+
+    static TestListItem createInteractiveTestItem(Activity activity, String id, int titleRes,
+            int infoRes, ButtonInfo buttonInfo) {
+        return createInteractiveTestItem(activity, id, titleRes, infoRes,
+                new ButtonInfo[] { buttonInfo });
+    }
+
+    static void requestDeleteManagedProfile(Context context) {
+        try {
+            Intent intent = new Intent(ByodHelperActivity.ACTION_REMOVE_MANAGED_PROFILE);
+            context.startActivity(intent);
+            String message = context.getString(R.string.provisioning_byod_delete_profile);
+            Toast.makeText(context, message, Toast.LENGTH_SHORT).show();
+        }
+        catch (ActivityNotFoundException e) {
+            Log.d(TAG, "requestDeleteProfileOwner: ActivityNotFoundException", e);
+        }
+    }
+
+    static void showBugreportNotification(Context context, String msg, int notificationId) {
+        NotificationManager mNotificationManager =
+                (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);
+        Notification notification = new Notification.Builder(context)
+                .setSmallIcon(R.drawable.icon)
+                .setContentTitle(context.getString(
+                        R.string.device_owner_requesting_bugreport_tests))
+                .setContentText(msg)
+                .setStyle(new Notification.BigTextStyle().bigText(msg))
+                .build();
+        mNotificationManager.notify(notificationId, notification);
+    }
+}
diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/managedprovisioning/WifiLockdownTestActivity.java b/apps/CtsVerifier/src/com/android/cts/verifier/managedprovisioning/WifiLockdownTestActivity.java
index 77f36b6..d5e9fd0 100644
--- a/apps/CtsVerifier/src/com/android/cts/verifier/managedprovisioning/WifiLockdownTestActivity.java
+++ b/apps/CtsVerifier/src/com/android/cts/verifier/managedprovisioning/WifiLockdownTestActivity.java
@@ -72,21 +72,21 @@
                 new Intent(Settings.ACTION_WIFI_SETTINGS));
         mSwitchLockdownOffButtonInfos = new ButtonInfo[] { new ButtonInfo(
                 R.string.switch_wifi_lockdown_off_button,
-                new Intent(this, DeviceOwnerPositiveTestActivity.CommandReceiver.class)
-                        .putExtra(DeviceOwnerPositiveTestActivity.EXTRA_COMMAND,
-                                DeviceOwnerPositiveTestActivity.COMMAND_SET_GLOBAL_SETTING)
-                        .putExtra(DeviceOwnerPositiveTestActivity.EXTRA_SETTING,
+                new Intent(this, CommandReceiverActivity.class)
+                        .putExtra(CommandReceiverActivity.EXTRA_COMMAND,
+                                CommandReceiverActivity.COMMAND_SET_GLOBAL_SETTING)
+                        .putExtra(CommandReceiverActivity.EXTRA_SETTING,
                                 Settings.Global.WIFI_DEVICE_OWNER_CONFIGS_LOCKDOWN)
-                        .putExtra(DeviceOwnerPositiveTestActivity.EXTRA_PARAMETER_1, "0"
+                        .putExtra(CommandReceiverActivity.EXTRA_VALUE, "0"
                 )), goToWifiSettings };
         mSwitchLockdownOnButtonInfos = new ButtonInfo[] { new ButtonInfo(
                 R.string.switch_wifi_lockdown_on_button,
-                new Intent(this, DeviceOwnerPositiveTestActivity.CommandReceiver.class)
-                        .putExtra(DeviceOwnerPositiveTestActivity.EXTRA_COMMAND,
-                                DeviceOwnerPositiveTestActivity.COMMAND_SET_GLOBAL_SETTING)
-                        .putExtra(DeviceOwnerPositiveTestActivity.EXTRA_SETTING,
+                new Intent(this, CommandReceiverActivity.class)
+                        .putExtra(CommandReceiverActivity.EXTRA_COMMAND,
+                                CommandReceiverActivity.COMMAND_SET_GLOBAL_SETTING)
+                        .putExtra(CommandReceiverActivity.EXTRA_SETTING,
                                 Settings.Global.WIFI_DEVICE_OWNER_CONFIGS_LOCKDOWN)
-                        .putExtra(DeviceOwnerPositiveTestActivity.EXTRA_PARAMETER_1, "1"
+                        .putExtra(CommandReceiverActivity.EXTRA_VALUE, "1"
                 )), goToWifiSettings };
 
         addTestsToAdapter(adapter);
@@ -132,22 +132,22 @@
     }
 
     private void addTestsToAdapter(final ArrayTestListAdapter adapter) {
-        adapter.add(DeviceOwnerPositiveTestActivity.createInteractiveTestItem(this,
+        adapter.add(Utils.createInteractiveTestItem(this,
                 CONFIG_MODIFIABLE_WHEN_UNLOCKED_TEST_ID,
                 R.string.device_owner_wifi_config_unlocked_modification_test,
                 R.string.device_owner_wifi_config_unlocked_modification_test_info,
                 mSwitchLockdownOffButtonInfos));
-        adapter.add(DeviceOwnerPositiveTestActivity.createInteractiveTestItem(this,
+        adapter.add(Utils.createInteractiveTestItem(this,
                 CONFIG_NOT_MODIFIABLE_WHEN_LOCKED_TEST_ID,
                 R.string.device_owner_wifi_config_locked_modification_test,
                 R.string.device_owner_wifi_config_locked_modification_test_info,
                 mSwitchLockdownOnButtonInfos));
-        adapter.add(DeviceOwnerPositiveTestActivity.createInteractiveTestItem(this,
+        adapter.add(Utils.createInteractiveTestItem(this,
                 CONFIG_CONNECTABLE_WHEN_LOCKED_TEST_ID,
                 R.string.device_owner_wifi_config_locked_connection_test,
                 R.string.device_owner_wifi_config_locked_connection_test_info,
                 mSwitchLockdownOnButtonInfos));
-        adapter.add(DeviceOwnerPositiveTestActivity.createInteractiveTestItem(this,
+        adapter.add(Utils.createInteractiveTestItem(this,
                 CONFIG_REMOVABLE_WHEN_UNLOCKED_TEST_ID,
                 R.string.device_owner_wifi_config_unlocked_removal_test,
                 R.string.device_owner_wifi_config_unlocked_removal_test_info,
diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/nfc/NfcTestActivity.java b/apps/CtsVerifier/src/com/android/cts/verifier/nfc/NfcTestActivity.java
index 68fc027..eb84d1e 100644
--- a/apps/CtsVerifier/src/com/android/cts/verifier/nfc/NfcTestActivity.java
+++ b/apps/CtsVerifier/src/com/android/cts/verifier/nfc/NfcTestActivity.java
@@ -22,6 +22,8 @@
 import com.android.cts.verifier.TestListAdapter.TestListItem;
 import com.android.cts.verifier.nfc.hce.HceEmulatorTestActivity;
 import com.android.cts.verifier.nfc.hce.HceReaderTestActivity;
+import com.android.cts.verifier.nfc.hcef.HceFEmulatorTestActivity;
+import com.android.cts.verifier.nfc.hcef.HceFReaderTestActivity;
 
 import android.content.Intent;
 import android.content.pm.PackageManager;
@@ -82,6 +84,16 @@
                     new Intent(this, HceEmulatorTestActivity.class), null));
         }
 
+        if (getPackageManager().hasSystemFeature(PackageManager.FEATURE_NFC_HOST_CARD_EMULATION_NFCF)) {
+            adapter.add(TestListItem.newCategory(this, R.string.nfc_hce_f));
+            adapter.add(TestListItem.newTest(this, R.string.nfc_hce_f_reader_tests,
+                    HceFReaderTestActivity.class.getName(),
+                    new Intent(this, HceFReaderTestActivity.class), null));
+            adapter.add(TestListItem.newTest(this, R.string.nfc_hce_f_emulator_tests,
+                    HceFEmulatorTestActivity.class.getName(),
+                    new Intent(this, HceFEmulatorTestActivity.class), null));
+        }
+
         setTestListAdapter(adapter);
     }
 
diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/nfc/hce/HceReaderTestActivity.java b/apps/CtsVerifier/src/com/android/cts/verifier/nfc/hce/HceReaderTestActivity.java
index 879916b..62e1701 100644
--- a/apps/CtsVerifier/src/com/android/cts/verifier/nfc/hce/HceReaderTestActivity.java
+++ b/apps/CtsVerifier/src/com/android/cts/verifier/nfc/hce/HceReaderTestActivity.java
@@ -46,78 +46,78 @@
                     new Intent(this, ProtocolParamsReaderActivity.class), null));
 
             adapter.add(TestListItem.newTest(this, R.string.nfc_hce_single_payment_reader,
-                    SimpleReaderActivity.class.getName(),
+                    getString(R.string.nfc_hce_single_payment_reader),
                     SinglePaymentEmulatorActivity.buildReaderIntent(this), null));
 
             adapter.add(TestListItem.newTest(this, R.string.nfc_hce_dual_payment_reader,
-                    SimpleReaderActivity.class.getName(),
+                    getString(R.string.nfc_hce_dual_payment_reader),
                     DualPaymentEmulatorActivity.buildReaderIntent(this), null));
 
             adapter.add(TestListItem.newTest(this, R.string.nfc_hce_change_default_reader,
-                    SimpleReaderActivity.class.getName(),
+                    getString(R.string.nfc_hce_change_default_reader),
                     ChangeDefaultEmulatorActivity.buildReaderIntent(this), null));
 
             adapter.add(TestListItem.newTest(this, R.string.nfc_hce_foreground_payment_reader,
-                    SimpleReaderActivity.class.getName(),
+                    getString(R.string.nfc_hce_foreground_payment_reader),
                     ForegroundPaymentEmulatorActivity.buildReaderIntent(this), null));
 
             adapter.add(TestListItem.newTest(this, R.string.nfc_hce_single_non_payment_reader,
-                    SimpleReaderActivity.class.getName(),
+                    getString(R.string.nfc_hce_single_non_payment_reader),
                     SingleNonPaymentEmulatorActivity.buildReaderIntent(this), null));
 
             adapter.add(TestListItem.newTest(this, R.string.nfc_hce_dual_non_payment_reader,
-                    SimpleReaderActivity.class.getName(),
+                    getString(R.string.nfc_hce_dual_non_payment_reader),
                     DualNonPaymentEmulatorActivity.buildReaderIntent(this), null));
 
             adapter.add(TestListItem.newTest(this, R.string.nfc_hce_conflicting_non_payment_reader,
-                    SimpleReaderActivity.class.getName(),
+                    getString(R.string.nfc_hce_conflicting_non_payment_reader),
                     ConflictingNonPaymentEmulatorActivity.buildReaderIntent(this), null));
 
             adapter.add(TestListItem.newTest(this, R.string.nfc_hce_foreground_non_payment_reader,
-                    SimpleReaderActivity.class.getName(),
+                    getString(R.string.nfc_hce_foreground_non_payment_reader),
                     ForegroundNonPaymentEmulatorActivity.buildReaderIntent(this), null));
 
             adapter.add(TestListItem.newTest(this, R.string.nfc_hce_throughput_reader,
-                    SimpleReaderActivity.class.getName(),
+                    getString(R.string.nfc_hce_throughput_reader),
                     ThroughputEmulatorActivity.buildReaderIntent(this), null));
 
             adapter.add(TestListItem.newTest(this, R.string.nfc_hce_tap_test_reader,
-                    SimpleReaderActivity.class.getName(),
+                    getString(R.string.nfc_hce_tap_test_reader),
                     TapTestEmulatorActivity.buildReaderIntent(this), null));
 
             adapter.add(TestListItem.newTest(this, R.string.nfc_hce_offhost_service_reader,
-                    SimpleReaderActivity.class.getName(),
+                    getString(R.string.nfc_hce_offhost_service_reader),
                     OffHostEmulatorActivity.buildReaderIntent(this), null));
 
             adapter.add(TestListItem.newTest(this, R.string.nfc_hce_on_and_offhost_service_reader,
-                    SimpleReaderActivity.class.getName(),
+                    getString(R.string.nfc_hce_on_and_offhost_service_reader),
                     OnAndOffHostEmulatorActivity.buildReaderIntent(this), null));
 
             adapter.add(TestListItem.newTest(this, R.string.nfc_hce_payment_dynamic_aids_reader,
-                    SimpleReaderActivity.class.getName(),
+                    getString(R.string.nfc_hce_payment_dynamic_aids_reader),
                     DynamicAidEmulatorActivity.buildReaderIntent(this), null));
 
             adapter.add(TestListItem.newTest(this, R.string.nfc_hce_large_num_aids_reader,
-                    SimpleReaderActivity.class.getName(),
+                    getString(R.string.nfc_hce_large_num_aids_reader),
                     LargeNumAidsEmulatorActivity.buildReaderIntent(this), null));
 
             NfcAdapter nfcAdapter = NfcAdapter.getDefaultAdapter(this);
             CardEmulation cardEmulation = CardEmulation.getInstance(nfcAdapter);
             if (cardEmulation.supportsAidPrefixRegistration()) {
                 adapter.add(TestListItem.newTest(this, R.string.nfc_hce_payment_prefix_aids_reader,
-                        SimpleReaderActivity.class.getName(),
+                        getString(R.string.nfc_hce_payment_prefix_aids_reader),
                         PrefixPaymentEmulatorActivity.buildReaderIntent(this), null));
 
                 adapter.add(TestListItem.newTest(this, R.string.nfc_hce_payment_prefix_aids_reader_2,
-                        SimpleReaderActivity.class.getName(),
+                        getString(R.string.nfc_hce_payment_prefix_aids_reader_2),
                         PrefixPaymentEmulator2Activity.buildReaderIntent(this), null));
 
                 adapter.add(TestListItem.newTest(this, R.string.nfc_hce_other_prefix_aids_reader,
-                        SimpleReaderActivity.class.getName(),
+                        getString(R.string.nfc_hce_other_prefix_aids_reader),
                         DualNonPaymentPrefixEmulatorActivity.buildReaderIntent(this), null));
 
                 adapter.add(TestListItem.newTest(this, R.string.nfc_hce_other_conflicting_prefix_aids_reader,
-                        SimpleReaderActivity.class.getName(),
+                        getString(R.string.nfc_hce_other_conflicting_prefix_aids_reader),
                         ConflictingNonPaymentPrefixEmulatorActivity.buildReaderIntent(this), null));
             }
         }
diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/nfc/hce/SimpleReaderActivity.java b/apps/CtsVerifier/src/com/android/cts/verifier/nfc/hce/SimpleReaderActivity.java
index 638bc6f..4fab77a 100644
--- a/apps/CtsVerifier/src/com/android/cts/verifier/nfc/hce/SimpleReaderActivity.java
+++ b/apps/CtsVerifier/src/com/android/cts/verifier/nfc/hce/SimpleReaderActivity.java
@@ -37,6 +37,7 @@
     NfcAdapter mAdapter;
     CommandApdu[] mApdus;
     String[] mResponses;
+    String mLabel;
 
     TextView mTextView;
     Spinner mSpinner;
@@ -49,8 +50,8 @@
         setPassFailButtonClickListeners();
         getPassButton().setEnabled(false);
 
-        String label = getIntent().getStringExtra(EXTRA_LABEL);
-        setTitle(label);
+        mLabel = getIntent().getStringExtra(EXTRA_LABEL);
+        setTitle(mLabel);
 
         mAdapter = NfcAdapter.getDefaultAdapter(this);
         mTextView = (TextView) findViewById(R.id.text);
@@ -187,4 +188,9 @@
     @Override
     public void onNothingSelected(AdapterView<?> parent) {
     }
+
+    @Override
+    public String getTestId() {
+        return mLabel;
+    }
 }
diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/nfc/hcef/HceFEmulatorActivity.java b/apps/CtsVerifier/src/com/android/cts/verifier/nfc/hcef/HceFEmulatorActivity.java
new file mode 100644
index 0000000..7118ae3
--- /dev/null
+++ b/apps/CtsVerifier/src/com/android/cts/verifier/nfc/hcef/HceFEmulatorActivity.java
@@ -0,0 +1,73 @@
+/*
+ * Copyright (C) 2016 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.verifier.nfc.hcef;
+
+import android.content.BroadcastReceiver;
+import android.content.ComponentName;
+import android.content.Context;
+import android.content.Intent;
+import android.content.IntentFilter;
+import android.nfc.NfcAdapter;
+import android.nfc.cardemulation.NfcFCardEmulation;
+import android.os.Bundle;
+
+import com.android.cts.verifier.PassFailButtons;
+import com.android.cts.verifier.R;
+
+public class HceFEmulatorActivity extends PassFailButtons.Activity{
+    static String ACTION_TEST_SUCCESS = "success";
+
+    NfcAdapter mAdapter;
+    NfcFCardEmulation mNfcFCardEmulation;
+
+    final BroadcastReceiver mReceiver = new BroadcastReceiver() {
+        @Override
+        public void onReceive(Context context, Intent intent) {
+            String action = intent.getAction();