Merge "Add a test for closing sockets when a VPN comes up." into nyc-dev
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
index c2b46d2..282b82e 100644
--- a/apps/CameraITS/tests/scene5/test_lens_shading_and_color_uniformity.py
+++ b/apps/CameraITS/tests/scene5/test_lens_shading_and_color_uniformity.py
@@ -41,9 +41,11 @@
     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_UFMT = 0.1   # uniformity allowance
+    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
@@ -111,7 +113,7 @@
         # evaluate y and r/g, b/g for each block
         ls_test_failed = []
         cu_test_failed = []
-        ls_thres_h = center_y * 1.001
+        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
diff --git a/apps/CtsVerifier/AndroidManifest.xml b/apps/CtsVerifier/AndroidManifest.xml
index f4e2829..b19c7cd 100644
--- a/apps/CtsVerifier/AndroidManifest.xml
+++ b/apps/CtsVerifier/AndroidManifest.xml
@@ -1862,6 +1862,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">
@@ -1873,6 +1877,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" />
@@ -1884,6 +1889,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>
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_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/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/values/strings.xml b/apps/CtsVerifier/res/values/strings.xml
index d2dae49..7fc4c17 100644
--- a/apps/CtsVerifier/res/values/strings.xml
+++ b/apps/CtsVerifier/res/values/strings.xml
@@ -1968,33 +1968,58 @@
         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_icon">Icon when work mode is off</string>
-    <string name="provisioning_byod_turn_off_work_icon_instruction">
-        This test verifies that a status bar icon indicates if work mode is off.\n
-        1. Press the go button to go to the settings apps, set work mode to off.\n
-        2. Verify that the status bar shows an icon indicating that work mode is off.\n
-        3. Set work mode to on.\n
-        4. Check that the work icon on the status bar is removed.
+    <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 the go button to go to the settings apps, set work mode to off.\n
-        2. Press home to go to the launcher.\n
-        3. Verify that work applications are greyed out.\n
-        4. Tap on a work application.\n
-        5. Verify that the application does not start.\n
-        6. Set work mode to on.\n
-        7. Go to the launcher and verify that you can start a work application.\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_notifications">Notifications when work mode is off</string>
-    <string name="provisioning_byod_turn_off_work_notifications_instruction">
-        This test verifies that work notifications are not shown if work mode is off.\n
-        1. Press the go button to send a work notification.\n
-        2. Set work mode to off.\n
-        3. Check that the work notification has disappeared.\n
-        4. Set work mode to on.\n
+
+    <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>
@@ -2521,6 +2546,10 @@
     Verify that the overlay appears and displays the text \"Overlay View Dummy Text\" when you tune
     to the \"Dummy\" channel.
     </string>
+    <string name="tv_input_discover_test_verify_size_changed">
+    Verify that video layout changes correctly according to the provided video track information,
+    including pixel aspect ratio.
+    </string>
     <string name="tv_input_discover_test_verify_global_search">
     Verify the TV app provides query results for 3rd-party input\'s channels and programs in
     global search results.
@@ -2716,7 +2745,7 @@
     <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>
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 02cdabb..944f7bf 100644
--- a/apps/CtsVerifier/src/com/android/cts/verifier/audio/AudioFrequencyLineActivity.java
+++ b/apps/CtsVerifier/src/com/android/cts/verifier/audio/AudioFrequencyLineActivity.java
@@ -180,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(
@@ -327,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) {
@@ -339,7 +339,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/AudioFrequencyMicActivity.java b/apps/CtsVerifier/src/com/android/cts/verifier/audio/AudioFrequencyMicActivity.java
index 12395ae..2571909 100644
--- a/apps/CtsVerifier/src/com/android/cts/verifier/audio/AudioFrequencyMicActivity.java
+++ b/apps/CtsVerifier/src/com/android/cts/verifier/audio/AudioFrequencyMicActivity.java
@@ -216,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(
@@ -465,7 +465,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;
@@ -478,7 +478,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 bc6c2fc..a3c8f96 100644
--- a/apps/CtsVerifier/src/com/android/cts/verifier/audio/AudioFrequencySpeakerActivity.java
+++ b/apps/CtsVerifier/src/com/android/cts/verifier/audio/AudioFrequencySpeakerActivity.java
@@ -165,7 +165,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(
@@ -342,7 +342,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;
@@ -355,7 +355,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
index 11474b3..56275c5 100644
--- a/apps/CtsVerifier/src/com/android/cts/verifier/audio/AudioFrequencyUnprocessedActivity.java
+++ b/apps/CtsVerifier/src/com/android/cts/verifier/audio/AudioFrequencyUnprocessedActivity.java
@@ -327,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) {
@@ -339,7 +339,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/managedprovisioning/ByodFlowTestActivity.java b/apps/CtsVerifier/src/com/android/cts/verifier/managedprovisioning/ByodFlowTestActivity.java
index 2df4599..5a20936 100644
--- a/apps/CtsVerifier/src/com/android/cts/verifier/managedprovisioning/ByodFlowTestActivity.java
+++ b/apps/CtsVerifier/src/com/android/cts/verifier/managedprovisioning/ByodFlowTestActivity.java
@@ -78,9 +78,6 @@
     private DialogTestListItem mPrintSettingsVisibleTest;
     private DialogTestListItem mIntentFiltersTest;
     private DialogTestListItem mPermissionLockdownTest;
-    private DialogTestListItem mTurnOffWorkIcon;
-    private DialogTestListItem mTurnOffWorkLauncher;
-    private DialogTestListItem mTurnOffWorkNotifications;
     private DialogTestListItem mCrossProfileImageCaptureSupportTest;
     private DialogTestListItem mCrossProfileVideoCaptureWithExtraOutputSupportTest;
     private DialogTestListItem mCrossProfileVideoCaptureWithoutExtraOutputSupportTest;
@@ -99,6 +96,7 @@
     private TestListItem mDisallowAppsControlTest;
     private TestListItem mOrganizationInfoTest;
     private TestListItem mPolicyTransparencyTest;
+    private TestListItem mTurnOffWorkFeaturesTest;
 
     public ByodFlowTestActivity() {
         super(R.layout.provisioning_byod,
@@ -346,6 +344,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,
@@ -354,24 +357,6 @@
                 R.string.profile_owner_permission_lockdown_test_info,
                 permissionCheckIntent);
 
-        mTurnOffWorkIcon = 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));
-
-        mTurnOffWorkLauncher = new DialogTestListItem(this,
-                R.string.provisioning_byod_turn_off_work_launcher,
-                "BYOD_TurnOffWorkStartApps",
-                R.string.provisioning_byod_turn_off_work_launcher_instruction,
-                new Intent(Settings.ACTION_SETTINGS));
-
-        mTurnOffWorkNotifications = 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));
-
         mSelectWorkChallenge = new DialogTestListItem(this,
                 R.string.provisioning_byod_select_work_challenge,
                 "BYOD_SelectWorkChallenge",
@@ -436,9 +421,7 @@
         adapter.add(mKeyguardDisabledFeaturesTest);
         adapter.add(mAuthenticationBoundKeyTest);
         adapter.add(mVpnTest);
-        adapter.add(mTurnOffWorkIcon);
-        adapter.add(mTurnOffWorkLauncher);
-        adapter.add(mTurnOffWorkNotifications);
+        adapter.add(mTurnOffWorkFeaturesTest);
         adapter.add(mSelectWorkChallenge);
         adapter.add(mConfirmWorkCredentials);
         adapter.add(mOrganizationInfoTest);
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 af71ebe..b162b58 100644
--- a/apps/CtsVerifier/src/com/android/cts/verifier/managedprovisioning/IntentFiltersTestHelper.java
+++ b/apps/CtsVerifier/src/com/android/cts/verifier/managedprovisioning/IntentFiltersTestHelper.java
@@ -181,13 +181,13 @@
         if (pm.hasSystemFeature(PackageManager.FEATURE_NFC)) {
             forwardedIntentsFromManaged.addAll(Arrays.asList(
                     new Intent(Settings.ACTION_NFC_SETTINGS),
-                    new Intent(Settings.ACTION_NFCSHARING_SETTINGS),
-                    new Intent(Settings.ACTION_NFC_PAYMENT_SETTINGS)));
+                    new Intent(Settings.ACTION_NFCSHARING_SETTINGS)));
         }
 
         if (pm.hasSystemFeature(PackageManager.FEATURE_NFC_HOST_CARD_EMULATION)) {
-            forwardedIntentsFromManaged.add(
-                    new Intent(CardEmulation.ACTION_CHANGE_DEFAULT));
+            forwardedIntentsFromManaged.addAll(Arrays.asList(
+                    new Intent(CardEmulation.ACTION_CHANGE_DEFAULT),
+                    new Intent(Settings.ACTION_NFC_PAYMENT_SETTINGS)));
         }
 
         if (pm.hasSystemFeature(PackageManager.FEATURE_CAMERA)) {
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/notifications/InteractiveVerifierActivity.java b/apps/CtsVerifier/src/com/android/cts/verifier/notifications/InteractiveVerifierActivity.java
index 25a36b6..27ad8b3 100644
--- a/apps/CtsVerifier/src/com/android/cts/verifier/notifications/InteractiveVerifierActivity.java
+++ b/apps/CtsVerifier/src/com/android/cts/verifier/notifications/InteractiveVerifierActivity.java
@@ -323,8 +323,10 @@
             if (id == R.string.nls_start_settings) {
                 launchSettings();
             } else if (id == R.string.attention_ready) {
-                mCurrentTest.status = READY;
-                next();
+                if (mCurrentTest != null) {
+                    mCurrentTest.status = READY;
+                    next();
+                }
             }
         }
     }
diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/tv/MockTvInputService.java b/apps/CtsVerifier/src/com/android/cts/verifier/tv/MockTvInputService.java
index f875684..3bfac3a 100644
--- a/apps/CtsVerifier/src/com/android/cts/verifier/tv/MockTvInputService.java
+++ b/apps/CtsVerifier/src/com/android/cts/verifier/tv/MockTvInputService.java
@@ -58,8 +58,9 @@
     private static final String SELECT_TRACK_ID = "id";
     private static final String CAPTION_ENABLED = "enabled";
     private static final String PAUSE_CALLED = "pause_called";
+    private static final float DISPLAY_RATIO_EPSILON = 0.01f;
 
-    private static Object sLock = new Object();
+    private static final Object sLock = new Object();
     private static Callback sTuneCallback = null;
     private static Callback sOverlayViewCallback = null;
     private static Callback sBroadcastCallback = null;
@@ -73,6 +74,7 @@
     private static Callback sFastForwardCallback = null;
     private static Callback sSeekToPreviousCallback = null;
     private static Callback sSeekToNextCallback = null;
+    private static Callback sOverlayViewSizeChangedCallback = null;
 
     private static TvContentRating sRating = null;
 
@@ -96,6 +98,15 @@
             new TvTrackInfo.Builder(TvTrackInfo.TYPE_SUBTITLE, "subtitle_kor")
             .setLanguage("kor")
             .build();
+    // These parameters make the display aspect ratio of sDummyVideoTrack be 4:3,
+    // which is one of common standards.
+    static final TvTrackInfo sDummyVideoTrack =
+            new TvTrackInfo.Builder(TvTrackInfo.TYPE_VIDEO, "video_dummy")
+            .setVideoWidth(704)
+            .setVideoHeight(480)
+            .setVideoPixelAspectRatio(0.909f)
+            .setVideoFrameRate(60)
+            .build();
 
     private final BroadcastReceiver mBroadcastReceiver = new BroadcastReceiver() {
         @Override
@@ -196,6 +207,12 @@
         }
     }
 
+    static void expectedVideoAspectRatio(View postTarget, Runnable successCallback) {
+        synchronized (sLock) {
+            sOverlayViewSizeChangedCallback = new Callback(postTarget, successCallback);
+        }
+    }
+
     static String getInputId(Context context) {
         return TvContract.buildInputId(new ComponentName(context,
                         MockTvInputService.class.getName()));
@@ -270,6 +287,7 @@
             mTracks.add(sSpaAudioTrack);
             mTracks.add(sEngSubtitleTrack);
             mTracks.add(sKorSubtitleTrack);
+            mTracks.add(sDummyVideoTrack);
         }
 
         @Override
@@ -324,7 +342,9 @@
         @Override
         public boolean onSetSurface(Surface surface) {
             mSurface = surface;
-            draw();
+            if (surface != null) {
+                draw();
+            }
             return true;
         }
 
@@ -350,6 +370,8 @@
             notifyTracksChanged(mTracks);
             notifyTrackSelected(TvTrackInfo.TYPE_AUDIO, sEngAudioTrack.getId());
             notifyTrackSelected(TvTrackInfo.TYPE_SUBTITLE, null);
+            notifyTrackSelected(TvTrackInfo.TYPE_VIDEO, sDummyVideoTrack.getId());
+
             notifyTimeShiftStatusChanged(TvInputManager.TIME_SHIFT_STATUS_AVAILABLE);
             mRecordStartTimeMs = mCurrentPositionMs = mLastCurrentPositionUpdateTimeMs
                     = System.currentTimeMillis();
@@ -480,6 +502,30 @@
             }
             mSpeed = params.getSpeed();
         }
+
+        @Override
+        public void onOverlayViewSizeChanged(int width, int height) {
+            synchronized(sLock) {
+                draw();
+                if (sOverlayViewSizeChangedCallback != null) {
+                    if (sDummyVideoTrack.getVideoHeight() <= 0
+                            || sDummyVideoTrack.getVideoWidth() <= 0) {
+                        Log.w(TAG,
+                                "The width or height of the selected video track is invalid.");
+                    } else if (height <= 0 || width <= 0) {
+                        Log.w(TAG, "The width or height of the OverlayView is incorrect.");
+                    } else if (Math.abs((float)width / height
+                            - (float)sDummyVideoTrack.getVideoWidth()
+                            * sDummyVideoTrack.getVideoPixelAspectRatio()
+                            / sDummyVideoTrack.getVideoHeight()) < DISPLAY_RATIO_EPSILON) {
+                        // Verify the video display aspect ratio is correct
+                        // and setVideoPixelAspectRatio() works for the view size.
+                        sOverlayViewSizeChangedCallback.post();
+                        sOverlayViewSizeChangedCallback = null;
+                    }
+                }
+            }
+        }
     }
 
     private static class Callback {
diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/tv/TvInputDiscoveryTestActivity.java b/apps/CtsVerifier/src/com/android/cts/verifier/tv/TvInputDiscoveryTestActivity.java
index 56c8ac0..ff8c1e8 100644
--- a/apps/CtsVerifier/src/com/android/cts/verifier/tv/TvInputDiscoveryTestActivity.java
+++ b/apps/CtsVerifier/src/com/android/cts/verifier/tv/TvInputDiscoveryTestActivity.java
@@ -48,6 +48,7 @@
     private View mVerifyTuneItem;
     private View mVerifyOverlayViewItem;
     private View mVerifyGlobalSearchItem;
+    private View mVerifyOverlayViewSizeChanged;
     private View mGoToEpgItem;
     private View mVerifyEpgItem;
     private View mTriggerSetupItem;
@@ -55,6 +56,7 @@
     private boolean mTuneVerified;
     private boolean mOverlayViewVerified;
     private boolean mGlobalSearchVerified;
+    private boolean mOverlayViewSizeChangedVerified;
 
     @Override
     public void onClick(View v) {
@@ -96,6 +98,16 @@
                     goToNextState(postTarget, failCallback);
                 }
             });
+            MockTvInputService.expectedVideoAspectRatio(postTarget, new Runnable() {
+                @Override
+                public void run() {
+                    postTarget.removeCallbacks(failCallback);
+                    setPassState(mVerifyOverlayViewSizeChanged, true);
+
+                    mOverlayViewSizeChangedVerified = true;
+                    goToNextState(postTarget, failCallback);
+                }
+            });
             MockTvInputService.expectOverlayView(postTarget, new Runnable() {
                 @Override
                 public void run() {
@@ -136,6 +148,8 @@
         mVerifyTuneItem = createAutoItem(R.string.tv_input_discover_test_verify_tune);
         mVerifyOverlayViewItem = createAutoItem(
                 R.string.tv_input_discover_test_verify_overlay_view);
+        mVerifyOverlayViewSizeChanged = createAutoItem(
+                R.string.tv_input_discover_test_verify_size_changed);
         mVerifyGlobalSearchItem = createAutoItem(
                 R.string.tv_input_discover_test_verify_global_search);
         mGoToEpgItem = createUserItem(R.string.tv_input_discover_test_go_to_epg,
@@ -155,7 +169,8 @@
     }
 
     private void goToNextState(View postTarget, Runnable failCallback) {
-        if (mTuneVerified && mOverlayViewVerified && mGlobalSearchVerified) {
+        if (mTuneVerified && mOverlayViewVerified
+                && mGlobalSearchVerified && mOverlayViewSizeChangedVerified) {
             postTarget.removeCallbacks(failCallback);
             setButtonEnabled(mGoToEpgItem, true);
         }
diff --git a/common/device-side/device-info/src/com/android/compatibility/common/deviceinfo/FeatureDeviceInfo.java b/common/device-side/device-info/src/com/android/compatibility/common/deviceinfo/FeatureDeviceInfo.java
index 414fcab..e9d2969 100644
--- a/common/device-side/device-info/src/com/android/compatibility/common/deviceinfo/FeatureDeviceInfo.java
+++ b/common/device-side/device-info/src/com/android/compatibility/common/deviceinfo/FeatureDeviceInfo.java
@@ -17,6 +17,7 @@
 
 import android.content.pm.FeatureInfo;
 import android.content.pm.PackageManager;
+import android.os.Build;
 
 import com.android.compatibility.common.util.DeviceInfoStore;
 
@@ -35,32 +36,46 @@
 
     @Override
     protected void collectDeviceInfo(DeviceInfoStore store) throws Exception {
-        PackageManager packageManager = getInstrumentation().getContext().getPackageManager();
+        PackageManager packageManager =
+                getInstrumentation().getContext().getPackageManager();
         store.startArray("feature");
 
-        Set<String> checkedFeatures = new HashSet<String>();
-        for (String featureName : getPackageManagerFeatures()) {
-            checkedFeatures.add(featureName);
-            boolean hasFeature = packageManager.hasSystemFeature(featureName);
-            addFeature(store, featureName, "sdk", hasFeature);
-        }
+        List<String> sdkFeatures = getPackageManagerFeatures();
 
         FeatureInfo[] featureInfos = packageManager.getSystemAvailableFeatures();
         if (featureInfos != null) {
             for (FeatureInfo featureInfo : featureInfos) {
-                if (featureInfo.name != null && !checkedFeatures.contains(featureInfo.name)) {
-                    addFeature(store, featureInfo.name, "other", true);
+                if (featureInfo.name != null) {
+                    // Check if this feature is a "sdk" feature.
+                    String type = "other";
+                    if (sdkFeatures.contains(featureInfo.name)) {
+                        type = "sdk";
+                        sdkFeatures.remove(featureInfo.name);
+                    }
+                    // Add the feature version if avaiable.
+                    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
+                        int version = featureInfo.version;
+                        addFeature(store, featureInfo.name, type, true, version);
+                    } else {
+                        addFeature(store, featureInfo.name, type, true);
+                    }
                 }
             }
         }
 
+        // Store the remaining "sdk" features not avaiable on this device.
+        for (String featureName : sdkFeatures) {
+            boolean hasFeature = packageManager.hasSystemFeature(featureName);
+            addFeature(store, featureName, "sdk", hasFeature);
+        }
+
         store.endArray();
     }
 
     /**
-     * Use reflection to get the features defined by the SDK. If there are features that do not fit
-     * the convention of starting with "FEATURE_" then they will still be shown under the
-     * "Other Features" section.
+     * Use reflection to get the features defined by the SDK. If there are
+     * features that do not fit the convention of starting with "FEATURE_"
+     * then they will still be shown under the "Other Features" section.
      *
      * @return list of feature names from sdk
      */
@@ -80,12 +95,29 @@
         }
     }
 
-    private void addFeature(DeviceInfoStore store, String name, String type, boolean available)
-            throws Exception {
+    private void addFeature(
+            DeviceInfoStore store,
+            String name,
+            String type,
+            boolean available) throws Exception {
         store.startGroup();
         store.addResult("name", name);
         store.addResult("type", type);
         store.addResult("available", available);
         store.endGroup();
     }
+
+    private void addFeature(
+            DeviceInfoStore store,
+            String name,
+            String type,
+            boolean available,
+            int version) throws Exception {
+        store.startGroup();
+        store.addResult("name", name);
+        store.addResult("type", type);
+        store.addResult("available", available);
+        store.addResult("version", version);
+        store.endGroup();
+    }
 }
diff --git a/common/host-side/tradefed/src/com/android/compatibility/common/tradefed/targetprep/WifiCheck.java b/common/host-side/tradefed/src/com/android/compatibility/common/tradefed/targetprep/WifiCheck.java
index 5863bd8..cfc4d7c 100644
--- a/common/host-side/tradefed/src/com/android/compatibility/common/tradefed/targetprep/WifiCheck.java
+++ b/common/host-side/tradefed/src/com/android/compatibility/common/tradefed/targetprep/WifiCheck.java
@@ -62,14 +62,16 @@
 
         if (mWifiSsid == null) { // no connection to create, check for existing connectivity
             if (!device.checkConnectivity()) {
-                throw new TargetSetupError("Device has no network connection, no ssid provided");
+                logError("Device has no network connection, no ssid provided, some modules " +
+                        "of CTS require an active network connection");
+                return;
             }
         } else { // network provided in options, attempt to create new connection
             logInfo("Attempting connection to \"%s\"", mWifiSsid);
             if (!device.connectToWifiNetwork(mWifiSsid, mWifiPsk)) { // attempt connection
-                throw new TargetSetupError(String.format(
-                        "Unable to connect to network \"%s\", some modules of CTS" +
-                        "require an active network connection", mWifiSsid));
+                logError("Unable to connect to network \"%s\", some modules of CTS" +
+                        "require an active network connection", mWifiSsid);
+                return;
             }
         }
         logInfo("Wifi is connected");
diff --git a/hostsidetests/appsecurity/src/android/appsecurity/cts/PrivilegedUpdateTests.java b/hostsidetests/appsecurity/src/android/appsecurity/cts/PrivilegedUpdateTests.java
index b2b4476..c726fb7 100644
--- a/hostsidetests/appsecurity/src/android/appsecurity/cts/PrivilegedUpdateTests.java
+++ b/hostsidetests/appsecurity/src/android/appsecurity/cts/PrivilegedUpdateTests.java
@@ -64,6 +64,7 @@
 
         assertNull(getDevice().installPackage(
                 MigrationHelper.getTestFile(mCtsBuild, TEST_APK), false));
+        getDevice().executeShellCommand("pm enable " + SHIM_PKG);
     }
 
     @Override
@@ -72,6 +73,7 @@
 
         getDevice().uninstallPackage(SHIM_PKG);
         getDevice().uninstallPackage(TEST_PKG);
+        getDevice().executeShellCommand("pm enable " + SHIM_PKG);
     }
 
     public void testSystemAppPriorities() throws Exception {
@@ -94,6 +96,28 @@
         }
     }
 
+    public void testDisableSystemApp() throws Exception {
+        getDevice().executeShellCommand("pm enable " + SHIM_PKG);
+        runDeviceTests(TEST_PKG, ".PrivilegedAppDisableTest", "testPrivAppAndEnabled");
+        getDevice().executeShellCommand("pm disable-user " + SHIM_PKG);
+        runDeviceTests(TEST_PKG, ".PrivilegedAppDisableTest", "testPrivAppAndDisabled");
+    }
+
+    public void testDisableUpdatedSystemApp() throws Exception {
+        getDevice().executeShellCommand("pm enable " + SHIM_PKG);
+        runDeviceTests(TEST_PKG, ".PrivilegedAppDisableTest", "testPrivAppAndEnabled");
+        try {
+            assertNull(getDevice().installPackage(
+                    MigrationHelper.getTestFile(mCtsBuild, SHIM_UPDATE_APK), true));
+            getDevice().executeShellCommand("pm disable-user " + SHIM_PKG);
+            runDeviceTests(TEST_PKG, ".PrivilegedAppDisableTest", "testUpdatedPrivAppAndDisabled");
+            getDevice().executeShellCommand("pm enable " + SHIM_PKG);
+            runDeviceTests(TEST_PKG, ".PrivilegedAppDisableTest", "testUpdatedPrivAppAndEnabled");
+        } finally {
+            getDevice().uninstallPackage(SHIM_PKG);
+        }
+    }
+
     private void runDeviceTests(String packageName, String testClassName, String testMethodName)
             throws DeviceNotAvailableException {
         Utils.runDeviceTests(getDevice(), packageName, testClassName, testMethodName);
diff --git a/hostsidetests/appsecurity/src/android/appsecurity/cts/Utils.java b/hostsidetests/appsecurity/src/android/appsecurity/cts/Utils.java
index 7048074..37aaeaf 100644
--- a/hostsidetests/appsecurity/src/android/appsecurity/cts/Utils.java
+++ b/hostsidetests/appsecurity/src/android/appsecurity/cts/Utils.java
@@ -85,7 +85,9 @@
             throw new AssertionError("Failed to successfully run device tests for "
                     + result.getName() + ": " + result.getRunFailureMessage());
         }
-
+        if (result.getNumTests() == 0) {
+            throw new AssertionError("No tests were run on the device");
+        }
         if (result.hasFailedTests()) {
             // build a meaningful error message
             StringBuilder errorBuilder = new StringBuilder("on-device tests failed:\n");
diff --git a/hostsidetests/appsecurity/test-apps/PrivilegedUpdateApp/src/com/android/cts/privilegedupdate/PrivilegedAppDisableTest.java b/hostsidetests/appsecurity/test-apps/PrivilegedUpdateApp/src/com/android/cts/privilegedupdate/PrivilegedAppDisableTest.java
new file mode 100644
index 0000000..606ada1
--- /dev/null
+++ b/hostsidetests/appsecurity/test-apps/PrivilegedUpdateApp/src/com/android/cts/privilegedupdate/PrivilegedAppDisableTest.java
@@ -0,0 +1,84 @@
+/*
+ * 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.privilegedupdate;
+
+import java.util.List;
+
+import android.content.ComponentName;
+import android.content.Intent;
+import android.content.pm.ApplicationInfo;
+import android.content.pm.PackageManager;
+import android.content.pm.ResolveInfo;
+import android.content.pm.PackageManager.NameNotFoundException;
+import android.net.Uri;
+import android.test.InstrumentationTestCase;
+
+/**
+ * Tests for system app type and enabled state
+ */
+public class PrivilegedAppDisableTest extends InstrumentationTestCase {
+    /** Package name of the privileged CTS shim */
+    private static final String PRIVILEGED_SHIM_PKG = "com.android.cts.priv.ctsshim";
+
+    public void testPrivAppAndEnabled() throws Exception {
+        assertEquals((getApplicationFlags() & ApplicationInfo.FLAG_UPDATED_SYSTEM_APP),
+                0);
+        assertPackageEnabledState(PRIVILEGED_SHIM_PKG,
+                PackageManager.COMPONENT_ENABLED_STATE_ENABLED);
+    }
+
+    public void testPrivAppAndDisabled() throws Exception {
+        assertEquals((getApplicationFlags() & ApplicationInfo.FLAG_UPDATED_SYSTEM_APP),
+                0);
+        assertPackageEnabledState(PRIVILEGED_SHIM_PKG,
+                PackageManager.COMPONENT_ENABLED_STATE_DISABLED_USER);
+    }
+
+    public void testUpdatedPrivAppAndEnabled() throws Exception {
+        assertEquals((getApplicationFlags() & ApplicationInfo.FLAG_UPDATED_SYSTEM_APP),
+                ApplicationInfo.FLAG_UPDATED_SYSTEM_APP);
+        assertPackageEnabledState(PRIVILEGED_SHIM_PKG,
+                PackageManager.COMPONENT_ENABLED_STATE_ENABLED);
+    }
+
+    public void testUpdatedPrivAppAndDisabled() throws Exception {
+        assertEquals((getApplicationFlags() & ApplicationInfo.FLAG_UPDATED_SYSTEM_APP),
+                ApplicationInfo.FLAG_UPDATED_SYSTEM_APP);
+        assertPackageEnabledState(PRIVILEGED_SHIM_PKG,
+                PackageManager.COMPONENT_ENABLED_STATE_DISABLED_USER);
+    }
+
+    private int getApplicationFlags() {
+        PackageManager pm = getInstrumentation().getContext().getPackageManager();
+        try {
+            ApplicationInfo aInfo = pm.getApplicationInfo(PRIVILEGED_SHIM_PKG,
+                    PackageManager.MATCH_DISABLED_COMPONENTS);
+            return aInfo.flags;
+        } catch (NameNotFoundException e) {
+            return 0;
+        }
+    }
+
+    private void assertPackageEnabledState(String packageName, int expectedState) {
+        PackageManager pm = getInstrumentation().getContext().getPackageManager();
+        int state = pm.getApplicationEnabledSetting(packageName);
+        if (state == PackageManager.COMPONENT_ENABLED_STATE_DEFAULT) {
+            state = PackageManager.COMPONENT_ENABLED_STATE_ENABLED;
+        }
+        assertEquals(expectedState, state);
+    }
+}
diff --git a/hostsidetests/appsecurity/test-apps/PrivilegedUpdateApp/src/com/android/cts/privilegedupdate/PrivilegedUpdateTest.java b/hostsidetests/appsecurity/test-apps/PrivilegedUpdateApp/src/com/android/cts/privilegedupdate/PrivilegedUpdateTest.java
index 7b92bea..9246256 100644
--- a/hostsidetests/appsecurity/test-apps/PrivilegedUpdateApp/src/com/android/cts/privilegedupdate/PrivilegedUpdateTest.java
+++ b/hostsidetests/appsecurity/test-apps/PrivilegedUpdateApp/src/com/android/cts/privilegedupdate/PrivilegedUpdateTest.java
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-package com.android.cts.intentfilter;
+package com.android.cts.privilegedupdate;
 
 import java.util.List;
 
diff --git a/hostsidetests/appsecurity/test-apps/UsePermissionApp23/src/com/android/cts/usepermission/BasePermissionsTest.java b/hostsidetests/appsecurity/test-apps/UsePermissionApp23/src/com/android/cts/usepermission/BasePermissionsTest.java
index fb838d4..1f02835 100644
--- a/hostsidetests/appsecurity/test-apps/UsePermissionApp23/src/com/android/cts/usepermission/BasePermissionsTest.java
+++ b/hostsidetests/appsecurity/test-apps/UsePermissionApp23/src/com/android/cts/usepermission/BasePermissionsTest.java
@@ -59,7 +59,7 @@
     private static final long IDLE_TIMEOUT_MILLIS = 500;
     private static final long GLOBAL_TIMEOUT_MILLIS = 5000;
 
-    private static final long RETRY_TIMEOUT = 30000;
+    private static final long RETRY_TIMEOUT = 5000;
 
     private static Map<String, String> sPermissionToLabelResNameMap = new ArrayMap<>();
     static {
@@ -328,7 +328,8 @@
             } catch (Exception e) {
                 fail("Cannot start activity: " + intent);
             }
-        }, (AccessibilityEvent event) -> event.getEventType() == AccessibilityEvent.TYPE_WINDOW_STATE_CHANGED
+        }, (AccessibilityEvent event) -> event.getEventType()
+                        == AccessibilityEvent.TYPE_WINDOW_STATE_CHANGED
          , GLOBAL_TIMEOUT_MILLIS);
     }
 
@@ -351,8 +352,8 @@
         return null;
     }
 
-    private static AccessibilityNodeInfo findByTextInCollection(AccessibilityNodeInfo root, String text)
-            throws Exception {
+    private static AccessibilityNodeInfo findByTextInCollection(AccessibilityNodeInfo root,
+            String text)  throws Exception {
         AccessibilityNodeInfo result;
         final int childCount = root.getChildCount();
         for (int i = 0; i < childCount; i++) {
@@ -361,9 +362,13 @@
                 continue;
             }
             if (child.getCollectionInfo() != null) {
+                scrollTop(child);
+                result = getNodeTimed(() -> findByText(child, text));
+                if (result != null) {
+                    return result;
+                }
                 while (child.getActionList().contains(AccessibilityAction.ACTION_SCROLL_FORWARD)) {
                     scrollForward(child);
-                    waitForIdle();
                     result = getNodeTimed(() -> findByText(child, text));
                     if (result != null) {
                         return result;
@@ -379,21 +384,46 @@
         return null;
     }
 
-    private static void scrollForward(AccessibilityNodeInfo node) throws Exception {
-        getInstrumentation().getUiAutomation().executeAndWaitForEvent(
-                () -> node.performAction(AccessibilityNodeInfo.ACTION_SCROLL_FORWARD),
-                (AccessibilityEvent event) -> event.getEventType() == AccessibilityEvent.TYPE_VIEW_SCROLLED,
-                GLOBAL_TIMEOUT_MILLIS);
+    private static void scrollTop(AccessibilityNodeInfo node) throws Exception {
+        try {
+            while (node.getActionList().contains(AccessibilityAction.ACTION_SCROLL_BACKWARD)) {
+                scroll(node, false);
+            }
+        } catch (TimeoutException e) {
+            /* ignore */
+        }
     }
 
+    private static void scrollForward(AccessibilityNodeInfo node) throws Exception {
+        try {
+            scroll(node, true);
+        } catch (TimeoutException e) {
+            /* ignore */
+        }
+    }
+
+    private static void scroll(AccessibilityNodeInfo node, boolean forward) throws Exception {
+        getInstrumentation().getUiAutomation().executeAndWaitForEvent(
+                () -> node.performAction(forward
+                        ? AccessibilityNodeInfo.ACTION_SCROLL_FORWARD
+                        : AccessibilityNodeInfo.ACTION_SCROLL_BACKWARD),
+                (AccessibilityEvent event) -> event.getEventType()
+                        == AccessibilityEvent.TYPE_VIEW_SCROLLED,
+                GLOBAL_TIMEOUT_MILLIS);
+        waitForIdle();
+    }
+
+
     private static void click(AccessibilityNodeInfo node) throws Exception {
         getInstrumentation().getUiAutomation().executeAndWaitForEvent(
                 () -> node.performAction(AccessibilityNodeInfo.ACTION_CLICK),
-                (AccessibilityEvent event) -> event.getEventType() == AccessibilityEvent.TYPE_VIEW_CLICKED,
+                (AccessibilityEvent event) -> event.getEventType()
+                        == AccessibilityEvent.TYPE_VIEW_CLICKED,
                 GLOBAL_TIMEOUT_MILLIS);
     }
 
-    private static AccessibilityNodeInfo findCollectionItem(AccessibilityNodeInfo current) throws Exception {
+    private static AccessibilityNodeInfo findCollectionItem(AccessibilityNodeInfo current)
+            throws Exception {
         AccessibilityNodeInfo result = current;
         while (result != null) {
             if (result.getCollectionItemInfo() != null) {
@@ -425,7 +455,8 @@
         return null;
     }
 
-    private static AccessibilityNodeInfo getNodeTimed(Callable<AccessibilityNodeInfo> callable) throws Exception {
+    private static AccessibilityNodeInfo getNodeTimed(
+            Callable<AccessibilityNodeInfo> callable) throws Exception {
         final long startTimeMillis = SystemClock.uptimeMillis();
         while (true) {
             AccessibilityNodeInfo node = callable.call();
@@ -433,12 +464,15 @@
                 return node;
             }
             final long elapsedTimeMillis = SystemClock.uptimeMillis() - startTimeMillis;
-            final long remainingTimeMillis = Math.min(startTimeMillis + RETRY_TIMEOUT, 2 * elapsedTimeMillis);
-            SystemClock.sleep(remainingTimeMillis);
+            if (elapsedTimeMillis > RETRY_TIMEOUT) {
+                return null;
+            }
+            SystemClock.sleep(2 * elapsedTimeMillis);
         }
     }
 
     private static void waitForIdle() throws TimeoutException {
-        getInstrumentation().getUiAutomation().waitForIdle(IDLE_TIMEOUT_MILLIS, GLOBAL_TIMEOUT_MILLIS);
+        getInstrumentation().getUiAutomation().waitForIdle(IDLE_TIMEOUT_MILLIS,
+                GLOBAL_TIMEOUT_MILLIS);
     }
  }
diff --git a/hostsidetests/compilation/Android.mk b/hostsidetests/compilation/Android.mk
index 40077f0..64e7063 100644
--- a/hostsidetests/compilation/Android.mk
+++ b/hostsidetests/compilation/Android.mk
@@ -18,6 +18,8 @@
 
 LOCAL_SRC_FILES := $(call all-java-files-under, src)
 
+LOCAL_JAVA_RESOURCE_DIRS := assets/
+
 LOCAL_MODULE_TAGS := tests
 
 # tag this module as a cts test artifact
@@ -27,6 +29,8 @@
 
 LOCAL_JAVA_LIBRARIES := cts-tradefed tradefed-prebuilt compatibility-host-util
 
+LOCAL_STATIC_JAVA_LIBRARIES := guavalib
+
 include $(BUILD_HOST_JAVA_LIBRARY)
 
 include $(call all-makefiles-under,$(LOCAL_PATH))
diff --git a/hostsidetests/compilation/AndroidTest.xml b/hostsidetests/compilation/AndroidTest.xml
index 4e5b0bd..acae9b5 100644
--- a/hostsidetests/compilation/AndroidTest.xml
+++ b/hostsidetests/compilation/AndroidTest.xml
@@ -14,10 +14,6 @@
      limitations under the License.
 -->
 <configuration description="Config for CTS Compilation Test">
-    <target_preparer class="com.android.compatibility.common.tradefed.targetprep.ApkInstaller">
-        <option name="cleanup-apks" value="true" />
-        <option name="test-file-name" value="CtsCompilationApp.apk" />
-    </target_preparer>
     <test class="com.android.compatibility.common.tradefed.testtype.JarHostTest" >
         <option name="jar" value="CtsCompilationTestCases.jar" />
     </test>
diff --git a/hostsidetests/compilation/app/AndroidManifest.xml b/hostsidetests/compilation/app/AndroidManifest.xml
index 99b13b2..33fc3ab 100755
--- a/hostsidetests/compilation/app/AndroidManifest.xml
+++ b/hostsidetests/compilation/app/AndroidManifest.xml
@@ -17,7 +17,7 @@
 
 <manifest xmlns:android="http://schemas.android.com/apk/res/android"
     package="android.cts.compilation">
-
+    <uses-sdk android:minSdkVersion="23" />
     <application>
         <activity android:name=".CompilationTargetActivity" >
             <intent-filter>
diff --git a/hostsidetests/compilation/app/src/android/cts/compilation/CompilationTargetActivity.java b/hostsidetests/compilation/app/src/android/cts/compilation/CompilationTargetActivity.java
index 37bbdab..e4c28fb 100644
--- a/hostsidetests/compilation/app/src/android/cts/compilation/CompilationTargetActivity.java
+++ b/hostsidetests/compilation/app/src/android/cts/compilation/CompilationTargetActivity.java
@@ -17,18 +17,284 @@
 package android.cts.compilation;
 
 import android.app.Activity;
-import android.os.Bundle;
+import android.os.AsyncTask;
 
-import java.lang.Override;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+import java.util.Random;
 
 /**
  * A simple activity which can be subjected to (dex to native) compilation.
+ *
+ * If you change this code, you need to regenerate APK and profile using the
+ * the new code - see instructions in {@code assets/README.txt}.
  */
 public class CompilationTargetActivity extends Activity {
 
+    private AsyncTask<Integer, String, Void> mTask;
+
     @Override
-    public void onCreate(Bundle bundle) {
-        super.onCreate(bundle);
+    protected void onResume() {
+        super.onResume();
+        setTitle("Starting...");
+        mTask = new AsyncTask<Integer, String, Void>() {
+            @Override
+            protected Void doInBackground(Integer... params) {
+                int numValues = params[0];
+                int numIter = params[1];
+                for (int i = 0; i < numIter; i++) {
+                    if (Thread.interrupted()) {
+                        break;
+                    }
+                    publishProgress("Step " + (i+1) + " of " + numIter);
+                    List<Integer> values = makeValues(numValues);
+                    Collections.shuffle(values);
+                    Collections.sort(values);
+                }
+                return null;
+            }
+
+            @Override
+            protected void onProgressUpdate(String... values) {
+                setTitle(values[0]);
+            }
+
+            @Override
+            protected void onPostExecute(Void aVoid) {
+                setTitle("Done");
+            }
+        };
+        mTask.execute(1024, 100 * 1000);
     }
 
+    @Override
+    protected void onPause() {
+        mTask.cancel(/* mayInterruptIfRunning */ true);
+        mTask = null;
+        super.onPause();
+    }
+
+    private List<Integer> makeValues(int numValues) {
+        List<Integer> result = new ArrayList<>();
+        Random random = new Random();
+        for (int i = 0; i < numValues; i++) {
+            int v = dispatch(random.nextInt());
+            result.add(v);
+        }
+        return result;
+    }
+
+    /**
+     * Dispatches to a bunch of simple methods because JIT profiles are only generated for
+     * apps with enough methods (10, as of May 2016).
+     */
+    private int dispatch(int i) {
+        int v = Math.abs(i % 100);
+        switch (v) {
+            case 0: return m0();
+            case 1: return m1();
+            case 2: return m2();
+            case 3: return m3();
+            case 4: return m4();
+            case 5: return m5();
+            case 6: return m6();
+            case 7: return m7();
+            case 8: return m8();
+            case 9: return m9();
+            case 10: return m10();
+            case 11: return m11();
+            case 12: return m12();
+            case 13: return m13();
+            case 14: return m14();
+            case 15: return m15();
+            case 16: return m16();
+            case 17: return m17();
+            case 18: return m18();
+            case 19: return m19();
+            case 20: return m20();
+            case 21: return m21();
+            case 22: return m22();
+            case 23: return m23();
+            case 24: return m24();
+            case 25: return m25();
+            case 26: return m26();
+            case 27: return m27();
+            case 28: return m28();
+            case 29: return m29();
+            case 30: return m30();
+            case 31: return m31();
+            case 32: return m32();
+            case 33: return m33();
+            case 34: return m34();
+            case 35: return m35();
+            case 36: return m36();
+            case 37: return m37();
+            case 38: return m38();
+            case 39: return m39();
+            case 40: return m40();
+            case 41: return m41();
+            case 42: return m42();
+            case 43: return m43();
+            case 44: return m44();
+            case 45: return m45();
+            case 46: return m46();
+            case 47: return m47();
+            case 48: return m48();
+            case 49: return m49();
+            case 50: return m50();
+            case 51: return m51();
+            case 52: return m52();
+            case 53: return m53();
+            case 54: return m54();
+            case 55: return m55();
+            case 56: return m56();
+            case 57: return m57();
+            case 58: return m58();
+            case 59: return m59();
+            case 60: return m60();
+            case 61: return m61();
+            case 62: return m62();
+            case 63: return m63();
+            case 64: return m64();
+            case 65: return m65();
+            case 66: return m66();
+            case 67: return m67();
+            case 68: return m68();
+            case 69: return m69();
+            case 70: return m70();
+            case 71: return m71();
+            case 72: return m72();
+            case 73: return m73();
+            case 74: return m74();
+            case 75: return m75();
+            case 76: return m76();
+            case 77: return m77();
+            case 78: return m78();
+            case 79: return m79();
+            case 80: return m80();
+            case 81: return m81();
+            case 82: return m82();
+            case 83: return m83();
+            case 84: return m84();
+            case 85: return m85();
+            case 86: return m86();
+            case 87: return m87();
+            case 88: return m88();
+            case 89: return m89();
+            case 90: return m90();
+            case 91: return m91();
+            case 92: return m92();
+            case 93: return m93();
+            case 94: return m94();
+            case 95: return m95();
+            case 96: return m96();
+            case 97: return m97();
+            case 98: return m98();
+            case 99: return m99();
+            default: throw new AssertionError(v + " out of bounds");
+        }
+    }
+
+    public int m0() { return new Random(0).nextInt(); }
+    public int m1() { return new Random(1).nextInt(); }
+    public int m2() { return new Random(2).nextInt(); }
+    public int m3() { return new Random(3).nextInt(); }
+    public int m4() { return new Random(4).nextInt(); }
+    public int m5() { return new Random(5).nextInt(); }
+    public int m6() { return new Random(6).nextInt(); }
+    public int m7() { return new Random(7).nextInt(); }
+    public int m8() { return new Random(8).nextInt(); }
+    public int m9() { return new Random(9).nextInt(); }
+    public int m10() { return new Random(10).nextInt(); }
+    public int m11() { return new Random(11).nextInt(); }
+    public int m12() { return new Random(12).nextInt(); }
+    public int m13() { return new Random(13).nextInt(); }
+    public int m14() { return new Random(14).nextInt(); }
+    public int m15() { return new Random(15).nextInt(); }
+    public int m16() { return new Random(16).nextInt(); }
+    public int m17() { return new Random(17).nextInt(); }
+    public int m18() { return new Random(18).nextInt(); }
+    public int m19() { return new Random(19).nextInt(); }
+    public int m20() { return new Random(20).nextInt(); }
+    public int m21() { return new Random(21).nextInt(); }
+    public int m22() { return new Random(22).nextInt(); }
+    public int m23() { return new Random(23).nextInt(); }
+    public int m24() { return new Random(24).nextInt(); }
+    public int m25() { return new Random(25).nextInt(); }
+    public int m26() { return new Random(26).nextInt(); }
+    public int m27() { return new Random(27).nextInt(); }
+    public int m28() { return new Random(28).nextInt(); }
+    public int m29() { return new Random(29).nextInt(); }
+    public int m30() { return new Random(30).nextInt(); }
+    public int m31() { return new Random(31).nextInt(); }
+    public int m32() { return new Random(32).nextInt(); }
+    public int m33() { return new Random(33).nextInt(); }
+    public int m34() { return new Random(34).nextInt(); }
+    public int m35() { return new Random(35).nextInt(); }
+    public int m36() { return new Random(36).nextInt(); }
+    public int m37() { return new Random(37).nextInt(); }
+    public int m38() { return new Random(38).nextInt(); }
+    public int m39() { return new Random(39).nextInt(); }
+    public int m40() { return new Random(40).nextInt(); }
+    public int m41() { return new Random(41).nextInt(); }
+    public int m42() { return new Random(42).nextInt(); }
+    public int m43() { return new Random(43).nextInt(); }
+    public int m44() { return new Random(44).nextInt(); }
+    public int m45() { return new Random(45).nextInt(); }
+    public int m46() { return new Random(46).nextInt(); }
+    public int m47() { return new Random(47).nextInt(); }
+    public int m48() { return new Random(48).nextInt(); }
+    public int m49() { return new Random(49).nextInt(); }
+    public int m50() { return new Random(50).nextInt(); }
+    public int m51() { return new Random(51).nextInt(); }
+    public int m52() { return new Random(52).nextInt(); }
+    public int m53() { return new Random(53).nextInt(); }
+    public int m54() { return new Random(54).nextInt(); }
+    public int m55() { return new Random(55).nextInt(); }
+    public int m56() { return new Random(56).nextInt(); }
+    public int m57() { return new Random(57).nextInt(); }
+    public int m58() { return new Random(58).nextInt(); }
+    public int m59() { return new Random(59).nextInt(); }
+    public int m60() { return new Random(60).nextInt(); }
+    public int m61() { return new Random(61).nextInt(); }
+    public int m62() { return new Random(62).nextInt(); }
+    public int m63() { return new Random(63).nextInt(); }
+    public int m64() { return new Random(64).nextInt(); }
+    public int m65() { return new Random(65).nextInt(); }
+    public int m66() { return new Random(66).nextInt(); }
+    public int m67() { return new Random(67).nextInt(); }
+    public int m68() { return new Random(68).nextInt(); }
+    public int m69() { return new Random(69).nextInt(); }
+    public int m70() { return new Random(70).nextInt(); }
+    public int m71() { return new Random(71).nextInt(); }
+    public int m72() { return new Random(72).nextInt(); }
+    public int m73() { return new Random(73).nextInt(); }
+    public int m74() { return new Random(74).nextInt(); }
+    public int m75() { return new Random(75).nextInt(); }
+    public int m76() { return new Random(76).nextInt(); }
+    public int m77() { return new Random(77).nextInt(); }
+    public int m78() { return new Random(78).nextInt(); }
+    public int m79() { return new Random(79).nextInt(); }
+    public int m80() { return new Random(80).nextInt(); }
+    public int m81() { return new Random(81).nextInt(); }
+    public int m82() { return new Random(82).nextInt(); }
+    public int m83() { return new Random(83).nextInt(); }
+    public int m84() { return new Random(84).nextInt(); }
+    public int m85() { return new Random(85).nextInt(); }
+    public int m86() { return new Random(86).nextInt(); }
+    public int m87() { return new Random(87).nextInt(); }
+    public int m88() { return new Random(88).nextInt(); }
+    public int m89() { return new Random(89).nextInt(); }
+    public int m90() { return new Random(90).nextInt(); }
+    public int m91() { return new Random(91).nextInt(); }
+    public int m92() { return new Random(92).nextInt(); }
+    public int m93() { return new Random(93).nextInt(); }
+    public int m94() { return new Random(94).nextInt(); }
+    public int m95() { return new Random(95).nextInt(); }
+    public int m96() { return new Random(96).nextInt(); }
+    public int m97() { return new Random(97).nextInt(); }
+    public int m98() { return new Random(98).nextInt(); }
+    public int m99() { return new Random(99).nextInt(); }
+
 }
diff --git a/hostsidetests/compilation/assets/CtsCompilationApp.apk b/hostsidetests/compilation/assets/CtsCompilationApp.apk
new file mode 100644
index 0000000..06a05af
--- /dev/null
+++ b/hostsidetests/compilation/assets/CtsCompilationApp.apk
Binary files differ
diff --git a/hostsidetests/compilation/assets/README.txt b/hostsidetests/compilation/assets/README.txt
new file mode 100644
index 0000000..896e5be
--- /dev/null
+++ b/hostsidetests/compilation/assets/README.txt
@@ -0,0 +1,11 @@
+This APK and profile file are generated from CompilationTargetActivity.java and must be
+updated if that file changes:
+
+$ (croot ; make CtsCompilationApp)
+$ cp ${ANDROID_BUILD_TOP}/out/target/product/${TARGET_PRODUCT}/data/app/CtsCompilationApp/CtsCompilationApp.apk .
+$ adb install CtsCompilationApp.apk
+
+  # Now run the app manually for a couple of minutes, look for it:
+$ adb shell ls -l /data/misc/profiles/cur/0/android.cts.compilation/primary.prof
+  # once the profile appears and is nonempty, grab it:
+$ adb pull /data/misc/profiles/cur/0/android.cts.compilation/primary.prof ./primary.prof
diff --git a/hostsidetests/compilation/assets/primary.prof b/hostsidetests/compilation/assets/primary.prof
new file mode 100644
index 0000000..a8dab63
--- /dev/null
+++ b/hostsidetests/compilation/assets/primary.prof
Binary files differ
diff --git a/hostsidetests/compilation/src/android/cts/compilation/CompilationTest.java b/hostsidetests/compilation/src/android/cts/compilation/CompilationTest.java
index 3e673ea..60abf6d 100644
--- a/hostsidetests/compilation/src/android/cts/compilation/CompilationTest.java
+++ b/hostsidetests/compilation/src/android/cts/compilation/CompilationTest.java
@@ -16,37 +16,172 @@
 
 package android.cts.compilation;
 
+import com.google.common.io.ByteStreams;
+import com.google.common.io.Files;
+
 import com.android.tradefed.device.DeviceNotAvailableException;
 import com.android.tradefed.device.ITestDevice;
 import com.android.tradefed.testtype.DeviceTestCase;
 
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.util.ArrayList;
 import java.util.Arrays;
+import java.util.List;
 import java.util.Locale;
 import java.util.regex.Matcher;
 import java.util.regex.Pattern;
 
+/**
+ * Tests that profile guided compilation succeeds regardless of whether a runtime
+ * profile of the target application is present on the device.
+ */
 public class CompilationTest extends DeviceTestCase {
     private static final String APPLICATION_PACKAGE = "android.cts.compilation";
 
+    enum ProfileLocation {
+        CUR("/data/misc/profiles/cur/0/" + APPLICATION_PACKAGE),
+        REF("/data/misc/profiles/ref/" + APPLICATION_PACKAGE);
+
+        private String directory;
+
+        ProfileLocation(String directory) {
+            this.directory = directory;
+        }
+
+        public String getDirectory() {
+            return directory;
+        }
+
+        public String getPath() {
+            return directory + "/primary.prof";
+        }
+    }
+
     private ITestDevice mDevice;
+    private byte[] profileBytes;
+    private File localProfileFile;
+    private String odexFilePath;
+    private byte[] initialOdexFileContents;
+    private File apkFile;
 
     @Override
     protected void setUp() throws Exception {
         super.setUp();
         mDevice = getDevice();
         mDevice.executeAdbCommand("root");
+        apkFile = File.createTempFile("CtsCompilationApp", ".apk");
+        try (OutputStream outputStream = new FileOutputStream(apkFile)) {
+            InputStream inputStream = getClass().getResourceAsStream("/CtsCompilationApp.apk");
+            ByteStreams.copy(inputStream, outputStream);
+        }
+        mDevice.uninstallPackage(APPLICATION_PACKAGE); // in case it's still installed
+        mDevice.installPackage(apkFile, false);
+
+        // Load snapshot of file contents from {@link ProfileLocation#CUR} after
+        // manually running the target application manually for a few minutes.
+        profileBytes = ByteStreams.toByteArray(getClass().getResourceAsStream("/primary.prof"));
+        localProfileFile = File.createTempFile("compilationtest", "prof");
+        Files.write(profileBytes, localProfileFile);
+        assertTrue("empty profile", profileBytes.length > 0); // sanity check
+
+        // ensure no profiles initially present
+        for (ProfileLocation profileLocation : ProfileLocation.values()) {
+            String clientPath = profileLocation.getPath();
+            if (mDevice.doesFileExist(clientPath)) {
+                executeAdbCommand(0, "shell", "rm", clientPath);
+            }
+        }
+        executeCompile(/* force */ true);
+        this.odexFilePath = getOdexFilePath();
+        this.initialOdexFileContents = readFileOnClient(odexFilePath);
+        assertTrue("empty odex file", initialOdexFileContents.length > 0); // sanity check
+    }
+
+    @Override
+    protected void tearDown() throws Exception {
+        localProfileFile.delete();
+        mDevice.uninstallPackage(APPLICATION_PACKAGE);
+        super.tearDown();
+    }
+
+    /*
+     The tests below test the remaining combinations of the "ref" (reference) and
+     "cur" (current) profile being available. The "cur" profile gets moved/merged
+     into the "ref" profile when it differs enough; as of 2016-05-10, "differs
+     enough" is based on number of methods and classes in profile_assistant.cc.
+
+     No nonempty profile exists right after an app is installed.
+     Once the app runs, a profile will get collected in "cur" first but
+     may make it to "ref" later. While the profile is being processed by
+     profile_assistant, it may only be available in "ref".
+     */
+
+    public void testForceCompile_noProfile() throws Exception {
+        compileWithProfilesAndCheckFilter();
+        byte[] odexFileContents = readFileOnClient(odexFilePath);
+        assertBytesEqual(initialOdexFileContents, odexFileContents);
+    }
+
+    public void testForceCompile_curProfile() throws Exception {
+        if (!isUseJitProfiles()) {
+            return;
+        }
+        compileWithProfilesAndCheckFilter(ProfileLocation.CUR);
+        assertTrue("ref profile should have been created by the compiler",
+                mDevice.doesFileExist(ProfileLocation.REF.getPath()));
+        assertFalse("odex compiled with cur profile should differ from the initial one without",
+                Arrays.equals(initialOdexFileContents, readFileOnClient(odexFilePath)));
+    }
+
+    public void testForceCompile_refProfile() throws Exception {
+        if (!isUseJitProfiles()) {
+            return;
+        }
+        compileWithProfilesAndCheckFilter(ProfileLocation.REF);
+        // We assume that the compiler isn't smart enough to realize that the
+        // previous odex was compiled before the ref profile was in place, even
+        // though theoretically it could be.
+        byte[] odexFileContents = readFileOnClient(odexFilePath);
+        assertBytesEqual(initialOdexFileContents, odexFileContents);
+    }
+
+    public void testForceCompile_curAndRefProfile() throws Exception {
+        if (!isUseJitProfiles()) {
+            return;
+        }
+        compileWithProfilesAndCheckFilter(ProfileLocation.CUR, ProfileLocation.REF);
+        // We assume that the compiler isn't smart enough to realize that the
+        // previous odex was compiled before the ref profile was in place, even
+        // though theoretically it could be.
+        byte[] odexFileContents = readFileOnClient(odexFilePath);
+        assertBytesEqual(initialOdexFileContents, odexFileContents);
+    }
+
+    private byte[] readFileOnClient(String clientPath) throws Exception {
+        assertTrue("File not found on client: " + clientPath,
+                mDevice.doesFileExist(clientPath));
+        File copyOnHost = File.createTempFile("host", "copy");
+        try {
+            executeAdbCommand("pull", clientPath, copyOnHost.getPath());
+            return Files.toByteArray(copyOnHost);
+        } finally {
+            boolean successIgnored = copyOnHost.delete();
+        }
     }
 
     /**
-     * Tests the case where no profile is available because the app has never run.
+     * Places {@link #profileBytes} in the specified locations, recompiles (without -f)
+     * and checks the compiler-filter in the odex file.
      */
-    public void testForceCompile_noProfileAvailable() throws Exception {
-        String stdoutContents = mDevice.executeAdbCommand("shell", "cmd", "package", "compile",
-                "-m", "speed-profile", "-f", APPLICATION_PACKAGE);
-        assertEquals("Success\n", stdoutContents);
-
-        // Find location of the base.odex file
-        String odexFilePath = getOdexFilePath();
+    private void compileWithProfilesAndCheckFilter(ProfileLocation... profileLocations)
+            throws Exception {
+        for (ProfileLocation profileLocation : profileLocations) {
+            writeProfile(profileLocation);
+        }
+        executeCompile(/* force */ false);
 
         // Confirm the compiler-filter used in creating the odex file
         String compilerFilter = getCompilerFilter(odexFilePath);
@@ -55,6 +190,44 @@
     }
 
     /**
+     * Invokes the dex2oat compiler on the client.
+     */
+    private void executeCompile(boolean force) throws Exception {
+        List<String> command = new ArrayList<>(Arrays.asList("shell", "cmd", "package", "compile",
+                "-m", "speed-profile"));
+        if (force) {
+            command.add("-f");
+        }
+        command.add(APPLICATION_PACKAGE);
+        String[] commandArray = command.toArray(new String[0]);
+        assertEquals("Success", executeAdbCommand(1, commandArray)[0]);
+    }
+
+    /**
+     * Copies {@link #localProfileFile} to the specified location on the client device.
+     */
+    private void writeProfile(ProfileLocation location) throws Exception {
+        String targetPath = location.getPath();
+        // Get the owner of the parent directory so we can set it on the file
+        String targetDir = location.getDirectory();
+        if (!mDevice.doesFileExist(targetDir)) {
+            fail("Not found: " + targetPath);
+        }
+        // in format group:user so we can directly pass it to chown
+        String owner = executeAdbCommand(1, "shell", "stat", "-c", "%U:%g", targetDir)[0];
+        // for some reason, I've observed the output starting with a single space
+        while (owner.startsWith(" ")) {
+            owner = owner.substring(1);
+        }
+        mDevice.executeAdbCommand("push", localProfileFile.getAbsolutePath(), targetPath);
+        executeAdbCommand(0, "shell", "chown", owner, targetPath);
+        // Verify that the file was written successfully
+        assertTrue("failed to create profile file", mDevice.doesFileExist(targetPath));
+        assertEquals(Integer.toString(profileBytes.length),
+                executeAdbCommand(1, "shell", "stat", "-c", "%s", targetPath)[0]);
+    }
+
+    /**
      * Parses the value for the key "compiler-filter" out of the output from
      * {@code oatdump --header-only}.
      */
@@ -89,6 +262,17 @@
         return result;
     }
 
+    /**
+     * Returns whether JIT profiles are enabled on this client. If not, the tests
+     * that rely on profiles cannot run.
+     * TODO: Use Assume.assumeTrue() if this test gets converted to JUnit 4.
+     */
+    private boolean isUseJitProfiles() throws Exception {
+        boolean propUseJitProfiles = Boolean.parseBoolean(
+                executeAdbCommand(1, "shell", "getprop", "dalvik.vm.usejitprofiles")[0]);
+        return propUseJitProfiles;
+    }
+
     private String[] executeAdbCommand(int numLinesOutputExpected, String... command)
             throws DeviceNotAvailableException {
         String[] lines = executeAdbCommand(command);
@@ -106,4 +290,10 @@
         String[] lines = output.equals("") ? new String[0] : output.split("\n");
         return lines;
     }
+
+    private static void assertBytesEqual(byte[] expected, byte[] actual) {
+        String msg = String.format("Expected %d bytes differ from actual %d bytes",
+                expected.length, actual.length);
+        assertTrue(msg, Arrays.equals(expected, actual));
+    }
 }
diff --git a/hostsidetests/cpptools/src/com/android/cts/cpptools/RunAsHostTest.java b/hostsidetests/cpptools/src/com/android/cts/cpptools/RunAsHostTest.java
index ae472de..231ca83 100644
--- a/hostsidetests/cpptools/src/com/android/cts/cpptools/RunAsHostTest.java
+++ b/hostsidetests/cpptools/src/com/android/cts/cpptools/RunAsHostTest.java
@@ -35,7 +35,7 @@
         String runAsResult = getDevice().executeShellCommand("run-as android.cpptools.app id -u");
         assertNotNull("adb shell command failed", runAsResult);
         runAsResult = runAsResult.trim();
-        Matcher appIdMatcher = Pattern.compile("^uid=([0-9]+).*$").matcher(runAsResult);
+        Matcher appIdMatcher = Pattern.compile("^([0-9]+)$").matcher(runAsResult);
         assertTrue("unexpected result returned by adb shell command: \"" + runAsResult + "\"",
                    appIdMatcher.matches());
         String appIdString = appIdMatcher.group(1);
diff --git a/hostsidetests/dumpsys/src/android/dumpsys/cts/DumpsysHostTest.java b/hostsidetests/dumpsys/src/android/dumpsys/cts/DumpsysHostTest.java
index e9b08a4..fee107e 100644
--- a/hostsidetests/dumpsys/src/android/dumpsys/cts/DumpsysHostTest.java
+++ b/hostsidetests/dumpsys/src/android/dumpsys/cts/DumpsysHostTest.java
@@ -128,11 +128,15 @@
     }
 
     private void checkPeriod(String[] parts) {
-        assertEquals(5, parts.length);
+        assertTrue("Expected 5 or 6, found: " + parts.length,
+                parts.length == 5 || parts.length == 6);
         assertNotNull(parts[1]); // date
         assertInteger(parts[2]); // start time (msec)
         assertInteger(parts[3]); // end time (msec)
         assertNotNull(parts[4]); // status
+        if (parts.length == 6) {
+            assertNotNull(parts[5]); // swapped-out-pss
+        }
     }
 
     private void checkPkgProc(String[] parts, int version) {
diff --git a/hostsidetests/net/app/src/com/android/cts/net/hostside/AbstractAppIdleTestCase.java b/hostsidetests/net/app/src/com/android/cts/net/hostside/AbstractAppIdleTestCase.java
new file mode 100644
index 0000000..13ce6ce
--- /dev/null
+++ b/hostsidetests/net/app/src/com/android/cts/net/hostside/AbstractAppIdleTestCase.java
@@ -0,0 +1,119 @@
+/*
+ * 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.net.hostside;
+
+/**
+ * Base class for metered and non-metered tests on idle apps.
+ */
+abstract class AbstractAppIdleTestCase extends AbstractRestrictBackgroundNetworkTestCase {
+
+    @Override
+    protected final void setUp() throws Exception {
+        super.setUp();
+
+        // Set initial state.
+        setUpMeteredNetwork();
+        removePowerSaveModeWhitelist(TEST_APP2_PKG);
+        setAppIdle(false);
+        turnBatteryOff();
+
+        registerBroadcastReceiver();
+    }
+
+    @Override
+    protected final void tearDown() throws Exception {
+        super.tearDown();
+
+        try {
+            tearDownMeteredNetwork();
+        } finally {
+            turnBatteryOn();
+            setAppIdle(false);
+        }
+    }
+
+    /**
+     * Sets the initial (non) metered network state.
+     *
+     * <p>By default is empty - it's up to subclasses to override.
+     */
+    protected void setUpMeteredNetwork() throws Exception {
+    }
+
+    /**
+     * Resets the (non) metered network state.
+     *
+     * <p>By default is empty - it's up to subclasses to override.
+     */
+    protected void tearDownMeteredNetwork() throws Exception {
+    }
+
+    public void testBackgroundNetworkAccess_enabled() throws Exception {
+        setAppIdle(true);
+        assertBackgroundNetworkAccess(false);
+
+        assertsForegroundAlwaysHasNetworkAccess();
+        setAppIdle(true);
+        assertBackgroundNetworkAccess(false);
+
+        // Make sure foreground app doesn't lose access upon enabling it.
+        setAppIdle(true);
+        launchActivity();
+        assertAppIdle(false); // Sanity check - not idle anymore, since activity was launched...
+        assertForegroundNetworkAccess();
+        finishActivity();
+        assertAppIdle(false); // Sanity check - not idle anymore, since activity was launched...
+        assertBackgroundNetworkAccess(true);
+        setAppIdle(true);
+        assertBackgroundNetworkAccess(false);
+
+        // Same for foreground service.
+        setAppIdle(true);
+        startForegroundService();
+        assertAppIdle(true); // Sanity check - still idle
+        assertForegroundServiceNetworkAccess();
+        stopForegroundService();
+        assertAppIdle(true);
+        assertBackgroundNetworkAccess(false);
+    }
+
+    public void testBackgroundNetworkAccess_whitelisted() throws Exception {
+        setAppIdle(true);
+        assertBackgroundNetworkAccess(false);
+
+        addPowerSaveModeWhitelist(TEST_APP2_PKG);
+        assertAppIdle(false); // Sanity check - not idle anymore, since whitelisted
+        assertBackgroundNetworkAccess(true);
+
+        removePowerSaveModeWhitelist(TEST_APP2_PKG);
+        assertAppIdle(true); // Sanity check - idle again, once whitelisted was removed
+        assertBackgroundNetworkAccess(false);
+
+        assertsForegroundAlwaysHasNetworkAccess();
+
+        // Sanity check - no whitelist, no access!
+        setAppIdle(true);
+        assertBackgroundNetworkAccess(false);
+    }
+
+    public void testBackgroundNetworkAccess_disabled() throws Exception {
+        assertBackgroundNetworkAccess(true);
+
+        assertsForegroundAlwaysHasNetworkAccess();
+        assertBackgroundNetworkAccess(true);
+    }
+}
diff --git a/hostsidetests/net/app/src/com/android/cts/net/hostside/BatterySaverModeTest.java b/hostsidetests/net/app/src/com/android/cts/net/hostside/AbstractBatterySaverModeTestCase.java
similarity index 68%
rename from hostsidetests/net/app/src/com/android/cts/net/hostside/BatterySaverModeTest.java
rename to hostsidetests/net/app/src/com/android/cts/net/hostside/AbstractBatterySaverModeTestCase.java
index 22b876a..2acc670 100644
--- a/hostsidetests/net/app/src/com/android/cts/net/hostside/BatterySaverModeTest.java
+++ b/hostsidetests/net/app/src/com/android/cts/net/hostside/AbstractBatterySaverModeTestCase.java
@@ -16,60 +16,78 @@
 
 package com.android.cts.net.hostside;
 
-//TODO: move this and BatterySaverModeNonMeteredTest's logic into a common superclass
-public class BatterySaverModeTest extends AbstractRestrictBackgroundNetworkTestCase {
+/**
+ * Base class for metered and non-metered Battery Saver Mode tests.
+ */
+abstract class AbstractBatterySaverModeTestCase extends AbstractRestrictBackgroundNetworkTestCase {
 
     @Override
-    public void setUp() throws Exception {
+    protected final void setUp() throws Exception {
         super.setUp();
 
         // Set initial state.
-        setMeteredNetwork();
+        setUpMeteredNetwork();
         removePowerSaveModeWhitelist(TEST_APP2_PKG);
-        setPowerSaveMode(false);
+        setBatterySaverMode(false);
 
         registerBroadcastReceiver();
     }
 
     @Override
-    protected void tearDown() throws Exception {
+    protected final void tearDown() throws Exception {
         super.tearDown();
 
         try {
-            resetMeteredNetwork();
+            tearDownMeteredNetwork();
         } finally {
-            setPowerSaveMode(false);
+            setBatterySaverMode(false);
         }
     }
 
+    /**
+     * Sets the initial (non) metered network state.
+     *
+     * <p>By default is empty - it's up to subclasses to override.
+     */
+    protected void setUpMeteredNetwork() throws Exception {
+    }
+
+    /**
+     * Resets the (non) metered network state.
+     *
+     * <p>By default is empty - it's up to subclasses to override.
+     */
+    protected void tearDownMeteredNetwork() throws Exception {
+    }
+
     public void testBackgroundNetworkAccess_enabled() throws Exception {
-        setPowerSaveMode(true);
+        setBatterySaverMode(true);
         assertBackgroundNetworkAccess(false);
 
         assertsForegroundAlwaysHasNetworkAccess();
         assertBackgroundNetworkAccess(false);
 
         // Make sure foreground app doesn't lose access upon enabling it.
-        setPowerSaveMode(false);
+        setBatterySaverMode(false);
         launchActivity();
         assertForegroundNetworkAccess();
-        setPowerSaveMode(true);
+        setBatterySaverMode(true);
         assertForegroundNetworkAccess();
         finishActivity();
         assertBackgroundNetworkAccess(false);
 
         // Same for foreground service.
-        setPowerSaveMode(false);
+        setBatterySaverMode(false);
         startForegroundService();
         assertForegroundNetworkAccess();
-        setPowerSaveMode(true);
+        setBatterySaverMode(true);
         assertForegroundNetworkAccess();
         stopForegroundService();
         assertBackgroundNetworkAccess(false);
     }
 
     public void testBackgroundNetworkAccess_whitelisted() throws Exception {
-        setPowerSaveMode(true);
+        setBatterySaverMode(true);
         assertBackgroundNetworkAccess(false);
 
         addPowerSaveModeWhitelist(TEST_APP2_PKG);
diff --git a/hostsidetests/net/app/src/com/android/cts/net/hostside/AbstractDozeModeTestCase.java b/hostsidetests/net/app/src/com/android/cts/net/hostside/AbstractDozeModeTestCase.java
new file mode 100644
index 0000000..f3c4935
--- /dev/null
+++ b/hostsidetests/net/app/src/com/android/cts/net/hostside/AbstractDozeModeTestCase.java
@@ -0,0 +1,111 @@
+/*
+ * 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.net.hostside;
+
+/**
+ * Base class for metered and non-metered Doze Mode tests.
+ */
+abstract class AbstractDozeModeTestCase extends AbstractRestrictBackgroundNetworkTestCase {
+
+    @Override
+    protected final void setUp() throws Exception {
+        super.setUp();
+
+        // Set initial state.
+        setUpMeteredNetwork();
+        removePowerSaveModeWhitelist(TEST_APP2_PKG);
+        setDozeMode(false);
+
+        registerBroadcastReceiver();
+    }
+
+    @Override
+    protected final void tearDown() throws Exception {
+        super.tearDown();
+
+        try {
+            tearDownMeteredNetwork();
+        } finally {
+            setDozeMode(false);
+        }
+    }
+
+    /**
+     * Sets the initial (non) metered network state.
+     *
+     * <p>By default is empty - it's up to subclasses to override.
+     */
+    protected void setUpMeteredNetwork() throws Exception {
+    }
+
+    /**
+     * Resets the (non) metered network state.
+     *
+     * <p>By default is empty - it's up to subclasses to override.
+     */
+    protected void tearDownMeteredNetwork() throws Exception {
+    }
+
+    public void testBackgroundNetworkAccess_enabled() throws Exception {
+        setDozeMode(true);
+        assertBackgroundNetworkAccess(false);
+
+        assertsForegroundAlwaysHasNetworkAccess();
+        assertBackgroundNetworkAccess(false);
+
+        // Make sure foreground service doesn't lose network access upon enabling doze.
+        setDozeMode(false);
+        startForegroundService();
+        assertForegroundNetworkAccess();
+        setDozeMode(true);
+        assertForegroundNetworkAccess();
+        stopForegroundService();
+        assertBackgroundState();
+        assertBackgroundNetworkAccess(false);
+    }
+
+    public void testBackgroundNetworkAccess_whitelisted() throws Exception {
+        setDozeMode(true);
+        assertBackgroundNetworkAccess(false);
+
+        addPowerSaveModeWhitelist(TEST_APP2_PKG);
+        assertBackgroundNetworkAccess(true);
+
+        removePowerSaveModeWhitelist(TEST_APP2_PKG);
+        assertBackgroundNetworkAccess(false);
+
+        assertsForegroundAlwaysHasNetworkAccess();
+        assertBackgroundNetworkAccess(false);
+    }
+
+    public void testBackgroundNetworkAccess_disabled() throws Exception {
+        assertBackgroundNetworkAccess(true);
+
+        assertsForegroundAlwaysHasNetworkAccess();
+        assertBackgroundNetworkAccess(true);
+    }
+
+    // Must override so it only tests foreground service - once an app goes to foreground, device
+    // leaves Doze Mode.
+    @Override
+    protected void assertsForegroundAlwaysHasNetworkAccess() throws Exception {
+        startForegroundService();
+        assertForegroundServiceNetworkAccess();
+        stopForegroundService();
+        assertBackgroundState();
+    }
+}
diff --git a/hostsidetests/net/app/src/com/android/cts/net/hostside/AbstractRestrictBackgroundNetworkTestCase.java b/hostsidetests/net/app/src/com/android/cts/net/hostside/AbstractRestrictBackgroundNetworkTestCase.java
index f2a69f2..17480e2 100644
--- a/hostsidetests/net/app/src/com/android/cts/net/hostside/AbstractRestrictBackgroundNetworkTestCase.java
+++ b/hostsidetests/net/app/src/com/android/cts/net/hostside/AbstractRestrictBackgroundNetworkTestCase.java
@@ -80,7 +80,7 @@
     private String mMeteredWifi;
 
     @Override
-    public void setUp() throws Exception {
+    protected void setUp() throws Exception {
         super.setUp();
 
         mInstrumentation = getInstrumentation();
@@ -329,7 +329,12 @@
      */
     protected void assertDelayedShellCommand(String command, final String expectedResult)
             throws Exception {
-        assertDelayedShellCommand(command, new ExpectResultChecker() {
+        assertDelayedShellCommand(command, 5, 1, expectedResult);
+    }
+
+    protected void assertDelayedShellCommand(String command, int maxTries, int napTimeSeconds,
+            final String expectedResult) throws Exception {
+        assertDelayedShellCommand(command, maxTries, napTimeSeconds, new ExpectResultChecker() {
 
             @Override
             public boolean isExpected(String result) {
@@ -345,21 +350,28 @@
 
     protected void assertDelayedShellCommand(String command, ExpectResultChecker checker)
             throws Exception {
-        final int maxTries = 5;
+        assertDelayedShellCommand(command, 5, 1, checker);
+    }
+    protected void assertDelayedShellCommand(String command, int maxTries, int napTimeSeconds,
+            ExpectResultChecker checker) throws Exception {
         String result = "";
         for (int i = 1; i <= maxTries; i++) {
             result = executeShellCommand(command).trim();
             if (checker.isExpected(result)) return;
             Log.v(TAG, "Command '" + command + "' returned '" + result + " instead of '"
                     + checker.getExpected() + "' on attempt #" + i
-                    + "; sleeping 1s before trying again");
-            Thread.sleep(SECOND_IN_MS);
+                    + "; sleeping " + napTimeSeconds + "s before trying again");
+            Thread.sleep(napTimeSeconds * SECOND_IN_MS);
         }
         fail("Command '" + command + "' did not return '" + checker.getExpected() + "' after "
                 + maxTries
                 + " attempts. Last result: '" + result + "'");
     }
 
+    /**
+     * Puts the device in a state where the active network is metered, or fail if it can't achieve
+     * that state.
+     */
     protected void setMeteredNetwork() throws Exception {
         final NetworkInfo info = mCm.getActiveNetworkInfo();
         final boolean metered = mCm.isActiveNetworkMetered();
@@ -375,17 +387,37 @@
         mMeteredWifi = netId;
         // Sanity check.
         assertWifiMeteredStatus(netId, true);
-        assertTrue("Could not set wifi '" + netId + "' as metered ("
-                + mCm.getActiveNetworkInfo() +")", mCm.isActiveNetworkMetered());
+        assertActiveNetworkMetered(true);
     }
 
+    /**
+     * Puts the device in a state where the active network is not metered, or fail if it can't
+     * achieve that state.
+     * <p>It assumes the device has a valid WI-FI connection.
+     */
     protected void resetMeteredNetwork() throws Exception {
-        if (mMeteredWifi == null) {
-            Log.d(TAG, "resetMeteredNetwork(): wifi not set as metered");
-            return;
+        if (mMeteredWifi != null) {
+            Log.i(TAG, "resetMeteredNetwork(): SID '" + mMeteredWifi
+                    + "' was set as metered by test case; resetting it");
+            setWifiMeteredStatus(mMeteredWifi, false);
+        } else {
+            final NetworkInfo info = mCm.getActiveNetworkInfo();
+            assertNotNull("Could not get active network", info);
+            if (!info.isMetered()) {
+                Log.d(TAG, "Active network is not metered: " + info);
+            } else if (info.getType() == ConnectivityManager.TYPE_WIFI) {
+                Log.i(TAG, "Setting active WI-FI network as metered: " + info );
+                setWifiMeteredStatus(false);
+            } else {
+                fail("Active network is not WI-FI hence cannot be set as non-metered: " + info);
+            }
         }
-        Log.i(TAG, "resetMeteredNetwork(): resetting " + mMeteredWifi);
-        setWifiMeteredStatus(mMeteredWifi, false);
+        assertActiveNetworkMetered(false); // Sanity check.
+    }
+
+    private void assertActiveNetworkMetered(boolean expected) {
+        final NetworkInfo info = mCm.getActiveNetworkInfo();
+        assertEquals("Wrong metered status for active network " + info, expected, info.isMetered());
     }
 
     private String setWifiMeteredStatus(boolean metered) throws Exception {
@@ -512,16 +544,63 @@
         assertPowerSaveModeWhitelist(packageName, false); // Sanity check
     }
 
-    protected void setPowerSaveMode(boolean enabled) throws Exception {
-        Log.i(TAG, "Setting power mode to " + enabled);
+    protected void turnBatteryOff() throws Exception {
+        executeSilentShellCommand("cmd battery unplug");
+    }
+
+    protected void turnBatteryOn() throws Exception {
+        executeSilentShellCommand("cmd battery reset");
+    }
+
+    protected void turnScreenOff() throws Exception {
+        executeSilentShellCommand("input keyevent KEYCODE_SLEEP");
+    }
+
+    protected void turnScreenOn() throws Exception {
+        executeSilentShellCommand("input keyevent KEYCODE_WAKEUP");
+        executeSilentShellCommand("wm dismiss-keyguard");
+    }
+
+    protected void setBatterySaverMode(boolean enabled) throws Exception {
+        Log.i(TAG, "Setting Battery Saver Mode to " + enabled);
         if (enabled) {
+            turnBatteryOff();
             executeSilentShellCommand("cmd battery unplug");
             executeSilentShellCommand("settings put global low_power 1");
         } else {
-            executeSilentShellCommand("cmd battery reset");
+            turnBatteryOn();
         }
     }
 
+    protected void setDozeMode(boolean enabled) throws Exception {
+        Log.i(TAG, "Setting Doze Mode to " + enabled);
+        if (enabled) {
+            turnBatteryOff();
+            turnScreenOff();
+            executeShellCommand("dumpsys deviceidle force-idle deep");
+        } else {
+            turnScreenOn();
+            turnBatteryOn();
+            executeShellCommand("dumpsys deviceidle unforce");
+        }
+        // Sanity check.
+        assertDozeMode(enabled);
+    }
+
+    protected void assertDozeMode(boolean enabled) throws Exception {
+        assertDelayedShellCommand("dumpsys deviceidle get deep", enabled ? "IDLE" : "ACTIVE");
+    }
+
+    protected void setAppIdle(boolean enabled) throws Exception {
+        Log.i(TAG, "Setting app idle to " + enabled);
+        executeSilentShellCommand("am set-inactive " + TEST_APP2_PKG + " " + enabled );
+        assertAppIdle(enabled); // Sanity check
+    }
+
+    protected void assertAppIdle(boolean enabled) throws Exception {
+        assertDelayedShellCommand("am get-inactive " + TEST_APP2_PKG, 10, 2, "Idle=" + enabled);
+    }
+
     /**
      * Starts a service that will register a broadcast receiver to receive
      * {@code RESTRICT_BACKGROUND_CHANGE} intents.
@@ -548,19 +627,23 @@
 
     protected void startForegroundService() throws Exception {
         executeShellCommand(
-                "am startservice com.android.cts.net.hostside.app2/.MyForegroundService");
+                "am startservice -f 1 com.android.cts.net.hostside.app2/.MyForegroundService");
+        assertForegroundServiceState();
     }
 
     protected void stopForegroundService() throws Exception {
         executeShellCommand(
-                "am stopservice com.android.cts.net.hostside.app2/.MyForegroundService");
+                "am startservice -f 2 com.android.cts.net.hostside.app2/.MyForegroundService");
+        // NOTE: cannot assert state because it depends on whether activity was on top before.
     }
 
     /**
      * Launches an activity on app2 so its process is elevated to foreground status.
      */
     protected void launchActivity() throws Exception {
+        turnScreenOn();
         executeShellCommand("am start com.android.cts.net.hostside.app2/.MyActivity");
+        assertForegroundState();
     }
 
     /**
@@ -608,8 +691,17 @@
         }
     }
 
+    /**
+     * Helper class used to assert the result of a Shell command.
+     */
     protected static interface ExpectResultChecker {
+        /**
+         * Checkes whether the result of the command matched the expectation.
+         */
         boolean isExpected(String result);
+        /**
+         * Gets the expected result so it's displayed on log and failure messages.
+         */
         String getExpected();
     }
 }
diff --git a/hostsidetests/net/app/src/com/android/cts/net/hostside/AppIdleMeteredTest.java b/hostsidetests/net/app/src/com/android/cts/net/hostside/AppIdleMeteredTest.java
new file mode 100644
index 0000000..e008c69
--- /dev/null
+++ b/hostsidetests/net/app/src/com/android/cts/net/hostside/AppIdleMeteredTest.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.net.hostside;
+
+public class AppIdleMeteredTest extends AbstractAppIdleTestCase {
+
+    @Override
+    protected void setUpMeteredNetwork() throws Exception {
+        setMeteredNetwork();
+    }
+
+    @Override
+    protected void tearDownMeteredNetwork() throws Exception {
+        resetMeteredNetwork();
+    }
+}
diff --git a/hostsidetests/net/app/src/com/android/cts/net/hostside/AppIdleNonMeteredTest.java b/hostsidetests/net/app/src/com/android/cts/net/hostside/AppIdleNonMeteredTest.java
new file mode 100644
index 0000000..633dc81
--- /dev/null
+++ b/hostsidetests/net/app/src/com/android/cts/net/hostside/AppIdleNonMeteredTest.java
@@ -0,0 +1,25 @@
+/*
+ * 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.net.hostside;
+
+public class AppIdleNonMeteredTest extends AbstractAppIdleTestCase {
+
+    @Override
+    protected void setUpMeteredNetwork() throws Exception {
+        resetMeteredNetwork();
+    }
+}
diff --git a/hostsidetests/net/app/src/com/android/cts/net/hostside/BatterySaverModeMeteredTest.java b/hostsidetests/net/app/src/com/android/cts/net/hostside/BatterySaverModeMeteredTest.java
new file mode 100644
index 0000000..3a88bbd
--- /dev/null
+++ b/hostsidetests/net/app/src/com/android/cts/net/hostside/BatterySaverModeMeteredTest.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.net.hostside;
+
+public class BatterySaverModeMeteredTest extends AbstractBatterySaverModeTestCase {
+
+    @Override
+    protected void setUpMeteredNetwork() throws Exception {
+        setMeteredNetwork();
+    }
+
+    @Override
+    protected void tearDownMeteredNetwork() throws Exception {
+        resetMeteredNetwork();
+    }
+}
diff --git a/hostsidetests/net/app/src/com/android/cts/net/hostside/BatterySaverModeNonMeteredTest.java b/hostsidetests/net/app/src/com/android/cts/net/hostside/BatterySaverModeNonMeteredTest.java
index d1db01c..646c4b9 100644
--- a/hostsidetests/net/app/src/com/android/cts/net/hostside/BatterySaverModeNonMeteredTest.java
+++ b/hostsidetests/net/app/src/com/android/cts/net/hostside/BatterySaverModeNonMeteredTest.java
@@ -16,71 +16,10 @@
 
 package com.android.cts.net.hostside;
 
-//TODO: move this and BatterySaverModeTest's logic into a common superclass
-public class BatterySaverModeNonMeteredTest extends AbstractRestrictBackgroundNetworkTestCase {
+public class BatterySaverModeNonMeteredTest extends AbstractBatterySaverModeTestCase {
 
     @Override
-    public void setUp() throws Exception {
-        super.setUp();
-
-        // Set initial state.
-        removePowerSaveModeWhitelist(TEST_APP2_PKG);
-        setPowerSaveMode(false);
-
-        registerBroadcastReceiver();
-    }
-
-    @Override
-    protected void tearDown() throws Exception {
-        super.tearDown();
-
-        setPowerSaveMode(false);
-    }
-
-    public void testBackgroundNetworkAccess_enabled() throws Exception {
-        setPowerSaveMode(true);
-        assertBackgroundNetworkAccess(false);
-
-        assertsForegroundAlwaysHasNetworkAccess();
-        assertBackgroundNetworkAccess(false);
-
-        // Make sure foreground app doesn't lose access upon enabling it.
-        setPowerSaveMode(false);
-        launchActivity();
-        assertForegroundNetworkAccess();
-        setPowerSaveMode(true);
-        assertForegroundNetworkAccess();
-        finishActivity();
-        assertBackgroundNetworkAccess(false);
-
-        // Same for foreground service.
-        setPowerSaveMode(false);
-        startForegroundService();
-        assertForegroundNetworkAccess();
-        setPowerSaveMode(true);
-        assertForegroundNetworkAccess();
-        stopForegroundService();
-        assertBackgroundNetworkAccess(false);
-    }
-
-    public void testBackgroundNetworkAccess_whitelisted() throws Exception {
-        setPowerSaveMode(true);
-        assertBackgroundNetworkAccess(false);
-
-        addPowerSaveModeWhitelist(TEST_APP2_PKG);
-        assertBackgroundNetworkAccess(true);
-
-        removePowerSaveModeWhitelist(TEST_APP2_PKG);
-        assertBackgroundNetworkAccess(false);
-
-        assertsForegroundAlwaysHasNetworkAccess();
-        assertBackgroundNetworkAccess(false);
-    }
-
-    public void testBackgroundNetworkAccess_disabled() throws Exception {
-        assertBackgroundNetworkAccess(true);
-
-        assertsForegroundAlwaysHasNetworkAccess();
-        assertBackgroundNetworkAccess(true);
+    protected void setUpMeteredNetwork() throws Exception {
+        resetMeteredNetwork();
     }
 }
diff --git a/hostsidetests/net/app/src/com/android/cts/net/hostside/DozeModeMeteredTest.java b/hostsidetests/net/app/src/com/android/cts/net/hostside/DozeModeMeteredTest.java
new file mode 100644
index 0000000..656d274
--- /dev/null
+++ b/hostsidetests/net/app/src/com/android/cts/net/hostside/DozeModeMeteredTest.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.net.hostside;
+
+public class DozeModeMeteredTest extends AbstractDozeModeTestCase {
+
+    @Override
+    protected void setUpMeteredNetwork() throws Exception {
+        setMeteredNetwork();
+    }
+
+    @Override
+    protected void tearDownMeteredNetwork() throws Exception {
+        resetMeteredNetwork();
+    }
+}
diff --git a/hostsidetests/net/app/src/com/android/cts/net/hostside/DozeModeNonMeteredTest.java b/hostsidetests/net/app/src/com/android/cts/net/hostside/DozeModeNonMeteredTest.java
new file mode 100644
index 0000000..c761238
--- /dev/null
+++ b/hostsidetests/net/app/src/com/android/cts/net/hostside/DozeModeNonMeteredTest.java
@@ -0,0 +1,25 @@
+/*
+ * 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.net.hostside;
+
+public class DozeModeNonMeteredTest extends AbstractDozeModeTestCase {
+
+    @Override
+    protected void setUpMeteredNetwork() throws Exception {
+        resetMeteredNetwork();
+    }
+}
diff --git a/hostsidetests/net/app/src/com/android/cts/net/hostside/MixedModesTest.java b/hostsidetests/net/app/src/com/android/cts/net/hostside/MixedModesTest.java
index 140d135..c97a0f9 100644
--- a/hostsidetests/net/app/src/com/android/cts/net/hostside/MixedModesTest.java
+++ b/hostsidetests/net/app/src/com/android/cts/net/hostside/MixedModesTest.java
@@ -47,7 +47,7 @@
         try {
             setRestrictBackground(false);
         } finally {
-            setPowerSaveMode(false);
+            setBatterySaverMode(false);
         }
     }
 
@@ -60,7 +60,7 @@
 
         try {
             setRestrictBackground(true);
-            setPowerSaveMode(true);
+            setBatterySaverMode(true);
 
             Log.v(TAG, "Not whitelisted for any.");
             assertBackgroundNetworkAccess(false);
@@ -126,7 +126,7 @@
         }
         Log.i(TAG, "testDataAndBatterySaverModes_nonMeteredNetwork() tests");
         setRestrictBackground(true);
-        setPowerSaveMode(true);
+        setBatterySaverMode(true);
 
         Log.v(TAG, "Not whitelisted for any.");
         assertBackgroundNetworkAccess(false);
diff --git a/hostsidetests/net/app2/src/com/android/cts/net/hostside/app2/MyForegroundService.java b/hostsidetests/net/app2/src/com/android/cts/net/hostside/app2/MyForegroundService.java
index 1afc3d6..b88c45d 100644
--- a/hostsidetests/net/app2/src/com/android/cts/net/hostside/app2/MyForegroundService.java
+++ b/hostsidetests/net/app2/src/com/android/cts/net/hostside/app2/MyForegroundService.java
@@ -28,6 +28,9 @@
  */
 public class MyForegroundService extends Service {
 
+    private static final int FLAG_START_FOREGROUND = 1;
+    private static final int FLAG_STOP_FOREGROUND = 2;
+
     @Override
     public IBinder onBind(Intent intent) {
         return null;
@@ -35,10 +38,21 @@
 
     @Override
     public int onStartCommand(Intent intent, int flags, int startId) {
-        Log.d(TAG, "MyForegroundService.onStartCommand(): " + intent);
-        startForeground(42, new Notification.Builder(this)
-            .setSmallIcon(R.drawable.ic_dialog_alert) // any icon is fine
-            .build());
+        Log.v(TAG, "MyForegroundService.onStartCommand(): " + intent);
+        switch (intent.getFlags()) {
+            case FLAG_START_FOREGROUND:
+                Log.d(TAG, "Starting foreground");
+                startForeground(42, new Notification.Builder(this)
+                        .setSmallIcon(R.drawable.ic_dialog_alert) // any icon is fine
+                        .build());
+                break;
+            case FLAG_STOP_FOREGROUND:
+                Log.d(TAG, "Stopping foreground");
+                stopForeground(true);
+                break;
+            default:
+                Log.wtf(TAG, "Invalid flag on intent " + intent);
+        }
         return START_STICKY;
     }
 }
diff --git a/hostsidetests/net/src/com/android/cts/net/HostsideRestrictBackgroundNetworkTests.java b/hostsidetests/net/src/com/android/cts/net/HostsideRestrictBackgroundNetworkTests.java
index 1a8634e..8152e55 100644
--- a/hostsidetests/net/src/com/android/cts/net/HostsideRestrictBackgroundNetworkTests.java
+++ b/hostsidetests/net/src/com/android/cts/net/HostsideRestrictBackgroundNetworkTests.java
@@ -36,6 +36,10 @@
         uninstallPackage(TEST_APP2_PKG, true);
     }
 
+    /**************************
+     * Data Saver Mode tests. *
+     **************************/
+
     public void testDataSaverMode_disabled() throws Exception {
         runDeviceTests(TEST_PKG, TEST_PKG + ".DataSaverModeTest",
                 "testGetRestrictBackgroundStatus_disabled");
@@ -77,18 +81,22 @@
                 "testGetRestrictBackgroundStatus_requiredWhitelistedPackages");
     }
 
-    public void testBatterySaverMode_disabled() throws Exception {
-        runDeviceTests(TEST_PKG, TEST_PKG + ".BatterySaverModeTest",
+    /*****************************
+     * Battery Saver Mode tests. *
+     *****************************/
+
+    public void testBatterySaverModeMetered_disabled() throws Exception {
+        runDeviceTests(TEST_PKG, TEST_PKG + ".BatterySaverModeMeteredTest",
                 "testBackgroundNetworkAccess_disabled");
     }
 
-    public void testBatterySaverMode_whitelisted() throws Exception {
-        runDeviceTests(TEST_PKG, TEST_PKG + ".BatterySaverModeTest",
+    public void testBatterySaverModeMetered_whitelisted() throws Exception {
+        runDeviceTests(TEST_PKG, TEST_PKG + ".BatterySaverModeMeteredTest",
                 "testBackgroundNetworkAccess_whitelisted");
     }
 
-    public void testBatterySaverMode_enabled() throws Exception {
-        runDeviceTests(TEST_PKG, TEST_PKG + ".BatterySaverModeTest",
+    public void testBatterySaverModeMetered_enabled() throws Exception {
+        runDeviceTests(TEST_PKG, TEST_PKG + ".BatterySaverModeMeteredTest",
                 "testBackgroundNetworkAccess_enabled");
     }
 
@@ -118,6 +126,88 @@
                 "testBackgroundNetworkAccess_enabled");
     }
 
+    /*******************
+     * App idle tests. *
+     *******************/
+
+    public void testAppIdleMetered_disabled() throws Exception {
+        runDeviceTests(TEST_PKG, TEST_PKG + ".AppIdleMeteredTest",
+                "testBackgroundNetworkAccess_disabled");
+    }
+
+    public void testAppIdleMetered_whitelisted() throws Exception {
+        runDeviceTests(TEST_PKG, TEST_PKG + ".AppIdleMeteredTest",
+                "testBackgroundNetworkAccess_whitelisted");
+    }
+
+    public void testAppIdleMetered_enabled() throws Exception {
+        runDeviceTests(TEST_PKG, TEST_PKG + ".AppIdleMeteredTest",
+                "testBackgroundNetworkAccess_enabled");
+    }
+
+    // TODO: currently power-save mode and idle uses the same whitelist, so this test would be
+    // redundant (as it would be testing the same as testBatterySaverMode_reinstall())
+    //    public void testAppIdle_reinstall() throws Exception {
+    //    }
+
+    public void testAppIdleNonMetered_disabled() throws Exception {
+        runDeviceTests(TEST_PKG, TEST_PKG + ".AppIdleNonMeteredTest",
+                "testBackgroundNetworkAccess_disabled");
+    }
+
+    public void testAppIdleNonMetered_whitelisted() throws Exception {
+        runDeviceTests(TEST_PKG, TEST_PKG + ".AppIdleNonMeteredTest",
+                "testBackgroundNetworkAccess_whitelisted");
+    }
+
+    public void testAppIdleNonMetered_enabled() throws Exception {
+        runDeviceTests(TEST_PKG, TEST_PKG + ".AppIdleNonMeteredTest",
+                "testBackgroundNetworkAccess_enabled");
+    }
+
+    /********************
+     * Doze Mode tests. *
+     ********************/
+
+    public void testDozeModeMetered_disabled() throws Exception {
+        runDeviceTests(TEST_PKG, TEST_PKG + ".DozeModeMeteredTest",
+                "testBackgroundNetworkAccess_disabled");
+    }
+
+    public void testDozeModeMetered_whitelisted() throws Exception {
+        runDeviceTests(TEST_PKG, TEST_PKG + ".DozeModeMeteredTest",
+                "testBackgroundNetworkAccess_whitelisted");
+    }
+
+    public void testDozeModeMetered_enabled() throws Exception {
+        runDeviceTests(TEST_PKG, TEST_PKG + ".DozeModeMeteredTest",
+                "testBackgroundNetworkAccess_enabled");
+    }
+
+    // TODO: currently power-save mode and idle uses the same whitelist, so this test would be
+    // redundant (as it would be testing the same as testBatterySaverMode_reinstall())
+    //    public void testDozeMode_reinstall() throws Exception {
+    //    }
+
+    public void testDozeModeNonMetered_disabled() throws Exception {
+        runDeviceTests(TEST_PKG, TEST_PKG + ".DozeModeNonMeteredTest",
+                "testBackgroundNetworkAccess_disabled");
+    }
+
+    public void testDozeModeNonMetered_whitelisted() throws Exception {
+        runDeviceTests(TEST_PKG, TEST_PKG + ".DozeModeNonMeteredTest",
+                "testBackgroundNetworkAccess_whitelisted");
+    }
+
+    public void testDozeModeNonMetered_enabled() throws Exception {
+        runDeviceTests(TEST_PKG, TEST_PKG + ".DozeModeNonMeteredTest",
+                "testBackgroundNetworkAccess_enabled");
+    }
+
+    /**********************
+     * Mixed modes tests. *
+     **********************/
+
     public void testDataAndBatterySaverModes_meteredNetwork() throws Exception {
         runDeviceTests(TEST_PKG, TEST_PKG + ".MixedModesTest",
                 "testDataAndBatterySaverModes_meteredNetwork");
@@ -128,6 +218,10 @@
                 "testDataAndBatterySaverModes_nonMeteredNetwork");
     }
 
+    /*******************
+     * Helper methods. *
+     *******************/
+
     private void assertRestrictBackgroundWhitelist(int uid, boolean expected) throws Exception {
         final int max_tries = 5;
         boolean actual = false;
diff --git a/hostsidetests/os/src/android/os/cts/OsHostTests.java b/hostsidetests/os/src/android/os/cts/OsHostTests.java
index d9d3ca4..0c2141c 100644
--- a/hostsidetests/os/src/android/os/cts/OsHostTests.java
+++ b/hostsidetests/os/src/android/os/cts/OsHostTests.java
@@ -54,7 +54,7 @@
     private static final Pattern HOST_PATTERN = Pattern.compile(".*hosts:\"(.*?)\"");
     // domains that should be validated against given our test apk
     private static final String HOST_EXPLICIT = "explicit.example.com";
-    private static final String HOST_WILDCARD = "wildcard.tld";
+    private static final String HOST_WILDCARD = "*.wildcard.tld";
 
     /**
      * A reference to the device under test.
@@ -103,7 +103,7 @@
 
             String[] options = { AbiUtils.createAbiFlag(mAbi.getName()) };
 
-            mDevice.executeAdbCommand("logcat", "-c");
+            mDevice.clearLogcat();
 
             String installResult = getDevice().installPackage(getTestAppFile(HOST_VERIFICATION_APK),
                     false /* = reinstall? */, options);
@@ -123,9 +123,9 @@
                     final String hostgroup = m.group(1);
                     HashSet<String> allHosts = new HashSet<String>(
                             Arrays.asList(hostgroup.split(" ")));
-                    assertTrue(allHosts.size() == 2);
-                    assertTrue(allHosts.contains(HOST_EXPLICIT));
-                    assertTrue(allHosts.contains(HOST_WILDCARD));
+                    assertEquals(2, allHosts.size());
+                    assertTrue("AllHosts Contains: " + allHosts, allHosts.contains(HOST_EXPLICIT));
+                    assertTrue("AllHosts Contains: " + allHosts, allHosts.contains(HOST_WILDCARD));
                     foundVerifierOutput = true;
                     break;
                 }
diff --git a/hostsidetests/services/activitymanager/app/AndroidManifest.xml b/hostsidetests/services/activitymanager/app/AndroidManifest.xml
index 9170ebb..7ab6e33 100755
--- a/hostsidetests/services/activitymanager/app/AndroidManifest.xml
+++ b/hostsidetests/services/activitymanager/app/AndroidManifest.xml
@@ -106,8 +106,8 @@
                   <layout android:defaultWidth="240dp"
                           android:defaultHeight="160dp"
                           android:gravity="top|left"
-                          android:minimalWidth="100dp"
-                          android:minimalHeight="80dp"
+                          android:minWidth="100dp"
+                          android:minHeight="80dp"
                   />
         </activity>
         <activity android:name=".TopRightLayoutActivity"
@@ -117,8 +117,8 @@
                   <layout android:defaultWidth="25%"
                           android:defaultHeight="35%"
                           android:gravity="top|right"
-                          android:minimalWidth="100dp"
-                          android:minimalHeight="80dp"
+                          android:minWidth="100dp"
+                          android:minHeight="80dp"
                   />
         </activity>
         <activity android:name=".BottomLeftLayoutActivity"
@@ -128,8 +128,8 @@
                   <layout android:defaultWidth="25%"
                           android:defaultHeight="35%"
                           android:gravity="bottom|left"
-                          android:minimalWidth="100dp"
-                          android:minimalHeight="80dp"
+                          android:minWidth="100dp"
+                          android:minHeight="80dp"
                   />
         </activity>
         <activity android:name=".BottomRightLayoutActivity"
@@ -139,8 +139,8 @@
                   <layout android:defaultWidth="240dp"
                           android:defaultHeight="160dp"
                           android:gravity="bottom|right"
-                          android:minimalWidth="100dp"
-                          android:minimalHeight="80dp"
+                          android:minWidth="100dp"
+                          android:minHeight="80dp"
                   />
         </activity>
     </application>
diff --git a/hostsidetests/services/activitymanager/src/android/server/cts/ActivityAndWindowManagersState.java b/hostsidetests/services/activitymanager/src/android/server/cts/ActivityAndWindowManagersState.java
index 54892de..42349c0 100644
--- a/hostsidetests/services/activitymanager/src/android/server/cts/ActivityAndWindowManagersState.java
+++ b/hostsidetests/services/activitymanager/src/android/server/cts/ActivityAndWindowManagersState.java
@@ -334,8 +334,8 @@
                             + ", stackId=" + stackId, aTaskBounds, wTaskBounds);
 
                     if (compareTaskAndStackBounds && stackId != FREEFORM_WORKSPACE_STACK_ID) {
-                        int aTaskMinWidth = aTask.getMinimalWidth();
-                        int aTaskMinHeight = aTask.getMinimalHeight();
+                        int aTaskMinWidth = aTask.getMinWidth();
+                        int aTaskMinHeight = aTask.getMinHeight();
 
                         if (aTaskMinWidth == -1 || aTaskMinHeight == -1) {
                             // Minimal dimension(s) not set for task - it should be using defaults.
diff --git a/hostsidetests/services/activitymanager/src/android/server/cts/ActivityManagerManifestLayoutTests.java b/hostsidetests/services/activitymanager/src/android/server/cts/ActivityManagerManifestLayoutTests.java
index 527d670..2395e55 100644
--- a/hostsidetests/services/activitymanager/src/android/server/cts/ActivityManagerManifestLayoutTests.java
+++ b/hostsidetests/services/activitymanager/src/android/server/cts/ActivityManagerManifestLayoutTests.java
@@ -41,8 +41,8 @@
     private static final int DEFAULT_HEIGHT_DP = 160;
     private static final float DEFAULT_WIDTH_FRACTION = 0.25f;
     private static final float DEFAULT_HEIGHT_FRACTION = 0.35f;
-    private static final int MINIMAL_WIDTH_DP = 100;
-    private static final int MINIMAL_HEIGHT_DP = 80;
+    private static final int MIN_WIDTH_DP = 100;
+    private static final int MIN_HEIGHT_DP = 80;
 
     private static final int GRAVITY_VER_CENTER = 0x01;
     private static final int GRAVITY_VER_TOP    = 0x02;
@@ -87,7 +87,7 @@
         final String activityName = "BottomRightLayoutActivity";
 
         // Issue command to resize to <0,0,1,1>. We expect the size to be floored at
-        // MINIMAL_WIDTH_DPxMINIMAL_HEIGHT_DP.
+        // MIN_WIDTH_DPxMIN_HEIGHT_DP.
         if (stackId == FREEFORM_WORKSPACE_STACK_ID) {
             launchActivityInStack(activityName, stackId);
             resizeActivityTask(activityName, 0, 0, 1, 1);
@@ -97,12 +97,12 @@
         }
         getDisplayAndWindowState(activityName, false);
 
-        final int minimalWidth = dpToPx(MINIMAL_WIDTH_DP, mDisplay.getDpi());
-        final int minimalHeight = dpToPx(MINIMAL_HEIGHT_DP, mDisplay.getDpi());
+        final int minWidth = dpToPx(MIN_WIDTH_DP, mDisplay.getDpi());
+        final int minHeight = dpToPx(MIN_HEIGHT_DP, mDisplay.getDpi());
         final Rectangle containingRect = mWindowState.getContainingFrame();
 
-        Assert.assertEquals("Minimum width is incorrect", minimalWidth, containingRect.width);
-        Assert.assertEquals("Minimum height is incorrect", minimalHeight, containingRect.height);
+        Assert.assertEquals("Min width is incorrect", minWidth, containingRect.width);
+        Assert.assertEquals("Min height is incorrect", minHeight, containingRect.height);
     }
 
     private void testLayout(
diff --git a/hostsidetests/services/activitymanager/src/android/server/cts/ActivityManagerState.java b/hostsidetests/services/activitymanager/src/android/server/cts/ActivityManagerState.java
index e56c32f..fd80474 100644
--- a/hostsidetests/services/activitymanager/src/android/server/cts/ActivityManagerState.java
+++ b/hostsidetests/services/activitymanager/src/android/server/cts/ActivityManagerState.java
@@ -48,7 +48,7 @@
     private final Pattern mFocusedActivityPattern =
             Pattern.compile("mFocusedActivity\\: ActivityRecord\\{(.+) u(\\d+) (\\S+) (\\S+)\\}");
     private final Pattern mFocusedStackPattern =
-            Pattern.compile("mFocusedStack=ActivityStack\\{(.+) stackId=(\\d+), (.+)");
+            Pattern.compile("mFocusedStack=ActivityStack\\{(.+) stackId=(\\d+), (.+)\\}(.+)");
 
     private final Pattern[] mExtractStackExitPatterns =
             { mStackIdPattern, mFocusedActivityPattern, mFocusedStackPattern};
@@ -536,15 +536,15 @@
         protected static final Pattern FULLSCREEN_PATTERN = Pattern.compile("mFullscreen=(\\S+)");
         protected static final Pattern BOUNDS_PATTERN =
                 Pattern.compile("mBounds=Rect\\((\\d+), (\\d+) - (\\d+), (\\d+)\\)");
-        protected static final Pattern MINIMAL_WIDTH_PATTERN =
-                Pattern.compile("mMinimalWidth=(\\d+)");
-        protected static final Pattern MINIMAL_HEIGHT_PATTERN =
-                Pattern.compile("mMinimalHeight=(\\d+)");
+        protected static final Pattern MIN_WIDTH_PATTERN =
+                Pattern.compile("mMinWidth=(\\d+)");
+        protected static final Pattern MIN_HEIGHT_PATTERN =
+                Pattern.compile("mMinHeight=(\\d+)");
 
         protected boolean mFullscreen;
         protected Rectangle mBounds;
-        protected int mMinimalWidth = -1;
-        protected int mMinimalHeight = -1;
+        protected int mMinWidth = -1;
+        protected int mMinHeight = -1;
 
         boolean extractFullscreen(String line) {
             final Matcher matcher = FULLSCREEN_PATTERN.matcher(line);
@@ -580,15 +580,15 @@
         }
 
         boolean extractMinimalSize(String line) {
-            final Matcher minWidthMatcher = MINIMAL_WIDTH_PATTERN.matcher(line);
-            final Matcher minHeightMatcher = MINIMAL_HEIGHT_PATTERN.matcher(line);
+            final Matcher minWidthMatcher = MIN_WIDTH_PATTERN.matcher(line);
+            final Matcher minHeightMatcher = MIN_HEIGHT_PATTERN.matcher(line);
 
             if (minWidthMatcher.matches()) {
                 log(line);
-                mMinimalWidth = Integer.valueOf(minWidthMatcher.group(1));
+                mMinWidth = Integer.valueOf(minWidthMatcher.group(1));
             } else if (minHeightMatcher.matches()) {
                 log(line);
-                mMinimalHeight = Integer.valueOf(minHeightMatcher.group(1));
+                mMinHeight = Integer.valueOf(minHeightMatcher.group(1));
             } else {
                 return false;
             }
@@ -603,12 +603,12 @@
             return mFullscreen;
         }
 
-        int getMinimalWidth() {
-            return mMinimalWidth;
+        int getMinWidth() {
+            return mMinWidth;
         }
 
-        int getMinimalHeight() {
-            return mMinimalHeight;
+        int getMinHeight() {
+            return mMinHeight;
         }
     }
 
diff --git a/hostsidetests/sustainedperf/Android.mk b/hostsidetests/sustainedperf/Android.mk
new file mode 100644
index 0000000..22c6d45
--- /dev/null
+++ b/hostsidetests/sustainedperf/Android.mk
@@ -0,0 +1,31 @@
+# Copyright (C) 2014 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+LOCAL_PATH := $(call my-dir)
+
+include $(CLEAR_VARS)
+
+LOCAL_SRC_FILES := $(call all-java-files-under, src)
+
+LOCAL_MODULE_TAGS := tests
+
+# tag this module as a cts test artifact
+LOCAL_COMPATIBILITY_SUITE := cts
+
+LOCAL_MODULE := CtsSustainedPerformanceHostTestCases
+LOCAL_JAVA_LIBRARIES := cts-tradefed tradefed-prebuilt compatibility-host-util
+
+include $(BUILD_HOST_JAVA_LIBRARY)
+
+include $(call all-makefiles-under,$(LOCAL_PATH))
diff --git a/hostsidetests/sustainedperf/AndroidTest.xml b/hostsidetests/sustainedperf/AndroidTest.xml
new file mode 100644
index 0000000..ae5cc27
--- /dev/null
+++ b/hostsidetests/sustainedperf/AndroidTest.xml
@@ -0,0 +1,33 @@
+<?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.
+-->
+<configuration description="Config for CTS Sustained Performance host test cases">
+    <target_preparer class="com.android.compatibility.common.tradefed.targetprep.ApkInstaller">
+        <option name="cleanup-apks" value="true" />
+        <option name="test-file-name" value="CtsSustainedPerformanceTestCases.apk" />
+    </target_preparer>
+    <target_preparer class="com.android.compatibility.common.tradefed.targetprep.ApkInstaller">
+        <option name="cleanup-apks" value="true" />
+        <option name="test-file-name" value="CtsSustainedPerformanceDeviceTestApp.apk" />
+    </target_preparer>
+    <target_preparer class="com.android.compatibility.common.tradefed.targetprep.FilePusher">
+        <option name="cleanup" value="true" />
+        <option name="push" value="dhry->/data/local/tmp/dhry" />
+        <option name="append-bitness" value="true" />
+    </target_preparer>
+    <test class="com.android.compatibility.common.tradefed.testtype.JarHostTest" >
+        <option name="jar" value="CtsSustainedPerformanceHostTestCases.jar" />
+    </test>
+</configuration>
diff --git a/hostsidetests/sustainedperf/app/Android.mk b/hostsidetests/sustainedperf/app/Android.mk
new file mode 100644
index 0000000..41f61e4
--- /dev/null
+++ b/hostsidetests/sustainedperf/app/Android.mk
@@ -0,0 +1,37 @@
+# Copyright (C) 2014 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+LOCAL_PATH:= $(call my-dir)
+
+include $(CLEAR_VARS)
+
+# Don't include this package in any target
+LOCAL_MODULE_TAGS := tests
+# When built, explicitly put it in the data partition.
+LOCAL_MODULE_PATH := $(TARGET_OUT_DATA_APPS)
+
+LOCAL_DEX_PREOPT := false
+
+LOCAL_PROGUARD_ENABLED := disabled
+
+LOCAL_SRC_FILES := $(call all-java-files-under, src)
+
+# tag this module as a cts test artifact
+LOCAL_COMPATIBILITY_SUITE := cts
+
+LOCAL_PACKAGE_NAME := CtsSustainedPerformanceDeviceTestApp
+
+LOCAL_SDK_VERSION := current
+
+include $(BUILD_PACKAGE)
diff --git a/hostsidetests/sustainedperf/app/AndroidManifest.xml b/hostsidetests/sustainedperf/app/AndroidManifest.xml
new file mode 100755
index 0000000..eff4a7f
--- /dev/null
+++ b/hostsidetests/sustainedperf/app/AndroidManifest.xml
@@ -0,0 +1,31 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ * Copyright (C) 2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ -->
+
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+    package="android.test.app">
+
+    <application>
+        <activity android:name=".DeviceTestActivity" >
+            <intent-filter>
+                <action android:name="android.intent.action.MAIN" />
+                <category android:name="android.intent.category.LAUNCHER" />
+            </intent-filter>
+        </activity>
+    </application>
+
+</manifest>
+
diff --git a/hostsidetests/sustainedperf/app/src/android/test/app/DeviceTestActivity.java b/hostsidetests/sustainedperf/app/src/android/test/app/DeviceTestActivity.java
new file mode 100644
index 0000000..92b8f1d
--- /dev/null
+++ b/hostsidetests/sustainedperf/app/src/android/test/app/DeviceTestActivity.java
@@ -0,0 +1,36 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.test.app;
+
+import android.app.Activity;
+import android.os.Bundle;
+import android.util.Log;
+import android.os.PowerManager;
+import java.lang.Override;
+import android.content.Context;
+
+public class DeviceTestActivity extends Activity {
+
+    @Override
+    public void onCreate(Bundle icicle) {
+        super.onCreate(icicle);
+        PowerManager pm = (PowerManager) getSystemService(Context.POWER_SERVICE);
+        if (pm.isSustainedPerformanceModeSupported()) {
+            Log.i("DeviceTestActivity", "Sustained Performance Mode is supported\n");
+        }
+    }
+}
diff --git a/hostsidetests/sustainedperf/dhrystone/Android.mk b/hostsidetests/sustainedperf/dhrystone/Android.mk
new file mode 100644
index 0000000..4c6b53d
--- /dev/null
+++ b/hostsidetests/sustainedperf/dhrystone/Android.mk
@@ -0,0 +1,18 @@
+LOCAL_PATH:= $(call my-dir)
+
+## sources have been created from Drystone-2.1.sh with below command:
+# ./Drystone-2.1.sh
+# sed -i 's/printf ("  Ptr_Comp:          %d\\n", (int) /printf ("  Ptr_Comp:          %p\\n", /g' dhry_1.c
+# sed -i 's,^} /\* Proc_,return 0; } /\* Proc_,g' *.c
+
+include $(CLEAR_VARS)
+LOCAL_MODULE := dhry
+LOCAL_SRC_FILES := dhry_1.c dhry_2.c
+LOCAL_CFLAGS := -O3 -fno-inline-functions -DMSC_CLOCK -DCLK_TCK=1000000
+LOCAL_CFLAGS += -Wno-return-type -Wno-implicit-function-declaration -Wno-implicit-int
+# Include both the 32 and 64 bit versions
+LOCAL_MULTILIB := both
+LOCAL_MODULE_STEM_32 := $(LOCAL_MODULE)32
+LOCAL_MODULE_STEM_64 := $(LOCAL_MODULE)64
+LOCAL_COMPATIBILITY_SUITE := cts
+include $(BUILD_EXECUTABLE)
diff --git a/hostsidetests/sustainedperf/dhrystone/Drystone-2.1.sh b/hostsidetests/sustainedperf/dhrystone/Drystone-2.1.sh
new file mode 100755
index 0000000..f2bf2c1
--- /dev/null
+++ b/hostsidetests/sustainedperf/dhrystone/Drystone-2.1.sh
@@ -0,0 +1,1424 @@
+#! /bin/sh
+# This is a shell archive, meaning:
+# 1. Remove everything above the #! /bin/sh line.
+# 2. Save the resulting text in a file.
+# 3. Execute the file with /bin/sh (not csh) to create:
+#        Rationale
+#        dhry.h
+#        dhry_1.c
+#        dhry_2.c
+# This archive created: Wed Jul  6 16:50:06 1988
+export PATH; PATH=/bin:/usr/bin:$PATH
+if test -f 'Rationale'
+then
+        echo shar: "will not over-write existing file 'Rationale'"
+else
+sed 's/^X//' << \SHAR_EOF > 'Rationale'
+XDhrystone Benchmark: Rationale for Version 2 and Measurement Rules
+X
+X                 Reinhold P. Weicker
+X                 Siemens AG, E STE 35
+X                 Postfach 3240
+X                 D-8520 Erlangen
+X                 Germany (West)
+X
+X
+X
+X
+XThe Dhrystone benchmark program [1] has become a popular benchmark  for
+XCPU/compiler  performance  measurement,  in  particular  in the area of
+Xminicomputers, workstations, PC's and  microprocesors.   It  apparently
+Xsatisfies a need for an easy-to-use integer benchmark; it gives a first
+Xperformance indication which  is  more  meaningful  than  MIPS  numbers
+Xwhich,  in  their  literal  meaning  (million instructions per second),
+Xcannot be used across different instruction sets (e.g. RISC vs.  CISC).
+XWith  the  increasing  use  of  the  benchmark,  it  seems necessary to
+Xreconsider the benchmark and to check whether it can still fulfill this
+Xfunction.   Version  2  of  Dhrystone  is  the  result  of  such  a re-
+Xevaluation, it has been made for two reasons:
+X
+Xo Dhrystone has been published in Ada [1], and Versions in Ada,  Pascal
+X  and  C  have  been  distributed  by Reinhold Weicker via floppy disk.
+X  However, the version that was used most often  for  benchmarking  has
+X  been  the version made by Rick Richardson by another translation from
+X  the Ada version into the C programming language, this  has  been  the
+X  version distributed via the UNIX network Usenet [2].
+X
+X  There is an obvious need for a common C version of Dhrystone, since C
+X  is  at  present  the most popular system programming language for the
+X  class of systems (microcomputers, minicomputers, workstations)  where
+X  Dhrystone  is  used  most.  There should be, as far as possible, only
+X  one C version of Dhrystone such that results can be compared  without
+X  restrictions.  In  the  past,  the  C  versions  distributed  by Rick
+X  Richardson (Version 1.1) and by Reinhold Weicker  had  small  (though
+X  not significant) differences.
+X
+X  Together with the new C version, the Ada  and  Pascal  versions  have
+X  been updated as well.
+X
+Xo As far as it is possible without changes to the Dhrystone statistics,
+X  optimizing  compilers  should  be prevented from removing significant
+X  statements.  It has turned out in the past that optimizing  compilers
+X  suppressed  code  generation  for  too many statements (by "dead code
+X  removal" or "dead variable  elimination").   This  has  lead  to  the
+X  danger  that  benchmarking results obtained by a naive application of
+X  Dhrystone - without inspection of the code that was generated - could
+X  become meaningless.
+X
+XThe overall policiy for version 2 has been  that  the  distribution  of
+Xstatements,  operand types and operand locality described in [1] should
+Xremain  unchanged  as  much  as  possible.   (Very  few  changes   were
+Xnecessary;  their  impact  should  be  negligible.)  Also, the order of
+Xstatements should  remain  unchanged.  Although  I  am  aware  of  some
+Xcritical  remarks on the benchmark - I agree with several of them - and
+Xknow some suggestions for improvement, I  didn't  want  to  change  the
+Xbenchmark  into  something  different  from  what  has  become known as
+X"Dhrystone"; the confusion generated by such a  change  would  probably
+Xoutweight  the  benefits. If I were to write a new benchmark program, I
+Xwouldn't give it the name "Dhrystone" since this  denotes  the  program
+Xpublished in [1].  However, I do recognize the need for a larger number
+Xof representative programs that can be used as benchmarks; users should
+Xalways be encouraged to use more than just one benchmark.
+X
+XThe  new  versions  (version  2.1  for  C,  Pascal  and  Ada)  will  be
+Xdistributed  as  widely as possible.  (Version 2.1 differs from version
+X2.0 distributed via the UNIX Network Usenet in March 1988 only in a few
+Xcorrections  for  minor  deficiencies  found  by users of version 2.0.)
+XReaders who want to use the benchmark for their  own  measurements  can
+Xobtain  a copy in machine-readable form on floppy disk (MS-DOS or XENIX
+Xformat) from the author.
+X
+X
+XIn general, version 2 follows - in the parts that are  significant  for
+Xperformance  measurement,  i.e.   within  the  measurement  loop  - the
+Xpublished (Ada) version and  the  C  versions  previously  distributed.
+XWhere  the  versions  distributed  by  Rick Richardson [2] and Reinhold
+XWeicker have been different, it  follows  the  version  distributed  by
+XReinhold  Weicker.  (However,  the  differences have been so small that
+Xtheir impact on execution time in all likelihood has been  negligible.)
+XThe  initialization  and  UNIX  instrumentation  part  - which had been
+Xomitted in [1] - follows mostly  the  ideas  of  Rick  Richardson  [2].
+XHowever,  any changes in the initialization part and in the printing of
+Xthe result have no impact on performance  measurement  since  they  are
+Xoutside  the  measaurement  loop.   As a concession to older compilers,
+Xnames have been made unique within the first 8  characters  for  the  C
+Xversion.
+X
+XThe original publication of Dhrystone did not  contain  any  statements
+Xfor  time  measurement  since  they  are  necessarily system-dependent.
+XHowever, it turned out that it is not enough just to inclose  the  main
+Xprocedure of Dhrystone in a loop and to measure the execution time.  If
+Xthe variables that are computed are not  used  somehow,  there  is  the
+Xdanger  that  the  compiler  considers  them  as  "dead  variables" and
+Xsuppresses code generation for a part of the statements.  Therefore  in
+Xversion  2  all  variables  of  "main"  are  printed  at the end of the
+Xprogram. This  also  permits  some  plausibility  control  for  correct
+Xexecution of the benchmark.
+X
+XAt several places in the benchmark, code has been added,  but  only  in
+Xbranches  that  are  not  executed.  The  intention  is that optimizing
+Xcompilers should be prevented from moving code out of  the  measurement
+Xloop,  or  from  removing code altogether. Statements that are executed
+Xhave been changed in very few places only.  In these  cases,  only  the
+Xrole  of  some operands has been changed, and it was made sure that the
+Xnumbers  defining  the  "Dhrystone   distribution"   (distribution   of
+Xstatements, operand types and locality) still hold as much as possible.
+XExcept for sophisticated  optimizing  compilers,  execution  times  for
+Xversion 2.1 should be the same as for previous versions.
+X
+XBecause of the self-imposed limitation that the order and  distribution
+Xof the executed statements should not be changed, there are still cases
+Xwhere optimizing compilers may not generate code for  some  statements.
+XTo   a   certain  degree,  this  is  unavoidable  for  small  synthetic
+Xbenchmarks.  Users of the benchmark are advised to check code  listings
+Xwhether code is generated for all statements of Dhrystone.
+X
+XContrary to the suggestion in the published paper and  its  realization
+Xin  the  versions  previously  distributed, no attempt has been made to
+Xsubtract the time for the measurement loop overhead. (This  calculation
+Xhas  proven  difficult  to implement in a correct way, and its omission
+Xmakes the program simpler.) However, since the loop check is  now  part
+Xof  the benchmark, this does have an impact - though a very minor one -
+Xon the  distribution  statistics  which  have  been  updated  for  this
+Xversion.
+X
+X
+XIn this section, all changes are described that affect the  measurement
+Xloop and that are not just renamings of variables. All remarks refer to
+Xthe C version; the other language versions have been updated similarly.
+X
+XIn addition to adding the measurement loop and the printout statements,
+Xchanges have been made at the following places:
+X
+Xo In procedure "main", three statements have been  added  in  the  non-
+X  executed "then" part of the statement
+X    if (Enum_Loc == Func_1 (Ch_Index, 'C'))
+X  they are
+X    strcpy (Str_2_Loc, "DHRYSTONE PROGRAM, 3'RD STRING");
+X    Int_2_Loc = Run_Index;
+X    Int_Glob = Run_Index;
+X  The string assignment prevents movement of the  preceding  assignment
+X  to  Str_2_Loc  (5'th statement of "main") out of the measurement loop
+X  (This probably will not happen for the C version, but it  did  happen
+X  with  another  language  and  compiler.)  The assignment to Int_2_Loc
+X  prevents value propagation  for  Int_2_Loc,  and  the  assignment  to
+X  Int_Glob  makes  the  value  of  Int_Glob possibly dependent from the
+X  value of Run_Index.
+X
+Xo In the three arithmetic computations at the end  of  the  measurement
+X  loop  in  "main  ", the role of some variables has been exchanged, to
+X  prevent the division from just cancelling out the  multiplication  as
+X  it  was in [1].  A very smart compiler might have recognized this and
+X  suppressed code generation for the division.
+X
+Xo For Proc_2, no code has been changed, but the values  of  the  actual
+X  parameter have changed due to changes in "main".
+X
+Xo In Proc_4, the second assignment has been changed from
+X    Bool_Loc = Bool_Loc | Bool_Glob;
+X  to
+X    Bool_Glob = Bool_Loc | Bool_Glob;
+X  It now assigns a value to  a  global  variable  instead  of  a  local
+X  variable (Bool_Loc); Bool_Loc would be a "dead variable" which is not
+X  used afterwards.
+X
+Xo In Func_1, the statement
+X    Ch_1_Glob = Ch_1_Loc;
+X  was added in the non-executed "else" part of the "if"  statement,  to
+X  prevent  the  suppression  of  code  generation for the assignment to
+X  Ch_1_Loc.
+X
+Xo In Func_2, the second character comparison statement has been changed
+X  to
+X    if (Ch_Loc == 'R')
+X  ('R' instead of 'X') because a comparison with 'X' is implied in  the
+X  preceding "if" statement.
+X
+X  Also in Func_2, the statement
+X    Int_Glob = Int_Loc;
+X  has been added in the non-executed part of the last  "if"  statement,
+X  in order to prevent Int_Loc from becoming a dead variable.
+X
+Xo In Func_3, a non-executed "else" part has  been  added  to  the  "if"
+X  statement.   While  the  program  would not be incorrect without this
+X  "else" part, it is considered bad programming practice if a  function
+X  can be left without a return value.
+X
+X  To compensate for this change, the (non-executed) "else" part in  the
+X  "if" statement of Proc_3 was removed.
+X
+XThe distribution statistics have been changed only by the  addition  of
+Xthe  measurement  loop  iteration (1 additional statement, 4 additional
+Xlocal integer operands) and  by  the  change  in  Proc_4  (one  operand
+Xchanged  from  local  to  global).  The  distribution statistics in the
+Xcomment headers have been updated accordingly.
+X
+X
+XThe string operations (string assignment and  string  comparison)  have
+Xnot  been  changed,  to  keep  the program consistent with the original
+Xversion.
+X
+XThere has been some  concern  that  the  string  operations  are  over-
+Xrepresented  in  the  program,  and that execution time is dominated by
+Xthese  operations.   This  was  true  in  particular  when   optimizing
+Xcompilers  removed  too much code in the main part of the program, this
+Xshould have been mitigated in version 2.
+X
+XIt should be noted that this is a language-dependent issue:   Dhrystone
+Xwas  first published in Ada, and with Ada or Pascal semantics, the time
+Xspent in the string operations is,  at  least  in  all  implementations
+Xknown  to  me, considerably smaller.  In Ada and Pascal, assignment and
+Xcomparison of strings are operators defined in the  language,  and  the
+Xupper  bounds of the strings occuring in Dhrystone are part of the type
+Xinformation known at compilation time.   The  compilers  can  therefore
+Xgenerate efficient inline code.  In C, string assignemt and comparisons
+Xare not part  of  the  language,  so  the  string  operations  must  be
+Xexpressed  in  terms  of the C library functions "strcpy" and "strcmp".
+X(ANSI  C  allows  an  implementation  to  use  inline  code  for  these
+Xfunctions.)   In addition to the overhead caused by additional function
+Xcalls, these functions are defined for  null-terminated  strings  where
+Xthe  length  of  the  strings  is  not  known  at compilation time; the
+Xfunction has to check every byte for  the  termination  condition  (the
+Xnull byte).
+X
+XObviously, a C library which includes efficiently  coded  "strcpy"  and
+X"strcmp"  functions  helps to obtain good Dhrystone results. However, I
+Xdon't think that this is unfair since string functions do  occur  quite
+Xfrequently  in real programs (editors, command interpreters, etc.).  If
+Xthe strings functions are  implemented  efficiently,  this  helps  real
+Xprograms as well as benchmark programs.
+X
+XI admit that the string comparison in Dhrystone terminates later (after
+Xscanning  20 characters) than most string comparisons in real programs.
+XFor consistency with  the  original  benchmark,  I  didn't  change  the
+Xprogram despite this weakness.
+X
+X
+XWhen Dhrystone is used, the following "ground rules" apply:
+X
+Xo Separate compilation (Ada and C versions)
+X
+X  As  mentioned  in  [1],  Dhrystone  was  written  to  reflect  actual
+X  programming  practice  in  systems  programming.   The  division into
+X  several compilation units (5 in the Ada version, 2 in the C  version)
+X  is  intended, as is the distribution of inter-module and intra-module
+X  subprogram  calls.   Although  on  many  systems  there  will  be  no
+X  difference  in  execution  time  to  a  Dhrystone  version  where all
+X  compilation units are merged into one file, the rule is that separate
+X  compilation  should  be used.  The intention is that real programming
+X  practice, where programs consist of  several  independently  compiled
+X  units, should be reflected.  This also has implies that the compiler,
+X  while compiling one  unit,  has  no  information  about  the  use  of
+X  variables,  register  allocation  etc.  occuring in other compilation
+X  units.  Although in real life  compilation  units  will  probably  be
+X  larger,  the  intention is that these effects of separate compilation
+X  are modeled in Dhrystone.
+X
+X  A few  language  systems  have  post-linkage  optimization  available
+X  (e.g.,  final  register allocation is performed after linkage).  This
+X  is a borderline case: Post-linkage optimization  involves  additional
+X  program  preparation time (although not as much as compilation in one
+X  unit) which may prevent its general use in practical programming.   I
+X  think that since it defeats the intentions given above, it should not
+X  be used for Dhrystone.
+X
+X  Unfortunately, ISO/ANSI Pascal does not contain language features for
+X  separate  compilation.   Although  most  commercial  Pascal compilers
+X  provide separate compilation in  some  way,  we  cannot  use  it  for
+X  Dhrystone  since such a version would not be portable.  Therefore, no
+X  attempt has been made  to  provide  a  Pascal  version  with  several
+X  compilation units.
+X
+Xo No procedure merging
+X
+X  Although  Dhrystone  contains  some  very  short   procedures   where
+X  execution  would  benefit  from  procedure  merging  (inlining, macro
+X  expansion of procedures), procedure merging is not to be  used.   The
+X  reason is that the percentage of procedure and function calls is part
+X  of the "Dhrystone distribution" of statements contained in [1].  This
+X  restriction  does  not hold for the string functions of the C version
+X  since ANSI C allows an implementation to use inline  code  for  these
+X  functions.
+X
+X
+X
+Xo Other optimizations are allowed, but they should be indicated
+X
+X  It is  often  hard  to  draw  an  exact  line  between  "normal  code
+X  generation"  and  "optimization" in compilers: Some compilers perform
+X  operations by default that are invoked in other compilers  only  when
+X  optimization  is explicitly requested.  Also, we cannot avoid that in
+X  benchmarking people try to achieve  results  that  look  as  good  as
+X  possible.   Therefore,  optimizations  performed by compilers - other
+X  than those listed above - are not forbidden when Dhrystone  execution
+X  times  are measured.  Dhrystone is not intended to be non-optimizable
+X  but is intended to be similarly optimizable as normal programs.   For
+X  example,  there  are  several  places  in Dhrystone where performance
+X  benefits from optimizations like  common  subexpression  elimination,
+X  value propagation etc., but normal programs usually also benefit from
+X  these optimizations.  Therefore, no effort was made  to  artificially
+X  prevent  such  optimizations.   However,  measurement  reports should
+X  indicate which compiler  optimization  levels  have  been  used,  and
+X  reporting  results with different levels of compiler optimization for
+X  the same hardware is encouraged.
+X
+Xo Default results are those without "register" declarations (C version)
+X
+X  When Dhrystone results are quoted without  additional  qualification,
+X  they  should  be  understood  as  results obtained without use of the
+X  "register" attribute. Good compilers should be able to make good  use
+X  of  registers  even  without  explicit register declarations ([3], p.
+X  193).
+X
+XOf  course,  for  experimental  purposes,  post-linkage   optimization,
+Xprocedure  merging  and/or  compilation  in  one  unit  can  be done to
+Xdetermine their effects.  However,  Dhrystone  numbers  obtained  under
+Xthese   conditions  should  be  explicitly  marked  as  such;  "normal"
+XDhrystone results should be understood as  results  obtained  following
+Xthe ground rules listed above.
+X
+XIn any case, for serious performance evaluation, users are  advised  to
+Xask  for  code listings and to check them carefully.  In this way, when
+Xresults for different systems  are  compared,  the  reader  can  get  a
+Xfeeling how much performance difference is due to compiler optimization
+Xand how much is due to hardware speed.
+X
+X
+XThe C version 2.1 of Dhrystone has been developed in  cooperation  with
+XRick Richardson (Tinton Falls, NJ), it incorporates many ideas from the
+X"Version 1.1" distributed previously  by  him  over  the  UNIX  network
+XUsenet.  Through  his  activity with Usenet, Rick Richardson has made a
+Xvery valuable contribution to the dissemination of  the  benchmark.   I
+Xalso  thank  Chaim  Benedelac  (National  Semiconductor),  David Ditzel
+X(SUN), Earl Killian and John  Mashey  (MIPS),  Alan  Smith  and  Rafael
+XSaavedra-Barrera  (UC  at  Berkeley)  for  their  help with comments on
+Xearlier versions of the benchmark.
+X
+X
+X[1]
+X   Reinhold P. Weicker:  Dhrystone:  A  Synthetic  Systems  Programming
+X   Benchmark.
+X   Communications of the ACM 27, 10 (Oct. 1984), 1013-1030
+X
+X[2]
+X   Rick Richardson: Dhrystone 1.1 Benchmark Summary (and Program Text)
+X   Informal Distribution via "Usenet", Last Version Known to me:  Sept.
+X   21, 1987
+X
+X[3]
+X   Brian W.  Kernighan  and  Dennis  M.  Ritchie:   The  C  Programming
+X   Language.
+X   Prentice-Hall, Englewood Cliffs (NJ) 1978
+X
+X
+X
+X
+X
+SHAR_EOF
+fi
+if test -f 'dhry.h'
+then
+        echo shar: "will not over-write existing file 'dhry.h'"
+else
+sed 's/^X//' << \SHAR_EOF > 'dhry.h'
+X/*
+X ****************************************************************************
+X *
+X *                   "DHRYSTONE" Benchmark Program
+X *                   -----------------------------
+X *                                                                            
+X *  Version:    C, Version 2.1
+X *                                                                            
+X *  File:       dhry.h (part 1 of 3)
+X *
+X *  Date:       May 17, 1988
+X *
+X *  Author:     Reinhold P. Weicker
+X *                      Siemens AG, E STE 35
+X *                      Postfach 3240
+X *                      8520 Erlangen
+X *                      Germany (West)
+X *                              Phone:  [xxx-49]-9131-7-20330
+X *                                      (8-17 Central European Time)
+X *                              Usenet: ..!mcvax!unido!estevax!weicker
+X *
+X *              Original Version (in Ada) published in
+X *              "Communications of the ACM" vol. 27., no. 10 (Oct. 1984),
+X *              pp. 1013 - 1030, together with the statistics
+X *              on which the distribution of statements etc. is based.
+X *
+X *              In this C version, the following C library functions are used:
+X *              - strcpy, strcmp (inside the measurement loop)
+X *              - printf, scanf (outside the measurement loop)
+X *              In addition, Berkeley UNIX system calls "times ()" or "time ()"
+X *              are used for execution time measurement. For measurements
+X *              on other systems, these calls have to be changed.
+X *
+X *  Collection of Results:
+X *              Reinhold Weicker (address see above) and
+X *              
+X *              Rick Richardson
+X *              PC Research. Inc.
+X *              94 Apple Orchard Drive
+X *              Tinton Falls, NJ 07724
+X *                      Phone:  (201) 389-8963 (9-17 EST)               
+X *                      Usenet: ...!uunet!pcrat!rick
+X *
+X *      Please send results to Rick Richardson and/or Reinhold Weicker.
+X *      Complete information should be given on hardware and software used.
+X *      Hardware information includes: Machine type, CPU, type and size
+X *      of caches; for microprocessors: clock frequency, memory speed
+X *      (number of wait states).
+X *      Software information includes: Compiler (and runtime library)
+X *      manufacturer and version, compilation switches, OS version.
+X *      The Operating System version may give an indication about the
+X *      compiler; Dhrystone itself performs no OS calls in the measurement loop.
+X *
+X *      The complete output generated by the program should be mailed
+X *      such that at least some checks for correctness can be made.
+X *
+X ***************************************************************************
+X *
+X *  History:    This version C/2.1 has been made for two reasons:
+X *
+X *              1) There is an obvious need for a common C version of
+X *              Dhrystone, since C is at present the most popular system
+X *              programming language for the class of processors
+X *              (microcomputers, minicomputers) where Dhrystone is used most.
+X *              There should be, as far as possible, only one C version of
+X *              Dhrystone such that results can be compared without
+X *              restrictions. In the past, the C versions distributed
+X *              by Rick Richardson (Version 1.1) and by Reinhold Weicker
+X *              had small (though not significant) differences.
+X *
+X *              2) As far as it is possible without changes to the Dhrystone
+X *              statistics, optimizing compilers should be prevented from
+X *              removing significant statements.
+X *
+X *              This C version has been developed in cooperation with
+X *              Rick Richardson (Tinton Falls, NJ), it incorporates many
+X *              ideas from the "Version 1.1" distributed previously by
+X *              him over the UNIX network Usenet.
+X *              I also thank Chaim Benedelac (National Semiconductor),
+X *              David Ditzel (SUN), Earl Killian and John Mashey (MIPS),
+X *              Alan Smith and Rafael Saavedra-Barrera (UC at Berkeley)
+X *              for their help with comments on earlier versions of the
+X *              benchmark.
+X *
+X *  Changes:    In the initialization part, this version follows mostly
+X *              Rick Richardson's version distributed via Usenet, not the
+X *              version distributed earlier via floppy disk by Reinhold Weicker.
+X *              As a concession to older compilers, names have been made
+X *              unique within the first 8 characters.
+X *              Inside the measurement loop, this version follows the
+X *              version previously distributed by Reinhold Weicker.
+X *
+X *              At several places in the benchmark, code has been added,
+X *              but within the measurement loop only in branches that 
+X *              are not executed. The intention is that optimizing compilers
+X *              should be prevented from moving code out of the measurement
+X *              loop, or from removing code altogether. Since the statements
+X *              that are executed within the measurement loop have NOT been
+X *              changed, the numbers defining the "Dhrystone distribution"
+X *              (distribution of statements, operand types and locality)
+X *              still hold. Except for sophisticated optimizing compilers,
+X *              execution times for this version should be the same as
+X *              for previous versions.
+X *              
+X *              Since it has proven difficult to subtract the time for the
+X *              measurement loop overhead in a correct way, the loop check
+X *              has been made a part of the benchmark. This does have
+X *              an impact - though a very minor one - on the distribution
+X *              statistics which have been updated for this version.
+X *
+X *              All changes within the measurement loop are described
+X *              and discussed in the companion paper "Rationale for
+X *              Dhrystone version 2".
+X *
+X *              Because of the self-imposed limitation that the order and
+X *              distribution of the executed statements should not be
+X *              changed, there are still cases where optimizing compilers
+X *              may not generate code for some statements. To a certain
+X *              degree, this is unavoidable for small synthetic benchmarks.
+X *              Users of the benchmark are advised to check code listings
+X *              whether code is generated for all statements of Dhrystone.
+X *
+X *              Version 2.1 is identical to version 2.0 distributed via
+X *              the UNIX network Usenet in March 1988 except that it corrects
+X *              some minor deficiencies that were found by users of version 2.0.
+X *              The following corrections have been made in the C version:
+X *              - The assignment to Number_Of_Runs was changed
+X *              - The constant Too_Small_Time was changed
+X *              - An "else" part was added to the "if" statement in Func_3;
+X *                for compensation, an "else" part was removed in Proc_3
+X *              - Shorter file names are used
+X *
+X ***************************************************************************
+X *
+X * Defines:     The following "Defines" are possible:
+X *              -DREG=register          (default: Not defined)
+X *                      As an approximation to what an average C programmer
+X *                      might do, the "register" storage class is applied
+X *                      (if enabled by -DREG=register)
+X *                      - for local variables, if they are used (dynamically)
+X *                        five or more times
+X *                      - for parameters if they are used (dynamically)
+X *                        six or more times
+X *                      Note that an optimal "register" strategy is
+X *                      compiler-dependent, and that "register" declarations
+X *                      do not necessarily lead to faster execution.
+X *              -DNOSTRUCTASSIGN        (default: Not defined)
+X *                      Define if the C compiler does not support
+X *                      assignment of structures.
+X *              -DNOENUMS               (default: Not defined)
+X *                      Define if the C compiler does not support
+X *                      enumeration types.
+X *              -DTIMES                 (default)
+X *              -DTIME
+X *                      The "times" function of UNIX (returning process times)
+X *                      or the "time" function (returning wallclock time)
+X *                      is used for measurement. 
+X *                      For single user machines, "time ()" is adequate. For
+X *                      multi-user machines where you cannot get single-user
+X *                      access, use the "times ()" function. If you have
+X *                      neither, use a stopwatch in the dead of night.
+X *                      "printf"s are provided marking the points "Start Timer"
+X *                      and "Stop Timer". DO NOT use the UNIX "time(1)"
+X *                      command, as this will measure the total time to
+X *                      run this program, which will (erroneously) include
+X *                      the time to allocate storage (malloc) and to perform
+X *                      the initialization.
+X *              -DHZ=nnn
+X *                      In Berkeley UNIX, the function "times" returns process
+X *                      time in 1/HZ seconds, with HZ = 60 for most systems.
+X *                      CHECK YOUR SYSTEM DESCRIPTION BEFORE YOU JUST APPLY
+X *                      A VALUE.
+X *
+X ***************************************************************************
+X *
+X *  Compilation model and measurement (IMPORTANT):
+X *
+X *  This C version of Dhrystone consists of three files:
+X *  - dhry.h (this file, containing global definitions and comments)
+X *  - dhry_1.c (containing the code corresponding to Ada package Pack_1)
+X *  - dhry_2.c (containing the code corresponding to Ada package Pack_2)
+X *
+X *  The following "ground rules" apply for measurements:
+X *  - Separate compilation
+X *  - No procedure merging
+X *  - Otherwise, compiler optimizations are allowed but should be indicated
+X *  - Default results are those without register declarations
+X *  See the companion paper "Rationale for Dhrystone Version 2" for a more
+X *  detailed discussion of these ground rules.
+X *
+X *  For 16-Bit processors (e.g. 80186, 80286), times for all compilation
+X *  models ("small", "medium", "large" etc.) should be given if possible,
+X *  together with a definition of these models for the compiler system used.
+X *
+X **************************************************************************
+X *
+X *  Dhrystone (C version) statistics:
+X *
+X *  [Comment from the first distribution, updated for version 2.
+X *   Note that because of language differences, the numbers are slightly
+X *   different from the Ada version.]
+X *
+X *  The following program contains statements of a high level programming
+X *  language (here: C) in a distribution considered representative:           
+X *
+X *    assignments                  52 (51.0 %)
+X *    control statements           33 (32.4 %)
+X *    procedure, function calls    17 (16.7 %)
+X *
+X *  103 statements are dynamically executed. The program is balanced with
+X *  respect to the three aspects:                                             
+X *
+X *    - statement type
+X *    - operand type
+X *    - operand locality
+X *         operand global, local, parameter, or constant.                     
+X *
+X *  The combination of these three aspects is balanced only approximately.    
+X *
+X *  1. Statement Type:                                                        
+X *  -----------------             number
+X *
+X *     V1 = V2                     9
+X *       (incl. V1 = F(..)
+X *     V = Constant               12
+X *     Assignment,                 7
+X *       with array element
+X *     Assignment,                 6
+X *       with record component
+X *                                --
+X *                                34       34
+X *
+X *     X = Y +|-|"&&"|"|" Z        5
+X *     X = Y +|-|"==" Constant     6
+X *     X = X +|- 1                 3
+X *     X = Y *|/ Z                 2
+X *     X = Expression,             1
+X *           two operators
+X *     X = Expression,             1
+X *           three operators
+X *                                --
+X *                                18       18
+X *
+X *     if ....                    14
+X *       with "else"      7
+X *       without "else"   7
+X *           executed        3
+X *           not executed    4
+X *     for ...                     7  |  counted every time
+X *     while ...                   4  |  the loop condition
+X *     do ... while                1  |  is evaluated
+X *     switch ...                  1
+X *     break                       1
+X *     declaration with            1
+X *       initialization
+X *                                --
+X *                                34       34
+X *
+X *     P (...)  procedure call    11
+X *       user procedure      10
+X *       library procedure    1
+X *     X = F (...)
+X *             function  call      6
+X *       user function        5                                         
+X *       library function     1                                               
+X *                                --                                          
+X *                                17       17
+X *                                        ---
+X *                                        103
+X *
+X *    The average number of parameters in procedure or function calls
+X *    is 1.82 (not counting the function values as implicit parameters).
+X *
+X *
+X *  2. Operators
+X *  ------------
+X *                          number    approximate
+X *                                    percentage
+X *
+X *    Arithmetic             32          50.8                                 
+X *
+X *       +                     21          33.3                              
+X *       -                      7          11.1                              
+X *       *                      3           4.8
+X *       / (int div)            1           1.6
+X *
+X *    Comparison             27           42.8
+X *
+X *       ==                     9           14.3
+X *       /=                     4            6.3
+X *       >                      1            1.6
+X *       <                      3            4.8
+X *       >=                     1            1.6
+X *       <=                     9           14.3
+X *
+X *    Logic                   4            6.3
+X *
+X *       && (AND-THEN)          1            1.6
+X *       |  (OR)                1            1.6
+X *       !  (NOT)               2            3.2
+X * 
+X *                           --          -----
+X *                           63          100.1
+X *
+X *
+X *  3. Operand Type (counted once per operand reference):
+X *  ---------------
+X *                          number    approximate
+X *                                    percentage
+X *
+X *     Integer               175        72.3 %
+X *     Character              45        18.6 %
+X *     Pointer                12         5.0 %
+X *     String30                6         2.5 %
+X *     Array                   2         0.8 %
+X *     Record                  2         0.8 %
+X *                           ---       -------
+X *                           242       100.0 %
+X *
+X *  When there is an access path leading to the final operand (e.g. a record
+X *  component), only the final data type on the access path is counted.       
+X *
+X *
+X *  4. Operand Locality:                                                      
+X *  -------------------
+X *                                number    approximate
+X *                                          percentage
+X *
+X *     local variable              114        47.1 %
+X *     global variable              22         9.1 %
+X *     parameter                    45        18.6 %
+X *        value                        23         9.5 %
+X *        reference                    22         9.1 %
+X *     function result               6         2.5 %
+X *     constant                     55        22.7 %
+X *                                 ---       -------
+X *                                 242       100.0 %
+X *
+X *
+X *  The program does not compute anything meaningful, but it is syntactically
+X *  and semantically correct. All variables have a value assigned to them
+X *  before they are used as a source operand.
+X *
+X *  There has been no explicit effort to account for the effects of a
+X *  cache, or to balance the use of long or short displacements for code or
+X *  data.
+X *
+X ***************************************************************************
+X */
+X
+X/* Compiler and system dependent definitions: */
+X
+X#ifndef TIME
+X#ifndef TIMES
+X#define TIMES
+X#endif
+X#endif
+X                /* Use times(2) time function unless    */
+X                /* explicitly defined otherwise         */
+X
+X#ifdef MSC_CLOCK
+X#undef HZ
+X#undef TIMES
+X#include <time.h>
+X#define HZ        CLK_TCK
+X#endif
+X                /* Use Microsoft C hi-res clock */
+X
+X#ifdef TIMES
+X#include <sys/types.h>
+X#include <sys/times.h>
+X                /* for "times" */
+X#endif
+X
+X#define Mic_secs_Per_Second     1000000.0
+X                /* Berkeley UNIX C returns process times in seconds/HZ */
+X
+X#ifdef  NOSTRUCTASSIGN
+X#define structassign(d, s)      memcpy(&(d), &(s), sizeof(d))
+X#else
+X#define structassign(d, s)      d = s
+X#endif
+X
+X#ifdef  NOENUM
+X#define Ident_1 0
+X#define Ident_2 1
+X#define Ident_3 2
+X#define Ident_4 3
+X#define Ident_5 4
+X  typedef int   Enumeration;
+X#else
+X  typedef       enum    {Ident_1, Ident_2, Ident_3, Ident_4, Ident_5}
+X                Enumeration;
+X#endif
+X        /* for boolean and enumeration types in Ada, Pascal */
+X
+X/* General definitions: */
+X
+X#include <stdio.h>
+X                /* for strcpy, strcmp */
+X
+X#define Null 0 
+X                /* Value of a Null pointer */
+X#define true  1
+X#define false 0
+X
+Xtypedef int     One_Thirty;
+Xtypedef int     One_Fifty;
+Xtypedef char    Capital_Letter;
+Xtypedef int     Boolean;
+Xtypedef char    Str_30 [31];
+Xtypedef int     Arr_1_Dim [50];
+Xtypedef int     Arr_2_Dim [50] [50];
+X
+Xtypedef struct record 
+X    {
+X    struct record *Ptr_Comp;
+X    Enumeration    Discr;
+X    union {
+X          struct {
+X                  Enumeration Enum_Comp;
+X                  int         Int_Comp;
+X                  char        Str_Comp [31];
+X                  } var_1;
+X          struct {
+X                  Enumeration E_Comp_2;
+X                  char        Str_2_Comp [31];
+X                  } var_2;
+X          struct {
+X                  char        Ch_1_Comp;
+X                  char        Ch_2_Comp;
+X                  } var_3;
+X          } variant;
+X      } Rec_Type, *Rec_Pointer;
+X
+X
+SHAR_EOF
+fi
+if test -f 'dhry_1.c'
+then
+        echo shar: "will not over-write existing file 'dhry_1.c'"
+else
+sed 's/^X//' << \SHAR_EOF > 'dhry_1.c'
+X/*
+X ****************************************************************************
+X *
+X *                   "DHRYSTONE" Benchmark Program
+X *                   -----------------------------
+X *                                                                            
+X *  Version:    C, Version 2.1
+X *                                                                            
+X *  File:       dhry_1.c (part 2 of 3)
+X *
+X *  Date:       May 17, 1988
+X *
+X *  Author:     Reinhold P. Weicker
+X *
+X ****************************************************************************
+X */
+X
+X#include "dhry.h"
+X
+X/* Global Variables: */
+X
+XRec_Pointer     Ptr_Glob,
+X                Next_Ptr_Glob;
+Xint             Int_Glob;
+XBoolean         Bool_Glob;
+Xchar            Ch_1_Glob,
+X                Ch_2_Glob;
+Xint             Arr_1_Glob [50];
+Xint             Arr_2_Glob [50] [50];
+X
+Xextern char     *malloc ();
+XEnumeration     Func_1 ();
+X  /* forward declaration necessary since Enumeration may not simply be int */
+X
+X#ifndef REG
+X        Boolean Reg = false;
+X#define REG
+X        /* REG becomes defined as empty */
+X        /* i.e. no register variables   */
+X#else
+X        Boolean Reg = true;
+X#endif
+X
+X/* variables for time measurement: */
+X
+X#ifdef TIMES
+Xstruct tms      time_info;
+Xextern  int     times ();
+X                /* see library function "times" */
+X#define Too_Small_Time (2*HZ)
+X                /* Measurements should last at least about 2 seconds */
+X#endif
+X#ifdef TIME
+Xextern long     time();
+X                /* see library function "time"  */
+X#define Too_Small_Time 2
+X                /* Measurements should last at least 2 seconds */
+X#endif
+X#ifdef MSC_CLOCK
+Xextern clock_t        clock();
+X#define Too_Small_Time (2*HZ)
+X#endif
+X
+Xlong            Begin_Time,
+X                End_Time,
+X                User_Time;
+Xfloat           Microseconds,
+X                Dhrystones_Per_Second;
+X
+X/* end of variables for time measurement */
+X
+X
+Xmain ()
+X/*****/
+X
+X  /* main program, corresponds to procedures        */
+X  /* Main and Proc_0 in the Ada version             */
+X{
+X        One_Fifty       Int_1_Loc;
+X  REG   One_Fifty       Int_2_Loc;
+X        One_Fifty       Int_3_Loc;
+X  REG   char            Ch_Index;
+X        Enumeration     Enum_Loc;
+X        Str_30          Str_1_Loc;
+X        Str_30          Str_2_Loc;
+X  REG   int             Run_Index;
+X  REG   int             Number_Of_Runs;
+X
+X  /* Initializations */
+X
+X  Next_Ptr_Glob = (Rec_Pointer) malloc (sizeof (Rec_Type));
+X  Ptr_Glob = (Rec_Pointer) malloc (sizeof (Rec_Type));
+X
+X  Ptr_Glob->Ptr_Comp                    = Next_Ptr_Glob;
+X  Ptr_Glob->Discr                       = Ident_1;
+X  Ptr_Glob->variant.var_1.Enum_Comp     = Ident_3;
+X  Ptr_Glob->variant.var_1.Int_Comp      = 40;
+X  strcpy (Ptr_Glob->variant.var_1.Str_Comp, 
+X          "DHRYSTONE PROGRAM, SOME STRING");
+X  strcpy (Str_1_Loc, "DHRYSTONE PROGRAM, 1'ST STRING");
+X
+X  Arr_2_Glob [8][7] = 10;
+X        /* Was missing in published program. Without this statement,    */
+X        /* Arr_2_Glob [8][7] would have an undefined value.             */
+X        /* Warning: With 16-Bit processors and Number_Of_Runs > 32000,  */
+X        /* overflow may occur for this array element.                   */
+X
+X  printf ("\n");
+X  printf ("Dhrystone Benchmark, Version 2.1 (Language: C)\n");
+X  printf ("\n");
+X  if (Reg)
+X  {
+X    printf ("Program compiled with 'register' attribute\n");
+X    printf ("\n");
+X  }
+X  else
+X  {
+X    printf ("Program compiled without 'register' attribute\n");
+X    printf ("\n");
+X  }
+X  printf ("Please give the number of runs through the benchmark: ");
+X  {
+X    int n;
+X    scanf ("%d", &n);
+X    Number_Of_Runs = n;
+X  }
+X  printf ("\n");
+X
+X  printf ("Execution starts, %d runs through Dhrystone\n", Number_Of_Runs);
+X
+X  /***************/
+X  /* Start timer */
+X  /***************/
+X 
+X#ifdef TIMES
+X  times (&time_info);
+X  Begin_Time = (long) time_info.tms_utime;
+X#endif
+X#ifdef TIME
+X  Begin_Time = time ( (long *) 0);
+X#endif
+X#ifdef MSC_CLOCK
+X  Begin_Time = clock();
+X#endif
+X
+X  for (Run_Index = 1; Run_Index <= Number_Of_Runs; ++Run_Index)
+X  {
+X
+X    Proc_5();
+X    Proc_4();
+X      /* Ch_1_Glob == 'A', Ch_2_Glob == 'B', Bool_Glob == true */
+X    Int_1_Loc = 2;
+X    Int_2_Loc = 3;
+X    strcpy (Str_2_Loc, "DHRYSTONE PROGRAM, 2'ND STRING");
+X    Enum_Loc = Ident_2;
+X    Bool_Glob = ! Func_2 (Str_1_Loc, Str_2_Loc);
+X      /* Bool_Glob == 1 */
+X    while (Int_1_Loc < Int_2_Loc)  /* loop body executed once */
+X    {
+X      Int_3_Loc = 5 * Int_1_Loc - Int_2_Loc;
+X        /* Int_3_Loc == 7 */
+X      Proc_7 (Int_1_Loc, Int_2_Loc, &Int_3_Loc);
+X        /* Int_3_Loc == 7 */
+X      Int_1_Loc += 1;
+X    } /* while */
+X      /* Int_1_Loc == 3, Int_2_Loc == 3, Int_3_Loc == 7 */
+X    Proc_8 (Arr_1_Glob, Arr_2_Glob, Int_1_Loc, Int_3_Loc);
+X      /* Int_Glob == 5 */
+X    Proc_1 (Ptr_Glob);
+X    for (Ch_Index = 'A'; Ch_Index <= Ch_2_Glob; ++Ch_Index)
+X                             /* loop body executed twice */
+X    {
+X      if (Enum_Loc == Func_1 (Ch_Index, 'C'))
+X          /* then, not executed */
+X        {
+X        Proc_6 (Ident_1, &Enum_Loc);
+X        strcpy (Str_2_Loc, "DHRYSTONE PROGRAM, 3'RD STRING");
+X        Int_2_Loc = Run_Index;
+X        Int_Glob = Run_Index;
+X        }
+X    }
+X      /* Int_1_Loc == 3, Int_2_Loc == 3, Int_3_Loc == 7 */
+X    Int_2_Loc = Int_2_Loc * Int_1_Loc;
+X    Int_1_Loc = Int_2_Loc / Int_3_Loc;
+X    Int_2_Loc = 7 * (Int_2_Loc - Int_3_Loc) - Int_1_Loc;
+X      /* Int_1_Loc == 1, Int_2_Loc == 13, Int_3_Loc == 7 */
+X    Proc_2 (&Int_1_Loc);
+X      /* Int_1_Loc == 5 */
+X
+X  } /* loop "for Run_Index" */
+X
+X  /**************/
+X  /* Stop timer */
+X  /**************/
+X  
+X#ifdef TIMES
+X  times (&time_info);
+X  End_Time = (long) time_info.tms_utime;
+X#endif
+X#ifdef TIME
+X  End_Time = time ( (long *) 0);
+X#endif
+X#ifdef MSC_CLOCK
+X  End_Time = clock();
+X#endif
+X
+X  printf ("Execution ends\n");
+X  printf ("\n");
+X  printf ("Final values of the variables used in the benchmark:\n");
+X  printf ("\n");
+X  printf ("Int_Glob:            %d\n", Int_Glob);
+X  printf ("        should be:   %d\n", 5);
+X  printf ("Bool_Glob:           %d\n", Bool_Glob);
+X  printf ("        should be:   %d\n", 1);
+X  printf ("Ch_1_Glob:           %c\n", Ch_1_Glob);
+X  printf ("        should be:   %c\n", 'A');
+X  printf ("Ch_2_Glob:           %c\n", Ch_2_Glob);
+X  printf ("        should be:   %c\n", 'B');
+X  printf ("Arr_1_Glob[8]:       %d\n", Arr_1_Glob[8]);
+X  printf ("        should be:   %d\n", 7);
+X  printf ("Arr_2_Glob[8][7]:    %d\n", Arr_2_Glob[8][7]);
+X  printf ("        should be:   Number_Of_Runs + 10\n");
+X  printf ("Ptr_Glob->\n");
+X  printf ("  Ptr_Comp:          %d\n", (int) Ptr_Glob->Ptr_Comp);
+X  printf ("        should be:   (implementation-dependent)\n");
+X  printf ("  Discr:             %d\n", Ptr_Glob->Discr);
+X  printf ("        should be:   %d\n", 0);
+X  printf ("  Enum_Comp:         %d\n", Ptr_Glob->variant.var_1.Enum_Comp);
+X  printf ("        should be:   %d\n", 2);
+X  printf ("  Int_Comp:          %d\n", Ptr_Glob->variant.var_1.Int_Comp);
+X  printf ("        should be:   %d\n", 17);
+X  printf ("  Str_Comp:          %s\n", Ptr_Glob->variant.var_1.Str_Comp);
+X  printf ("        should be:   DHRYSTONE PROGRAM, SOME STRING\n");
+X  printf ("Next_Ptr_Glob->\n");
+X  printf ("  Ptr_Comp:          %d\n", (int) Next_Ptr_Glob->Ptr_Comp);
+X  printf ("        should be:   (implementation-dependent), same as above\n");
+X  printf ("  Discr:             %d\n", Next_Ptr_Glob->Discr);
+X  printf ("        should be:   %d\n", 0);
+X  printf ("  Enum_Comp:         %d\n", Next_Ptr_Glob->variant.var_1.Enum_Comp);
+X  printf ("        should be:   %d\n", 1);
+X  printf ("  Int_Comp:          %d\n", Next_Ptr_Glob->variant.var_1.Int_Comp);
+X  printf ("        should be:   %d\n", 18);
+X  printf ("  Str_Comp:          %s\n",
+X                                Next_Ptr_Glob->variant.var_1.Str_Comp);
+X  printf ("        should be:   DHRYSTONE PROGRAM, SOME STRING\n");
+X  printf ("Int_1_Loc:           %d\n", Int_1_Loc);
+X  printf ("        should be:   %d\n", 5);
+X  printf ("Int_2_Loc:           %d\n", Int_2_Loc);
+X  printf ("        should be:   %d\n", 13);
+X  printf ("Int_3_Loc:           %d\n", Int_3_Loc);
+X  printf ("        should be:   %d\n", 7);
+X  printf ("Enum_Loc:            %d\n", Enum_Loc);
+X  printf ("        should be:   %d\n", 1);
+X  printf ("Str_1_Loc:           %s\n", Str_1_Loc);
+X  printf ("        should be:   DHRYSTONE PROGRAM, 1'ST STRING\n");
+X  printf ("Str_2_Loc:           %s\n", Str_2_Loc);
+X  printf ("        should be:   DHRYSTONE PROGRAM, 2'ND STRING\n");
+X  printf ("\n");
+X
+X  User_Time = End_Time - Begin_Time;
+X
+X  if (User_Time < Too_Small_Time)
+X  {
+X    printf ("Measured time too small to obtain meaningful results\n");
+X    printf ("Please increase number of runs\n");
+X    printf ("\n");
+X  }
+X  else
+X  {
+X#ifdef TIME
+X    Microseconds = (float) User_Time * Mic_secs_Per_Second 
+X                        / (float) Number_Of_Runs;
+X    Dhrystones_Per_Second = (float) Number_Of_Runs / (float) User_Time;
+X#else
+X    Microseconds = (float) User_Time * Mic_secs_Per_Second 
+X                        / ((float) HZ * ((float) Number_Of_Runs));
+X    Dhrystones_Per_Second = ((float) HZ * (float) Number_Of_Runs)
+X                        / (float) User_Time;
+X#endif
+X    printf ("Microseconds for one run through Dhrystone: ");
+X    printf ("%6.1f \n", Microseconds);
+X    printf ("Dhrystones per Second:                      ");
+X    printf ("%6.1f \n", Dhrystones_Per_Second);
+X    printf ("\n");
+X  }
+X  
+X}
+X
+X
+XProc_1 (Ptr_Val_Par)
+X/******************/
+X
+XREG Rec_Pointer Ptr_Val_Par;
+X    /* executed once */
+X{
+X  REG Rec_Pointer Next_Record = Ptr_Val_Par->Ptr_Comp;  
+X                                        /* == Ptr_Glob_Next */
+X  /* Local variable, initialized with Ptr_Val_Par->Ptr_Comp,    */
+X  /* corresponds to "rename" in Ada, "with" in Pascal           */
+X  
+X  structassign (*Ptr_Val_Par->Ptr_Comp, *Ptr_Glob); 
+X  Ptr_Val_Par->variant.var_1.Int_Comp = 5;
+X  Next_Record->variant.var_1.Int_Comp 
+X        = Ptr_Val_Par->variant.var_1.Int_Comp;
+X  Next_Record->Ptr_Comp = Ptr_Val_Par->Ptr_Comp;
+X  Proc_3 (&Next_Record->Ptr_Comp);
+X    /* Ptr_Val_Par->Ptr_Comp->Ptr_Comp 
+X                        == Ptr_Glob->Ptr_Comp */
+X  if (Next_Record->Discr == Ident_1)
+X    /* then, executed */
+X  {
+X    Next_Record->variant.var_1.Int_Comp = 6;
+X    Proc_6 (Ptr_Val_Par->variant.var_1.Enum_Comp, 
+X           &Next_Record->variant.var_1.Enum_Comp);
+X    Next_Record->Ptr_Comp = Ptr_Glob->Ptr_Comp;
+X    Proc_7 (Next_Record->variant.var_1.Int_Comp, 10, 
+X           &Next_Record->variant.var_1.Int_Comp);
+X  }
+X  else /* not executed */
+X    structassign (*Ptr_Val_Par, *Ptr_Val_Par->Ptr_Comp);
+X} /* Proc_1 */
+X
+X
+XProc_2 (Int_Par_Ref)
+X/******************/
+X    /* executed once */
+X    /* *Int_Par_Ref == 1, becomes 4 */
+X
+XOne_Fifty   *Int_Par_Ref;
+X{
+X  One_Fifty  Int_Loc;  
+X  Enumeration   Enum_Loc;
+X
+X  Int_Loc = *Int_Par_Ref + 10;
+X  do /* executed once */
+X    if (Ch_1_Glob == 'A')
+X      /* then, executed */
+X    {
+X      Int_Loc -= 1;
+X      *Int_Par_Ref = Int_Loc - Int_Glob;
+X      Enum_Loc = Ident_1;
+X    } /* if */
+X  while (Enum_Loc != Ident_1); /* true */
+X} /* Proc_2 */
+X
+X
+XProc_3 (Ptr_Ref_Par)
+X/******************/
+X    /* executed once */
+X    /* Ptr_Ref_Par becomes Ptr_Glob */
+X
+XRec_Pointer *Ptr_Ref_Par;
+X
+X{
+X  if (Ptr_Glob != Null)
+X    /* then, executed */
+X    *Ptr_Ref_Par = Ptr_Glob->Ptr_Comp;
+X  Proc_7 (10, Int_Glob, &Ptr_Glob->variant.var_1.Int_Comp);
+X} /* Proc_3 */
+X
+X
+XProc_4 () /* without parameters */
+X/*******/
+X    /* executed once */
+X{
+X  Boolean Bool_Loc;
+X
+X  Bool_Loc = Ch_1_Glob == 'A';
+X  Bool_Glob = Bool_Loc | Bool_Glob;
+X  Ch_2_Glob = 'B';
+X} /* Proc_4 */
+X
+X
+XProc_5 () /* without parameters */
+X/*******/
+X    /* executed once */
+X{
+X  Ch_1_Glob = 'A';
+X  Bool_Glob = false;
+X} /* Proc_5 */
+X
+X
+X        /* Procedure for the assignment of structures,          */
+X        /* if the C compiler doesn't support this feature       */
+X#ifdef  NOSTRUCTASSIGN
+Xmemcpy (d, s, l)
+Xregister char   *d;
+Xregister char   *s;
+Xregister int    l;
+X{
+X        while (l--) *d++ = *s++;
+X}
+X#endif
+X
+X
+SHAR_EOF
+fi
+if test -f 'dhry_2.c'
+then
+        echo shar: "will not over-write existing file 'dhry_2.c'"
+else
+sed 's/^X//' << \SHAR_EOF > 'dhry_2.c'
+X/*
+X ****************************************************************************
+X *
+X *                   "DHRYSTONE" Benchmark Program
+X *                   -----------------------------
+X *                                                                            
+X *  Version:    C, Version 2.1
+X *                                                                            
+X *  File:       dhry_2.c (part 3 of 3)
+X *
+X *  Date:       May 17, 1988
+X *
+X *  Author:     Reinhold P. Weicker
+X *
+X ****************************************************************************
+X */
+X
+X#include "dhry.h"
+X
+X#ifndef REG
+X#define REG
+X        /* REG becomes defined as empty */
+X        /* i.e. no register variables   */
+X#endif
+X
+Xextern  int     Int_Glob;
+Xextern  char    Ch_1_Glob;
+X
+X
+XProc_6 (Enum_Val_Par, Enum_Ref_Par)
+X/*********************************/
+X    /* executed once */
+X    /* Enum_Val_Par == Ident_3, Enum_Ref_Par becomes Ident_2 */
+X
+XEnumeration  Enum_Val_Par;
+XEnumeration *Enum_Ref_Par;
+X{
+X  *Enum_Ref_Par = Enum_Val_Par;
+X  if (! Func_3 (Enum_Val_Par))
+X    /* then, not executed */
+X    *Enum_Ref_Par = Ident_4;
+X  switch (Enum_Val_Par)
+X  {
+X    case Ident_1: 
+X      *Enum_Ref_Par = Ident_1;
+X      break;
+X    case Ident_2: 
+X      if (Int_Glob > 100)
+X        /* then */
+X      *Enum_Ref_Par = Ident_1;
+X      else *Enum_Ref_Par = Ident_4;
+X      break;
+X    case Ident_3: /* executed */
+X      *Enum_Ref_Par = Ident_2;
+X      break;
+X    case Ident_4: break;
+X    case Ident_5: 
+X      *Enum_Ref_Par = Ident_3;
+X      break;
+X  } /* switch */
+X} /* Proc_6 */
+X
+X
+XProc_7 (Int_1_Par_Val, Int_2_Par_Val, Int_Par_Ref)
+X/**********************************************/
+X    /* executed three times                                      */ 
+X    /* first call:      Int_1_Par_Val == 2, Int_2_Par_Val == 3,  */
+X    /*                  Int_Par_Ref becomes 7                    */
+X    /* second call:     Int_1_Par_Val == 10, Int_2_Par_Val == 5, */
+X    /*                  Int_Par_Ref becomes 17                   */
+X    /* third call:      Int_1_Par_Val == 6, Int_2_Par_Val == 10, */
+X    /*                  Int_Par_Ref becomes 18                   */
+XOne_Fifty       Int_1_Par_Val;
+XOne_Fifty       Int_2_Par_Val;
+XOne_Fifty      *Int_Par_Ref;
+X{
+X  One_Fifty Int_Loc;
+X
+X  Int_Loc = Int_1_Par_Val + 2;
+X  *Int_Par_Ref = Int_2_Par_Val + Int_Loc;
+X} /* Proc_7 */
+X
+X
+XProc_8 (Arr_1_Par_Ref, Arr_2_Par_Ref, Int_1_Par_Val, Int_2_Par_Val)
+X/*********************************************************************/
+X    /* executed once      */
+X    /* Int_Par_Val_1 == 3 */
+X    /* Int_Par_Val_2 == 7 */
+XArr_1_Dim       Arr_1_Par_Ref;
+XArr_2_Dim       Arr_2_Par_Ref;
+Xint             Int_1_Par_Val;
+Xint             Int_2_Par_Val;
+X{
+X  REG One_Fifty Int_Index;
+X  REG One_Fifty Int_Loc;
+X
+X  Int_Loc = Int_1_Par_Val + 5;
+X  Arr_1_Par_Ref [Int_Loc] = Int_2_Par_Val;
+X  Arr_1_Par_Ref [Int_Loc+1] = Arr_1_Par_Ref [Int_Loc];
+X  Arr_1_Par_Ref [Int_Loc+30] = Int_Loc;
+X  for (Int_Index = Int_Loc; Int_Index <= Int_Loc+1; ++Int_Index)
+X    Arr_2_Par_Ref [Int_Loc] [Int_Index] = Int_Loc;
+X  Arr_2_Par_Ref [Int_Loc] [Int_Loc-1] += 1;
+X  Arr_2_Par_Ref [Int_Loc+20] [Int_Loc] = Arr_1_Par_Ref [Int_Loc];
+X  Int_Glob = 5;
+X} /* Proc_8 */
+X
+X
+XEnumeration Func_1 (Ch_1_Par_Val, Ch_2_Par_Val)
+X/*************************************************/
+X    /* executed three times                                         */
+X    /* first call:      Ch_1_Par_Val == 'H', Ch_2_Par_Val == 'R'    */
+X    /* second call:     Ch_1_Par_Val == 'A', Ch_2_Par_Val == 'C'    */
+X    /* third call:      Ch_1_Par_Val == 'B', Ch_2_Par_Val == 'C'    */
+X
+XCapital_Letter   Ch_1_Par_Val;
+XCapital_Letter   Ch_2_Par_Val;
+X{
+X  Capital_Letter        Ch_1_Loc;
+X  Capital_Letter        Ch_2_Loc;
+X
+X  Ch_1_Loc = Ch_1_Par_Val;
+X  Ch_2_Loc = Ch_1_Loc;
+X  if (Ch_2_Loc != Ch_2_Par_Val)
+X    /* then, executed */
+X    return (Ident_1);
+X  else  /* not executed */
+X  {
+X    Ch_1_Glob = Ch_1_Loc;
+X    return (Ident_2);
+X   }
+X} /* Func_1 */
+X
+X
+XBoolean Func_2 (Str_1_Par_Ref, Str_2_Par_Ref)
+X/*************************************************/
+X    /* executed once */
+X    /* Str_1_Par_Ref == "DHRYSTONE PROGRAM, 1'ST STRING" */
+X    /* Str_2_Par_Ref == "DHRYSTONE PROGRAM, 2'ND STRING" */
+X
+XStr_30  Str_1_Par_Ref;
+XStr_30  Str_2_Par_Ref;
+X{
+X  REG One_Thirty        Int_Loc;
+X      Capital_Letter    Ch_Loc;
+X
+X  Int_Loc = 2;
+X  while (Int_Loc <= 2) /* loop body executed once */
+X    if (Func_1 (Str_1_Par_Ref[Int_Loc],
+X                Str_2_Par_Ref[Int_Loc+1]) == Ident_1)
+X      /* then, executed */
+X    {
+X      Ch_Loc = 'A';
+X      Int_Loc += 1;
+X    } /* if, while */
+X  if (Ch_Loc >= 'W' && Ch_Loc < 'Z')
+X    /* then, not executed */
+X    Int_Loc = 7;
+X  if (Ch_Loc == 'R')
+X    /* then, not executed */
+X    return (true);
+X  else /* executed */
+X  {
+X    if (strcmp (Str_1_Par_Ref, Str_2_Par_Ref) > 0)
+X      /* then, not executed */
+X    {
+X      Int_Loc += 7;
+X      Int_Glob = Int_Loc;
+X      return (true);
+X    }
+X    else /* executed */
+X      return (false);
+X  } /* if Ch_Loc */
+X} /* Func_2 */
+X
+X
+XBoolean Func_3 (Enum_Par_Val)
+X/***************************/
+X    /* executed once        */
+X    /* Enum_Par_Val == Ident_3 */
+XEnumeration Enum_Par_Val;
+X{
+X  Enumeration Enum_Loc;
+X
+X  Enum_Loc = Enum_Par_Val;
+X  if (Enum_Loc == Ident_3)
+X    /* then, executed */
+X    return (true);
+X  else /* not executed */
+X    return (false);
+X} /* Func_3 */
+X
+SHAR_EOF
+fi
+exit 0
+#        End of shell archive
diff --git a/hostsidetests/sustainedperf/dhrystone/LICENSE.TXT b/hostsidetests/sustainedperf/dhrystone/LICENSE.TXT
new file mode 100644
index 0000000..84090c0
--- /dev/null
+++ b/hostsidetests/sustainedperf/dhrystone/LICENSE.TXT
@@ -0,0 +1,70 @@
+==============================================================================
+LLVM Release License
+==============================================================================
+University of Illinois/NCSA
+Open Source License
+
+Copyright (c) 2003-2015 University of Illinois at Urbana-Champaign.
+All rights reserved.
+
+Developed by:
+
+    LLVM Team
+
+    University of Illinois at Urbana-Champaign
+
+    http://llvm.org
+
+Permission is hereby granted, free of charge, to any person obtaining a copy of
+this software and associated documentation files (the "Software"), to deal with
+the Software without restriction, including without limitation the rights to
+use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
+of the Software, and to permit persons to whom the Software is furnished to do
+so, subject to the following conditions:
+
+    * Redistributions of source code must retain the above copyright notice,
+      this list of conditions and the following disclaimers.
+
+    * Redistributions in binary form must reproduce the above copyright notice,
+      this list of conditions and the following disclaimers in the
+      documentation and/or other materials provided with the distribution.
+
+    * Neither the names of the LLVM Team, University of Illinois at
+      Urbana-Champaign, nor the names of its contributors may be used to
+      endorse or promote products derived from this Software without specific
+      prior written permission.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
+FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
+CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS WITH THE
+SOFTWARE.
+
+==============================================================================
+Copyrights and Licenses for Third Party Software Distributed with LLVM:
+==============================================================================
+The LLVM software contains code written by third parties.  Such software will
+have its own individual LICENSE.TXT file in the directory in which it appears.
+This file will describe the copyrights, license, and restrictions which apply
+to that code.
+
+The disclaimer of warranty in the University of Illinois Open Source License
+applies to all code in the LLVM Distribution, and nothing in any of the
+other licenses gives permission to use the names of the LLVM Team or the
+University of Illinois to endorse or promote products derived from this
+Software.
+
+The following pieces of software have additional or alternate copyrights,
+licenses, and/or restrictions:
+
+Program             Directory
+-------             ---------
+Autoconf            llvm/autoconf
+                    llvm/projects/ModuleMaker/autoconf
+Google Test         llvm/utils/unittest/googletest
+OpenBSD regex       llvm/lib/Support/{reg*, COPYRIGHT.regex}
+pyyaml tests        llvm/test/YAMLParser/{*.data, LICENSE.TXT}
+ARM contributions   llvm/lib/Target/ARM/LICENSE.TXT
+md5 contributions   llvm/lib/Support/MD5.cpp llvm/include/llvm/Support/MD5.h
diff --git a/hostsidetests/sustainedperf/dhrystone/Rationale b/hostsidetests/sustainedperf/dhrystone/Rationale
new file mode 100644
index 0000000..0d93e10
--- /dev/null
+++ b/hostsidetests/sustainedperf/dhrystone/Rationale
@@ -0,0 +1,360 @@
+Dhrystone Benchmark: Rationale for Version 2 and Measurement Rules
+
+                 Reinhold P. Weicker
+                 Siemens AG, E STE 35
+                 Postfach 3240
+                 D-8520 Erlangen
+                 Germany (West)
+
+
+
+
+The Dhrystone benchmark program [1] has become a popular benchmark  for
+CPU/compiler  performance  measurement,  in  particular  in the area of
+minicomputers, workstations, PC's and  microprocesors.   It  apparently
+satisfies a need for an easy-to-use integer benchmark; it gives a first
+performance indication which  is  more  meaningful  than  MIPS  numbers
+which,  in  their  literal  meaning  (million instructions per second),
+cannot be used across different instruction sets (e.g. RISC vs.  CISC).
+With  the  increasing  use  of  the  benchmark,  it  seems necessary to
+reconsider the benchmark and to check whether it can still fulfill this
+function.   Version  2  of  Dhrystone  is  the  result  of  such  a re-
+evaluation, it has been made for two reasons:
+
+o Dhrystone has been published in Ada [1], and Versions in Ada,  Pascal
+  and  C  have  been  distributed  by Reinhold Weicker via floppy disk.
+  However, the version that was used most often  for  benchmarking  has
+  been  the version made by Rick Richardson by another translation from
+  the Ada version into the C programming language, this  has  been  the
+  version distributed via the UNIX network Usenet [2].
+
+  There is an obvious need for a common C version of Dhrystone, since C
+  is  at  present  the most popular system programming language for the
+  class of systems (microcomputers, minicomputers, workstations)  where
+  Dhrystone  is  used  most.  There should be, as far as possible, only
+  one C version of Dhrystone such that results can be compared  without
+  restrictions.  In  the  past,  the  C  versions  distributed  by Rick
+  Richardson (Version 1.1) and by Reinhold Weicker  had  small  (though
+  not significant) differences.
+
+  Together with the new C version, the Ada  and  Pascal  versions  have
+  been updated as well.
+
+o As far as it is possible without changes to the Dhrystone statistics,
+  optimizing  compilers  should  be prevented from removing significant
+  statements.  It has turned out in the past that optimizing  compilers
+  suppressed  code  generation  for  too many statements (by "dead code
+  removal" or "dead variable  elimination").   This  has  lead  to  the
+  danger  that  benchmarking results obtained by a naive application of
+  Dhrystone - without inspection of the code that was generated - could
+  become meaningless.
+
+The overall policiy for version 2 has been  that  the  distribution  of
+statements,  operand types and operand locality described in [1] should
+remain  unchanged  as  much  as  possible.   (Very  few  changes   were
+necessary;  their  impact  should  be  negligible.)  Also, the order of
+statements should  remain  unchanged.  Although  I  am  aware  of  some
+critical  remarks on the benchmark - I agree with several of them - and
+know some suggestions for improvement, I  didn't  want  to  change  the
+benchmark  into  something  different  from  what  has  become known as
+"Dhrystone"; the confusion generated by such a  change  would  probably
+outweight  the  benefits. If I were to write a new benchmark program, I
+wouldn't give it the name "Dhrystone" since this  denotes  the  program
+published in [1].  However, I do recognize the need for a larger number
+of representative programs that can be used as benchmarks; users should
+always be encouraged to use more than just one benchmark.
+
+The  new  versions  (version  2.1  for  C,  Pascal  and  Ada)  will  be
+distributed  as  widely as possible.  (Version 2.1 differs from version
+2.0 distributed via the UNIX Network Usenet in March 1988 only in a few
+corrections  for  minor  deficiencies  found  by users of version 2.0.)
+Readers who want to use the benchmark for their  own  measurements  can
+obtain  a copy in machine-readable form on floppy disk (MS-DOS or XENIX
+format) from the author.
+
+
+In general, version 2 follows - in the parts that are  significant  for
+performance  measurement,  i.e.   within  the  measurement  loop  - the
+published (Ada) version and  the  C  versions  previously  distributed.
+Where  the  versions  distributed  by  Rick Richardson [2] and Reinhold
+Weicker have been different, it  follows  the  version  distributed  by
+Reinhold  Weicker.  (However,  the  differences have been so small that
+their impact on execution time in all likelihood has been  negligible.)
+The  initialization  and  UNIX  instrumentation  part  - which had been
+omitted in [1] - follows mostly  the  ideas  of  Rick  Richardson  [2].
+However,  any changes in the initialization part and in the printing of
+the result have no impact on performance  measurement  since  they  are
+outside  the  measaurement  loop.   As a concession to older compilers,
+names have been made unique within the first 8  characters  for  the  C
+version.
+
+The original publication of Dhrystone did not  contain  any  statements
+for  time  measurement  since  they  are  necessarily system-dependent.
+However, it turned out that it is not enough just to inclose  the  main
+procedure of Dhrystone in a loop and to measure the execution time.  If
+the variables that are computed are not  used  somehow,  there  is  the
+danger  that  the  compiler  considers  them  as  "dead  variables" and
+suppresses code generation for a part of the statements.  Therefore  in
+version  2  all  variables  of  "main"  are  printed  at the end of the
+program. This  also  permits  some  plausibility  control  for  correct
+execution of the benchmark.
+
+At several places in the benchmark, code has been added,  but  only  in
+branches  that  are  not  executed.  The  intention  is that optimizing
+compilers should be prevented from moving code out of  the  measurement
+loop,  or  from  removing code altogether. Statements that are executed
+have been changed in very few places only.  In these  cases,  only  the
+role  of  some operands has been changed, and it was made sure that the
+numbers  defining  the  "Dhrystone   distribution"   (distribution   of
+statements, operand types and locality) still hold as much as possible.
+Except for sophisticated  optimizing  compilers,  execution  times  for
+version 2.1 should be the same as for previous versions.
+
+Because of the self-imposed limitation that the order and  distribution
+of the executed statements should not be changed, there are still cases
+where optimizing compilers may not generate code for  some  statements.
+To   a   certain  degree,  this  is  unavoidable  for  small  synthetic
+benchmarks.  Users of the benchmark are advised to check code  listings
+whether code is generated for all statements of Dhrystone.
+
+Contrary to the suggestion in the published paper and  its  realization
+in  the  versions  previously  distributed, no attempt has been made to
+subtract the time for the measurement loop overhead. (This  calculation
+has  proven  difficult  to implement in a correct way, and its omission
+makes the program simpler.) However, since the loop check is  now  part
+of  the benchmark, this does have an impact - though a very minor one -
+on the  distribution  statistics  which  have  been  updated  for  this
+version.
+
+
+In this section, all changes are described that affect the  measurement
+loop and that are not just renamings of variables. All remarks refer to
+the C version; the other language versions have been updated similarly.
+
+In addition to adding the measurement loop and the printout statements,
+changes have been made at the following places:
+
+o In procedure "main", three statements have been  added  in  the  non-
+  executed "then" part of the statement
+    if (Enum_Loc == Func_1 (Ch_Index, 'C'))
+  they are
+    strcpy (Str_2_Loc, "DHRYSTONE PROGRAM, 3'RD STRING");
+    Int_2_Loc = Run_Index;
+    Int_Glob = Run_Index;
+  The string assignment prevents movement of the  preceding  assignment
+  to  Str_2_Loc  (5'th statement of "main") out of the measurement loop
+  (This probably will not happen for the C version, but it  did  happen
+  with  another  language  and  compiler.)  The assignment to Int_2_Loc
+  prevents value propagation  for  Int_2_Loc,  and  the  assignment  to
+  Int_Glob  makes  the  value  of  Int_Glob possibly dependent from the
+  value of Run_Index.
+
+o In the three arithmetic computations at the end  of  the  measurement
+  loop  in  "main  ", the role of some variables has been exchanged, to
+  prevent the division from just cancelling out the  multiplication  as
+  it  was in [1].  A very smart compiler might have recognized this and
+  suppressed code generation for the division.
+
+o For Proc_2, no code has been changed, but the values  of  the  actual
+  parameter have changed due to changes in "main".
+
+o In Proc_4, the second assignment has been changed from
+    Bool_Loc = Bool_Loc | Bool_Glob;
+  to
+    Bool_Glob = Bool_Loc | Bool_Glob;
+  It now assigns a value to  a  global  variable  instead  of  a  local
+  variable (Bool_Loc); Bool_Loc would be a "dead variable" which is not
+  used afterwards.
+
+o In Func_1, the statement
+    Ch_1_Glob = Ch_1_Loc;
+  was added in the non-executed "else" part of the "if"  statement,  to
+  prevent  the  suppression  of  code  generation for the assignment to
+  Ch_1_Loc.
+
+o In Func_2, the second character comparison statement has been changed
+  to
+    if (Ch_Loc == 'R')
+  ('R' instead of 'X') because a comparison with 'X' is implied in  the
+  preceding "if" statement.
+
+  Also in Func_2, the statement
+    Int_Glob = Int_Loc;
+  has been added in the non-executed part of the last  "if"  statement,
+  in order to prevent Int_Loc from becoming a dead variable.
+
+o In Func_3, a non-executed "else" part has  been  added  to  the  "if"
+  statement.   While  the  program  would not be incorrect without this
+  "else" part, it is considered bad programming practice if a  function
+  can be left without a return value.
+
+  To compensate for this change, the (non-executed) "else" part in  the
+  "if" statement of Proc_3 was removed.
+
+The distribution statistics have been changed only by the  addition  of
+the  measurement  loop  iteration (1 additional statement, 4 additional
+local integer operands) and  by  the  change  in  Proc_4  (one  operand
+changed  from  local  to  global).  The  distribution statistics in the
+comment headers have been updated accordingly.
+
+
+The string operations (string assignment and  string  comparison)  have
+not  been  changed,  to  keep  the program consistent with the original
+version.
+
+There has been some  concern  that  the  string  operations  are  over-
+represented  in  the  program,  and that execution time is dominated by
+these  operations.   This  was  true  in  particular  when   optimizing
+compilers  removed  too much code in the main part of the program, this
+should have been mitigated in version 2.
+
+It should be noted that this is a language-dependent issue:   Dhrystone
+was  first published in Ada, and with Ada or Pascal semantics, the time
+spent in the string operations is,  at  least  in  all  implementations
+known  to  me, considerably smaller.  In Ada and Pascal, assignment and
+comparison of strings are operators defined in the  language,  and  the
+upper  bounds of the strings occuring in Dhrystone are part of the type
+information known at compilation time.   The  compilers  can  therefore
+generate efficient inline code.  In C, string assignemt and comparisons
+are not part  of  the  language,  so  the  string  operations  must  be
+expressed  in  terms  of the C library functions "strcpy" and "strcmp".
+(ANSI  C  allows  an  implementation  to  use  inline  code  for  these
+functions.)   In addition to the overhead caused by additional function
+calls, these functions are defined for  null-terminated  strings  where
+the  length  of  the  strings  is  not  known  at compilation time; the
+function has to check every byte for  the  termination  condition  (the
+null byte).
+
+Obviously, a C library which includes efficiently  coded  "strcpy"  and
+"strcmp"  functions  helps to obtain good Dhrystone results. However, I
+don't think that this is unfair since string functions do  occur  quite
+frequently  in real programs (editors, command interpreters, etc.).  If
+the strings functions are  implemented  efficiently,  this  helps  real
+programs as well as benchmark programs.
+
+I admit that the string comparison in Dhrystone terminates later (after
+scanning  20 characters) than most string comparisons in real programs.
+For consistency with  the  original  benchmark,  I  didn't  change  the
+program despite this weakness.
+
+
+When Dhrystone is used, the following "ground rules" apply:
+
+o Separate compilation (Ada and C versions)
+
+  As  mentioned  in  [1],  Dhrystone  was  written  to  reflect  actual
+  programming  practice  in  systems  programming.   The  division into
+  several compilation units (5 in the Ada version, 2 in the C  version)
+  is  intended, as is the distribution of inter-module and intra-module
+  subprogram  calls.   Although  on  many  systems  there  will  be  no
+  difference  in  execution  time  to  a  Dhrystone  version  where all
+  compilation units are merged into one file, the rule is that separate
+  compilation  should  be used.  The intention is that real programming
+  practice, where programs consist of  several  independently  compiled
+  units, should be reflected.  This also has implies that the compiler,
+  while compiling one  unit,  has  no  information  about  the  use  of
+  variables,  register  allocation  etc.  occuring in other compilation
+  units.  Although in real life  compilation  units  will  probably  be
+  larger,  the  intention is that these effects of separate compilation
+  are modeled in Dhrystone.
+
+  A few  language  systems  have  post-linkage  optimization  available
+  (e.g.,  final  register allocation is performed after linkage).  This
+  is a borderline case: Post-linkage optimization  involves  additional
+  program  preparation time (although not as much as compilation in one
+  unit) which may prevent its general use in practical programming.   I
+  think that since it defeats the intentions given above, it should not
+  be used for Dhrystone.
+
+  Unfortunately, ISO/ANSI Pascal does not contain language features for
+  separate  compilation.   Although  most  commercial  Pascal compilers
+  provide separate compilation in  some  way,  we  cannot  use  it  for
+  Dhrystone  since such a version would not be portable.  Therefore, no
+  attempt has been made  to  provide  a  Pascal  version  with  several
+  compilation units.
+
+o No procedure merging
+
+  Although  Dhrystone  contains  some  very  short   procedures   where
+  execution  would  benefit  from  procedure  merging  (inlining, macro
+  expansion of procedures), procedure merging is not to be  used.   The
+  reason is that the percentage of procedure and function calls is part
+  of the "Dhrystone distribution" of statements contained in [1].  This
+  restriction  does  not hold for the string functions of the C version
+  since ANSI C allows an implementation to use inline  code  for  these
+  functions.
+
+
+
+o Other optimizations are allowed, but they should be indicated
+
+  It is  often  hard  to  draw  an  exact  line  between  "normal  code
+  generation"  and  "optimization" in compilers: Some compilers perform
+  operations by default that are invoked in other compilers  only  when
+  optimization  is explicitly requested.  Also, we cannot avoid that in
+  benchmarking people try to achieve  results  that  look  as  good  as
+  possible.   Therefore,  optimizations  performed by compilers - other
+  than those listed above - are not forbidden when Dhrystone  execution
+  times  are measured.  Dhrystone is not intended to be non-optimizable
+  but is intended to be similarly optimizable as normal programs.   For
+  example,  there  are  several  places  in Dhrystone where performance
+  benefits from optimizations like  common  subexpression  elimination,
+  value propagation etc., but normal programs usually also benefit from
+  these optimizations.  Therefore, no effort was made  to  artificially
+  prevent  such  optimizations.   However,  measurement  reports should
+  indicate which compiler  optimization  levels  have  been  used,  and
+  reporting  results with different levels of compiler optimization for
+  the same hardware is encouraged.
+
+o Default results are those without "register" declarations (C version)
+
+  When Dhrystone results are quoted without  additional  qualification,
+  they  should  be  understood  as  results obtained without use of the
+  "register" attribute. Good compilers should be able to make good  use
+  of  registers  even  without  explicit register declarations ([3], p.
+  193).
+
+Of  course,  for  experimental  purposes,  post-linkage   optimization,
+procedure  merging  and/or  compilation  in  one  unit  can  be done to
+determine their effects.  However,  Dhrystone  numbers  obtained  under
+these   conditions  should  be  explicitly  marked  as  such;  "normal"
+Dhrystone results should be understood as  results  obtained  following
+the ground rules listed above.
+
+In any case, for serious performance evaluation, users are  advised  to
+ask  for  code listings and to check them carefully.  In this way, when
+results for different systems  are  compared,  the  reader  can  get  a
+feeling how much performance difference is due to compiler optimization
+and how much is due to hardware speed.
+
+
+The C version 2.1 of Dhrystone has been developed in  cooperation  with
+Rick Richardson (Tinton Falls, NJ), it incorporates many ideas from the
+"Version 1.1" distributed previously  by  him  over  the  UNIX  network
+Usenet.  Through  his  activity with Usenet, Rick Richardson has made a
+very valuable contribution to the dissemination of  the  benchmark.   I
+also  thank  Chaim  Benedelac  (National  Semiconductor),  David Ditzel
+(SUN), Earl Killian and John  Mashey  (MIPS),  Alan  Smith  and  Rafael
+Saavedra-Barrera  (UC  at  Berkeley)  for  their  help with comments on
+earlier versions of the benchmark.
+
+
+[1]
+   Reinhold P. Weicker:  Dhrystone:  A  Synthetic  Systems  Programming
+   Benchmark.
+   Communications of the ACM 27, 10 (Oct. 1984), 1013-1030
+
+[2]
+   Rick Richardson: Dhrystone 1.1 Benchmark Summary (and Program Text)
+   Informal Distribution via "Usenet", Last Version Known to me:  Sept.
+   21, 1987
+
+[3]
+   Brian W.  Kernighan  and  Dennis  M.  Ritchie:   The  C  Programming
+   Language.
+   Prentice-Hall, Englewood Cliffs (NJ) 1978
+
+
+
+
+
diff --git a/hostsidetests/sustainedperf/dhrystone/dhry.h b/hostsidetests/sustainedperf/dhrystone/dhry.h
new file mode 100644
index 0000000..ef96b41
--- /dev/null
+++ b/hostsidetests/sustainedperf/dhrystone/dhry.h
@@ -0,0 +1,436 @@
+/*
+ ****************************************************************************
+ *
+ *                   "DHRYSTONE" Benchmark Program
+ *                   -----------------------------
+ *                                                                            
+ *  Version:    C, Version 2.1
+ *                                                                            
+ *  File:       dhry.h (part 1 of 3)
+ *
+ *  Date:       May 17, 1988
+ *
+ *  Author:     Reinhold P. Weicker
+ *                      Siemens AG, E STE 35
+ *                      Postfach 3240
+ *                      8520 Erlangen
+ *                      Germany (West)
+ *                              Phone:  [xxx-49]-9131-7-20330
+ *                                      (8-17 Central European Time)
+ *                              Usenet: ..!mcvax!unido!estevax!weicker
+ *
+ *              Original Version (in Ada) published in
+ *              "Communications of the ACM" vol. 27., no. 10 (Oct. 1984),
+ *              pp. 1013 - 1030, together with the statistics
+ *              on which the distribution of statements etc. is based.
+ *
+ *              In this C version, the following C library functions are used:
+ *              - strcpy, strcmp (inside the measurement loop)
+ *              - printf, scanf (outside the measurement loop)
+ *              In addition, Berkeley UNIX system calls "times ()" or "time ()"
+ *              are used for execution time measurement. For measurements
+ *              on other systems, these calls have to be changed.
+ *
+ *  Collection of Results:
+ *              Reinhold Weicker (address see above) and
+ *              
+ *              Rick Richardson
+ *              PC Research. Inc.
+ *              94 Apple Orchard Drive
+ *              Tinton Falls, NJ 07724
+ *                      Phone:  (201) 389-8963 (9-17 EST)               
+ *                      Usenet: ...!uunet!pcrat!rick
+ *
+ *      Please send results to Rick Richardson and/or Reinhold Weicker.
+ *      Complete information should be given on hardware and software used.
+ *      Hardware information includes: Machine type, CPU, type and size
+ *      of caches; for microprocessors: clock frequency, memory speed
+ *      (number of wait states).
+ *      Software information includes: Compiler (and runtime library)
+ *      manufacturer and version, compilation switches, OS version.
+ *      The Operating System version may give an indication about the
+ *      compiler; Dhrystone itself performs no OS calls in the measurement loop.
+ *
+ *      The complete output generated by the program should be mailed
+ *      such that at least some checks for correctness can be made.
+ *
+ ***************************************************************************
+ *
+ *  History:    This version C/2.1 has been made for two reasons:
+ *
+ *              1) There is an obvious need for a common C version of
+ *              Dhrystone, since C is at present the most popular system
+ *              programming language for the class of processors
+ *              (microcomputers, minicomputers) where Dhrystone is used most.
+ *              There should be, as far as possible, only one C version of
+ *              Dhrystone such that results can be compared without
+ *              restrictions. In the past, the C versions distributed
+ *              by Rick Richardson (Version 1.1) and by Reinhold Weicker
+ *              had small (though not significant) differences.
+ *
+ *              2) As far as it is possible without changes to the Dhrystone
+ *              statistics, optimizing compilers should be prevented from
+ *              removing significant statements.
+ *
+ *              This C version has been developed in cooperation with
+ *              Rick Richardson (Tinton Falls, NJ), it incorporates many
+ *              ideas from the "Version 1.1" distributed previously by
+ *              him over the UNIX network Usenet.
+ *              I also thank Chaim Benedelac (National Semiconductor),
+ *              David Ditzel (SUN), Earl Killian and John Mashey (MIPS),
+ *              Alan Smith and Rafael Saavedra-Barrera (UC at Berkeley)
+ *              for their help with comments on earlier versions of the
+ *              benchmark.
+ *
+ *  Changes:    In the initialization part, this version follows mostly
+ *              Rick Richardson's version distributed via Usenet, not the
+ *              version distributed earlier via floppy disk by Reinhold Weicker.
+ *              As a concession to older compilers, names have been made
+ *              unique within the first 8 characters.
+ *              Inside the measurement loop, this version follows the
+ *              version previously distributed by Reinhold Weicker.
+ *
+ *              At several places in the benchmark, code has been added,
+ *              but within the measurement loop only in branches that 
+ *              are not executed. The intention is that optimizing compilers
+ *              should be prevented from moving code out of the measurement
+ *              loop, or from removing code altogether. Since the statements
+ *              that are executed within the measurement loop have NOT been
+ *              changed, the numbers defining the "Dhrystone distribution"
+ *              (distribution of statements, operand types and locality)
+ *              still hold. Except for sophisticated optimizing compilers,
+ *              execution times for this version should be the same as
+ *              for previous versions.
+ *              
+ *              Since it has proven difficult to subtract the time for the
+ *              measurement loop overhead in a correct way, the loop check
+ *              has been made a part of the benchmark. This does have
+ *              an impact - though a very minor one - on the distribution
+ *              statistics which have been updated for this version.
+ *
+ *              All changes within the measurement loop are described
+ *              and discussed in the companion paper "Rationale for
+ *              Dhrystone version 2".
+ *
+ *              Because of the self-imposed limitation that the order and
+ *              distribution of the executed statements should not be
+ *              changed, there are still cases where optimizing compilers
+ *              may not generate code for some statements. To a certain
+ *              degree, this is unavoidable for small synthetic benchmarks.
+ *              Users of the benchmark are advised to check code listings
+ *              whether code is generated for all statements of Dhrystone.
+ *
+ *              Version 2.1 is identical to version 2.0 distributed via
+ *              the UNIX network Usenet in March 1988 except that it corrects
+ *              some minor deficiencies that were found by users of version 2.0.
+ *              The following corrections have been made in the C version:
+ *              - The assignment to Number_Of_Runs was changed
+ *              - The constant Too_Small_Time was changed
+ *              - An "else" part was added to the "if" statement in Func_3;
+ *                for compensation, an "else" part was removed in Proc_3
+ *              - Shorter file names are used
+ *
+ ***************************************************************************
+ *
+ * Defines:     The following "Defines" are possible:
+ *              -DREG=register          (default: Not defined)
+ *                      As an approximation to what an average C programmer
+ *                      might do, the "register" storage class is applied
+ *                      (if enabled by -DREG=register)
+ *                      - for local variables, if they are used (dynamically)
+ *                        five or more times
+ *                      - for parameters if they are used (dynamically)
+ *                        six or more times
+ *                      Note that an optimal "register" strategy is
+ *                      compiler-dependent, and that "register" declarations
+ *                      do not necessarily lead to faster execution.
+ *              -DNOSTRUCTASSIGN        (default: Not defined)
+ *                      Define if the C compiler does not support
+ *                      assignment of structures.
+ *              -DNOENUMS               (default: Not defined)
+ *                      Define if the C compiler does not support
+ *                      enumeration types.
+ *              -DTIMES                 (default)
+ *              -DTIME
+ *                      The "times" function of UNIX (returning process times)
+ *                      or the "time" function (returning wallclock time)
+ *                      is used for measurement. 
+ *                      For single user machines, "time ()" is adequate. For
+ *                      multi-user machines where you cannot get single-user
+ *                      access, use the "times ()" function. If you have
+ *                      neither, use a stopwatch in the dead of night.
+ *                      "printf"s are provided marking the points "Start Timer"
+ *                      and "Stop Timer". DO NOT use the UNIX "time(1)"
+ *                      command, as this will measure the total time to
+ *                      run this program, which will (erroneously) include
+ *                      the time to allocate storage (malloc) and to perform
+ *                      the initialization.
+ *              -DHZ=nnn
+ *                      In Berkeley UNIX, the function "times" returns process
+ *                      time in 1/HZ seconds, with HZ = 60 for most systems.
+ *                      CHECK YOUR SYSTEM DESCRIPTION BEFORE YOU JUST APPLY
+ *                      A VALUE.
+ *
+ ***************************************************************************
+ *
+ *  Compilation model and measurement (IMPORTANT):
+ *
+ *  This C version of Dhrystone consists of three files:
+ *  - dhry.h (this file, containing global definitions and comments)
+ *  - dhry_1.c (containing the code corresponding to Ada package Pack_1)
+ *  - dhry_2.c (containing the code corresponding to Ada package Pack_2)
+ *
+ *  The following "ground rules" apply for measurements:
+ *  - Separate compilation
+ *  - No procedure merging
+ *  - Otherwise, compiler optimizations are allowed but should be indicated
+ *  - Default results are those without register declarations
+ *  See the companion paper "Rationale for Dhrystone Version 2" for a more
+ *  detailed discussion of these ground rules.
+ *
+ *  For 16-Bit processors (e.g. 80186, 80286), times for all compilation
+ *  models ("small", "medium", "large" etc.) should be given if possible,
+ *  together with a definition of these models for the compiler system used.
+ *
+ **************************************************************************
+ *
+ *  Dhrystone (C version) statistics:
+ *
+ *  [Comment from the first distribution, updated for version 2.
+ *   Note that because of language differences, the numbers are slightly
+ *   different from the Ada version.]
+ *
+ *  The following program contains statements of a high level programming
+ *  language (here: C) in a distribution considered representative:           
+ *
+ *    assignments                  52 (51.0 %)
+ *    control statements           33 (32.4 %)
+ *    procedure, function calls    17 (16.7 %)
+ *
+ *  103 statements are dynamically executed. The program is balanced with
+ *  respect to the three aspects:                                             
+ *
+ *    - statement type
+ *    - operand type
+ *    - operand locality
+ *         operand global, local, parameter, or constant.                     
+ *
+ *  The combination of these three aspects is balanced only approximately.    
+ *
+ *  1. Statement Type:                                                        
+ *  -----------------             number
+ *
+ *     V1 = V2                     9
+ *       (incl. V1 = F(..)
+ *     V = Constant               12
+ *     Assignment,                 7
+ *       with array element
+ *     Assignment,                 6
+ *       with record component
+ *                                --
+ *                                34       34
+ *
+ *     X = Y +|-|"&&"|"|" Z        5
+ *     X = Y +|-|"==" Constant     6
+ *     X = X +|- 1                 3
+ *     X = Y *|/ Z                 2
+ *     X = Expression,             1
+ *           two operators
+ *     X = Expression,             1
+ *           three operators
+ *                                --
+ *                                18       18
+ *
+ *     if ....                    14
+ *       with "else"      7
+ *       without "else"   7
+ *           executed        3
+ *           not executed    4
+ *     for ...                     7  |  counted every time
+ *     while ...                   4  |  the loop condition
+ *     do ... while                1  |  is evaluated
+ *     switch ...                  1
+ *     break                       1
+ *     declaration with            1
+ *       initialization
+ *                                --
+ *                                34       34
+ *
+ *     P (...)  procedure call    11
+ *       user procedure      10
+ *       library procedure    1
+ *     X = F (...)
+ *             function  call      6
+ *       user function        5                                         
+ *       library function     1                                               
+ *                                --                                          
+ *                                17       17
+ *                                        ---
+ *                                        103
+ *
+ *    The average number of parameters in procedure or function calls
+ *    is 1.82 (not counting the function values as implicit parameters).
+ *
+ *
+ *  2. Operators
+ *  ------------
+ *                          number    approximate
+ *                                    percentage
+ *
+ *    Arithmetic             32          50.8                                 
+ *
+ *       +                     21          33.3                              
+ *       -                      7          11.1                              
+ *       *                      3           4.8
+ *       / (int div)            1           1.6
+ *
+ *    Comparison             27           42.8
+ *
+ *       ==                     9           14.3
+ *       /=                     4            6.3
+ *       >                      1            1.6
+ *       <                      3            4.8
+ *       >=                     1            1.6
+ *       <=                     9           14.3
+ *
+ *    Logic                   4            6.3
+ *
+ *       && (AND-THEN)          1            1.6
+ *       |  (OR)                1            1.6
+ *       !  (NOT)               2            3.2
+ * 
+ *                           --          -----
+ *                           63          100.1
+ *
+ *
+ *  3. Operand Type (counted once per operand reference):
+ *  ---------------
+ *                          number    approximate
+ *                                    percentage
+ *
+ *     Integer               175        72.3 %
+ *     Character              45        18.6 %
+ *     Pointer                12         5.0 %
+ *     String30                6         2.5 %
+ *     Array                   2         0.8 %
+ *     Record                  2         0.8 %
+ *                           ---       -------
+ *                           242       100.0 %
+ *
+ *  When there is an access path leading to the final operand (e.g. a record
+ *  component), only the final data type on the access path is counted.       
+ *
+ *
+ *  4. Operand Locality:                                                      
+ *  -------------------
+ *                                number    approximate
+ *                                          percentage
+ *
+ *     local variable              114        47.1 %
+ *     global variable              22         9.1 %
+ *     parameter                    45        18.6 %
+ *        value                        23         9.5 %
+ *        reference                    22         9.1 %
+ *     function result               6         2.5 %
+ *     constant                     55        22.7 %
+ *                                 ---       -------
+ *                                 242       100.0 %
+ *
+ *
+ *  The program does not compute anything meaningful, but it is syntactically
+ *  and semantically correct. All variables have a value assigned to them
+ *  before they are used as a source operand.
+ *
+ *  There has been no explicit effort to account for the effects of a
+ *  cache, or to balance the use of long or short displacements for code or
+ *  data.
+ *
+ ***************************************************************************
+ */
+
+/* Compiler and system dependent definitions: */
+
+#ifndef TIME
+#ifndef TIMES
+#define TIMES
+#endif
+#endif
+                /* Use times(2) time function unless    */
+                /* explicitly defined otherwise         */
+
+#ifdef MSC_CLOCK
+#undef HZ
+#undef TIMES
+#include <time.h>
+#define HZ        CLK_TCK
+#endif
+                /* Use Microsoft C hi-res clock */
+
+#ifdef TIMES
+#include <sys/types.h>
+#include <sys/times.h>
+                /* for "times" */
+#endif
+
+#define Mic_secs_Per_Second     1000000.0
+                /* Berkeley UNIX C returns process times in seconds/HZ */
+
+#ifdef  NOSTRUCTASSIGN
+#define structassign(d, s)      memcpy(&(d), &(s), sizeof(d))
+#else
+#define structassign(d, s)      d = s
+#endif
+
+#ifdef  NOENUM
+#define Ident_1 0
+#define Ident_2 1
+#define Ident_3 2
+#define Ident_4 3
+#define Ident_5 4
+  typedef int   Enumeration;
+#else
+  typedef       enum    {Ident_1, Ident_2, Ident_3, Ident_4, Ident_5}
+                Enumeration;
+#endif
+        /* for boolean and enumeration types in Ada, Pascal */
+
+/* General definitions: */
+
+#include <stdio.h>
+                /* for strcpy, strcmp */
+
+#define Null 0 
+                /* Value of a Null pointer */
+#define true  1
+#define false 0
+
+typedef int     One_Thirty;
+typedef int     One_Fifty;
+typedef char    Capital_Letter;
+typedef int     Boolean;
+typedef char    Str_30 [31];
+typedef int     Arr_1_Dim [50];
+typedef int     Arr_2_Dim [50] [50];
+
+typedef struct record 
+    {
+    struct record *Ptr_Comp;
+    Enumeration    Discr;
+    union {
+          struct {
+                  Enumeration Enum_Comp;
+                  int         Int_Comp;
+                  char        Str_Comp [31];
+                  } var_1;
+          struct {
+                  Enumeration E_Comp_2;
+                  char        Str_2_Comp [31];
+                  } var_2;
+          struct {
+                  char        Ch_1_Comp;
+                  char        Ch_2_Comp;
+                  } var_3;
+          } variant;
+      } Rec_Type, *Rec_Pointer;
+
+
diff --git a/hostsidetests/sustainedperf/dhrystone/dhry_1.c b/hostsidetests/sustainedperf/dhrystone/dhry_1.c
new file mode 100644
index 0000000..c1198d1
--- /dev/null
+++ b/hostsidetests/sustainedperf/dhrystone/dhry_1.c
@@ -0,0 +1,318 @@
+/*
+ ****************************************************************************
+ *
+ *                   "DHRYSTONE" Benchmark Program
+ *                   -----------------------------
+ *                                                                            
+ *  Version:    C, Version 2.1
+ *                                                                            
+ *  File:       dhry_1.c (part 2 of 3)
+ *
+ *  Date:       May 17, 1988
+ *
+ *  Author:     Reinhold P. Weicker
+ *
+ ****************************************************************************
+ */
+
+#include "dhry.h"
+
+/* Global Variables: */
+
+Rec_Pointer     Ptr_Glob,
+                Next_Ptr_Glob;
+int             Int_Glob;
+Boolean         Bool_Glob;
+char            Ch_1_Glob,
+                Ch_2_Glob;
+int             Arr_1_Glob [50];
+int             Arr_2_Glob [50] [50];
+
+extern char     *malloc ();
+Enumeration     Func_1 ();
+  /* forward declaration necessary since Enumeration may not simply be int */
+
+#ifndef REG
+        Boolean Reg = false;
+#define REG
+        /* REG becomes defined as empty */
+        /* i.e. no register variables   */
+#else
+        Boolean Reg = true;
+#endif
+
+/* variables for time measurement: */
+
+#ifdef TIMES
+struct tms      time_info;
+extern  int     times ();
+                /* see library function "times" */
+#define Too_Small_Time (2*HZ)
+                /* Measurements should last at least about 2 seconds */
+#endif
+#ifdef TIME
+extern long     time();
+                /* see library function "time"  */
+#define Too_Small_Time 2
+                /* Measurements should last at least 2 seconds */
+#endif
+#ifdef MSC_CLOCK
+extern clock_t        clock();
+#define Too_Small_Time (2*HZ)
+#endif
+
+long            Begin_Time,
+                End_Time,
+                User_Time;
+float           Microseconds,
+                Dhrystones_Per_Second;
+
+/* end of variables for time measurement */
+
+
+main ()
+/*****/
+
+  /* main program, corresponds to procedures        */
+  /* Main and Proc_0 in the Ada version             */
+{
+        One_Fifty       Int_1_Loc;
+  REG   One_Fifty       Int_2_Loc;
+        One_Fifty       Int_3_Loc;
+  REG   char            Ch_Index;
+        Enumeration     Enum_Loc;
+        Str_30          Str_1_Loc;
+        Str_30          Str_2_Loc;
+  REG   int             Run_Index;
+  REG   int             Number_Of_Runs;
+
+  /* Initializations */
+
+  Next_Ptr_Glob = (Rec_Pointer) malloc (sizeof (Rec_Type));
+  Ptr_Glob = (Rec_Pointer) malloc (sizeof (Rec_Type));
+
+  Ptr_Glob->Ptr_Comp                    = Next_Ptr_Glob;
+  Ptr_Glob->Discr                       = Ident_1;
+  Ptr_Glob->variant.var_1.Enum_Comp     = Ident_3;
+  Ptr_Glob->variant.var_1.Int_Comp      = 40;
+  strcpy (Ptr_Glob->variant.var_1.Str_Comp, 
+          "DHRYSTONE PROGRAM, SOME STRING");
+  strcpy (Str_1_Loc, "DHRYSTONE PROGRAM, 1'ST STRING");
+
+  Arr_2_Glob [8][7] = 10;
+        /* Was missing in published program. Without this statement,    */
+        /* Arr_2_Glob [8][7] would have an undefined value.             */
+        /* Warning: With 16-Bit processors and Number_Of_Runs > 32000,  */
+        /* overflow may occur for this array element.                   */
+     int n;
+     scanf ("%d", &n);
+     Number_Of_Runs = n;
+
+
+  /***************/
+  /* Start timer */
+  /***************/
+ 
+#ifdef TIMES
+  times (&time_info);
+  Begin_Time = (long) time_info.tms_utime;
+#endif
+#ifdef TIME
+  Begin_Time = time ( (long *) 0);
+#endif
+#ifdef MSC_CLOCK
+  Begin_Time = clock();
+#endif
+
+  for (Run_Index = 1; Run_Index <= Number_Of_Runs; ++Run_Index)
+  {
+
+    Proc_5();
+    Proc_4();
+      /* Ch_1_Glob == 'A', Ch_2_Glob == 'B', Bool_Glob == true */
+    Int_1_Loc = 2;
+    Int_2_Loc = 3;
+    strcpy (Str_2_Loc, "DHRYSTONE PROGRAM, 2'ND STRING");
+    Enum_Loc = Ident_2;
+    Bool_Glob = ! Func_2 (Str_1_Loc, Str_2_Loc);
+      /* Bool_Glob == 1 */
+    while (Int_1_Loc < Int_2_Loc)  /* loop body executed once */
+    {
+      Int_3_Loc = 5 * Int_1_Loc - Int_2_Loc;
+        /* Int_3_Loc == 7 */
+      Proc_7 (Int_1_Loc, Int_2_Loc, &Int_3_Loc);
+        /* Int_3_Loc == 7 */
+      Int_1_Loc += 1;
+    } /* while */
+      /* Int_1_Loc == 3, Int_2_Loc == 3, Int_3_Loc == 7 */
+    Proc_8 (Arr_1_Glob, Arr_2_Glob, Int_1_Loc, Int_3_Loc);
+      /* Int_Glob == 5 */
+    Proc_1 (Ptr_Glob);
+    for (Ch_Index = 'A'; Ch_Index <= Ch_2_Glob; ++Ch_Index)
+                             /* loop body executed twice */
+    {
+      if (Enum_Loc == Func_1 (Ch_Index, 'C'))
+          /* then, not executed */
+        {
+        Proc_6 (Ident_1, &Enum_Loc);
+        strcpy (Str_2_Loc, "DHRYSTONE PROGRAM, 3'RD STRING");
+        Int_2_Loc = Run_Index;
+        Int_Glob = Run_Index;
+        }
+    }
+      /* Int_1_Loc == 3, Int_2_Loc == 3, Int_3_Loc == 7 */
+    Int_2_Loc = Int_2_Loc * Int_1_Loc;
+    Int_1_Loc = Int_2_Loc / Int_3_Loc;
+    Int_2_Loc = 7 * (Int_2_Loc - Int_3_Loc) - Int_1_Loc;
+      /* Int_1_Loc == 1, Int_2_Loc == 13, Int_3_Loc == 7 */
+    Proc_2 (&Int_1_Loc);
+      /* Int_1_Loc == 5 */
+
+  } /* loop "for Run_Index" */
+
+  /**************/
+  /* Stop timer */
+  /**************/
+  
+#ifdef TIMES
+  times (&time_info);
+  End_Time = (long) time_info.tms_utime;
+#endif
+#ifdef TIME
+  End_Time = time ( (long *) 0);
+#endif
+#ifdef MSC_CLOCK
+  End_Time = clock();
+#endif
+  User_Time = End_Time - Begin_Time;
+
+  if (User_Time < Too_Small_Time)
+  {
+    printf ("Measured time too small to obtain meaningful results\n");
+    printf ("Please increase number of runs\n");
+    printf ("\n");
+  }
+  else
+  {
+#ifdef TIME
+    Microseconds = (float) User_Time * Mic_secs_Per_Second 
+                        / (float) Number_Of_Runs;
+    Dhrystones_Per_Second = (float) Number_Of_Runs / (float) User_Time;
+#else
+    Microseconds = (float) User_Time * Mic_secs_Per_Second 
+                        / ((float) HZ * ((float) Number_Of_Runs));
+    Dhrystones_Per_Second = ((float) HZ * (float) Number_Of_Runs)
+                        / (float) User_Time;
+#endif
+    printf ("%6.1f \n", Dhrystones_Per_Second);
+  }
+  
+}
+
+
+Proc_1 (Ptr_Val_Par)
+/******************/
+
+REG Rec_Pointer Ptr_Val_Par;
+    /* executed once */
+{
+  REG Rec_Pointer Next_Record = Ptr_Val_Par->Ptr_Comp;  
+                                        /* == Ptr_Glob_Next */
+  /* Local variable, initialized with Ptr_Val_Par->Ptr_Comp,    */
+  /* corresponds to "rename" in Ada, "with" in Pascal           */
+  
+  structassign (*Ptr_Val_Par->Ptr_Comp, *Ptr_Glob); 
+  Ptr_Val_Par->variant.var_1.Int_Comp = 5;
+  Next_Record->variant.var_1.Int_Comp 
+        = Ptr_Val_Par->variant.var_1.Int_Comp;
+  Next_Record->Ptr_Comp = Ptr_Val_Par->Ptr_Comp;
+  Proc_3 (&Next_Record->Ptr_Comp);
+    /* Ptr_Val_Par->Ptr_Comp->Ptr_Comp 
+                        == Ptr_Glob->Ptr_Comp */
+  if (Next_Record->Discr == Ident_1)
+    /* then, executed */
+  {
+    Next_Record->variant.var_1.Int_Comp = 6;
+    Proc_6 (Ptr_Val_Par->variant.var_1.Enum_Comp, 
+           &Next_Record->variant.var_1.Enum_Comp);
+    Next_Record->Ptr_Comp = Ptr_Glob->Ptr_Comp;
+    Proc_7 (Next_Record->variant.var_1.Int_Comp, 10, 
+           &Next_Record->variant.var_1.Int_Comp);
+  }
+  else /* not executed */
+    structassign (*Ptr_Val_Par, *Ptr_Val_Par->Ptr_Comp);
+return 0; } /* Proc_1 */
+
+
+Proc_2 (Int_Par_Ref)
+/******************/
+    /* executed once */
+    /* *Int_Par_Ref == 1, becomes 4 */
+
+One_Fifty   *Int_Par_Ref;
+{
+  One_Fifty  Int_Loc;  
+  Enumeration   Enum_Loc;
+
+  Int_Loc = *Int_Par_Ref + 10;
+  do /* executed once */
+    if (Ch_1_Glob == 'A')
+      /* then, executed */
+    {
+      Int_Loc -= 1;
+      *Int_Par_Ref = Int_Loc - Int_Glob;
+      Enum_Loc = Ident_1;
+    } /* if */
+  while (Enum_Loc != Ident_1); /* true */
+return 0; } /* Proc_2 */
+
+
+Proc_3 (Ptr_Ref_Par)
+/******************/
+    /* executed once */
+    /* Ptr_Ref_Par becomes Ptr_Glob */
+
+Rec_Pointer *Ptr_Ref_Par;
+
+{
+  if (Ptr_Glob != Null)
+    /* then, executed */
+    *Ptr_Ref_Par = Ptr_Glob->Ptr_Comp;
+  Proc_7 (10, Int_Glob, &Ptr_Glob->variant.var_1.Int_Comp);
+return 0; } /* Proc_3 */
+
+
+Proc_4 () /* without parameters */
+/*******/
+    /* executed once */
+{
+  Boolean Bool_Loc;
+
+  Bool_Loc = Ch_1_Glob == 'A';
+  Bool_Glob = Bool_Loc | Bool_Glob;
+  Ch_2_Glob = 'B';
+return 0; } /* Proc_4 */
+
+
+Proc_5 () /* without parameters */
+/*******/
+    /* executed once */
+{
+  Ch_1_Glob = 'A';
+  Bool_Glob = false;
+return 0; } /* Proc_5 */
+
+
+        /* Procedure for the assignment of structures,          */
+        /* if the C compiler doesn't support this feature       */
+#ifdef  NOSTRUCTASSIGN
+memcpy (d, s, l)
+register char   *d;
+register char   *s;
+register int    l;
+{
+        while (l--) *d++ = *s++;
+}
+#endif
+
+
diff --git a/hostsidetests/sustainedperf/dhrystone/dhry_2.c b/hostsidetests/sustainedperf/dhrystone/dhry_2.c
new file mode 100644
index 0000000..3166a7e
--- /dev/null
+++ b/hostsidetests/sustainedperf/dhrystone/dhry_2.c
@@ -0,0 +1,192 @@
+/*
+ ****************************************************************************
+ *
+ *                   "DHRYSTONE" Benchmark Program
+ *                   -----------------------------
+ *                                                                            
+ *  Version:    C, Version 2.1
+ *                                                                            
+ *  File:       dhry_2.c (part 3 of 3)
+ *
+ *  Date:       May 17, 1988
+ *
+ *  Author:     Reinhold P. Weicker
+ *
+ ****************************************************************************
+ */
+
+#include "dhry.h"
+
+#ifndef REG
+#define REG
+        /* REG becomes defined as empty */
+        /* i.e. no register variables   */
+#endif
+
+extern  int     Int_Glob;
+extern  char    Ch_1_Glob;
+
+
+Proc_6 (Enum_Val_Par, Enum_Ref_Par)
+/*********************************/
+    /* executed once */
+    /* Enum_Val_Par == Ident_3, Enum_Ref_Par becomes Ident_2 */
+
+Enumeration  Enum_Val_Par;
+Enumeration *Enum_Ref_Par;
+{
+  *Enum_Ref_Par = Enum_Val_Par;
+  if (! Func_3 (Enum_Val_Par))
+    /* then, not executed */
+    *Enum_Ref_Par = Ident_4;
+  switch (Enum_Val_Par)
+  {
+    case Ident_1: 
+      *Enum_Ref_Par = Ident_1;
+      break;
+    case Ident_2: 
+      if (Int_Glob > 100)
+        /* then */
+      *Enum_Ref_Par = Ident_1;
+      else *Enum_Ref_Par = Ident_4;
+      break;
+    case Ident_3: /* executed */
+      *Enum_Ref_Par = Ident_2;
+      break;
+    case Ident_4: break;
+    case Ident_5: 
+      *Enum_Ref_Par = Ident_3;
+      break;
+  } /* switch */
+return 0; } /* Proc_6 */
+
+
+Proc_7 (Int_1_Par_Val, Int_2_Par_Val, Int_Par_Ref)
+/**********************************************/
+    /* executed three times                                      */ 
+    /* first call:      Int_1_Par_Val == 2, Int_2_Par_Val == 3,  */
+    /*                  Int_Par_Ref becomes 7                    */
+    /* second call:     Int_1_Par_Val == 10, Int_2_Par_Val == 5, */
+    /*                  Int_Par_Ref becomes 17                   */
+    /* third call:      Int_1_Par_Val == 6, Int_2_Par_Val == 10, */
+    /*                  Int_Par_Ref becomes 18                   */
+One_Fifty       Int_1_Par_Val;
+One_Fifty       Int_2_Par_Val;
+One_Fifty      *Int_Par_Ref;
+{
+  One_Fifty Int_Loc;
+
+  Int_Loc = Int_1_Par_Val + 2;
+  *Int_Par_Ref = Int_2_Par_Val + Int_Loc;
+return 0; } /* Proc_7 */
+
+
+Proc_8 (Arr_1_Par_Ref, Arr_2_Par_Ref, Int_1_Par_Val, Int_2_Par_Val)
+/*********************************************************************/
+    /* executed once      */
+    /* Int_Par_Val_1 == 3 */
+    /* Int_Par_Val_2 == 7 */
+Arr_1_Dim       Arr_1_Par_Ref;
+Arr_2_Dim       Arr_2_Par_Ref;
+int             Int_1_Par_Val;
+int             Int_2_Par_Val;
+{
+  REG One_Fifty Int_Index;
+  REG One_Fifty Int_Loc;
+
+  Int_Loc = Int_1_Par_Val + 5;
+  Arr_1_Par_Ref [Int_Loc] = Int_2_Par_Val;
+  Arr_1_Par_Ref [Int_Loc+1] = Arr_1_Par_Ref [Int_Loc];
+  Arr_1_Par_Ref [Int_Loc+30] = Int_Loc;
+  for (Int_Index = Int_Loc; Int_Index <= Int_Loc+1; ++Int_Index)
+    Arr_2_Par_Ref [Int_Loc] [Int_Index] = Int_Loc;
+  Arr_2_Par_Ref [Int_Loc] [Int_Loc-1] += 1;
+  Arr_2_Par_Ref [Int_Loc+20] [Int_Loc] = Arr_1_Par_Ref [Int_Loc];
+  Int_Glob = 5;
+return 0; } /* Proc_8 */
+
+
+Enumeration Func_1 (Ch_1_Par_Val, Ch_2_Par_Val)
+/*************************************************/
+    /* executed three times                                         */
+    /* first call:      Ch_1_Par_Val == 'H', Ch_2_Par_Val == 'R'    */
+    /* second call:     Ch_1_Par_Val == 'A', Ch_2_Par_Val == 'C'    */
+    /* third call:      Ch_1_Par_Val == 'B', Ch_2_Par_Val == 'C'    */
+
+Capital_Letter   Ch_1_Par_Val;
+Capital_Letter   Ch_2_Par_Val;
+{
+  Capital_Letter        Ch_1_Loc;
+  Capital_Letter        Ch_2_Loc;
+
+  Ch_1_Loc = Ch_1_Par_Val;
+  Ch_2_Loc = Ch_1_Loc;
+  if (Ch_2_Loc != Ch_2_Par_Val)
+    /* then, executed */
+    return (Ident_1);
+  else  /* not executed */
+  {
+    Ch_1_Glob = Ch_1_Loc;
+    return (Ident_2);
+   }
+} /* Func_1 */
+
+
+Boolean Func_2 (Str_1_Par_Ref, Str_2_Par_Ref)
+/*************************************************/
+    /* executed once */
+    /* Str_1_Par_Ref == "DHRYSTONE PROGRAM, 1'ST STRING" */
+    /* Str_2_Par_Ref == "DHRYSTONE PROGRAM, 2'ND STRING" */
+
+Str_30  Str_1_Par_Ref;
+Str_30  Str_2_Par_Ref;
+{
+  REG One_Thirty        Int_Loc;
+      Capital_Letter    Ch_Loc;
+
+  Int_Loc = 2;
+  while (Int_Loc <= 2) /* loop body executed once */
+    if (Func_1 (Str_1_Par_Ref[Int_Loc],
+                Str_2_Par_Ref[Int_Loc+1]) == Ident_1)
+      /* then, executed */
+    {
+      Ch_Loc = 'A';
+      Int_Loc += 1;
+    } /* if, while */
+  if (Ch_Loc >= 'W' && Ch_Loc < 'Z')
+    /* then, not executed */
+    Int_Loc = 7;
+  if (Ch_Loc == 'R')
+    /* then, not executed */
+    return (true);
+  else /* executed */
+  {
+    if (strcmp (Str_1_Par_Ref, Str_2_Par_Ref) > 0)
+      /* then, not executed */
+    {
+      Int_Loc += 7;
+      Int_Glob = Int_Loc;
+      return (true);
+    }
+    else /* executed */
+      return (false);
+  } /* if Ch_Loc */
+} /* Func_2 */
+
+
+Boolean Func_3 (Enum_Par_Val)
+/***************************/
+    /* executed once        */
+    /* Enum_Par_Val == Ident_3 */
+Enumeration Enum_Par_Val;
+{
+  Enumeration Enum_Loc;
+
+  Enum_Loc = Enum_Par_Val;
+  if (Enum_Loc == Ident_3)
+    /* then, executed */
+    return (true);
+  else /* not executed */
+    return (false);
+} /* Func_3 */
+
diff --git a/hostsidetests/sustainedperf/shadertoy_android/Android.mk b/hostsidetests/sustainedperf/shadertoy_android/Android.mk
new file mode 100644
index 0000000..0c6c2a4
--- /dev/null
+++ b/hostsidetests/sustainedperf/shadertoy_android/Android.mk
@@ -0,0 +1,38 @@
+# Copyright (C) 2008 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+LOCAL_PATH:= $(call my-dir)
+
+include $(CLEAR_VARS)
+
+# don't include this package in any target
+LOCAL_MODULE_TAGS := tests
+# and when built explicitly put it in the data partition
+LOCAL_MODULE_PATH := $(TARGET_OUT_DATA_APPS)
+
+# Include both the 32 and 64 bit versions
+LOCAL_MULTILIB := both
+
+LOCAL_JNI_SHARED_LIBRARIES := libgltest libc++
+#LOCAL_SHARED_LIBRARIES := libc++
+#LOCAL_STATIC_LIBRARIES := libc++_static
+LOCAL_SRC_FILES := $(call all-java-files-under, src)
+LOCAL_PACKAGE_NAME := CtsSustainedPerformanceTestCases
+
+LOCAL_SDK_VERSION := current
+
+# Tag this module as a cts test artifact
+LOCAL_COMPATIBILITY_SUITE := cts
+include $(BUILD_PACKAGE)
+include $(call all-makefiles-under,$(LOCAL_PATH))
diff --git a/hostsidetests/sustainedperf/shadertoy_android/AndroidManifest.xml b/hostsidetests/sustainedperf/shadertoy_android/AndroidManifest.xml
new file mode 100644
index 0000000..77dee18
--- /dev/null
+++ b/hostsidetests/sustainedperf/shadertoy_android/AndroidManifest.xml
@@ -0,0 +1,41 @@
+<?xml version="1.0" encoding="utf-8"?>

+<!--

+/*

+**

+** Copyright 2009, The Android Open Source Project

+**

+** Licensed under the Apache License, Version 2.0 (the "License");

+** you may not use this file except in compliance with the License.

+** You may obtain a copy of the License at

+**

+**     http://www.apache.org/licenses/LICENSE-2.0

+**

+** Unless required by applicable law or agreed to in writing, software

+** distributed under the License is distributed on an "AS IS" BASIS,

+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.

+** See the License for the specific language governing permissions and

+** limitations under the License.

+*/

+-->

+

+<manifest xmlns:android="http://schemas.android.com/apk/res/android"

+    package="com.android.gputest">

+    <application

+            android:label="@string/gpustresstest_activity">

+        <activity android:name="GPUStressTestActivity"

+                android:theme="@android:style/Theme.NoTitleBar.Fullscreen"

+                android:launchMode="singleTask"

+                android:configChanges="orientation|keyboardHidden">

+            <intent-filter>

+                <action android:name="android.intent.action.MAIN" />

+                <category android:name="android.intent.category.LAUNCHER" />

+            </intent-filter>

+        </activity>

+    </application>

+    <uses-feature android:glEsVersion="0x00020000"/>

+    <uses-sdk android:minSdkVersion="5"/>

+    <uses-permission android:name="android.permission.INTERNET" />

+    <uses-permission android:name="com.qti.permission.PROFILER" />

+    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>

+    <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>

+</manifest>

diff --git a/hostsidetests/sustainedperf/shadertoy_android/jni/Android.mk b/hostsidetests/sustainedperf/shadertoy_android/jni/Android.mk
new file mode 100644
index 0000000..c06bac2
--- /dev/null
+++ b/hostsidetests/sustainedperf/shadertoy_android/jni/Android.mk
@@ -0,0 +1,29 @@
+# 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.

+#

+

+LOCAL_PATH:= $(call my-dir)

+

+include $(CLEAR_VARS)

+

+LOCAL_MODULE    := libgltest

+

+LOCAL_SRC_FILES := shaders.cpp \

+                   shadertoy_renderer.cpp \

+                   shadertoy_shader.cpp \

+                   hooks_android.cpp \

+                   utils.cpp

+

+LOCAL_LDLIBS    := -llog -lGLESv2 -lEGL

+include $(BUILD_SHARED_LIBRARY)

diff --git a/hostsidetests/sustainedperf/shadertoy_android/jni/Application.mk b/hostsidetests/sustainedperf/shadertoy_android/jni/Application.mk
new file mode 100644
index 0000000..433f6cf
--- /dev/null
+++ b/hostsidetests/sustainedperf/shadertoy_android/jni/Application.mk
@@ -0,0 +1,23 @@
+# 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.

+#

+

+NDK_TOOLCHAIN_VERSION := 4.8

+APP_ABI := armeabi-v7a

+APP_PLATFORM := android-22

+

+#  Enable C++11. However, pthread, rtti and exceptions aren’t enabled

+APP_CPPFLAGS += -std=c++11

+APP_STL := gnustl_static

+LOCAL_C_INCLUDES += ${ANDROID_NDK}/sources/cxx-stl/gnu-libstdc++/4.8/include

diff --git a/hostsidetests/sustainedperf/shadertoy_android/jni/hooks_android.cpp b/hostsidetests/sustainedperf/shadertoy_android/jni/hooks_android.cpp
new file mode 100644
index 0000000..d6b83f4
--- /dev/null
+++ b/hostsidetests/sustainedperf/shadertoy_android/jni/hooks_android.cpp
@@ -0,0 +1,36 @@
+/*

+ * 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.

+ */

+

+#include <jni.h>

+

+extern void Init(int width, int height);

+extern void DrawFrame();

+extern void Cleanup();

+

+extern "C" {

+    JNIEXPORT void JNICALL Java_com_android_gputest_GLtestLib_init(JNIEnv * env, jobject obj,  jint width, jint height);

+    JNIEXPORT void JNICALL Java_com_android_gputest_GLtestLib_step(JNIEnv * env, jobject obj);

+};

+

+JNIEXPORT void JNICALL Java_com_android_gputest_GLtestLib_init(__attribute__((unused)) JNIEnv * env,__attribute__((unused)) jobject obj,  jint width, jint height)

+{

+    Init(width, height);

+}

+

+JNIEXPORT void JNICALL Java_com_android_gputest_GLtestLib_step(__attribute__((unused)) JNIEnv * env,__attribute__((unused)) jobject obj)

+{

+    DrawFrame();

+}

diff --git a/hostsidetests/sustainedperf/shadertoy_android/jni/shaders.cpp b/hostsidetests/sustainedperf/shadertoy_android/jni/shaders.cpp
new file mode 100644
index 0000000..105652d
--- /dev/null
+++ b/hostsidetests/sustainedperf/shadertoy_android/jni/shaders.cpp
@@ -0,0 +1,152 @@
+/*

+ * 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.

+ */

+

+#include <string>

+

+std::string g_shader = R"(

+

+// various noise functions

+float Hash2d(vec2 uv)

+{

+    float f = uv.x + uv.y * 47.0;

+    return fract(cos(f*3.333)*100003.9);

+}

+float Hash3d(vec3 uv)

+{

+    float f = uv.x + uv.y * 37.0 + uv.z * 521.0;

+    return fract(cos(f*3.333)*100003.9);

+}

+float mixP(float f0, float f1, float a)

+{

+    return mix(f0, f1, a*a*(3.0-2.0*a));

+}

+const vec2 zeroOne = vec2(0.0, 1.0);

+float noise2d(vec2 uv)

+{

+    vec2 fr = fract(uv.xy);

+    vec2 fl = floor(uv.xy);

+    float h00 = Hash2d(fl);

+    float h10 = Hash2d(fl + zeroOne.yx);

+    float h01 = Hash2d(fl + zeroOne);

+    float h11 = Hash2d(fl + zeroOne.yy);

+    return mixP(mixP(h00, h10, fr.x), mixP(h01, h11, fr.x), fr.y);

+}

+float noise2dT(vec2 uv)

+{

+    vec2 fr = fract(uv);

+    vec2 smooth = fr*fr*(3.0-2.0*fr);

+    vec2 fl = floor(uv);

+    uv = smooth + fl;

+    return texture2D(iChannel0, (uv + 0.5)/iChannelResolution[0].xy).y; // use constant here instead?

+}

+float noise(vec3 uv)

+{

+    vec3 fr = fract(uv.xyz);

+    vec3 fl = floor(uv.xyz);

+    float h000 = Hash3d(fl);

+    float h100 = Hash3d(fl + zeroOne.yxx);

+    float h010 = Hash3d(fl + zeroOne.xyx);

+    float h110 = Hash3d(fl + zeroOne.yyx);

+    float h001 = Hash3d(fl + zeroOne.xxy);

+    float h101 = Hash3d(fl + zeroOne.yxy);

+    float h011 = Hash3d(fl + zeroOne.xyy);

+    float h111 = Hash3d(fl + zeroOne.yyy);

+    return mixP(

+        mixP(mixP(h000, h100, fr.x), mixP(h010, h110, fr.x), fr.y),

+        mixP(mixP(h001, h101, fr.x), mixP(h011, h111, fr.x), fr.y)

+        , fr.z);

+}

+

+float PI=3.14159265;

+

+vec3 saturate(vec3 a)

+{

+    return clamp(a, 0.0, 1.0);

+}

+vec2 saturate(vec2 a)

+{

+    return clamp(a, 0.0, 1.0);

+}

+float saturate(float a)

+{

+    return clamp(a, 0.0, 1.0);

+}

+

+float Density(vec3 p)

+{

+    //float ws = 0.06125*0.125;

+    //vec3 warp = vec3(noise(p*ws), noise(p*ws + 111.11), noise(p*ws + 7111.11));

+    float final = noise(p*0.06125);// + sin(iGlobalTime)*0.5-1.95 + warp.x*4.0;

+    float other = noise(p*0.06125 + 1234.567);

+    other -= 0.5;

+    final -= 0.5;

+    final = 0.1/(abs(final*final*other));

+    final += 0.5;

+    return final*0.0001;

+}

+

+void mainImage( out vec4 fragColor, in vec2 fragCoord )

+{

+    // ---------------- First, set up the camera rays for ray marching ----------------

+    vec2 uv = fragCoord.xy/iResolution.xy * 2.0 - 1.0;// - 0.5;

+

+    // Camera up vector.

+    vec3 camUp=vec3(0,1,0); // vuv

+

+    // Camera lookat.

+    vec3 camLookat=vec3(0,0.0,0);   // vrp

+

+    float mx=iMouse.x/iResolution.x*PI*2.0 + iGlobalTime * 0.01;

+    float my=-iMouse.y/iResolution.y*10.0 + sin(iGlobalTime * 0.03)*0.2+0.2;//*PI/2.01;

+    vec3 camPos=vec3(cos(my)*cos(mx),sin(my),cos(my)*sin(mx))*(200.2);  // prp

+

+    // Camera setup.

+    vec3 camVec=normalize(camLookat - camPos);//vpn

+    vec3 sideNorm=normalize(cross(camUp, camVec));  // u

+    vec3 upNorm=cross(camVec, sideNorm);//v

+    vec3 worldFacing=(camPos + camVec);//vcv

+    vec3 worldPix = worldFacing + uv.x * sideNorm * (iResolution.x/iResolution.y) + uv.y * upNorm;//scrCoord

+    vec3 relVec = normalize(worldPix - camPos);//scp

+

+    // --------------------------------------------------------------------------------

+    float t = 0.0;

+    float inc = 0.02;

+    float maxDepth = 70.0;

+    vec3 pos = vec3(0,0,0);

+    float density = 0.0;

+    // ray marching time

+    for (int i = 0; i < 37; i++)    // This is the count of how many times the ray actually marches.

+    {

+        if ((t > maxDepth)) break;

+        pos = camPos + relVec * t;

+        float temp = Density(pos);

+        //temp *= saturate(t-1.0);

+

+        inc = 1.9 + temp*0.05;  // add temp because this makes it look extra crazy!

+        density += temp * inc;

+        t += inc;

+    }

+

+    // --------------------------------------------------------------------------------

+    // Now that we have done our ray marching, let's put some color on this.

+    vec3 finalColor = vec3(0.01,0.1,1.0)* density*0.2;

+

+    // output the final color with sqrt for "gamma correction"

+    fragColor = vec4(sqrt(clamp(finalColor, 0.0, 1.0)),1.0);

+}

+

+

+)";

diff --git a/hostsidetests/sustainedperf/shadertoy_android/jni/shadertoy_renderer.cpp b/hostsidetests/sustainedperf/shadertoy_android/jni/shadertoy_renderer.cpp
new file mode 100644
index 0000000..7718784
--- /dev/null
+++ b/hostsidetests/sustainedperf/shadertoy_android/jni/shadertoy_renderer.cpp
@@ -0,0 +1,131 @@
+/*

+ * 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.

+ */

+

+#include "shadertoy_shader.h"

+#include "utils.h"

+

+#include <fstream>

+#include <sstream>

+#include <android/log.h>

+

+int g_framebuffer_width = 0;

+int g_framebuffer_height = 0;

+GLuint g_quad_vao = 0;

+

+ShadertoyShader shader;

+

+#define  LOG_TAG    "GPUStressTestActivity"

+#define  LOGI(...)  __android_log_print(ANDROID_LOG_INFO,LOG_TAG,__VA_ARGS__)

+#define  LOGE(...)  __android_log_print(ANDROID_LOG_ERROR,LOG_TAG,__VA_ARGS__)

+

+double NowInMs() {

+  timespec timeval;

+  clock_gettime(CLOCK_REALTIME, &timeval);

+  double time = 1000.0 * timeval.tv_sec + (double) timeval.tv_nsec / 1e6;

+  return time;

+}

+

+

+GLuint CreateFullscreenQuad() {

+  GLfloat quadVertices[] = {

+    // Positions

+    -1.0f, 1.0f,

+    -1.0f, -1.0f,

+    1.0f, -1.0f,

+

+    -1.0f, 1.0f,

+    1.0f, -1.0f,

+    1.0f, 1.0f,

+  };

+

+  // Setup screen VAO

+  GLuint quadVAO, quadVBO;

+  glGenVertexArrays(1, &quadVAO);

+  glGenBuffers(1, &quadVBO);

+  glBindVertexArray(quadVAO);

+  glBindBuffer(GL_ARRAY_BUFFER, quadVBO);

+  glBufferData(GL_ARRAY_BUFFER, sizeof(quadVertices), &quadVertices, GL_STATIC_DRAW);

+  glEnableVertexAttribArray(0);

+  glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, 2 * sizeof(GLfloat), (GLvoid*)0);

+  glBindVertexArray(0);

+

+  return quadVAO;

+}

+

+void CreateShader() {

+  extern std::string g_shader;

+  shader.CreateShaderFromString(g_shader);

+}

+

+void Init(int width, int height) {

+  GLint num_extensions = 0;

+  glGetIntegerv(GL_NUM_EXTENSIONS, &num_extensions);

+  for (GLint i = 0; i < num_extensions; ++i) {

+    const char* extension = (char*)(

+      glGetStringi(GL_EXTENSIONS, i));

+  }

+

+  g_framebuffer_width = width;

+  g_framebuffer_height = height;

+

+

+  CreateShader();

+  g_quad_vao = CreateFullscreenQuad();

+}

+

+void DrawFrame() {

+  static double previous_time = 0;

+  static float angle = 0.0f;

+  static double elapsed_time_sum = 0;

+  static double gpu_timer_elapsed_sum = 0;

+  static double start_time = NowInMs();

+

+  // After how many frames to report the avg frame time.

+  int kFrameReportInterval = 1;

+  static int frame_count = 0;

+

+  frame_count++;

+  if (frame_count == kFrameReportInterval) {

+    LOGI("%f\n", elapsed_time_sum / (double)kFrameReportInterval);

+

+    frame_count = 0;

+    elapsed_time_sum = 0;

+    gpu_timer_elapsed_sum = 0;

+  }

+

+  double current_time = NowInMs();

+  double elapsed_time = current_time - previous_time;

+  previous_time = current_time;

+  elapsed_time_sum += elapsed_time;

+  float global_time = (float)(NowInMs() - start_time);

+

+  glViewport(0, 0, g_framebuffer_width, g_framebuffer_height);

+

+  glClearColor(0.2f, 0.3f, 0.3f, 1.0f);

+  glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

+

+  float fov = 45;

+

+  shader.PrepareForDraw(g_framebuffer_width, g_framebuffer_height, global_time, frame_count, (float)elapsed_time);

+

+  glBindVertexArray(g_quad_vao);

+

+  glDrawArrays(GL_TRIANGLES, 0, 6);

+}

+

+void Cleanup() {

+

+}

diff --git a/hostsidetests/sustainedperf/shadertoy_android/jni/shadertoy_shader.cpp b/hostsidetests/sustainedperf/shadertoy_android/jni/shadertoy_shader.cpp
new file mode 100644
index 0000000..c74876d
--- /dev/null
+++ b/hostsidetests/sustainedperf/shadertoy_android/jni/shadertoy_shader.cpp
@@ -0,0 +1,157 @@
+/*

+ * 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.

+ */

+

+#include "shadertoy_shader.h"

+#include "utils.h"

+

+#define _USE_MATH_DEFINES

+#include <math.h>

+

+namespace {

+bool CompileShader10(GLuint shader, const std::string& shader_string) {

+  std::string prefix = "#version 100\n";

+  std::string string_with_prefix = prefix + shader_string;

+  const char* shader_str[] = { string_with_prefix.data() };

+  glShaderSource(shader, 1, shader_str, NULL);

+  glCompileShader(shader);

+

+  GLint success;

+  GLchar infoLog[512];

+  glGetShaderiv(shader, GL_COMPILE_STATUS, &success);

+  if (!success)

+  {

+    glGetShaderInfoLog(shader, 512, NULL, infoLog);

+    LOGI("Shader Failed to compile: %s -- %s\n", *shader_str, infoLog);

+    return false;

+  }

+  return true;

+}

+};  // namespace

+

+

+ShadertoyShader::ShadertoyShader() :

+ uiResolution_(-1), uiGlobalTime_(-1), uiFrame_(-1), uiTimeDelta_(-1),

+ uiChannel0_(-1), unViewport_(-1), unCorners_(-1), shader_program_(0) {

+

+  GLuint tex_ids[4];

+  glGenTextures(4, &tex_ids[0]);

+  for (int ii = 0; ii < 4; ii++) {

+    input_textures_[ii].width = 0;

+    input_textures_[ii].height = 0;

+    input_textures_[ii].id = tex_ids[ii];

+  }

+}

+

+ShadertoyShader::~ShadertoyShader() {

+  GLuint ids[] = { input_textures_[0].id, input_textures_[1].id, input_textures_[2].id, input_textures_[3].id, };

+  glDeleteTextures(4, ids);

+}

+

+void ShadertoyShader::CreateShaderFromString(const std::string& shader_string) {

+  CreateShader(shader_string);

+}

+

+void ShadertoyShader::GetUniformLocations() {

+  glUseProgram(shader_program_);

+  uiResolution_ = glGetUniformLocation(shader_program_, "iResolution");

+  uiGlobalTime_ = glGetUniformLocation(shader_program_, "iGlobalTime");

+  uiFrame_ = glGetUniformLocation(shader_program_, "iFrame");

+  uiTimeDelta_ = glGetUniformLocation(shader_program_, "iTimeDelta");

+  uiChannel0_ = glGetUniformLocation(shader_program_, "iChannel0");

+

+  if (uiChannel0_ != -1)

+    glUniform1i(uiChannel0_, 0);

+

+  unViewport_ = glGetUniformLocation(shader_program_, "unViewport");

+  unCorners_ = glGetUniformLocation(shader_program_, "unCorners");

+

+  glUseProgram(0);

+}

+

+void ShadertoyShader::CreateShader(const std::string fragment_string) {

+  std::string vertex_string = SHADER0([]() {

+    attribute vec2 pos;

+    void main() {

+      gl_Position = vec4(pos.xy, 0.0, 1.0);

+    }

+  });

+

+  std::string shader_toy_fragment_header = SHADER0([]() {

+    precision highp float;

+    uniform vec3 iResolution;

+    uniform float iGlobalTime;

+    uniform vec4 iMouse;

+    uniform int iFrame;

+    uniform float iTimeDelta;

+    uniform vec3 iChannelResolution[4];

+    uniform sampler2D iChannel0;

+    vec4 texture2DGrad(sampler2D s, in vec2 uv, vec2 gx, vec2 gy) { return texture2D(s, uv); }

+    vec4 texture2DLod(sampler2D s, in vec2 uv, in float lod) { return texture2D(s, uv); }

+    void mainImage(out vec4 c, in vec2 f);

+  });

+

+  std::string shader_toy_fragment_footer = SHADER0([]() {

+    void main(void) {

+      vec4 shader_color = vec4(0, 0, 0, 1);

+      mainImage(shader_color, gl_FragCoord.xy);

+      shader_color.w = 1.0;

+      gl_FragColor = shader_color;

+    }

+  });

+

+  std::string complete_fragment_string = shader_toy_fragment_header + fragment_string + shader_toy_fragment_footer;

+

+  GLuint vertex_shader = glCreateShader(GL_VERTEX_SHADER);

+  CompileShader10(vertex_shader, vertex_string);

+

+  GLuint fragment_shader = glCreateShader(GL_FRAGMENT_SHADER);

+  CompileShader10(fragment_shader, complete_fragment_string);

+

+  // Link shaders

+  shader_program_ = glCreateProgram();

+  LinkProgram(shader_program_, vertex_shader, fragment_shader);

+

+  GetUniformLocations();

+

+  glDeleteShader(vertex_shader);

+  glDeleteShader(fragment_shader);

+}

+

+void ShadertoyShader::PrepareForDraw(int width, int height, float global_time, int frame, float time_delta) {

+  glUseProgram(shader_program_);

+

+  // Set the uniforms

+  if (uiResolution_ != -1)

+    glUniform3f(uiResolution_, (float)width, (float)height, 1);

+  if (uiGlobalTime_ != -1)

+    glUniform1f(uiGlobalTime_, global_time);

+  if (uiFrame_ != -1)

+    glUniform1f(uiFrame_, (float)frame);

+  if (uiTimeDelta_ != -1)

+    glUniform1f(uiTimeDelta_, time_delta);

+

+  glActiveTexture(GL_TEXTURE0);

+  glBindTexture(GL_TEXTURE_2D, input_textures_[0].id);

+  glActiveTexture(GL_TEXTURE1);

+  glBindTexture(GL_TEXTURE_2D, input_textures_[1].id);

+  glActiveTexture(GL_TEXTURE2);

+  glBindTexture(GL_TEXTURE_2D, input_textures_[2].id);

+  glActiveTexture(GL_TEXTURE3);

+  glBindTexture(GL_TEXTURE_2D, input_textures_[3].id);

+

+  if (unViewport_ != -1)

+    glUniform4f(unViewport_, 0, 0, (float)width, (float)height);

+}

diff --git a/hostsidetests/sustainedperf/shadertoy_android/jni/shadertoy_shader.h b/hostsidetests/sustainedperf/shadertoy_android/jni/shadertoy_shader.h
new file mode 100644
index 0000000..3823700
--- /dev/null
+++ b/hostsidetests/sustainedperf/shadertoy_android/jni/shadertoy_shader.h
@@ -0,0 +1,59 @@
+/*

+ * 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.

+ */

+

+#ifndef SHADERTOY_SHADER_H

+#define SHADERTOY_SHADER_H

+

+#include <GLES3/gl31.h>

+

+#include <fstream>

+#include <sstream>

+

+struct InputTextures {

+  GLuint id;

+  GLint uniform_location;

+  int width;

+  int height;

+};

+

+class ShadertoyShader {

+ public:

+  ShadertoyShader();

+  ~ShadertoyShader();

+

+  void CreateShaderFromString(const std::string& shader_string);

+  void PrepareForDraw(int width, int height, float global_time, int frame, float time_delta);

+

+ private:

+   void CreateShader(const std::string fragment_string);

+   void GetUniformLocations();

+

+   GLint uiResolution_;

+   GLint uiGlobalTime_;

+   GLint uiFrame_;

+   GLint uiTimeDelta_;

+   GLint uiChannel0_;

+   GLint unViewport_;

+   GLint unCorners_;

+

+   GLuint shader_program_;

+

+   struct InputTextures input_textures_[4];

+};

+

+

+

+#endif // SHADERTOY_SHADER_H

diff --git a/hostsidetests/sustainedperf/shadertoy_android/jni/utils.cpp b/hostsidetests/sustainedperf/shadertoy_android/jni/utils.cpp
new file mode 100644
index 0000000..41aab16
--- /dev/null
+++ b/hostsidetests/sustainedperf/shadertoy_android/jni/utils.cpp
@@ -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.

+ */

+

+#define _USE_MATH_DEFINES

+#include <math.h>

+#include "utils.h"

+

+float DegToRad(float deg) {

+  return deg * (float)M_PI / 180.0f;

+}

+

+bool CompileShader(GLuint shader, const std::string& shader_string) {

+  std::string prefix = "#version 300 es\n";

+  std::string string_with_prefix = prefix + shader_string;

+  const char* shader_str[] = { string_with_prefix.data() };

+  glShaderSource(shader, 1, shader_str, NULL);

+  glCompileShader(shader);

+

+  GLint success;

+  GLchar infoLog[512];

+  glGetShaderiv(shader, GL_COMPILE_STATUS, &success);

+  if (!success)

+  {

+    glGetShaderInfoLog(shader, 512, NULL, infoLog);

+    LOGI("Shader Failed to compile: %s -- %s\n", *shader_str, infoLog);

+    return false;

+  }

+  return true;

+}

+

+bool LinkProgram(GLuint program, GLuint vertex_shader, GLuint fragment_shader) {

+  glAttachShader(program, vertex_shader);

+  glAttachShader(program, fragment_shader);

+  glLinkProgram(program);

+

+  // Check for linking errors

+  GLint success;

+  GLchar infoLog[512];

+  glGetProgramiv(program, GL_LINK_STATUS, &success);

+  if (!success) {

+    glGetProgramInfoLog(program, 512, NULL, infoLog);

+    LOGE("Shader failed to link: %s\n", infoLog);

+    return false;

+  }

+

+  return true;

+}

+

+GLenum GLCheckError() {

+  return GLCheckErrorStr("");

+}

+

+GLenum GLCheckErrorStr(std::string msg) {

+  GLenum e = glGetError();

+  std::string str;

+  if (e != GL_NO_ERROR) {

+    switch (e) {

+    case GL_INVALID_ENUM:

+      str = "GL_INVALID_ENUM";

+      break;

+    case GL_INVALID_OPERATION:

+      str = "GL_INVALID_OPERATION";

+      break;

+    case GL_INVALID_VALUE:

+      str = "GL_INVALID_VALUE";

+      break;

+    case GL_OUT_OF_MEMORY:

+      str = "GL_OUT_OF_MEMORY";

+      break;

+    case GL_INVALID_FRAMEBUFFER_OPERATION:

+      str = "GL_INVALID_FRAMEBUFFER_OPERATION";

+      break;

+    }

+    LOGE("OpenGL error : %s : %s (%#08x)\n", msg.c_str(), str.c_str(), e);

+  }

+  return e;

+}

diff --git a/hostsidetests/sustainedperf/shadertoy_android/jni/utils.h b/hostsidetests/sustainedperf/shadertoy_android/jni/utils.h
new file mode 100644
index 0000000..f14a9bf
--- /dev/null
+++ b/hostsidetests/sustainedperf/shadertoy_android/jni/utils.h
@@ -0,0 +1,67 @@
+/*

+ * 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.

+ */

+

+#ifndef COMMON_UTILS_H

+#define COMMON_UTILS_H

+

+#include <math.h>

+#include <string>

+

+#include <android/log.h>

+

+#include <GLES3/gl31.h>

+#include <GLES3/gl3ext.h>

+

+#define LOG_TAG "GPUStressTestActivity"

+#define  LOGI(...)  __android_log_print(ANDROID_LOG_INFO,LOG_TAG,__VA_ARGS__)

+#define  LOGE(...)  __android_log_print(ANDROID_LOG_ERROR,LOG_TAG,__VA_ARGS__)

+

+inline void PrintGLError(...) {

+  __android_log_print(ANDROID_LOG_ERROR,LOG_TAG, "GL_ERROR");

+}

+

+#ifdef LOG_GL_ERRORS

+#define GL_CALL(call)                      \

+  {                                        \

+    call;                                  \

+    if (glGetError() != GL_NO_ERROR) {     \

+      PrintGLError();                      \

+    }                                      \

+  }

+#else

+#define GL_CALL(call)                      \

+  {                                        \

+    call;                                  \

+  }

+#endif

+

+template <size_t size>

+std::string StripLambda(const char(&shader)[size]) {

+  return std::string(shader + 6, shader + size - 2);

+}

+

+#define SHADER0(Src) StripLambda(#Src)

+

+bool CompileShader(GLuint shader, const std::string& shader_string);

+bool LinkProgram(GLuint program, GLuint vertex_shader, GLuint fragment_shader);

+

+// Converts from degrees to radians.

+float DegToRad(float deg);

+

+GLenum GLCheckError();

+GLenum GLCheckErrorStr(std::string str);

+

+#endif // COMMON_UTILS_H

diff --git a/hostsidetests/sustainedperf/shadertoy_android/res/values/strings.xml b/hostsidetests/sustainedperf/shadertoy_android/res/values/strings.xml
new file mode 100644
index 0000000..b6ebf69
--- /dev/null
+++ b/hostsidetests/sustainedperf/shadertoy_android/res/values/strings.xml
@@ -0,0 +1,29 @@
+<?xml version="1.0" encoding="utf-8"?>

+<!--

+/*

+**

+** Copyright 2006, 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.

+*/

+-->

+

+<!-- This file contains resource definitions for displayed strings, allowing

+     them to be changed based on the locale and options. -->

+

+<resources>

+    <!-- Simple strings. -->

+    <string name="gpustresstest_activity">GPUSTRESSTEST</string>

+

+</resources>

+

diff --git a/hostsidetests/sustainedperf/shadertoy_android/src/GLtestLib.java b/hostsidetests/sustainedperf/shadertoy_android/src/GLtestLib.java
new file mode 100644
index 0000000..f0a8dbf
--- /dev/null
+++ b/hostsidetests/sustainedperf/shadertoy_android/src/GLtestLib.java
@@ -0,0 +1,33 @@
+/*

+ * Copyright (C) 2014 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.gputest;

+

+// Wrapper for native library

+

+public class GLtestLib {

+

+     static {

+         System.loadLibrary("gltest");

+     }

+

+    /**

+     * @param width the current view width

+     * @param height the current view height

+     */

+     public static native void init(int width, int height);

+     public static native void step();

+}

diff --git a/hostsidetests/sustainedperf/shadertoy_android/src/GLtestView.java b/hostsidetests/sustainedperf/shadertoy_android/src/GLtestView.java
new file mode 100644
index 0000000..a6dab62
--- /dev/null
+++ b/hostsidetests/sustainedperf/shadertoy_android/src/GLtestView.java
@@ -0,0 +1,339 @@
+/*

+ * 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.gputest;

+/*

+ * Copyright (C) 2008 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 android.content.Context;

+import android.graphics.PixelFormat;

+import android.opengl.GLSurfaceView;

+import android.util.AttributeSet;

+import android.util.Log;

+import android.view.KeyEvent;

+import android.view.MotionEvent;

+

+import javax.microedition.khronos.egl.EGL10;

+import javax.microedition.khronos.egl.EGLConfig;

+import javax.microedition.khronos.egl.EGLContext;

+import javax.microedition.khronos.egl.EGLDisplay;

+import javax.microedition.khronos.opengles.GL10;

+

+/**

+ * A simple GLSurfaceView sub-class that demonstrate how to perform

+ * OpenGL ES 2.0 rendering into a GL Surface. Note the following important

+ * details:

+ *

+ * - The class must use a custom context factory to enable 2.0 rendering.

+ *   See ContextFactory class definition below.

+ *

+ * - The class must use a custom EGLConfigChooser to be able to select

+ *   an EGLConfig that supports 2.0. This is done by providing a config

+ *   specification to eglChooseConfig() that has the attribute

+ *   EGL10.ELG_RENDERABLE_TYPE containing the EGL_OPENGL_ES2_BIT flag

+ *   set. See ConfigChooser class definition below.

+ *

+ * - The class must select the surface's format, then choose an EGLConfig

+ *   that matches it exactly (with regards to red/green/blue/alpha channels

+ *   bit depths). Failure to do so would result in an EGL_BAD_MATCH error.

+ */

+class GLtestView extends GLSurfaceView {

+    private static String TAG = "GLtestView";

+    private static final boolean DEBUG = false;

+

+    public GLtestView(Context context) {

+        super(context);

+        init(false, 0, 0);

+    }

+

+    public GLtestView(Context context, boolean translucent, int depth, int stencil) {

+        super(context);

+        init(translucent, depth, stencil);

+    }

+

+    private void init(boolean translucent, int depth, int stencil) {

+

+        /* By default, GLSurfaceView() creates a RGB_565 opaque surface.

+         * If we want a translucent one, we should change the surface's

+         * format here, using PixelFormat.TRANSLUCENT for GL Surfaces

+         * is interpreted as any 32-bit surface with alpha by SurfaceFlinger.

+         */

+        if (translucent) {

+            this.getHolder().setFormat(PixelFormat.TRANSLUCENT);

+        }

+

+        /* Setup the context factory for 2.0 rendering.

+         * See ContextFactory class definition below

+         */

+        setEGLContextFactory(new ContextFactory());

+

+        /* We need to choose an EGLConfig that matches the format of

+         * our surface exactly. This is going to be done in our

+         * custom config chooser. See ConfigChooser class definition

+         * below.

+         */

+        setEGLConfigChooser( translucent ?

+                             new ConfigChooser(8, 8, 8, 8, depth, stencil) :

+                             new ConfigChooser(5, 6, 5, 0, depth, stencil) );

+

+        /* Set the renderer responsible for frame rendering */

+        setRenderer(new Renderer());

+    }

+

+    private static class ContextFactory implements GLSurfaceView.EGLContextFactory {

+        private static int EGL_CONTEXT_CLIENT_VERSION = 0x3098;

+        public EGLContext createContext(EGL10 egl, EGLDisplay display, EGLConfig eglConfig) {

+            Log.w(TAG, "creating OpenGL ES 3.0 context");

+            checkEglError("Before eglCreateContext", egl);

+            int[] attrib_list = {EGL_CONTEXT_CLIENT_VERSION, 3, EGL10.EGL_NONE };

+            EGLContext context = egl.eglCreateContext(display, eglConfig, EGL10.EGL_NO_CONTEXT, attrib_list);

+            checkEglError("After eglCreateContext", egl);

+            return context;

+        }

+

+        public void destroyContext(EGL10 egl, EGLDisplay display, EGLContext context) {

+            egl.eglDestroyContext(display, context);

+        }

+    }

+

+    private static void checkEglError(String prompt, EGL10 egl) {

+        int error;

+        while ((error = egl.eglGetError()) != EGL10.EGL_SUCCESS) {

+            Log.e(TAG, String.format("%s: EGL error: 0x%x", prompt, error));

+        }

+    }

+

+    private static class ConfigChooser implements GLSurfaceView.EGLConfigChooser {

+

+        public ConfigChooser(int r, int g, int b, int a, int depth, int stencil) {

+            mRedSize = r;

+            mGreenSize = g;

+            mBlueSize = b;

+            mAlphaSize = a;

+            mDepthSize = depth;

+            mStencilSize = stencil;

+        }

+

+        /* This EGL config specification is used to specify 2.0 rendering.

+         * We use a minimum size of 4 bits for red/green/blue, but will

+         * perform actual matching in chooseConfig() below.

+         */

+        private static int EGL_OPENGL_ES2_BIT = 4;

+        private static int[] s_configAttribs2 =

+        {

+            EGL10.EGL_RED_SIZE, 4,

+            EGL10.EGL_GREEN_SIZE, 4,

+            EGL10.EGL_BLUE_SIZE, 4,

+            EGL10.EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT,

+            EGL10.EGL_NONE

+        };

+

+        public EGLConfig chooseConfig(EGL10 egl, EGLDisplay display) {

+

+            /* Get the number of minimally matching EGL configurations

+             */

+            int[] num_config = new int[1];

+            egl.eglChooseConfig(display, s_configAttribs2, null, 0, num_config);

+

+            int numConfigs = num_config[0];

+

+            if (numConfigs <= 0) {

+                throw new IllegalArgumentException("No configs match configSpec");

+            }

+

+            /* Allocate then read the array of minimally matching EGL configs

+             */

+            EGLConfig[] configs = new EGLConfig[numConfigs];

+            egl.eglChooseConfig(display, s_configAttribs2, configs, numConfigs, num_config);

+

+            if (DEBUG) {

+                 printConfigs(egl, display, configs);

+            }

+            /* Now return the "best" one

+             */

+            return chooseConfig(egl, display, configs);

+        }

+

+        public EGLConfig chooseConfig(EGL10 egl, EGLDisplay display,

+                EGLConfig[] configs) {

+            for(EGLConfig config : configs) {

+                int d = findConfigAttrib(egl, display, config,

+                        EGL10.EGL_DEPTH_SIZE, 0);

+                int s = findConfigAttrib(egl, display, config,

+                        EGL10.EGL_STENCIL_SIZE, 0);

+

+                // We need at least mDepthSize and mStencilSize bits

+                if (d < mDepthSize || s < mStencilSize)

+                    continue;

+

+                // We want an *exact* match for red/green/blue/alpha

+                int r = findConfigAttrib(egl, display, config,

+                        EGL10.EGL_RED_SIZE, 0);

+                int g = findConfigAttrib(egl, display, config,

+                            EGL10.EGL_GREEN_SIZE, 0);

+                int b = findConfigAttrib(egl, display, config,

+                            EGL10.EGL_BLUE_SIZE, 0);

+                int a = findConfigAttrib(egl, display, config,

+                        EGL10.EGL_ALPHA_SIZE, 0);

+

+                if (r == mRedSize && g == mGreenSize && b == mBlueSize && a == mAlphaSize)

+                    return config;

+            }

+            return null;

+        }

+

+        private int findConfigAttrib(EGL10 egl, EGLDisplay display,

+                EGLConfig config, int attribute, int defaultValue) {

+

+            if (egl.eglGetConfigAttrib(display, config, attribute, mValue)) {

+                return mValue[0];

+            }

+            return defaultValue;

+        }

+

+        private void printConfigs(EGL10 egl, EGLDisplay display,

+            EGLConfig[] configs) {

+            int numConfigs = configs.length;

+            Log.w(TAG, String.format("%d configurations", numConfigs));

+            for (int i = 0; i < numConfigs; i++) {

+                Log.w(TAG, String.format("Configuration %d:\n", i));

+                printConfig(egl, display, configs[i]);

+            }

+        }

+

+        private void printConfig(EGL10 egl, EGLDisplay display,

+                EGLConfig config) {

+            int[] attributes = {

+                    EGL10.EGL_BUFFER_SIZE,

+                    EGL10.EGL_ALPHA_SIZE,

+                    EGL10.EGL_BLUE_SIZE,

+                    EGL10.EGL_GREEN_SIZE,

+                    EGL10.EGL_RED_SIZE,

+                    EGL10.EGL_DEPTH_SIZE,

+                    EGL10.EGL_STENCIL_SIZE,

+                    EGL10.EGL_CONFIG_CAVEAT,

+                    EGL10.EGL_CONFIG_ID,

+                    EGL10.EGL_LEVEL,

+                    EGL10.EGL_MAX_PBUFFER_HEIGHT,

+                    EGL10.EGL_MAX_PBUFFER_PIXELS,

+                    EGL10.EGL_MAX_PBUFFER_WIDTH,

+                    EGL10.EGL_NATIVE_RENDERABLE,

+                    EGL10.EGL_NATIVE_VISUAL_ID,

+                    EGL10.EGL_NATIVE_VISUAL_TYPE,

+                    0x3030, // EGL10.EGL_PRESERVED_RESOURCES,

+                    EGL10.EGL_SAMPLES,

+                    EGL10.EGL_SAMPLE_BUFFERS,

+                    EGL10.EGL_SURFACE_TYPE,

+                    EGL10.EGL_TRANSPARENT_TYPE,

+                    EGL10.EGL_TRANSPARENT_RED_VALUE,

+                    EGL10.EGL_TRANSPARENT_GREEN_VALUE,

+                    EGL10.EGL_TRANSPARENT_BLUE_VALUE,

+                    0x3039, // EGL10.EGL_BIND_TO_TEXTURE_RGB,

+                    0x303A, // EGL10.EGL_BIND_TO_TEXTURE_RGBA,

+                    0x303B, // EGL10.EGL_MIN_SWAP_INTERVAL,

+                    0x303C, // EGL10.EGL_MAX_SWAP_INTERVAL,

+                    EGL10.EGL_LUMINANCE_SIZE,

+                    EGL10.EGL_ALPHA_MASK_SIZE,

+                    EGL10.EGL_COLOR_BUFFER_TYPE,

+                    EGL10.EGL_RENDERABLE_TYPE,

+                    0x3042 // EGL10.EGL_CONFORMANT

+            };

+            String[] names = {

+                    "EGL_BUFFER_SIZE",

+                    "EGL_ALPHA_SIZE",

+                    "EGL_BLUE_SIZE",

+                    "EGL_GREEN_SIZE",

+                    "EGL_RED_SIZE",

+                    "EGL_DEPTH_SIZE",

+                    "EGL_STENCIL_SIZE",

+                    "EGL_CONFIG_CAVEAT",

+                    "EGL_CONFIG_ID",

+                    "EGL_LEVEL",

+                    "EGL_MAX_PBUFFER_HEIGHT",

+                    "EGL_MAX_PBUFFER_PIXELS",

+                    "EGL_MAX_PBUFFER_WIDTH",

+                    "EGL_NATIVE_RENDERABLE",

+                    "EGL_NATIVE_VISUAL_ID",

+                    "EGL_NATIVE_VISUAL_TYPE",

+                    "EGL_PRESERVED_RESOURCES",

+                    "EGL_SAMPLES",

+                    "EGL_SAMPLE_BUFFERS",

+                    "EGL_SURFACE_TYPE",

+                    "EGL_TRANSPARENT_TYPE",

+                    "EGL_TRANSPARENT_RED_VALUE",

+                    "EGL_TRANSPARENT_GREEN_VALUE",

+                    "EGL_TRANSPARENT_BLUE_VALUE",

+                    "EGL_BIND_TO_TEXTURE_RGB",

+                    "EGL_BIND_TO_TEXTURE_RGBA",

+                    "EGL_MIN_SWAP_INTERVAL",

+                    "EGL_MAX_SWAP_INTERVAL",

+                    "EGL_LUMINANCE_SIZE",

+                    "EGL_ALPHA_MASK_SIZE",

+                    "EGL_COLOR_BUFFER_TYPE",

+                    "EGL_RENDERABLE_TYPE",

+                    "EGL_CONFORMANT"

+            };

+            int[] value = new int[1];

+            for (int i = 0; i < attributes.length; i++) {

+                int attribute = attributes[i];

+                String name = names[i];

+                if ( egl.eglGetConfigAttrib(display, config, attribute, value)) {

+                    Log.w(TAG, String.format("  %s: %d\n", name, value[0]));

+                } else {

+                    // Log.w(TAG, String.format("  %s: failed\n", name));

+                    while (egl.eglGetError() != EGL10.EGL_SUCCESS);

+                }

+            }

+        }

+

+        // Subclasses can adjust these values:

+        protected int mRedSize;

+        protected int mGreenSize;

+        protected int mBlueSize;

+        protected int mAlphaSize;

+        protected int mDepthSize;

+        protected int mStencilSize;

+        private int[] mValue = new int[1];

+    }

+

+    private static class Renderer implements GLSurfaceView.Renderer {

+        public void onDrawFrame(GL10 gl) {

+            GLtestLib.step();

+        }

+

+        public void onSurfaceChanged(GL10 gl, int width, int height) {

+            GLtestLib.init(width, height);

+        }

+

+        public void onSurfaceCreated(GL10 gl, EGLConfig config) {

+            // Do nothing.

+        }

+    }

+}

diff --git a/hostsidetests/sustainedperf/shadertoy_android/src/GPUStressTestActivity.java b/hostsidetests/sustainedperf/shadertoy_android/src/GPUStressTestActivity.java
new file mode 100644
index 0000000..c135d9d
--- /dev/null
+++ b/hostsidetests/sustainedperf/shadertoy_android/src/GPUStressTestActivity.java
@@ -0,0 +1,53 @@
+/*

+ * Copyright (C) 2014 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.gputest;

+

+import android.app.Activity;

+import android.os.Bundle;

+import android.util.Log;

+import android.view.WindowManager;

+import java.io.File;

+

+

+public class GPUStressTestActivity extends Activity {

+

+    GLtestView mView;

+

+    @Override protected void onCreate(Bundle icicle) {

+        super.onCreate(icicle);

+        Bundle b = this.getIntent().getExtras();

+        getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);

+        if (b != null) {

+            boolean value = b.getBoolean("SustainedPerformanceMode");

+            if (value) {

+                getWindow().setSustainedPerformanceMode(true);

+            }

+        }

+        mView = new GLtestView(getApplication());

+        setContentView(mView);

+    }

+

+    @Override protected void onPause() {

+        super.onPause();

+        mView.onPause();

+    }

+

+    @Override protected void onResume() {

+        super.onResume();

+        mView.onResume();

+    }

+}

diff --git a/hostsidetests/sustainedperf/src/android/SustainedPerformance/cts/SustainedPerformanceHostTest.java b/hostsidetests/sustainedperf/src/android/SustainedPerformance/cts/SustainedPerformanceHostTest.java
new file mode 100644
index 0000000..0035f8e
--- /dev/null
+++ b/hostsidetests/sustainedperf/src/android/SustainedPerformance/cts/SustainedPerformanceHostTest.java
@@ -0,0 +1,247 @@
+/*
+ * 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 android.sustainedPerformance.cts;
+
+import com.android.ddmlib.MultiLineReceiver;
+import com.android.ddmlib.IShellOutputReceiver;
+import com.android.tradefed.device.ITestDevice;
+import com.android.tradefed.testtype.DeviceTestCase;
+import com.android.ddmlib.Log;
+import java.util.Scanner;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.concurrent.TimeUnit;
+import java.util.*;
+/**
+ * Test to check if device implements Sustained Performance Mode
+ */
+public class SustainedPerformanceHostTest extends DeviceTestCase {
+
+    ITestDevice device;
+    private static final String PACKAGE = "com.android.gputest";
+    private static final String CLASS = "GPUStressTestActivity";
+    private static final String START_COMMAND = String.format(
+            "am start -W -a android.intent.action.MAIN -n %s/%s.%s",
+            PACKAGE, PACKAGE, CLASS);
+    private static final String START_COMMAND_MODE = String.format(
+            "am start -W -a android.intent.action.MAIN -n %s/%s.%s --ez SustainedPerformanceMode true",
+            PACKAGE, PACKAGE, CLASS);
+    private static final String STOP_COMMAND = String.format(
+            "am force-stop %s", PACKAGE);
+    private static final String TEST_PACKAGE = "android.test.app";
+    private static final String TEST_CLASS = "DeviceTestActivity";
+    private static final String START_TEST_COMMAND = String.format(
+            "am start -W -a android.intent.action.MAIN -n %s/%s.%s",
+            TEST_PACKAGE, TEST_PACKAGE, TEST_CLASS);
+    private static final String DHRYSTONE = "/data/local/tmp/";
+    private static final String LOG_TAG = "sustainedPerfTest";
+
+    private static ArrayList<Double> appResultsWithMode = new ArrayList<Double>();
+    private static ArrayList<Double> appResultsWithoutMode = new ArrayList<Double>();
+    private static ArrayList<Double> dhrystoneResultsWithMode = new ArrayList<Double>();
+    private static ArrayList<Double> dhrystoneResultsWithoutMode = new ArrayList<Double>();
+    private double dhryMin = Double.MAX_VALUE, dhryMax = Double.MIN_VALUE;
+    private static long testDuration = 1800000; //30 minutes
+
+    public class Dhrystone implements Runnable {
+        private boolean modeEnabled;
+        private long startTime;
+        private long loopCount = 3000000;
+
+        public Dhrystone(boolean enabled) {
+            modeEnabled = enabled;
+            startTime = System.currentTimeMillis();
+        }
+
+        public void run() {
+            double[] testSet = new double[3];
+            int index = 0;
+            try {
+                device.executeShellCommand("cd " + DHRYSTONE + " ; chmod 777 dhry");
+                while (true) {
+                    String result = device.executeShellCommand("echo " + loopCount + " | " + DHRYSTONE + "dhry");
+                    if (Math.abs(System.currentTimeMillis() - startTime) >= testDuration) {
+                        break;
+                    } else if (result.contains("Measured time too small")) {
+                         loopCount = loopCount*10;
+                    } else if (!result.isEmpty()){
+                         double dmips = Double.parseDouble(result);
+                         testSet[index++] = dmips;
+                         if (index == 3) {
+                             synchronized(this) {
+                                 if (modeEnabled) {
+                                     dhrystoneResultsWithMode.add(testSet[1]);
+                                 } else {
+                                     dhrystoneResultsWithoutMode.add(testSet[1]);
+                                 }
+                                 if (testSet[1] > dhryMax) {
+                                     dhryMax = testSet[1];
+                                 }
+                                 if (testSet[1] < dhryMin) {
+                                     dhryMin = testSet[1];
+                                 }
+                                 index = 0;
+                             }
+                        }
+                    }
+               }
+           } catch (Exception e) {
+               Log.e(LOG_TAG, e.toString());
+
+           }
+        }
+    }
+
+    public void analyzeResults(String logs, boolean mode) {
+        Double[] testSet = new Double[10];
+        int index = 0;
+        double min = Double.MAX_VALUE, max = Double.MIN_VALUE;
+
+        Scanner in = new Scanner(logs);
+        while (in.hasNextLine()) {
+            String line = in.nextLine();
+            if(line.startsWith("I/"+CLASS)) {
+                Double time = Double.parseDouble(line.split(":")[1]);
+                testSet[index++] = time;
+                if (index == 10) {
+                    Arrays.sort(testSet);
+                    if (mode) {
+                        appResultsWithMode.add(testSet[5]);
+                    } else {
+                        appResultsWithoutMode.add(testSet[5]);
+                    }
+                    if (testSet[5] > max) {
+                        max = testSet[5];
+                    }
+                    if (testSet[5] < min) {
+                        min = testSet[5];
+                    }
+                    index = 0;
+                }
+            }
+        }
+        in.close();
+        double diff = (max - min)*100/max;
+        if (mode) {
+            appResultsWithMode.add(0, min);
+            appResultsWithMode.add(1, max);
+            appResultsWithMode.add(2, diff);
+        } else {
+            appResultsWithoutMode.add(0, min);
+            appResultsWithoutMode.add(1, max);
+            appResultsWithoutMode.add(2, diff);
+        }
+    }
+
+    private void setUpEnvironment() throws Exception {
+        device.disconnectFromWifi();
+        dhryMin = Double.MAX_VALUE;
+        dhryMax = Double.MIN_VALUE;
+        Thread.sleep(600000);
+        device.executeAdbCommand("logcat", "-c");
+        device.executeShellCommand("settings put global airplane_mode_on 1");
+        device.executeShellCommand("am broadcast -a android.intent.action.AIRPLANE_MODE --ez state true");
+    }
+
+    public void testShader() throws Exception {
+        device = getDevice();
+
+        /**
+         * Check if the device supports Sustained Performance Mode.
+         * If not then assert true and return.
+         **/
+        device.executeAdbCommand("logcat", "-c");
+        device.executeShellCommand(START_TEST_COMMAND);
+        String logs = device.executeAdbCommand("logcat", "-v", "brief", "-d", TEST_CLASS + ":I", "*:S");
+        String testString = "";
+        Scanner in = new Scanner(logs);
+        while (in.hasNextLine()) {
+            String line = in.nextLine();
+            if(line.startsWith("I/"+TEST_CLASS)) {
+                testString = line.split(":")[1].trim();
+            }
+        }
+        in.close();
+        if (testString.isEmpty()) {
+            assertTrue(true);
+            return;
+        }
+
+        appResultsWithoutMode.clear();
+        appResultsWithMode.clear();
+        dhrystoneResultsWithoutMode.clear();
+        dhrystoneResultsWithMode.clear();
+
+        /*
+         * Run the test without the mode.
+         * Start the application and collect stats.
+         * Run two threads of dhrystone and collect stats.
+         */
+        setUpEnvironment();
+        device.executeShellCommand(START_COMMAND);
+        Thread dhrystone = new Thread(new Dhrystone(false));
+        Thread dhrystone1 = new Thread(new Dhrystone(false));
+        dhrystone.start();
+        dhrystone1.start();
+        Thread.sleep(testDuration);
+        device.executeShellCommand(STOP_COMMAND);
+        dhrystone.join();
+        dhrystone1.join();
+        logs = device.executeAdbCommand("logcat", "-v", "brief", "-d", CLASS + ":I", "*:S");
+        analyzeResults(logs, false);
+        double diff = (dhryMax - dhryMin)*100/dhryMax;
+        dhrystoneResultsWithoutMode.add(0, dhryMin);
+        dhrystoneResultsWithoutMode.add(1, dhryMax);
+        dhrystoneResultsWithoutMode.add(2, diff);
+
+        /*
+         * Run the test with the mode.
+         * Start the application and collect stats.
+         * Run two threads of dhrystone and collect stats.
+         */
+        setUpEnvironment();
+        device.executeShellCommand(START_COMMAND_MODE);
+        dhrystone = new Thread(new Dhrystone(true));
+        dhrystone1 = new Thread(new Dhrystone(true));
+        dhrystone.start();
+        dhrystone1.start();
+        Thread.sleep(testDuration);
+        device.executeShellCommand(STOP_COMMAND);
+        dhrystone.join();
+        dhrystone1.join();
+        logs = device.executeAdbCommand("logcat", "-v", "brief", "-d", CLASS + ":I", "*:S");
+        analyzeResults(logs, true);
+        diff = (dhryMax - dhryMin)*100/dhryMax;
+        dhrystoneResultsWithMode.add(0, dhryMin);
+        dhrystoneResultsWithMode.add(1, dhryMax);
+        dhrystoneResultsWithMode.add(2, diff);
+
+        device.executeShellCommand("settings put global airplane_mode_on 0");
+        device.executeShellCommand("am broadcast -a android.intent.action.AIRPLANE_MODE --ez state false");
+
+        double perfdegradapp = (appResultsWithMode.get(1) - appResultsWithoutMode.get(1))*100/appResultsWithMode.get(1);
+        double perfdegraddhry = (dhrystoneResultsWithoutMode.get(0) - dhrystoneResultsWithMode.get(0))*100/dhrystoneResultsWithoutMode.get(0);
+
+        /*
+         * Checks if the performance in the mode is consistent with
+         * 5% error margin.
+         */
+        assertFalse("Results in the mode are not sustainable",
+                (dhrystoneResultsWithMode.get(2) > 5) ||
+                (appResultsWithMode.get(2)) > 5);
+    }
+}
diff --git a/tests/accessibility/Android.mk b/tests/accessibility/Android.mk
index 42245f25..1bcc20d 100644
--- a/tests/accessibility/Android.mk
+++ b/tests/accessibility/Android.mk
@@ -29,8 +29,8 @@
 # Tag this module as a cts test artifact
 LOCAL_COMPATIBILITY_SUITE := cts
 
-LOCAL_SDK_VERSION := current
+LOCAL_SDK_VERSION := test_current
 
 include $(BUILD_CTS_PACKAGE)
 
-include $(call all-makefiles-under,$(LOCAL_PATH))
\ No newline at end of file
+include $(call all-makefiles-under,$(LOCAL_PATH))
diff --git a/tests/accessibilityservice/Android.mk b/tests/accessibilityservice/Android.mk
index 8ce6e99..aee708c 100644
--- a/tests/accessibilityservice/Android.mk
+++ b/tests/accessibilityservice/Android.mk
@@ -27,6 +27,6 @@
 
 LOCAL_PACKAGE_NAME := CtsAccessibilityServiceTestCases
 
-LOCAL_SDK_VERSION := current
+LOCAL_SDK_VERSION := test_current
 
 include $(BUILD_CTS_PACKAGE)
diff --git a/tests/accessibilityservice/src/android/accessibilityservice/cts/AccessibilityMagnificationTest.java b/tests/accessibilityservice/src/android/accessibilityservice/cts/AccessibilityMagnificationTest.java
index ca3ec96..b6dcd9d 100644
--- a/tests/accessibilityservice/src/android/accessibilityservice/cts/AccessibilityMagnificationTest.java
+++ b/tests/accessibilityservice/src/android/accessibilityservice/cts/AccessibilityMagnificationTest.java
@@ -21,6 +21,7 @@
 import android.accessibilityservice.AccessibilityServiceInfo;
 import android.content.res.Resources;
 import android.graphics.Region;
+import android.provider.Settings;
 import android.test.InstrumentationTestCase;
 import android.util.DisplayMetrics;
 
@@ -35,20 +36,27 @@
 
     /** Maximum timeout when waiting for a magnification callback. */
     public static final int LISTENER_TIMEOUT_MILLIS = 500;
-
+    public static final String ACCESSIBILITY_DISPLAY_MAGNIFICATION_ENABLED =
+            "accessibility_display_magnification_enabled";
     private StubMagnificationAccessibilityService mService;
 
     @Override
     public void setUp() throws Exception {
         super.setUp();
-
+        ShellCommandBuilder.create(this)
+                .deleteSecureSetting(ACCESSIBILITY_DISPLAY_MAGNIFICATION_ENABLED)
+                .run();
+        // Starting the service will force the accessibility subsystem to examine its settings, so
+        // it will update magnification in the process to disable it.
         mService = StubMagnificationAccessibilityService.enableSelf(this);
     }
 
     @Override
     protected void tearDown() throws Exception {
-        mService.runOnServiceSync(() -> mService.disableSelf());
-        mService = null;
+        if (mService != null) {
+            mService.runOnServiceSync(() -> mService.disableSelfAndRemove());
+            mService = null;
+        }
 
         super.tearDown();
     }
@@ -122,4 +130,104 @@
             controller.removeListener(listener);
         }
     }
+
+    public void testMagnificationServiceShutsDownWhileMagnifying_shouldReturnTo1x() {
+        final MagnificationController controller = mService.getMagnificationController();
+        mService.runOnServiceSync(() -> controller.setScale(2.0f, false));
+
+        mService.runOnServiceSync(() -> mService.disableSelf());
+        mService = null;
+        InstrumentedAccessibilityService service = InstrumentedAccessibilityService.enableService(
+                this, InstrumentedAccessibilityService.class);
+        final MagnificationController controller2 = service.getMagnificationController();
+        try {
+            assertEquals("Magnification must reset when a service dies",
+                    1.0f, controller2.getScale());
+        } finally {
+            service.runOnServiceSync(() -> service.disableSelf());
+        }
+    }
+
+    public void testGetMagnificationRegion_whenCanControlMagnification_shouldNotBeEmpty() {
+        final MagnificationController controller = mService.getMagnificationController();
+        Region magnificationRegion = controller.getMagnificationRegion();
+        assertFalse("Magnification region should not be empty when "
+                 + "magnification is being actively controlled", magnificationRegion.isEmpty());
+    }
+
+    public void testGetMagnificationRegion_whenCantControlMagnification_shouldBeEmpty() {
+        mService.runOnServiceSync(() -> mService.disableSelf());
+        mService = null;
+        InstrumentedAccessibilityService service = InstrumentedAccessibilityService.enableService(
+                this, InstrumentedAccessibilityService.class);
+        try {
+            final MagnificationController controller = service.getMagnificationController();
+            Region magnificationRegion = controller.getMagnificationRegion();
+            assertTrue("Magnification region should be empty when magnification "
+                    + "is not being actively controlled", magnificationRegion.isEmpty());
+        } finally {
+            service.runOnServiceSync(() -> service.disableSelf());
+        }
+    }
+
+    public void testGetMagnificationRegion_whenMagnificationGesturesEnabled_shouldNotBeEmpty() {
+        ShellCommandBuilder.create(this)
+                .putSecureSetting(ACCESSIBILITY_DISPLAY_MAGNIFICATION_ENABLED, "1")
+                .run();
+        mService.runOnServiceSync(() -> mService.disableSelf());
+        mService = null;
+        InstrumentedAccessibilityService service = InstrumentedAccessibilityService.enableService(
+                this, InstrumentedAccessibilityService.class);
+        try {
+            final MagnificationController controller = service.getMagnificationController();
+            Region magnificationRegion = controller.getMagnificationRegion();
+            assertFalse("Magnification region should not be empty when magnification "
+                    + "gestures are active", magnificationRegion.isEmpty());
+        } finally {
+            service.runOnServiceSync(() -> service.disableSelf());
+            ShellCommandBuilder.create(this)
+                    .deleteSecureSetting(ACCESSIBILITY_DISPLAY_MAGNIFICATION_ENABLED)
+                    .run();
+        }
+    }
+
+    public void testAnimatingMagnification() throws InterruptedException {
+        final MagnificationController controller = mService.getMagnificationController();
+        final int timeBetweenAnimationChanges = 100;
+
+        final float scale1 = 5.0f;
+        final float x1 = 500;
+        final float y1 = 1000;
+
+        final float scale2 = 4.0f;
+        final float x2 = 500;
+        final float y2 = 1500;
+
+        final float scale3 = 2.1f;
+        final float x3 = 700;
+        final float y3 = 700;
+
+        for (int i = 0; i < 5; i++) {
+            mService.runOnServiceSync(() -> {
+                controller.setScale(scale1, true);
+                controller.setCenter(x1, y1, true);
+            });
+
+            Thread.sleep(timeBetweenAnimationChanges);
+
+            mService.runOnServiceSync(() -> {
+                controller.setScale(scale2, true);
+                controller.setCenter(x2, y2, true);
+            });
+
+            Thread.sleep(timeBetweenAnimationChanges);
+
+            mService.runOnServiceSync(() -> {
+                controller.setScale(scale3, true);
+                controller.setCenter(x3, y3, true);
+            });
+
+            Thread.sleep(timeBetweenAnimationChanges);
+        }
+    }
 }
diff --git a/tests/accessibilityservice/src/android/accessibilityservice/cts/InstrumentedAccessibilityService.java b/tests/accessibilityservice/src/android/accessibilityservice/cts/InstrumentedAccessibilityService.java
index 99efb2c..4a9ce08 100644
--- a/tests/accessibilityservice/src/android/accessibilityservice/cts/InstrumentedAccessibilityService.java
+++ b/tests/accessibilityservice/src/android/accessibilityservice/cts/InstrumentedAccessibilityService.java
@@ -56,6 +56,14 @@
         // Stub method.
     }
 
+    public void disableSelfAndRemove() {
+        disableSelf();
+
+        synchronized (sInstances) {
+            sInstances.remove(getClass());
+        }
+    }
+
     public void runOnServiceSync(Runnable runner) {
         final SyncRunnable sr = new SyncRunnable(runner, TIMEOUT_SERVICE_PERFORM_SYNC);
         mHandler.post(sr);
@@ -112,6 +120,10 @@
 
                 final T instance = getInstanceForClass(clazz, TIMEOUT_SERVICE_ENABLE);
                 if (instance == null) {
+                    ShellCommandBuilder.create(testCase)
+                            .putSecureSetting(Settings.Secure.ENABLED_ACCESSIBILITY_SERVICES,
+                                    enabledServices)
+                            .run();
                     throw new RuntimeException("Starting accessibility service " + serviceName
                             + " took longer than " + TIMEOUT_SERVICE_ENABLE + "ms");
                 }
diff --git a/tests/app/app/AndroidManifest.xml b/tests/app/app/AndroidManifest.xml
index cc06ead..10a6792 100644
--- a/tests/app/app/AndroidManifest.xml
+++ b/tests/app/app/AndroidManifest.xml
@@ -51,6 +51,8 @@
         <uses-library android:name="android.test.runner" />
         <uses-library android:name="org.apache.http.legacy" android:required="false" />
 
+        <activity android:name="android.app.stubs.ScreenOnActivity" />
+
         <activity android:name="android.app.stubs.ActionBarActivity" />
 
         <activity android:name="android.app.stubs.DialogStubActivity"
diff --git a/tests/app/app/src/android/app/stubs/InstrumentationTestActivity.java b/tests/app/app/src/android/app/stubs/InstrumentationTestActivity.java
index 8e36beb..495bae2 100644
--- a/tests/app/app/src/android/app/stubs/InstrumentationTestActivity.java
+++ b/tests/app/app/src/android/app/stubs/InstrumentationTestActivity.java
@@ -28,6 +28,7 @@
 import android.view.MenuItem;
 import android.view.MotionEvent;
 import android.view.View;
+import android.view.WindowManager;
 import android.widget.TextView;
 
 public class InstrumentationTestActivity extends Activity {
@@ -61,6 +62,9 @@
         mTextView = new MockTextView(this);
         setContentView(mTextView);
         mOnCreateCalled = true;
+        getWindow().addFlags(WindowManager.LayoutParams.FLAG_DISMISS_KEYGUARD
+                | WindowManager.LayoutParams.FLAG_TURN_SCREEN_ON
+                | WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
     }
 
     class MockTextView extends TextView {
diff --git a/tests/app/app/src/android/app/stubs/LauncherActivityStub.java b/tests/app/app/src/android/app/stubs/LauncherActivityStub.java
index f309b04..4102b06 100644
--- a/tests/app/app/src/android/app/stubs/LauncherActivityStub.java
+++ b/tests/app/app/src/android/app/stubs/LauncherActivityStub.java
@@ -20,6 +20,7 @@
 import android.content.Intent;
 import android.os.Bundle;
 import android.view.View;
+import android.view.WindowManager;
 import android.widget.ListView;
 
 public class LauncherActivityStub extends LauncherActivity {
@@ -54,6 +55,9 @@
     protected void onCreate(Bundle savedInstanceState) {
         super.onCreate(savedInstanceState);
         isOnCreateCalled = true;
+        getWindow().addFlags(WindowManager.LayoutParams.FLAG_DISMISS_KEYGUARD
+                | WindowManager.LayoutParams.FLAG_TURN_SCREEN_ON
+                | WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
     }
 
     @Override
diff --git a/tests/app/app/src/android/app/stubs/ScreenOnActivity.java b/tests/app/app/src/android/app/stubs/ScreenOnActivity.java
new file mode 100644
index 0000000..84a5ac6
--- /dev/null
+++ b/tests/app/app/src/android/app/stubs/ScreenOnActivity.java
@@ -0,0 +1,36 @@
+/*
+ * 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 android.app.stubs;
+
+import android.app.Activity;
+import android.content.Intent;
+import android.os.Bundle;
+import android.view.WindowManager;
+
+/**
+ * An activity to turn on the screen
+ */
+public final class ScreenOnActivity extends Activity {
+
+    @Override
+    public void onCreate(Bundle bundle) {
+        super.onCreate(bundle);
+        getWindow().addFlags(WindowManager.LayoutParams.FLAG_DISMISS_KEYGUARD
+                | WindowManager.LayoutParams.FLAG_TURN_SCREEN_ON
+                | WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
+    }
+}
diff --git a/tests/app/src/android/app/cts/ActivityManagerTest.java b/tests/app/src/android/app/cts/ActivityManagerTest.java
index c03ad6d..8bd118e 100644
--- a/tests/app/src/android/app/cts/ActivityManagerTest.java
+++ b/tests/app/src/android/app/cts/ActivityManagerTest.java
@@ -30,6 +30,7 @@
 import android.app.stubs.ActivityManagerRecentTwoActivity;
 import android.app.stubs.MockApplicationActivity;
 import android.app.stubs.MockService;
+import android.app.stubs.ScreenOnActivity;
 import android.content.BroadcastReceiver;
 import android.content.Context;
 import android.content.Intent;
@@ -81,6 +82,7 @@
         mActivityManager = (ActivityManager) mContext.getSystemService(Context.ACTIVITY_SERVICE);
         mStartedActivityList = new ArrayList<Activity>();
         mErrorProcessID = -1;
+        startSubActivity(ScreenOnActivity.class);
     }
 
     @Override
@@ -349,9 +351,6 @@
         errList = mActivityManager.getProcessesInErrorState();
     }
 
-    public void testRestartPackage() {
-    }
-
     public void testGetDeviceConfigurationInfo() {
         ConfigurationInfo conInf = mActivityManager.getDeviceConfigurationInfo();
         assertNotNull(conInf);
diff --git a/tests/app/src/android/app/cts/KeyguardManagerTest.java b/tests/app/src/android/app/cts/KeyguardManagerTest.java
index 23410ed5..b476023 100644
--- a/tests/app/src/android/app/cts/KeyguardManagerTest.java
+++ b/tests/app/src/android/app/cts/KeyguardManagerTest.java
@@ -37,10 +37,4 @@
         final KeyguardManager.KeyguardLock keyLock = keyguardManager.newKeyguardLock(TAG);
         assertNotNull(keyLock);
     }
-
-    public void testInKeyguardRestrictedInputMode() {
-    }
-
-    public void testExitKeyguardSecurely() {
-    }
 }
diff --git a/tests/aslr/AndroidTest.xml b/tests/aslr/AndroidTest.xml
index c04e1ab..d610519 100644
--- a/tests/aslr/AndroidTest.xml
+++ b/tests/aslr/AndroidTest.xml
@@ -23,5 +23,7 @@
         <option name="native-test-device-path" value="/data/local/tmp" />
         <option name="module-name" value="CtsAslrMallocTestCases" />
         <option name="runtime-hint" value="3m30s" />
+        <!-- test-timeout unit is ms, value = 10 min -->
+        <option name="native-test-timeout" value="600000" />
     </test>
 </configuration>
\ No newline at end of file
diff --git a/tests/jdwp/AndroidTest.xml b/tests/jdwp/AndroidTest.xml
index 301f9f5..e3205b5 100644
--- a/tests/jdwp/AndroidTest.xml
+++ b/tests/jdwp/AndroidTest.xml
@@ -31,7 +31,6 @@
         <option name="dalvik-arg" value="-Xcompiler-option" />
         <option name="dalvik-arg" value="--debuggable" />
         <option name="dalvik-arg" value="-Djpda.settings.verbose=false" />
-        <option name="dalvik-arg" value="-Djpda.settings.syncPort=34017" />
         <option name="dalvik-arg" value="-Djpda.settings.timeout=10000" />
         <option name="dalvik-arg" value="-Djpda.settings.waitingTime=10000" />
         <option name="dalvik-arg" value="-Djpda.settings.debuggeeJavaPath='dalvikvm|#ABI#| -XXlib:libart.so -Xcompiler-option --debuggable'" />
diff --git a/tests/tests/app/src/android/app/cts/ApplyOverrideConfigurationActivity.java b/tests/tests/app/src/android/app/cts/ApplyOverrideConfigurationActivity.java
index 305d0a8..a43e58c 100644
--- a/tests/tests/app/src/android/app/cts/ApplyOverrideConfigurationActivity.java
+++ b/tests/tests/app/src/android/app/cts/ApplyOverrideConfigurationActivity.java
@@ -18,6 +18,8 @@
 import android.app.Activity;
 import android.content.Context;
 import android.content.res.Configuration;
+import android.os.Bundle;
+import android.view.WindowManager;
 
 import java.util.concurrent.CompletableFuture;
 import java.util.concurrent.Future;
@@ -28,6 +30,15 @@
     private CompletableFuture<Configuration> mOnConfigurationChangedFuture = null;
 
     @Override
+    protected void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+
+        getWindow().addFlags(WindowManager.LayoutParams.FLAG_DISMISS_KEYGUARD
+                | WindowManager.LayoutParams.FLAG_TURN_SCREEN_ON
+                | WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
+    }
+
+    @Override
     protected void attachBaseContext(Context newBase) {
         super.attachBaseContext(newBase);
 
diff --git a/tests/tests/content/AndroidTest.xml b/tests/tests/content/AndroidTest.xml
index a8a8727..e87771c 100644
--- a/tests/tests/content/AndroidTest.xml
+++ b/tests/tests/content/AndroidTest.xml
@@ -14,7 +14,6 @@
      limitations under the License.
 -->
 <configuration description="Config for CTS Content test cases">
-    <target_preparer class="com.android.compatibility.common.tradefed.targetprep.WifiCheck" />
     <target_preparer class="com.android.compatibility.common.tradefed.targetprep.ApkInstaller">
         <option name="cleanup-apks" value="true" />
         <option name="test-file-name" value="CtsContentTestCases.apk" />
diff --git a/tests/tests/content/src/android/content/res/cts/ConfigurationTest.java b/tests/tests/content/src/android/content/res/cts/ConfigurationTest.java
index bc0f42e..dbc3e21 100644
--- a/tests/tests/content/src/android/content/res/cts/ConfigurationTest.java
+++ b/tests/tests/content/src/android/content/res/cts/ConfigurationTest.java
@@ -20,9 +20,9 @@
 
 import android.content.pm.ActivityInfo;
 import android.content.res.Configuration;
+import android.os.LocaleList;
 import android.os.Parcel;
 import android.test.AndroidTestCase;
-import android.util.LocaleList;
 import android.view.View;
 
 public class ConfigurationTest extends AndroidTestCase {
diff --git a/tests/tests/content/src/android/content/res/cts/ResourcesTest.java b/tests/tests/content/src/android/content/res/cts/ResourcesTest.java
index f264f1c..73f441b 100644
--- a/tests/tests/content/src/android/content/res/cts/ResourcesTest.java
+++ b/tests/tests/content/src/android/content/res/cts/ResourcesTest.java
@@ -32,10 +32,10 @@
 import android.content.res.XmlResourceParser;
 import android.graphics.drawable.Drawable;
 import android.os.Bundle;
+import android.os.LocaleList;
 import android.test.AndroidTestCase;
 import android.util.AttributeSet;
 import android.util.DisplayMetrics;
-import android.util.LocaleList;
 import android.util.TypedValue;
 import android.util.Xml;
 import android.view.Display;
diff --git a/tests/tests/graphics/src/android/graphics/cts/PaintTest.java b/tests/tests/graphics/src/android/graphics/cts/PaintTest.java
index aa8348a..d50897fe 100644
--- a/tests/tests/graphics/src/android/graphics/cts/PaintTest.java
+++ b/tests/tests/graphics/src/android/graphics/cts/PaintTest.java
@@ -35,9 +35,9 @@
 import android.graphics.Typeface;
 import android.graphics.Xfermode;
 import android.os.Build;
+import android.os.LocaleList;
 import android.test.AndroidTestCase;
 import android.text.SpannedString;
-import android.util.LocaleList;
 import android.util.Log;
 
 import java.util.Locale;
diff --git a/tests/tests/media/src/android/media/cts/AudioNativeTest.java b/tests/tests/media/src/android/media/cts/AudioNativeTest.java
index 9ec60bf..8d428b4 100644
--- a/tests/tests/media/src/android/media/cts/AudioNativeTest.java
+++ b/tests/tests/media/src/android/media/cts/AudioNativeTest.java
@@ -198,6 +198,9 @@
     }
 
     public void testOutputChannelMasks() {
+        if (!hasAudioOutput()) {
+            return;
+        }
         AudioTrackNative track = new AudioTrackNative();
 
         // TODO: when b/23899814 is fixed, use AudioManager.getDevices() to enumerate
@@ -223,6 +226,9 @@
     }
 
     public void testInputChannelMasks() {
+        if (!hasMicrophone()) {
+            return;
+        }
         AudioRecordNative recorder = new AudioRecordNative();
 
         // TODO: when b/23899814 is fixed, use AudioManager.getDevices() to enumerate
@@ -292,6 +298,11 @@
                 PackageManager.FEATURE_MICROPHONE);
     }
 
+    private boolean hasAudioOutput() {
+        return getContext().getPackageManager().hasSystemFeature(
+                PackageManager.FEATURE_AUDIO_OUTPUT);
+    }
+
     private static native void nativeAppendixBBufferQueue();
     private static native void nativeAppendixBRecording();
 }
diff --git a/tests/tests/media/src/android/media/cts/AudioRecordingConfigurationTest.java b/tests/tests/media/src/android/media/cts/AudioRecordingConfigurationTest.java
index a8fb8fc..7c1bb37 100644
--- a/tests/tests/media/src/android/media/cts/AudioRecordingConfigurationTest.java
+++ b/tests/tests/media/src/android/media/cts/AudioRecordingConfigurationTest.java
@@ -28,6 +28,10 @@
 import android.os.Parcel;
 import android.util.Log;
 
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+
 public class AudioRecordingConfigurationTest extends CtsAndroidTestCase {
     private final static String TAG = "AudioRecordingConfigurationTest";
 
@@ -98,7 +102,7 @@
         AudioManager am = new AudioManager(getContext());
         assertNotNull("Could not create AudioManager", am);
 
-        AudioRecordingConfiguration[] configs = am.getActiveRecordingConfigurations();
+        List<AudioRecordingConfiguration> configs = am.getActiveRecordingConfigurations();
         assertNotNull("Invalid null array of record configurations before recording", configs);
 
         assertEquals(AudioRecord.STATE_INITIALIZED, mAudioRecord.getState());
@@ -110,8 +114,8 @@
         configs = am.getActiveRecordingConfigurations();
         assertNotNull("Invalid null array of record configurations during recording", configs);
         assertTrue("no active record configurations (empty array) during recording",
-                configs.length > 0);
-        final int nbConfigsDuringRecording = configs.length;
+                configs.size() > 0);
+        final int nbConfigsDuringRecording = configs.size();
 
         // verify our recording shows as one of the recording configs
         assertTrue("Test source/session not amongst active record configurations",
@@ -123,7 +127,7 @@
         Thread.sleep(TEST_TIMING_TOLERANCE_MS);
         configs = am.getActiveRecordingConfigurations();
         assertTrue("end of recording not reported in record configs",
-                configs.length < nbConfigsDuringRecording);
+                configs.size() < nbConfigsDuringRecording);
     }
 
     public void testCallback() throws Exception {
@@ -162,7 +166,7 @@
         // just call the callback once directly so it's marked as tested
         final AudioManager.AudioRecordingCallback arc =
                 (AudioManager.AudioRecordingCallback) callback;
-        arc.onRecordingConfigChanged(new AudioRecordingConfiguration[0]);
+        arc.onRecordingConfigChanged(new ArrayList<AudioRecordingConfiguration>());
     }
 
     public void testParcel() throws Exception {
@@ -177,15 +181,15 @@
         assertEquals(AudioRecord.RECORDSTATE_RECORDING, mAudioRecord.getRecordingState());
         Thread.sleep(TEST_TIMING_TOLERANCE_MS);
 
-        AudioRecordingConfiguration[] configs = am.getActiveRecordingConfigurations();
-        assertTrue("Empty array of record configs during recording", configs.length > 0);
-        assertEquals(0, configs[0].describeContents());
+        List<AudioRecordingConfiguration> configs = am.getActiveRecordingConfigurations();
+        assertTrue("Empty array of record configs during recording", configs.size() > 0);
+        assertEquals(0, configs.get(0).describeContents());
 
         // marshall a AudioRecordingConfiguration and compare to unmarshalled
         final Parcel srcParcel = Parcel.obtain();
         final Parcel dstParcel = Parcel.obtain();
 
-        configs[0].writeToParcel(srcParcel, 0 /*no public flags for marshalling*/);
+        configs.get(0).writeToParcel(srcParcel, 0 /*no public flags for marshalling*/);
         final byte[] mbytes = srcParcel.marshall();
         dstParcel.unmarshall(mbytes, 0, mbytes.length);
         dstParcel.setDataPosition(0);
@@ -194,7 +198,7 @@
 
         assertNotNull("Failure to unmarshall AudioRecordingConfiguration", unmarshalledConf);
         assertEquals("Source and destination AudioRecordingConfiguration not equal",
-                configs[0], unmarshalledConf);
+                configs.get(0), unmarshalledConf);
     }
 
     class MyAudioRecordingCallback extends AudioManager.AudioRecordingCallback {
@@ -216,7 +220,7 @@
         }
 
         @Override
-        public void onRecordingConfigChanged(AudioRecordingConfiguration[] configs) {
+        public void onRecordingConfigChanged(List<AudioRecordingConfiguration> configs) {
             mCalled = true;
             mParamMatch = verifyAudioConfig(mTestSource, mTestSession, mAudioRecord.getFormat(),
                     mAudioRecord.getRoutedDevice(), configs);
@@ -230,24 +234,26 @@
     }
 
     private static boolean verifyAudioConfig(int source, int session, AudioFormat format,
-            AudioDeviceInfo device, AudioRecordingConfiguration[] configs) {
-        for (int i = 0 ; i < configs.length ; i++) {
-            if ((configs[i].getClientAudioSource() == source)
-                    && (configs[i].getClientAudioSessionId() == session)
+            AudioDeviceInfo device, List<AudioRecordingConfiguration> configs) {
+        final Iterator<AudioRecordingConfiguration> confIt = configs.iterator();
+        while (confIt.hasNext()) {
+            final AudioRecordingConfiguration config = confIt.next();
+            if ((config.getClientAudioSource() == source)
+                    && (config.getClientAudioSessionId() == session)
                     // test the client format matches that requested (same as the AudioRecord's)
-                    && (configs[i].getClientFormat().getEncoding() == format.getEncoding())
-                    && (configs[i].getClientFormat().getSampleRate() == format.getSampleRate())
-                    && (configs[i].getClientFormat().getChannelMask() == format.getChannelMask())
-                    && (configs[i].getClientFormat().getChannelIndexMask() ==
+                    && (config.getClientFormat().getEncoding() == format.getEncoding())
+                    && (config.getClientFormat().getSampleRate() == format.getSampleRate())
+                    && (config.getClientFormat().getChannelMask() == format.getChannelMask())
+                    && (config.getClientFormat().getChannelIndexMask() ==
                             format.getChannelIndexMask())
                     // test the device format is configured
-                    && (configs[i].getFormat().getEncoding() != AudioFormat.ENCODING_INVALID)
-                    && (configs[i].getFormat().getSampleRate() > 0)
+                    && (config.getFormat().getEncoding() != AudioFormat.ENCODING_INVALID)
+                    && (config.getFormat().getSampleRate() > 0)
                     //  for the channel mask, either the position or index-based value must be valid
-                    && ((configs[i].getFormat().getChannelMask() != AudioFormat.CHANNEL_INVALID)
-                            || (configs[i].getFormat().getChannelIndexMask() !=
+                    && ((config.getFormat().getChannelMask() != AudioFormat.CHANNEL_INVALID)
+                            || (config.getFormat().getChannelIndexMask() !=
                                     AudioFormat.CHANNEL_INVALID))
-                    && deviceMatch(device, configs[i].getAudioDevice())) {
+                    && deviceMatch(device, config.getAudioDevice())) {
                 return true;
             }
         }
diff --git a/tests/tests/media/src/android/media/cts/DecodeAccuracyTest.java b/tests/tests/media/src/android/media/cts/DecodeAccuracyTest.java
index 319df5a..f6cfc82 100644
--- a/tests/tests/media/src/android/media/cts/DecodeAccuracyTest.java
+++ b/tests/tests/media/src/android/media/cts/DecodeAccuracyTest.java
@@ -41,27 +41,6 @@
 
     /* <------------- Tests Using H264 -------------> */
     @TimeoutReq(minutes = TESTCASE_WAITTIME_MIN)
-    public void testH264TextureViewVideoDecode() throws Exception {
-        runDecodeAccuracyTest(
-                new TextureViewFactory(),
-                new VideoFormat(H264_VIDEO_FILE_NAME));
-    }
-
-    @TimeoutReq(minutes = TESTCASE_WAITTIME_MIN)
-    public void testH264TextureViewLargerHeightVideoDecode() throws Exception {
-        runDecodeAccuracyTest(
-                new TextureViewFactory(),
-                getLargerHeightVideoFormat(new VideoFormat(H264_VIDEO_FILE_NAME)));
-    }
-
-    @TimeoutReq(minutes = TESTCASE_WAITTIME_MIN)
-    public void testH264TextureViewLargerWidthVideoDecode() throws Exception {
-        runDecodeAccuracyTest(
-                new TextureViewFactory(),
-                getLargerWidthVideoFormat(new VideoFormat(H264_VIDEO_FILE_NAME)));
-    }
-
-    @TimeoutReq(minutes = TESTCASE_WAITTIME_MIN)
     public void testH264GLViewVideoDecode() throws Exception {
         runDecodeAccuracyTest(
                 new GLSurfaceViewFactory(),
@@ -84,27 +63,6 @@
 
     /* <------------- Tests Using VP9 -------------> */
     @TimeoutReq(minutes = TESTCASE_WAITTIME_MIN)
-    public void testVP9TextureViewVideoDecode() throws Exception {
-        runDecodeAccuracyTest(
-                new TextureViewFactory(),
-                new VideoFormat(VP9_VIDEO_FILE_NAME));
-    }
-
-    @TimeoutReq(minutes = TESTCASE_WAITTIME_MIN)
-    public void testVP9TextureViewLargerHeightVideoDecode() throws Exception {
-        runDecodeAccuracyTest(
-                new TextureViewFactory(),
-                getLargerHeightVideoFormat(new VideoFormat(VP9_VIDEO_FILE_NAME)));
-    }
-
-    @TimeoutReq(minutes = TESTCASE_WAITTIME_MIN)
-    public void testVP9TextureViewLargerWidthVideoDecode() throws Exception {
-        runDecodeAccuracyTest(
-                new TextureViewFactory(),
-                getLargerWidthVideoFormat(new VideoFormat(VP9_VIDEO_FILE_NAME)));
-    }
-
-    @TimeoutReq(minutes = TESTCASE_WAITTIME_MIN)
     public void testVP9GLViewVideoDecode() throws Exception {
         runDecodeAccuracyTest(
                 new GLSurfaceViewFactory(),
@@ -128,15 +86,6 @@
     private void runDecodeAccuracyTest(VideoViewFactory videoViewFactory, VideoFormat videoFormat) {
         checkNotNull(videoViewFactory);
         checkNotNull(videoFormat);
-        if (!DisplayUtil.canPlay360p(getHelper().getContext())) {
-            MediaUtils.skipTest("Display does not support 360p.");
-            return;
-        }
-        if (!DisplayUtil.currentOrientationCanPlay360p(getHelper().getContext())) {
-            Log.w(TAG, "Current screen orientation does not support 360p.");
-            Log.i(TAG, "Rotate screen orientation and continue.");
-            getHelper().rotateOrientation();
-        }
         View videoView = videoViewFactory.createView(getHelper().getContext());
         // If view is intended and available to display.
         if (videoView != null) {
@@ -220,38 +169,4 @@
         };
     }
 
-    private static final class DisplayUtil {
-
-        public static boolean canPlay360p(Context context) {
-            return displayMetricsHasMinPixelSize(context, 360);
-        }
-
-        public static boolean currentOrientationCanPlay360p(Context context) {
-            DisplayMetrics metrics = getDisplayMetrics(context);
-            return metrics.widthPixels >= 480 && metrics.heightPixels >= 360;
-        }
-
-        private static boolean displayMetricsHasMinPixelSize(Context context, int minPixelSize) {
-            return getDisplayMetricsMinPixelSize(context) >= minPixelSize;
-        }
-
-        private static int getDisplayMetricsMinPixelSize(Context context) {
-            DisplayMetrics metrics = getDisplayMetrics(context);
-            return Math.min(metrics.widthPixels, metrics.heightPixels);
-        }
-
-        private static DisplayMetrics getDisplayMetrics(Context context) {
-            checkNotNull(context);
-            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1) {
-                DisplayMetrics metrics = new DisplayMetrics();
-                ((WindowManager) context.getSystemService(Context.WINDOW_SERVICE))
-                        .getDefaultDisplay().getRealMetrics(metrics);
-                return metrics;
-            } else {
-                return context.getResources().getDisplayMetrics();
-            }
-        }
-
-    }
-
 }
diff --git a/tests/tests/media/src/android/media/cts/LoudnessEnhancerTest.java b/tests/tests/media/src/android/media/cts/LoudnessEnhancerTest.java
index 8923445..25d3b4c 100644
--- a/tests/tests/media/src/android/media/cts/LoudnessEnhancerTest.java
+++ b/tests/tests/media/src/android/media/cts/LoudnessEnhancerTest.java
@@ -46,6 +46,9 @@
 
     //Test case 0.0: test constructor and release
     public void test0_0ConstructorAndRelease() throws Exception {
+        if (!hasAudioOutput()) {
+            return;
+        }
         AudioManager am = (AudioManager) getContext().getSystemService(Context.AUDIO_SERVICE);
         assertNotNull("null AudioManager", am);
         getLoudnessEnhancer(0);
@@ -63,6 +66,9 @@
 
     //Test case 1.0: test set/get target gain
     public void test1_0TargetGain() throws Exception {
+        if (!hasAudioOutput()) {
+            return;
+        }
         getLoudnessEnhancer(0);
         try {
             mLE.setTargetGain(0);
@@ -80,8 +86,52 @@
         }
     }
 
-  //Test case 2.0: test loudness gain change in audio
-    public void test2_0MeasureGainChange() throws Exception {
+    //-----------------------------------------------------------------
+    // 2 - Effect enable/disable
+    //----------------------------------
+
+    //Test case 2.0: test setEnabled() and getEnabled() in valid state
+    public void test2_0SetEnabledGetEnabled() throws Exception {
+        if (!hasAudioOutput()) {
+            return;
+        }
+        getLoudnessEnhancer(getSessionId());
+        try {
+            mLE.setEnabled(true);
+            assertTrue("invalid state from getEnabled", mLE.getEnabled());
+            mLE.setEnabled(false);
+            assertFalse("invalid state to getEnabled", mLE.getEnabled());
+            // test passed
+        } catch (IllegalStateException e) {
+            fail("setEnabled() in wrong state");
+        } finally {
+            releaseLoudnessEnhancer();
+        }
+    }
+
+    //Test case 2.1: test setEnabled() throws exception after release
+    public void test2_1SetEnabledAfterRelease() throws Exception {
+        if (!hasAudioOutput()) {
+            return;
+        }
+        getLoudnessEnhancer(getSessionId());
+        mLE.release();
+        try {
+            mLE.setEnabled(true);
+            fail("setEnabled() processed after release()");
+        } catch (IllegalStateException e) {
+            // test passed
+        } finally {
+            releaseLoudnessEnhancer();
+        }
+    }
+
+    //-----------------------------------------------------------------
+    // 3 - check effect using visualizer effect
+    //----------------------------------
+
+    //Test case 3.0: test loudness gain change in audio
+    public void test3_0MeasureGainChange() throws Exception {
         if (!hasAudioOutput()) {
             return;
         }
@@ -91,7 +141,7 @@
         try {
             // this test will play a 1kHz sine wave with peaks at -40dB, and apply 6 db gain
             // using loudness enhancement
-            mp = MediaPlayer.create(getContext(), R.raw.sine1khzs40dblong);
+            mp = MediaPlayer.create(getContext(), R.raw.sine1khzm40db);
             final int LOUDNESS_GAIN = 600;
             final int MAX_MEASUREMENT_ERROR_MB = 200;
             assertNotNull("null MediaPlayer", mp);
@@ -138,6 +188,7 @@
 
             MeasurementPeakRms measurement = new MeasurementPeakRms();
             status = visualizer.getMeasurementPeakRms(measurement);
+            assertEquals("getMeasurementPeakRms() reports failure", Visualizer.SUCCESS, status);
 
             //run for a new set of 3 seconds, get new measurement
             mLE.setTargetGain(LOUDNESS_GAIN);
@@ -147,23 +198,18 @@
             mLE.setEnabled(true);
 
             visualizer.setMeasurementMode(Visualizer.MEASUREMENT_MODE_PEAK_RMS);
-            currentPosition = mp.getCurrentPosition();
-            maxTry = 10;
-            tryCount = 0;
-            while (tryCount < maxTry) {
-                Thread.sleep(50);
-                tryCount++;
-            }
+            Thread.sleep(500);
 
             MeasurementPeakRms measurement2 = new MeasurementPeakRms();
             status = visualizer.getMeasurementPeakRms(measurement2);
+            assertEquals("getMeasurementPeakRms() reports failure", Visualizer.SUCCESS, status);
 
             //compare both measurements
             am.setStreamVolume(AudioManager.STREAM_MUSIC, originalVolume, 0);
             assertEquals("getMeasurementPeakRms() reports failure",
                     Visualizer.SUCCESS, status);
-            Log.i("VisTest", "peak="+measurement.mPeak+"  rms="+measurement.mRms);
-            Log.i("VisTest", "peak2="+measurement2.mPeak+"  rms2="+measurement2.mRms);
+            Log.i("LETest", "peak="+measurement.mPeak+"  rms="+measurement.mRms);
+            Log.i("LETest", "peak2="+measurement2.mPeak+"  rms2="+measurement2.mRms);
 
             int deltaPeak = Math.abs(measurement2.mPeak - (measurement.mPeak + LOUDNESS_GAIN) );
             assertTrue("peak deviation in mB = "+deltaPeak, deltaPeak < MAX_MEASUREMENT_ERROR_MB);
diff --git a/tests/tests/media/src/android/media/cts/RingtoneManagerTest.java b/tests/tests/media/src/android/media/cts/RingtoneManagerTest.java
index 0045577..96b33da 100644
--- a/tests/tests/media/src/android/media/cts/RingtoneManagerTest.java
+++ b/tests/tests/media/src/android/media/cts/RingtoneManagerTest.java
@@ -62,16 +62,32 @@
         mOriginalVolume = mAudioManager.getStreamVolume(AudioManager.STREAM_RING);
         mDefaultUri = RingtoneManager.getActualDefaultRingtoneUri(mContext,
                 RingtoneManager.TYPE_RINGTONE);
-        mAudioManager.adjustStreamVolume(AudioManager.STREAM_RING, AudioManager.ADJUST_RAISE,
-                AudioManager.FLAG_ALLOW_RINGER_MODES);
+
+        try {
+            Utils.toggleNotificationPolicyAccess(
+                    mContext.getPackageName(), getInstrumentation(), true);
+            mAudioManager.adjustStreamVolume(AudioManager.STREAM_RING, AudioManager.ADJUST_RAISE,
+                    AudioManager.FLAG_ALLOW_RINGER_MODES);
+        } finally {
+            Utils.toggleNotificationPolicyAccess(
+                    mContext.getPackageName(), getInstrumentation(), false);
+        }
+
     }
 
     @Override
     protected void tearDown() throws Exception {
-        // restore original ringer settings
-        if (mAudioManager != null) {
-            mAudioManager.setStreamVolume(AudioManager.STREAM_RING, mOriginalVolume,
-                    AudioManager.FLAG_ALLOW_RINGER_MODES);
+        try {
+            Utils.toggleNotificationPolicyAccess(
+                    mContext.getPackageName(), getInstrumentation(), true);
+            // restore original ringer settings
+            if (mAudioManager != null) {
+                mAudioManager.setStreamVolume(AudioManager.STREAM_RING, mOriginalVolume,
+                        AudioManager.FLAG_ALLOW_RINGER_MODES);
+            }
+        } finally {
+            Utils.toggleNotificationPolicyAccess(
+                    mContext.getPackageName(), getInstrumentation(), false);
         }
         RingtoneManager.setActualDefaultRingtoneUri(mContext, RingtoneManager.TYPE_RINGTONE,
                 mDefaultUri);
diff --git a/tests/tests/media/src/android/media/cts/RingtoneTest.java b/tests/tests/media/src/android/media/cts/RingtoneTest.java
index de21bdd..1477f3f 100644
--- a/tests/tests/media/src/android/media/cts/RingtoneTest.java
+++ b/tests/tests/media/src/android/media/cts/RingtoneTest.java
@@ -49,14 +49,16 @@
         mOriginalRingerMode = mAudioManager.getRingerMode();
         mOriginalVolume = mAudioManager.getStreamVolume(AudioManager.STREAM_RING);
         mOriginalStreamType = mRingtone.getStreamType();
-        // set ringer to a reasonable volume
+
         int maxVolume = mAudioManager.getStreamMaxVolume(AudioManager.STREAM_RING);
-        mAudioManager.setStreamVolume(AudioManager.STREAM_RING, maxVolume / 2,
-                AudioManager.FLAG_ALLOW_RINGER_MODES);
-        // make sure that we are not in silent mode
+
         try {
             Utils.toggleNotificationPolicyAccess(
                     mContext.getPackageName(), getInstrumentation(), true);
+            // set ringer to a reasonable volume
+            mAudioManager.setStreamVolume(AudioManager.STREAM_RING, maxVolume / 2,
+                    AudioManager.FLAG_ALLOW_RINGER_MODES);
+            // make sure that we are not in silent mode
             mAudioManager.setRingerMode(AudioManager.RINGER_MODE_NORMAL);
         } finally {
             Utils.toggleNotificationPolicyAccess(
@@ -91,12 +93,12 @@
                 Utils.toggleNotificationPolicyAccess(
                         mContext.getPackageName(), getInstrumentation(), true);
                 mAudioManager.setRingerMode(mOriginalRingerMode);
+                mAudioManager.setStreamVolume(AudioManager.STREAM_RING, mOriginalVolume,
+                        AudioManager.FLAG_ALLOW_RINGER_MODES);
             } finally {
                 Utils.toggleNotificationPolicyAccess(
                         mContext.getPackageName(), getInstrumentation(), false);
             }
-            mAudioManager.setStreamVolume(AudioManager.STREAM_RING, mOriginalVolume,
-                    AudioManager.FLAG_ALLOW_RINGER_MODES);
         }
         RingtoneManager.setActualDefaultRingtoneUri(mContext, RingtoneManager.TYPE_RINGTONE,
                 mDefaultRingUri);
diff --git a/tests/tests/net/AndroidTest.xml b/tests/tests/net/AndroidTest.xml
index dc80339..5194da3 100644
--- a/tests/tests/net/AndroidTest.xml
+++ b/tests/tests/net/AndroidTest.xml
@@ -13,7 +13,6 @@
      limitations under the License.
 -->
 <configuration description="Config for CTS Net test cases">
-    <target_preparer class="com.android.compatibility.common.tradefed.targetprep.WifiCheck" />
     <target_preparer class="com.android.compatibility.common.tradefed.targetprep.ApkInstaller">
         <option name="cleanup-apks" value="true" />
         <option name="test-file-name" value="CtsNetTestCases.apk" />
diff --git a/tests/tests/networksecurityconfig/networksecurityconfig-attributes/AndroidManifest.xml b/tests/tests/networksecurityconfig/networksecurityconfig-attributes/AndroidManifest.xml
index c2018ba..9356074 100644
--- a/tests/tests/networksecurityconfig/networksecurityconfig-attributes/AndroidManifest.xml
+++ b/tests/tests/networksecurityconfig/networksecurityconfig-attributes/AndroidManifest.xml
@@ -18,10 +18,8 @@
 
 <manifest xmlns:android="http://schemas.android.com/apk/res/android"
         package="android.security.net.config.cts.CtsNetSecConfigAttributeTestCases">
-  <application>
+  <application android:networkSecurityConfig="@xml/network_security_config">
       <uses-library android:name="android.test.runner"/>
-      <meta-data android:name="android.security.net.config"
-                 android:resource="@xml/network_security_config" />
   </application>
 
   <uses-permission android:name="android.permission.INTERNET" />
diff --git a/tests/tests/networksecurityconfig/networksecurityconfig-basic-domain/AndroidManifest.xml b/tests/tests/networksecurityconfig/networksecurityconfig-basic-domain/AndroidManifest.xml
index 0fd1a59..565f23a 100644
--- a/tests/tests/networksecurityconfig/networksecurityconfig-basic-domain/AndroidManifest.xml
+++ b/tests/tests/networksecurityconfig/networksecurityconfig-basic-domain/AndroidManifest.xml
@@ -18,10 +18,8 @@
 
 <manifest xmlns:android="http://schemas.android.com/apk/res/android"
         package="android.security.net.config.cts.CtsNetSecConfigBasicDomainConfigTestCases">
-  <application>
+  <application android:networkSecurityConfig="@xml/network_security_config">
       <uses-library android:name="android.test.runner"/>
-      <meta-data android:name="android.security.net.config"
-                 android:resource="@xml/network_security_config" />
   </application>
 
   <uses-permission android:name="android.permission.INTERNET" />
diff --git a/tests/tests/networksecurityconfig/networksecurityconfig-cleartext/AndroidManifest.xml b/tests/tests/networksecurityconfig/networksecurityconfig-cleartext/AndroidManifest.xml
index dbb4770..b387ffa 100644
--- a/tests/tests/networksecurityconfig/networksecurityconfig-cleartext/AndroidManifest.xml
+++ b/tests/tests/networksecurityconfig/networksecurityconfig-cleartext/AndroidManifest.xml
@@ -18,10 +18,8 @@
 
 <manifest xmlns:android="http://schemas.android.com/apk/res/android"
         package="android.security.net.config.cts.CtsNetSecConfigCleartextTrafficTestCases">
-  <application>
+  <application android:networkSecurityConfig="@xml/network_security_config">
       <uses-library android:name="android.test.runner"/>
-      <meta-data android:name="android.security.net.config"
-                 android:resource="@xml/network_security_config" />
   </application>
 
   <uses-permission android:name="android.permission.INTERNET" />
diff --git a/tests/tests/networksecurityconfig/networksecurityconfig-debug-basic-disabled/AndroidManifest.xml b/tests/tests/networksecurityconfig/networksecurityconfig-debug-basic-disabled/AndroidManifest.xml
index 9464950..3f15f81 100644
--- a/tests/tests/networksecurityconfig/networksecurityconfig-debug-basic-disabled/AndroidManifest.xml
+++ b/tests/tests/networksecurityconfig/networksecurityconfig-debug-basic-disabled/AndroidManifest.xml
@@ -18,10 +18,9 @@
 
 <manifest xmlns:android="http://schemas.android.com/apk/res/android"
         package="android.security.net.config.cts.CtsNetSecConfigBasicDebugDisabledTestCases">
-  <application android:debuggable="false">
+  <application android:debuggable="false"
+               android:networkSecurityConfig="@xml/network_security_config">
       <uses-library android:name="android.test.runner"/>
-      <meta-data android:name="android.security.net.config"
-                 android:resource="@xml/network_security_config" />
   </application>
 
   <uses-permission android:name="android.permission.INTERNET" />
diff --git a/tests/tests/networksecurityconfig/networksecurityconfig-debug-basic-enabled/AndroidManifest.xml b/tests/tests/networksecurityconfig/networksecurityconfig-debug-basic-enabled/AndroidManifest.xml
index 2a46c8c..6d98702 100644
--- a/tests/tests/networksecurityconfig/networksecurityconfig-debug-basic-enabled/AndroidManifest.xml
+++ b/tests/tests/networksecurityconfig/networksecurityconfig-debug-basic-enabled/AndroidManifest.xml
@@ -18,10 +18,9 @@
 
 <manifest xmlns:android="http://schemas.android.com/apk/res/android"
         package="android.security.net.config.cts.CtsNetSecConfigBasicDebugEnabledTestCases">
-  <application android:debuggable="true">
+  <application android:debuggable="true"
+               android:networkSecurityConfig="@xml/network_security_config">
       <uses-library android:name="android.test.runner"/>
-      <meta-data android:name="android.security.net.config"
-                 android:resource="@xml/network_security_config" />
   </application>
 
   <uses-permission android:name="android.permission.INTERNET" />
diff --git a/tests/tests/networksecurityconfig/networksecurityconfig-invalid-pin/AndroidManifest.xml b/tests/tests/networksecurityconfig/networksecurityconfig-invalid-pin/AndroidManifest.xml
index e01dc07..b3b32b5 100644
--- a/tests/tests/networksecurityconfig/networksecurityconfig-invalid-pin/AndroidManifest.xml
+++ b/tests/tests/networksecurityconfig/networksecurityconfig-invalid-pin/AndroidManifest.xml
@@ -18,10 +18,8 @@
 
 <manifest xmlns:android="http://schemas.android.com/apk/res/android"
         package="android.security.net.config.cts.CtsNetSecConfigInvalidPinTestCases">
-  <application>
+  <application android:networkSecurityConfig="@xml/network_security_config">
       <uses-library android:name="android.test.runner"/>
-      <meta-data android:name="android.security.net.config"
-                 android:resource="@xml/network_security_config" />
   </application>
 
   <uses-permission android:name="android.permission.INTERNET" />
diff --git a/tests/tests/networksecurityconfig/networksecurityconfig-nested-domains/AndroidManifest.xml b/tests/tests/networksecurityconfig/networksecurityconfig-nested-domains/AndroidManifest.xml
index 358644e..1790150 100644
--- a/tests/tests/networksecurityconfig/networksecurityconfig-nested-domains/AndroidManifest.xml
+++ b/tests/tests/networksecurityconfig/networksecurityconfig-nested-domains/AndroidManifest.xml
@@ -18,10 +18,8 @@
 
 <manifest xmlns:android="http://schemas.android.com/apk/res/android"
         package="android.security.net.config.cts.CtsNetSecConfigNestedDomainConfigTestCases">
-  <application>
+  <application android:networkSecurityConfig="@xml/network_security_config">
       <uses-library android:name="android.test.runner"/>
-      <meta-data android:name="android.security.net.config"
-                 android:resource="@xml/network_security_config" />
   </application>
 
   <uses-permission android:name="android.permission.INTERNET" />
diff --git a/tests/tests/networksecurityconfig/networksecurityconfig-resourcesrc/AndroidManifest.xml b/tests/tests/networksecurityconfig/networksecurityconfig-resourcesrc/AndroidManifest.xml
index 492a914..46787160 100644
--- a/tests/tests/networksecurityconfig/networksecurityconfig-resourcesrc/AndroidManifest.xml
+++ b/tests/tests/networksecurityconfig/networksecurityconfig-resourcesrc/AndroidManifest.xml
@@ -18,10 +18,8 @@
 
 <manifest xmlns:android="http://schemas.android.com/apk/res/android"
         package="android.security.net.config.cts.CtsNetSecConfigResourcesSrcTestCases">
-  <application>
+  <application android:networkSecurityConfig="@xml/network_security_config">
       <uses-library android:name="android.test.runner"/>
-      <meta-data android:name="android.security.net.config"
-                 android:resource="@xml/network_security_config" />
   </application>
 
   <uses-permission android:name="android.permission.INTERNET" />
diff --git a/tests/tests/util/src/android/util/cts/LocaleListTest.java b/tests/tests/os/src/android/os/cts/LocaleListTest.java
similarity index 99%
rename from tests/tests/util/src/android/util/cts/LocaleListTest.java
rename to tests/tests/os/src/android/os/cts/LocaleListTest.java
index 7693adf..bc30e5c 100644
--- a/tests/tests/util/src/android/util/cts/LocaleListTest.java
+++ b/tests/tests/os/src/android/os/cts/LocaleListTest.java
@@ -14,10 +14,10 @@
  * limitations under the License.
  */
 
-package android.util.cts;
+package android.os.cts;
 
+import android.os.LocaleList;
 import android.os.Parcel;
-import android.util.LocaleList;
 import android.test.AndroidTestCase;
 
 import java.util.Locale;
diff --git a/tests/tests/os/src/android/os/cts/SecurityPatchTest.java b/tests/tests/os/src/android/os/cts/SecurityPatchTest.java
index f35af2e..d24c2ec 100644
--- a/tests/tests/os/src/android/os/cts/SecurityPatchTest.java
+++ b/tests/tests/os/src/android/os/cts/SecurityPatchTest.java
@@ -32,7 +32,7 @@
     private static final String SECURITY_PATCH_DATE_ERROR =
             "ro.build.version.security_patch should be \"%d-%02d\" or later. Found \"%s\"";
     private static final int SECURITY_PATCH_YEAR = 2016;
-    private static final int SECURITY_PATCH_MONTH = 05;
+    private static final int SECURITY_PATCH_MONTH = 07;
 
     private boolean mSkipTests = false;
 
diff --git a/tests/tests/permission/src/android/permission/cts/AudioPermissionTest.java b/tests/tests/permission/src/android/permission/cts/AudioPermissionTest.java
deleted file mode 100644
index 66565dc..0000000
--- a/tests/tests/permission/src/android/permission/cts/AudioPermissionTest.java
+++ /dev/null
@@ -1,113 +0,0 @@
-/*
- * Copyright (C) 2009 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.permission.cts;
-
-import android.content.Context;
-import android.media.MediaPlayer;
-import android.media.MediaRecorder;
-import android.media.AudioManager;
-import android.net.Uri;
-import android.os.Environment;
-import android.test.AndroidTestCase;
-import android.test.suitebuilder.annotation.LargeTest;
-
-/**
- * Test that audio-related Permissions are enforced.
- */
-public class AudioPermissionTest extends AndroidTestCase {
-
-    static String PATH_PREFIX = Environment.getExternalStorageDirectory().toString();
-    static String AUDIO_CAPTURE_PATH = PATH_PREFIX + "this-should-not-exist.amr";
-    static int BEAUTY_SLEEP_INTERVAL = 5 * 1000;
-
-    MediaPlayer mMediaPlayer = null;
-    MediaRecorder mMediaRecorder = null;
-    boolean mRecorded = false;
-
-    @Override
-    protected void setUp() throws Exception {
-        super.setUp();
-        mMediaRecorder = new MediaRecorder();
-    }
-
-    @LargeTest
-    void testMicrophoneRecording() {
-        mMediaRecorder.setAudioSource(MediaRecorder.AudioSource.MIC);
-        mMediaRecorder.setOutputFormat(MediaRecorder.OutputFormat.THREE_GPP);
-        mMediaRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.AMR_NB);
-        mMediaRecorder.setOutputFile(AUDIO_CAPTURE_PATH);
-
-        try {
-            mMediaRecorder.prepare();
-        }
-        catch (SecurityException e) {
-            // expected...?
-            return;
-        } catch (Exception e) {
-            fail("Could not prepare MediaRecorder: " + e.toString());
-        }
-
-        try {
-            mMediaRecorder.start();
-        } catch (SecurityException e) {
-            // expected
-            return;
-        }
-
-        try {
-            Thread.sleep(BEAUTY_SLEEP_INTERVAL);
-        } catch (InterruptedException e) {
-            // OK
-        }
-
-        try {
-            mMediaRecorder.stop();
-            mMediaRecorder.release();
-            mRecorded = true;
-            fail("Recorded from MediaRecorder.AudioSource.MIC");
-        } catch (SecurityException e) {
-            // expected
-            mRecorded = false;
-        }
-    }
-
-    void doRemoteMp3(Uri uri) {
-        try {
-            MediaPlayer plyr = new MediaPlayer();
-            plyr.setDataSource(mContext, uri);
-            plyr.setAudioStreamType(AudioManager.STREAM_MUSIC);
-            plyr.prepare();
-            plyr.seekTo(1000);    // Just to try.
-            plyr.start();
-            Thread.sleep(BEAUTY_SLEEP_INTERVAL / 10);
-            plyr.stop();
-            fail("We just downloaded a song off the Internet with no permissions, and uploaded arbitrary data in the query string");
-            plyr.release();
-        } catch (SecurityException e) {
-            // expected
-        } catch (Exception e) {
-            fail("Got further than we should have trying to load a remote media source");
-        }
-    }
-
-    @LargeTest
-    void testRemoteMp3() {
-        doRemoteMp3(Uri.parse("http://labs.isecpartners.com/chris/noodle.mp3?secret=1234"));
-    }
-
-}
-
diff --git a/tests/tests/permission2/src/android/permission2/cts/NoReceiveSmsPermissionTest.java b/tests/tests/permission2/src/android/permission2/cts/NoReceiveSmsPermissionTest.java
index 6258667..d0cafe9 100644
--- a/tests/tests/permission2/src/android/permission2/cts/NoReceiveSmsPermissionTest.java
+++ b/tests/tests/permission2/src/android/permission2/cts/NoReceiveSmsPermissionTest.java
@@ -26,6 +26,7 @@
 import android.telephony.SmsManager;
 import android.telephony.TelephonyManager;
 import android.test.AndroidTestCase;
+import android.text.TextUtils;
 import android.util.Log;
 
 /**
@@ -78,7 +79,7 @@
             }
         }
 
-        assertTrue("Sms not sent successfully, test environment problem?",
+        assertTrue("[RERUN] Sms not sent successfully. Check signal.",
                 receiver.isMessageSent());
         assertFalse("Sms received without proper permissions", receiver.isSmsReceived());
     }
@@ -93,6 +94,9 @@
                  getContext().getSystemService(Context.TELEPHONY_SERVICE);
         // get current phone number
         String currentNumber = telephony.getLine1Number();
+        assertFalse("[RERUN] SIM card does not provide phone number. Use a suitable SIM Card.",
+                TextUtils.isEmpty(currentNumber));
+
         Log.i(LOG_TAG, String.format("Sending SMS to self: %s", currentNumber));
         sendSms(currentNumber, "test message", sentIntent, deliveryIntent);
     }
diff --git a/tests/tests/print/src/android/print/cts/BasePrintTest.java b/tests/tests/print/src/android/print/cts/BasePrintTest.java
index 497c63e..7f0ae5d 100644
--- a/tests/tests/print/src/android/print/cts/BasePrintTest.java
+++ b/tests/tests/print/src/android/print/cts/BasePrintTest.java
@@ -32,6 +32,7 @@
 import android.graphics.pdf.PdfDocument;
 import android.os.Bundle;
 import android.os.CancellationSignal;
+import android.os.LocaleList;
 import android.os.ParcelFileDescriptor;
 import android.os.SystemClock;
 import android.print.PageRange;
@@ -55,7 +56,6 @@
 import android.support.test.uiautomator.UiSelector;
 import android.test.InstrumentationTestCase;
 import android.util.DisplayMetrics;
-import android.util.LocaleList;
 import android.util.Log;
 
 import org.hamcrest.BaseMatcher;
diff --git a/tests/tests/security/AndroidManifest.xml b/tests/tests/security/AndroidManifest.xml
index 7a67b08..1423aca 100644
--- a/tests/tests/security/AndroidManifest.xml
+++ b/tests/tests/security/AndroidManifest.xml
@@ -37,6 +37,14 @@
 
         <service android:name="android.security.cts.activity.SecureRandomService"
                  android:process=":secureRandom"/>
+        <activity
+            android:name="android.security.cts.DisplayDriverActivity"
+            android:label="Test qhwc::MDPCompLowRes::allocLayerPipes (Qualcomm)">
+            <intent-filter>
+                <action android:name="android.intent.action.MAIN"/>
+                <category android:name="android.intent.category.FRAMEWORK_INSTRUMENTATION_TEST"/>
+            </intent-filter>
+        </activity>
     </application>
 
     <instrumentation android:name="android.support.test.runner.AndroidJUnitRunner"
diff --git a/tests/tests/security/res/layout/activity_displaydriver.xml b/tests/tests/security/res/layout/activity_displaydriver.xml
new file mode 100755
index 0000000..9009dbf
--- /dev/null
+++ b/tests/tests/security/res/layout/activity_displaydriver.xml
@@ -0,0 +1,34 @@
+<?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:layout_width="fill_parent"

+    android:layout_height="fill_parent"

+    android:gravity="center"

+    android:orientation="vertical">

+

+    <VideoView

+        android:id="@+id/videoview"

+        android:layout_width="300dp"

+        android:layout_height="250dp"

+        android:layout_gravity="center"/>

+

+</LinearLayout>

+

+

+

+

diff --git a/tests/tests/security/res/raw/cve_2015_1531_b_19270126.jpg b/tests/tests/security/res/raw/cve_2015_1531_b_19270126.jpg
new file mode 100644
index 0000000..09f8a7e
--- /dev/null
+++ b/tests/tests/security/res/raw/cve_2015_1531_b_19270126.jpg
Binary files differ
diff --git a/tests/tests/security/res/raw/cve_2015_1532.png b/tests/tests/security/res/raw/cve_2015_1532.png
new file mode 100644
index 0000000..57924ae
--- /dev/null
+++ b/tests/tests/security/res/raw/cve_2015_1532.png
Binary files differ
diff --git a/tests/tests/security/res/raw/fuzz.webm b/tests/tests/security/res/raw/fuzz.webm
new file mode 100755
index 0000000..e5d95ce
--- /dev/null
+++ b/tests/tests/security/res/raw/fuzz.webm
Binary files differ
diff --git a/tests/tests/security/src/android/security/cts/AllocatePixelRefIntOverflowTest.java b/tests/tests/security/src/android/security/cts/AllocatePixelRefIntOverflowTest.java
new file mode 100644
index 0000000..288f445
--- /dev/null
+++ b/tests/tests/security/src/android/security/cts/AllocatePixelRefIntOverflowTest.java
@@ -0,0 +1,42 @@
+/*
+ * 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 android.security.cts;
+
+import android.graphics.Bitmap;
+import android.graphics.BitmapFactory;
+import android.test.AndroidTestCase;
+
+import java.io.InputStream;
+
+import android.security.cts.R;
+
+public class AllocatePixelRefIntOverflowTest extends AndroidTestCase {
+
+    /**
+     * Verifies that the device is not vulnerable to ANDROID-19270126: Android
+     * BitmapFactory.decodeStream JPG allocPixelRef integer overflow
+     */
+    public void testAllocateJavaPixelRefIntOverflow() {
+        InputStream exploitImage = mContext.getResources().openRawResource(
+                R.raw.cve_2015_1531_b_19270126);
+        /**
+         * The decodeStream method results in SIGSEGV (Segmentation fault) on unpatched devices
+         * while decoding the exploit image which will lead to process crash
+         */
+        BitmapFactory.decodeStream(exploitImage);
+    }
+}
diff --git a/tests/tests/security/src/android/security/cts/BitmapFactoryDecodeStreamTest.java b/tests/tests/security/src/android/security/cts/BitmapFactoryDecodeStreamTest.java
new file mode 100644
index 0000000..4d51ea7
--- /dev/null
+++ b/tests/tests/security/src/android/security/cts/BitmapFactoryDecodeStreamTest.java
@@ -0,0 +1,40 @@
+/*
+ * 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 android.security.cts;
+
+import android.graphics.BitmapFactory;
+import android.test.AndroidTestCase;
+
+import android.security.cts.R;
+
+import java.io.BufferedInputStream;
+import java.io.InputStream;
+
+public class BitmapFactoryDecodeStreamTest extends AndroidTestCase {
+    /*
+     * This test case reproduces the bug in CVE-2015-1532.
+     * It verifies that the BitmapFactory:decodeStream method is not vulnerable
+     * to heap corruption by trying to open a crafted PNG image with incorrect
+     * npTc chunk.
+     */
+    public void testNinePatchHeapOverflow() throws Exception {
+        InputStream inStream = new BufferedInputStream(mContext.getResources().openRawResource(
+                R.raw.cve_2015_1532));
+        BitmapFactory.decodeStream(inStream);
+
+    }
+}
diff --git a/tests/tests/security/src/android/security/cts/DisplayDriverActivity.java b/tests/tests/security/src/android/security/cts/DisplayDriverActivity.java
new file mode 100755
index 0000000..ca6c898
--- /dev/null
+++ b/tests/tests/security/src/android/security/cts/DisplayDriverActivity.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 android.security.cts;

+

+import android.security.cts.R;

+

+import android.app.Activity;

+import android.os.Bundle;

+

+public class DisplayDriverActivity extends Activity {

+    @Override

+    protected void onCreate(Bundle savedInstanceState) {

+        super.onCreate(savedInstanceState);

+        setContentView(R.layout.activity_displaydriver);

+    }

+}

diff --git a/tests/tests/security/src/android/security/cts/DisplayDriverTest.java b/tests/tests/security/src/android/security/cts/DisplayDriverTest.java
new file mode 100755
index 0000000..7f3a0d4
--- /dev/null
+++ b/tests/tests/security/src/android/security/cts/DisplayDriverTest.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 android.security.cts;

+

+import android.security.cts.R;

+

+import android.app.Activity;

+import android.media.MediaPlayer;

+import android.media.MediaPlayer.OnErrorListener;

+import android.net.Uri;

+import android.os.SystemClock;

+import android.test.ActivityInstrumentationTestCase2;

+import android.widget.MediaController;

+import android.widget.VideoView;

+

+public class DisplayDriverTest extends

+        ActivityInstrumentationTestCase2<DisplayDriverActivity> {

+    /**

+     * The maximum time to wait for an operation.

+     */

+    private static final int TIMEOUT_ASYNC_PROCESSING = 3000;

+    private Activity mActivity;

+

+    public DisplayDriverTest() {

+        super(DisplayDriverActivity.class);

+    }

+

+    /**

+     * Checks whether video crashed or not

+     * 1. Initializes mTriggered to false

+     * 2. sets mTriggered to true if onError() occurred while playing video

+     */

+    private static class MockListener {

+        private boolean mTriggered;

+

+        MockListener() {

+            mTriggered = false;

+        }

+

+        public boolean isTriggered() {

+            return mTriggered;

+        }

+

+        protected void onEvent() {

+            mTriggered = true;

+        }

+    }

+

+    private static class MockOnErrorListener extends MockListener implements

+            OnErrorListener {

+        public boolean onError(MediaPlayer mp, int what, int extra) {

+            super.onEvent();

+            return false;

+        }

+    }

+

+    @Override

+    protected void setUp() throws Exception {

+        super.setUp();

+        mActivity = getActivity();

+        assertNotNull("Failed to get the activity instance", mActivity);

+    }

+

+    /**

+     * 1. Runs the vulnerable video by registering OnErrorListener for VideoView

+     * 2. Wait for max time taken by video to crash and hit OnErrorListener

+     * 3. if video crashed - Pass the test case otherwise Fail the test case

+     */

+    public void testDisplayDriver_cve_2015_6634() {

+        final MockOnErrorListener listener = new MockOnErrorListener();

+        mActivity.runOnUiThread(new Runnable() {

+            @Override

+            public void run() {

+                try {

+                    MediaController mMediaControls =

+                            new MediaController(mActivity);

+                    VideoView mVideoView =

+                            (VideoView) mActivity.findViewById(R.id.videoview);

+                    mVideoView.setMediaController(mMediaControls);

+                    mVideoView.setOnErrorListener(listener);

+                    mVideoView.setVideoURI(Uri.parse("android.resource://" +

+                            mActivity.getPackageName() + "/" + R.raw.fuzz));

+                    mVideoView.start();

+                } catch (Exception e) {

+                    listener.onError(null, 0, 0);

+                }

+            }

+        });

+        SystemClock.sleep(TIMEOUT_ASYNC_PROCESSING);

+        assertTrue("Test case failed due to vulnerability in the video: " +

+                        "Device is vulenrable to CVE-2015-6634", listener.isTriggered());

+    }

+

+    @Override

+    protected void tearDown() throws Exception {

+        if (mActivity != null) {

+            mActivity.finish();

+        }

+        super.tearDown();

+    }

+}

diff --git a/tests/tests/telephony2/src/android/telephony2/cts/PhoneNumberTest.java b/tests/tests/telephony2/src/android/telephony2/cts/PhoneNumberTest.java
index 65392c4..8149baa 100644
--- a/tests/tests/telephony2/src/android/telephony2/cts/PhoneNumberTest.java
+++ b/tests/tests/telephony2/src/android/telephony2/cts/PhoneNumberTest.java
@@ -16,6 +16,8 @@
 
 package android.telephony2.cts;
 
+import android.content.Context;
+import android.content.pm.PackageManager;
 import android.os.ParcelFileDescriptor;
 import android.telephony.TelephonyManager;
 import android.test.InstrumentationTestCase;
@@ -48,8 +50,13 @@
     }
 
     public void testGetLine1Number() {
-        TelephonyManager tm = getInstrumentation().getContext().getSystemService(
-                TelephonyManager.class);
+        Context context = getInstrumentation().getContext();
+        PackageManager packageManager = context.getPackageManager();
+        if (!packageManager.hasSystemFeature(PackageManager.FEATURE_TELEPHONY)) {
+            return;
+        }
+
+        TelephonyManager tm = context.getSystemService(TelephonyManager.class);
 
         setDefaultSmsApp(true);
 
diff --git a/tests/tests/text/AndroidTest.xml b/tests/tests/text/AndroidTest.xml
index 4b9d24d..5fef3cb 100644
--- a/tests/tests/text/AndroidTest.xml
+++ b/tests/tests/text/AndroidTest.xml
@@ -14,7 +14,6 @@
      limitations under the License.
 -->
 <configuration description="Config for CTS Text test cases">
-    <target_preparer class="com.android.compatibility.common.tradefed.targetprep.WifiCheck" />
     <target_preparer class="com.android.compatibility.common.tradefed.targetprep.ApkInstaller">
         <option name="cleanup-apks" value="true" />
         <option name="test-file-name" value="CtsTextTestCases.apk" />
diff --git a/tests/tests/text/src/android/text/style/cts/LocaleSpanTest.java b/tests/tests/text/src/android/text/style/cts/LocaleSpanTest.java
index f44cca5..bb7cdd9 100644
--- a/tests/tests/text/src/android/text/style/cts/LocaleSpanTest.java
+++ b/tests/tests/text/src/android/text/style/cts/LocaleSpanTest.java
@@ -18,11 +18,11 @@
 
 import junit.framework.TestCase;
 import android.annotation.NonNull;
+import android.os.LocaleList;
 import android.os.Parcel;
 import android.test.suitebuilder.annotation.SmallTest;
 import android.text.TextPaint;
 import android.text.style.LocaleSpan;
-import android.util.LocaleList;
 
 public class LocaleSpanTest extends TestCase {
 
diff --git a/tests/tests/uiautomation/Android.mk b/tests/tests/uiautomation/Android.mk
index d9fc278..c595635 100644
--- a/tests/tests/uiautomation/Android.mk
+++ b/tests/tests/uiautomation/Android.mk
@@ -29,7 +29,7 @@
 
 LOCAL_PACKAGE_NAME := CtsUiAutomationTestCases
 
-LOCAL_SDK_VERSION := current
+LOCAL_SDK_VERSION := test_current
 
 include $(BUILD_CTS_PACKAGE)
 
diff --git a/tests/tests/view/res/layout/view_layout.xml b/tests/tests/view/res/layout/view_layout.xml
index df1fae9..64ebe39 100644
--- a/tests/tests/view/res/layout/view_layout.xml
+++ b/tests/tests/view/res/layout/view_layout.xml
@@ -111,15 +111,15 @@
           android:orientation="vertical"
           android:layout_width="match_parent"
           android:layout_height="70px"
-          android:pointerShape="crosshair">
+          android:pointerIcon="crosshair">
         <View android:layout_width="match_parent"
               android:layout_height="20px"
-              android:pointerShape="help"/>
+              android:pointerIcon="help"/>
         <View android:layout_width="match_parent"
               android:layout_height="20px"/>
         <View android:layout_width="match_parent"
               android:layout_height="20px"
-              android:pointerShape="@drawable/custom_pointer_icon"/>
+              android:pointerIcon="@drawable/custom_pointer_icon"/>
       </LinearLayout>
     </LinearLayout>
 
diff --git a/tests/tests/view/src/android/view/cts/MockView.java b/tests/tests/view/src/android/view/cts/MockView.java
index f07e991..c5e4ab4 100644
--- a/tests/tests/view/src/android/view/cts/MockView.java
+++ b/tests/tests/view/src/android/view/cts/MockView.java
@@ -69,7 +69,7 @@
     private boolean mCalledComputeScroll = false;
     private boolean mCalledDispatchKeyEventPreIme = false;
     private boolean mCalledOnKeyPreIme = false;
-    private boolean mCalledGetPointerIcon = false;
+    private boolean mCalledOnResolvePointerIcon = false;
     private boolean mCalledOnVisibilityAggregated = false;
     private boolean mCalledDispatchStartTemporaryDetach = false;
     private boolean mCalledDispatchFinishTemporaryDetach = false;
@@ -614,13 +614,13 @@
     }
 
     @Override
-    public PointerIcon getPointerIcon(MotionEvent event, float x, float y) {
-        mCalledGetPointerIcon = true;
-        return super.getPointerIcon(event, x, y);
+    public PointerIcon onResolvePointerIcon(MotionEvent event, int pointerIndex) {
+        mCalledOnResolvePointerIcon = true;
+        return super.onResolvePointerIcon(event, pointerIndex);
     }
 
-    public boolean hasCalledGetPointerIcon() {
-        return mCalledGetPointerIcon;
+    public boolean hasCalledOnResolvePointerIcon() {
+        return mCalledOnResolvePointerIcon;
     }
 
     @Override
@@ -716,7 +716,7 @@
         mCalledComputeScroll = false;
         mCalledDispatchKeyEventPreIme = false;
         mCalledOnKeyPreIme = false;
-        mCalledGetPointerIcon = false;
+        mCalledOnResolvePointerIcon = false;
         mCalledOnVisibilityAggregated = false;
         mCalledOnVisibilityAggregated = false;
         mCalledDispatchStartTemporaryDetach = false;
diff --git a/tests/tests/view/src/android/view/cts/ViewTest.java b/tests/tests/view/src/android/view/cts/ViewTest.java
index 3f667f5..d3ff57d 100644
--- a/tests/tests/view/src/android/view/cts/ViewTest.java
+++ b/tests/tests/view/src/android/view/cts/ViewTest.java
@@ -377,73 +377,73 @@
         getInstrumentation().sendPointerSync(event);
         getInstrumentation().waitForIdleSync();
 
-        assertTrue(view.hasCalledGetPointerIcon());
+        assertTrue(view.hasCalledOnResolvePointerIcon());
 
         final MockView view2 = (MockView) mActivity.findViewById(R.id.scroll_view);
-        assertFalse(view2.hasCalledGetPointerIcon());
+        assertFalse(view2.hasCalledOnResolvePointerIcon());
     }
 
-    public void testAccessPointerShape() {
+    public void testAccessPointerIcon() {
         View view = mActivity.findViewById(R.id.pointer_icon_layout);
         MotionEvent event = MotionEvent.obtain(0, 0, MotionEvent.ACTION_HOVER_MOVE,
                                                view.getX(), view.getY(), 0);
 
-        // First view has pointerShape="help"
-        assertEquals(PointerIcon.getSystemIcon(mActivity, PointerIcon.STYLE_HELP),
-                     view.getPointerIcon(event, 0, 0));
+        // First view has pointerIcon="help"
+        assertEquals(PointerIcon.getSystemIcon(mActivity, PointerIcon.TYPE_HELP),
+                     view.onResolvePointerIcon(event, 0));
 
-        // Second view inherits pointerShape="crosshair" from the parent
+        // Second view inherits pointerIcon="crosshair" from the parent
         event.setLocation(0, 21);
-        assertEquals(PointerIcon.getSystemIcon(mActivity, PointerIcon.STYLE_CROSSHAIR),
-                     view.getPointerIcon(event, 0, 21));
+        assertEquals(PointerIcon.getSystemIcon(mActivity, PointerIcon.TYPE_CROSSHAIR),
+                     view.onResolvePointerIcon(event, 0));
 
-        // Third view has custom pointer shape defined in a resource.
+        // Third view has custom pointer icon defined in a resource.
         event.setLocation(0, 41);
-        assertNotNull(view.getPointerIcon(event, 0, 41));
+        assertNotNull(view.onResolvePointerIcon(event, 0));
 
-        // Parent view has pointerShape="crosshair"
+        // Parent view has pointerIcon="crosshair"
         event.setLocation(0, 61);
-        assertEquals(PointerIcon.getSystemIcon(mActivity, PointerIcon.STYLE_CROSSHAIR),
-                     view.getPointerIcon(event, 0, 61));
+        assertEquals(PointerIcon.getSystemIcon(mActivity, PointerIcon.TYPE_CROSSHAIR),
+                     view.onResolvePointerIcon(event, 0));
 
-        // Outside of the parent view, no pointer shape defined.
+        // Outside of the parent view, no pointer icon defined.
         event.setLocation(0, 71);
-        assertNull(view.getPointerIcon(event, 0, 71));
+        assertNull(view.onResolvePointerIcon(event, 0));
 
-        view.setPointerIcon(PointerIcon.getSystemIcon(mActivity, PointerIcon.STYLE_TEXT));
-        assertEquals(PointerIcon.getSystemIcon(mActivity, PointerIcon.STYLE_TEXT),
-                     view.getPointerIcon(event, 0,71));
+        view.setPointerIcon(PointerIcon.getSystemIcon(mActivity, PointerIcon.TYPE_TEXT));
+        assertEquals(PointerIcon.getSystemIcon(mActivity, PointerIcon.TYPE_TEXT),
+                     view.onResolvePointerIcon(event, 0));
         event.recycle();
     }
 
     public void testCreatePointerIcons() {
-        assertSystemPointerIcon(PointerIcon.STYLE_NULL);
-        assertSystemPointerIcon(PointerIcon.STYLE_DEFAULT);
-        assertSystemPointerIcon(PointerIcon.STYLE_ARROW);
-        assertSystemPointerIcon(PointerIcon.STYLE_CONTEXT_MENU);
-        assertSystemPointerIcon(PointerIcon.STYLE_HAND);
-        assertSystemPointerIcon(PointerIcon.STYLE_HELP);
-        assertSystemPointerIcon(PointerIcon.STYLE_WAIT);
-        assertSystemPointerIcon(PointerIcon.STYLE_CELL);
-        assertSystemPointerIcon(PointerIcon.STYLE_CROSSHAIR);
-        assertSystemPointerIcon(PointerIcon.STYLE_TEXT);
-        assertSystemPointerIcon(PointerIcon.STYLE_VERTICAL_TEXT);
-        assertSystemPointerIcon(PointerIcon.STYLE_ALIAS);
-        assertSystemPointerIcon(PointerIcon.STYLE_COPY);
-        assertSystemPointerIcon(PointerIcon.STYLE_NO_DROP);
-        assertSystemPointerIcon(PointerIcon.STYLE_ALL_SCROLL);
-        assertSystemPointerIcon(PointerIcon.STYLE_HORIZONTAL_DOUBLE_ARROW);
-        assertSystemPointerIcon(PointerIcon.STYLE_VERTICAL_DOUBLE_ARROW);
-        assertSystemPointerIcon(PointerIcon.STYLE_TOP_RIGHT_DIAGONAL_DOUBLE_ARROW);
-        assertSystemPointerIcon(PointerIcon.STYLE_TOP_LEFT_DIAGONAL_DOUBLE_ARROW);
-        assertSystemPointerIcon(PointerIcon.STYLE_ZOOM_IN);
-        assertSystemPointerIcon(PointerIcon.STYLE_ZOOM_OUT);
-        assertSystemPointerIcon(PointerIcon.STYLE_GRAB);
+        assertSystemPointerIcon(PointerIcon.TYPE_NULL);
+        assertSystemPointerIcon(PointerIcon.TYPE_DEFAULT);
+        assertSystemPointerIcon(PointerIcon.TYPE_ARROW);
+        assertSystemPointerIcon(PointerIcon.TYPE_CONTEXT_MENU);
+        assertSystemPointerIcon(PointerIcon.TYPE_HAND);
+        assertSystemPointerIcon(PointerIcon.TYPE_HELP);
+        assertSystemPointerIcon(PointerIcon.TYPE_WAIT);
+        assertSystemPointerIcon(PointerIcon.TYPE_CELL);
+        assertSystemPointerIcon(PointerIcon.TYPE_CROSSHAIR);
+        assertSystemPointerIcon(PointerIcon.TYPE_TEXT);
+        assertSystemPointerIcon(PointerIcon.TYPE_VERTICAL_TEXT);
+        assertSystemPointerIcon(PointerIcon.TYPE_ALIAS);
+        assertSystemPointerIcon(PointerIcon.TYPE_COPY);
+        assertSystemPointerIcon(PointerIcon.TYPE_NO_DROP);
+        assertSystemPointerIcon(PointerIcon.TYPE_ALL_SCROLL);
+        assertSystemPointerIcon(PointerIcon.TYPE_HORIZONTAL_DOUBLE_ARROW);
+        assertSystemPointerIcon(PointerIcon.TYPE_VERTICAL_DOUBLE_ARROW);
+        assertSystemPointerIcon(PointerIcon.TYPE_TOP_RIGHT_DIAGONAL_DOUBLE_ARROW);
+        assertSystemPointerIcon(PointerIcon.TYPE_TOP_LEFT_DIAGONAL_DOUBLE_ARROW);
+        assertSystemPointerIcon(PointerIcon.TYPE_ZOOM_IN);
+        assertSystemPointerIcon(PointerIcon.TYPE_ZOOM_OUT);
+        assertSystemPointerIcon(PointerIcon.TYPE_GRAB);
 
-        assertNotNull(PointerIcon.loadCustomIcon(mResources, R.drawable.custom_pointer_icon));
+        assertNotNull(PointerIcon.load(mResources, R.drawable.custom_pointer_icon));
 
         Bitmap bitmap = BitmapFactory.decodeResource(mResources, R.drawable.icon_blue);
-        assertNotNull(PointerIcon.createCustomIcon(bitmap, 0, 0));
+        assertNotNull(PointerIcon.create(bitmap, 0, 0));
     }
 
     private void assertSystemPointerIcon(int style) {
@@ -3876,7 +3876,7 @@
 
         assertFalse(view.hasPointerCapture());
 
-        view.setPointerCapture();
+        view.requestPointerCapture();
         assertTrue(view.hasPointerCapture());
         getInstrumentation().sendPointerSync(dummyMotion);
         getInstrumentation().waitForIdleSync();
@@ -3895,7 +3895,7 @@
         });
         getInstrumentation().waitForIdleSync();
 
-        view.setPointerCapture();
+        view.requestPointerCapture();
         assertTrue(view.hasPointerCapture());
         assertFalse(view2.hasPointerCapture());
 
@@ -3905,7 +3905,7 @@
         assertFalse(view2.hasCalledOnHoverEvent());
         view.reset();
 
-        view2.setPointerCapture();
+        view2.requestPointerCapture();
         assertFalse(view.hasPointerCapture());
         assertTrue(view2.hasPointerCapture());
 
diff --git a/tests/tests/view/src/android/view/inputmethod/cts/EditorInfoTest.java b/tests/tests/view/src/android/view/inputmethod/cts/EditorInfoTest.java
index 22c6be4..e9c3058 100644
--- a/tests/tests/view/src/android/view/inputmethod/cts/EditorInfoTest.java
+++ b/tests/tests/view/src/android/view/inputmethod/cts/EditorInfoTest.java
@@ -18,10 +18,10 @@
 
 
 import android.os.Bundle;
+import android.os.LocaleList;
 import android.os.Parcel;
 import android.test.AndroidTestCase;
 import android.text.TextUtils;
-import android.util.LocaleList;
 import android.util.Printer;
 import android.view.inputmethod.EditorInfo;
 
diff --git a/tests/tests/webkit/AndroidTest.xml b/tests/tests/webkit/AndroidTest.xml
index e6649e1..7e8ed69 100644
--- a/tests/tests/webkit/AndroidTest.xml
+++ b/tests/tests/webkit/AndroidTest.xml
@@ -14,7 +14,6 @@
      limitations under the License.
 -->
 <configuration description="Config for CTS Webkit test cases">
-    <target_preparer class="com.android.compatibility.common.tradefed.targetprep.WifiCheck" />
     <target_preparer class="com.android.compatibility.common.tradefed.targetprep.LocationCheck" />
     <target_preparer class="com.android.compatibility.common.tradefed.targetprep.ApkInstaller">
         <option name="cleanup-apks" value="true" />
diff --git a/tests/tests/widget/AndroidTest.xml b/tests/tests/widget/AndroidTest.xml
index ed7742a..d0cb110 100644
--- a/tests/tests/widget/AndroidTest.xml
+++ b/tests/tests/widget/AndroidTest.xml
@@ -14,7 +14,6 @@
      limitations under the License.
 -->
 <configuration description="Config for CTS Widget test cases">
-    <target_preparer class="com.android.compatibility.common.tradefed.targetprep.WifiCheck" />
     <target_preparer class="com.android.compatibility.common.tradefed.targetprep.ApkInstaller">
         <option name="cleanup-apks" value="true" />
         <option name="test-file-name" value="CtsWidgetTestCases.apk" />
diff --git a/tests/tests/widget/src/android/widget/cts/TextViewTest.java b/tests/tests/widget/src/android/widget/cts/TextViewTest.java
index effc685..4a709dd 100644
--- a/tests/tests/widget/src/android/widget/cts/TextViewTest.java
+++ b/tests/tests/widget/src/android/widget/cts/TextViewTest.java
@@ -39,6 +39,7 @@
 import android.graphics.drawable.Drawable;
 import android.net.Uri;
 import android.os.Bundle;
+import android.os.LocaleList;
 import android.os.Parcelable;
 import android.test.ActivityInstrumentationTestCase2;
 import android.test.TouchUtils;
@@ -77,7 +78,6 @@
 import android.text.style.UnderlineSpan;
 import android.text.util.Linkify;
 import android.util.DisplayMetrics;
-import android.util.LocaleList;
 import android.util.TypedValue;
 import android.view.ActionMode;
 import android.view.ContextMenu;
diff --git a/tests/tvprovider/AndroidTest.xml b/tests/tvprovider/AndroidTest.xml
index f92b37d..36c423d 100644
--- a/tests/tvprovider/AndroidTest.xml
+++ b/tests/tvprovider/AndroidTest.xml
@@ -20,5 +20,7 @@
     </target_preparer>
     <test class="com.android.tradefed.testtype.AndroidJUnitTest" >
         <option name="package" value="android.tvprovider.cts" />
+        <!-- test-timeout unit is ms, value = 30 min -->
+        <option name="test-timeout" value="1800000" />
     </test>
 </configuration>
diff --git a/tests/vr/src/android/vr/cts/OpenGLESActivity.java b/tests/vr/src/android/vr/cts/OpenGLESActivity.java
index 1286594..2879114 100644
--- a/tests/vr/src/android/vr/cts/OpenGLESActivity.java
+++ b/tests/vr/src/android/vr/cts/OpenGLESActivity.java
@@ -43,13 +43,16 @@
     public static final String EXTRA_VIEW_INDEX = "viewIndex";
     public static final String EXTRA_PROTECTED = "protected";
     public static final String EXTRA_PRIORITY = "priority";
+    public static final String EXTRA_MUTABLE = "mutable";
     public static final String EXTRA_LATCH_COUNT = "latchCount";
 
 
     public static final int EGL_PROTECTED_CONTENT_EXT = 0x32C0;
 
-    // Context priority enums are not exposed in Java.
+    // EGL extension enums are not exposed in Java.
     public static final int EGL_CONTEXT_PRIORITY_LEVEL_IMG = 0x3100;
+    public static final int EGL_MUTABLE_RENDER_BUFFER_BIT = 0x1000;
+    private static final int EGL_OPENGL_ES3_BIT_KHR = 0x40;
 
     OpenGLES20View mView;
     Renderer mRenderer;
@@ -65,10 +68,11 @@
         int viewIndex = getIntent().getIntExtra(EXTRA_VIEW_INDEX, -1);
         int protectedAttribute = getIntent().getIntExtra(EXTRA_PROTECTED, -1);
         int priorityAttribute = getIntent().getIntExtra(EXTRA_PRIORITY, -1);
+        int mutableAttribute =  getIntent().getIntExtra(EXTRA_MUTABLE, 0);
         int latchCount = getIntent().getIntExtra(EXTRA_LATCH_COUNT, 1);
         mLatch = new CountDownLatch(latchCount);
         mView = new OpenGLES20View(this, viewIndex, protectedAttribute, priorityAttribute,
-            mLatch);
+            mutableAttribute, mLatch);
 
         setContentView(mView);
     }
@@ -180,7 +184,7 @@
     class OpenGLES20View extends GLSurfaceView {
 
         public OpenGLES20View(Context context, int index, int protectedAttribute,
-            int priorityAttribute, CountDownLatch latch) {
+            int priorityAttribute, int mutableAttribute, CountDownLatch latch) {
             super(context);
             setEGLContextClientVersion(2);
 
@@ -189,8 +193,11 @@
                 setEGLWindowSurfaceFactory(new ProtectedWindowSurfaceFactory());
             } else if (priorityAttribute != 0) {
                 setEGLContextFactory(new PriorityContextFactory(priorityAttribute));
+            } else if (mutableAttribute != 0 && supportsVrHighPerformance()) {
+                setEGLConfigChooser(new MutableEGLConfigChooser());
             }
 
+
             if (index == 1) {
                 mRenderer = new RendererBasicTest(latch);
             } else  if (index == 2) {
@@ -229,7 +236,7 @@
             EGLContext context = egl.eglCreateContext(display, config, EGL10.EGL_NO_CONTEXT,
                 attrib_list);
             if (context == EGL10.EGL_NO_CONTEXT) {
-              Log.e(TAG, "Error creating EGL context.");
+                Log.e(TAG, "Error creating EGL context.");
             }
             checkEglError("eglCreateContext");
             return context;
@@ -237,7 +244,7 @@
 
         public void destroyContext(EGL10 egl, EGLDisplay display, EGLContext context) {
             if (!egl.eglDestroyContext(display, context)) {
-              Log.e("DefaultContextFactory", "display:" + display + " context: " + context);
+                Log.e("DefaultContextFactory", "display:" + display + " context: " + context);
             }
           }
     }
@@ -270,23 +277,101 @@
 
     private class ProtectedWindowSurfaceFactory implements GLSurfaceView.EGLWindowSurfaceFactory {
 
-      public EGLSurface createWindowSurface(EGL10 egl, EGLDisplay display,
-                                            EGLConfig config, Object nativeWindow) {
-        EGLSurface result = null;
-        try {
-          boolean highPerf = supportsVrHighPerformance();
-          int[] attrib_list = { highPerf ? EGL_PROTECTED_CONTENT_EXT : EGL10.EGL_NONE,
-                  highPerf ? EGL14.EGL_TRUE : EGL10.EGL_NONE, EGL10.EGL_NONE };
-          result = egl.eglCreateWindowSurface(display, config, nativeWindow, attrib_list);
-          checkEglError("eglCreateWindowSurface");
-        } catch (IllegalArgumentException e) {
-          Log.e(TAG, "eglCreateWindowSurface", e);
+        public EGLSurface createWindowSurface(EGL10 egl, EGLDisplay display,
+                                              EGLConfig config, Object nativeWindow) {
+          EGLSurface result = null;
+          try {
+              boolean highPerf = supportsVrHighPerformance();
+              int[] attrib_list = { highPerf ? EGL_PROTECTED_CONTENT_EXT : EGL10.EGL_NONE,
+                      highPerf ? EGL14.EGL_TRUE : EGL10.EGL_NONE, EGL10.EGL_NONE };
+              result = egl.eglCreateWindowSurface(display, config, nativeWindow, attrib_list);
+              checkEglError("eglCreateWindowSurface");
+          } catch (IllegalArgumentException e) {
+              Log.e(TAG, "eglCreateWindowSurface", e);
+          }
+          return result;
         }
-        return result;
-      }
 
-      public void destroySurface(EGL10 egl, EGLDisplay display, EGLSurface surface) {
-        egl.eglDestroySurface(display, surface);
-      }
+        public void destroySurface(EGL10 egl, EGLDisplay display, EGLSurface surface) {
+            egl.eglDestroySurface(display, surface);
+        }
+    }
+
+    private class MutableEGLConfigChooser implements GLSurfaceView.EGLConfigChooser {
+        public EGLConfig chooseConfig(EGL10 egl, EGLDisplay display) {
+            int[] configSpec = new int[] {
+                EGL10.EGL_RED_SIZE, 8,
+                EGL10.EGL_GREEN_SIZE, 8,
+                EGL10.EGL_BLUE_SIZE, 8,
+                EGL10.EGL_ALPHA_SIZE, 8,
+                EGL10.EGL_DEPTH_SIZE, 16,
+                EGL10.EGL_STENCIL_SIZE, 8,
+                EGL10.EGL_RENDERABLE_TYPE, EGL_OPENGL_ES3_BIT_KHR,
+                EGL10.EGL_SURFACE_TYPE, EGL10.EGL_WINDOW_BIT | EGL_MUTABLE_RENDER_BUFFER_BIT,
+                EGL10.EGL_NONE
+            };
+
+            int[] num_config = new int[1];
+            if (!egl.eglChooseConfig(display, configSpec, null, 0, num_config)) {
+                throw new IllegalArgumentException("eglChooseConfig failed");
+            }
+
+            int numConfigs = num_config[0];
+            if (numConfigs <= 0) {
+                throw new IllegalArgumentException("No configs match configSpec");
+            }
+
+            EGLConfig[] configs = new EGLConfig[numConfigs];
+            if (!egl.eglChooseConfig(display, configSpec, configs, numConfigs,
+                    num_config)) {
+                throw new IllegalArgumentException("eglChooseConfig#2 failed");
+            }
+            EGLConfig config = chooseConfig(egl, display, configs);
+            if (config == null) {
+                throw new IllegalArgumentException("No config chosen");
+            }
+            return config;
+        }
+        public EGLConfig chooseConfig(EGL10 egl, EGLDisplay display,
+                EGLConfig[] configs) {
+            for (EGLConfig config : configs) {
+                int d = findConfigAttrib(egl, display, config,
+                        EGL10.EGL_DEPTH_SIZE, 0);
+                int s = findConfigAttrib(egl, display, config,
+                        EGL10.EGL_STENCIL_SIZE, 0);
+
+                // We need at least mDepthSize and mStencilSize bits
+                if (d < 16 || s < 8)
+                    continue;
+
+                // We want an *exact* match for red/green/blue/alpha
+                int r = findConfigAttrib(egl, display, config,
+                        EGL10.EGL_RED_SIZE, 0);
+                int g = findConfigAttrib(egl, display, config,
+                            EGL10.EGL_GREEN_SIZE, 0);
+                int b = findConfigAttrib(egl, display, config,
+                            EGL10.EGL_BLUE_SIZE, 0);
+                int a = findConfigAttrib(egl, display, config,
+                        EGL10.EGL_ALPHA_SIZE, 0);
+
+                int mask = findConfigAttrib(egl, display, config,
+                        EGL10.EGL_SURFACE_TYPE, 0);
+
+                if (r == 8 && g == 8 && b == 8 && a == 8 &&
+                        (mask & EGL_MUTABLE_RENDER_BUFFER_BIT) != 0)
+                    return config;
+            }
+            return null;
+        }
+
+        private int findConfigAttrib(EGL10 egl, EGLDisplay display,
+                EGLConfig config, int attribute, int defaultValue) {
+
+            int[] value = new int[1];
+            if (egl.eglGetConfigAttrib(display, config, attribute, value)) {
+                return value[0];
+            }
+            return defaultValue;
+        }
     }
 }
diff --git a/tests/vr/src/android/vr/cts/VrExtensionBehaviorTest.java b/tests/vr/src/android/vr/cts/VrExtensionBehaviorTest.java
index 4226f15..7294cfe 100644
--- a/tests/vr/src/android/vr/cts/VrExtensionBehaviorTest.java
+++ b/tests/vr/src/android/vr/cts/VrExtensionBehaviorTest.java
@@ -37,11 +37,12 @@
     }
 
     private OpenGLESActivity getGlEsActivity(int viewIndex, int createProtected,
-        int priorityAttribute) {
+        int priorityAttribute, int mutableAttribute) {
         Intent intent = new Intent();
         intent.putExtra(OpenGLESActivity.EXTRA_VIEW_INDEX, viewIndex);
         intent.putExtra(OpenGLESActivity.EXTRA_PROTECTED, createProtected);
         intent.putExtra(OpenGLESActivity.EXTRA_PRIORITY, priorityAttribute);
+        intent.putExtra(OpenGLESActivity.EXTRA_MUTABLE, mutableAttribute);
         setActivityIntent(intent);
         OpenGLESActivity activity = getActivity();
         assertTrue(activity.waitForFrameDrawn());
@@ -52,7 +53,7 @@
      * Tests that protected content contexts and surfaces can be created.
      */
     public void testProtectedContent() throws Throwable {
-        mActivity = getGlEsActivity(1, 1, 0);
+        mActivity = getGlEsActivity(1, 1, 0, 0);
         if (!mActivity.supportsVrHighPerformance())
             return;
 
@@ -76,7 +77,7 @@
      * Tests that textures can be marked as protected.
      */
     public void testProtectedTextures() throws Throwable {
-        mActivity = getGlEsActivity(2, 1, 0);
+        mActivity = getGlEsActivity(2, 1, 0, 0);
         if (!mActivity.supportsVrHighPerformance())
             return;
 
@@ -126,7 +127,7 @@
      */
     public void testMutableRenderBuffer() throws Throwable {
 
-        mActivity = getGlEsActivity(1, 0, 0);
+        mActivity = getGlEsActivity(1, 0, 0, 1);
         if (!mActivity.supportsVrHighPerformance())
             return;
 
@@ -141,14 +142,14 @@
                     EGL14.EGL_TRUE);
                 swapBuffers();
                 assertTrue("Unable to enable single buffered mode",
-                    OpenGLESActivity.contextHasAttributeWithValue(
+                    OpenGLESActivity.surfaceHasAttributeWithValue(
                         EGL14.EGL_RENDER_BUFFER, EGL14.EGL_SINGLE_BUFFER));
 
                 OpenGLESActivity.setSurfaceAttribute(EGL14.EGL_RENDER_BUFFER,
                     EGL14.EGL_BACK_BUFFER);
                 swapBuffers();
                 assertTrue("Unable to disable single buffered mode",
-                    OpenGLESActivity.contextHasAttributeWithValue(
+                    OpenGLESActivity.surfaceHasAttributeWithValue(
                         EGL14.EGL_RENDER_BUFFER, EGL14.EGL_BACK_BUFFER));
             }
         });
@@ -158,7 +159,7 @@
      * Runs a context priority test.
      */
     private void runContextPriorityTest(int priority) throws Throwable {
-        mActivity = getGlEsActivity(1, 0, priority);
+        mActivity = getGlEsActivity(1, 0, priority, 0);
         if (!mActivity.supportsVrHighPerformance())
             return;
 
diff --git a/tools/cts-tradefed/res/config/collect-tests-only.xml b/tools/cts-tradefed/res/config/collect-tests-only.xml
index ce4c5a4..9ee7d51 100644
--- a/tools/cts-tradefed/res/config/collect-tests-only.xml
+++ b/tools/cts-tradefed/res/config/collect-tests-only.xml
@@ -24,7 +24,6 @@
          information, as that would be dishonest, and dishonesty kills kittens :'( -->
     <option name="compatibility:plan" value="collect-tests-only" />
 
-    <option name="skip-device-info" value="true" />
     <option name="skip-preconditions" value="true" />
     <option name="skip-connectivity-check" value="true" />
     <option name="preparer-whitelist" value="com.android.compatibility.common.tradefed.targetprep.ApkInstaller" />
diff --git a/tools/cts-tradefed/res/config/cts-known-failures.xml b/tools/cts-tradefed/res/config/cts-known-failures.xml
index 5ba1028..9c5bd1c 100644
--- a/tools/cts-tradefed/res/config/cts-known-failures.xml
+++ b/tools/cts-tradefed/res/config/cts-known-failures.xml
@@ -71,9 +71,6 @@
 
     <option name="compatibility:exclude-filter" value="CtsCarTestCases" />
 
-    <!-- b/27578806 -->
-    <option name="compatibility:exclude-filter" value="CtsCppToolsTestCases com.android.cts.cpptools.RunAsHostTest#testRunAs" />
-
     <!-- b/23776893 -->
     <option name="compatibility:exclude-filter" value="CtsDumpsysHostTestCases android.dumpsys.cts.DumpsysHostTest#testBatterystatsOutput" />
     <option name="compatibility:exclude-filter" value="CtsDumpsysHostTestCases android.dumpsys.cts.DumpsysHostTest#testGfxinfoFramestats" />
diff --git a/tools/cts-tradefed/res/config/cts-preconditions.xml b/tools/cts-tradefed/res/config/cts-preconditions.xml
index ebbe541..c1de7cd 100644
--- a/tools/cts-tradefed/res/config/cts-preconditions.xml
+++ b/tools/cts-tradefed/res/config/cts-preconditions.xml
@@ -50,6 +50,10 @@
         <option name="dest-dir" value="device-info-files/"/>
     </target_preparer>
 
+    <!-- The following values are used in cts/common/device-side/util/DeviceReportLog.java,
+    cts/common/host-side/util/MetricsReportLog.java and tools/tradefed-host/util/ReportLogUtil.java.
+    Any change in these values must also be translated to the stated files.
+    -->
     <target_preparer class="com.android.compatibility.common.tradefed.targetprep.ReportLogCollector">
         <option name="src-dir" value="/sdcard/report-log-files/"/>
         <option name="dest-dir" value="report-log-files/"/>
diff --git a/tools/tradefed-host/src/com/android/cts/tradefed/testtype/CtsTest.java b/tools/tradefed-host/src/com/android/cts/tradefed/testtype/CtsTest.java
index 85faf17..ffd1f2f 100644
--- a/tools/tradefed-host/src/com/android/cts/tradefed/testtype/CtsTest.java
+++ b/tools/tradefed-host/src/com/android/cts/tradefed/testtype/CtsTest.java
@@ -22,6 +22,7 @@
 import com.android.cts.tradefed.device.DeviceInfoCollector;
 import com.android.cts.tradefed.result.CtsTestStatus;
 import com.android.cts.tradefed.result.PlanCreator;
+import com.android.cts.tradefed.util.ReportLogUtil;
 import com.android.ddmlib.Log;
 import com.android.ddmlib.Log.LogLevel;
 import com.android.ddmlib.testrunner.TestIdentifier;
@@ -519,6 +520,8 @@
             // always collect the device info, even for resumed runs, since test will likely be
             // running on a different device
             collectDeviceInfo(getDevice(), mCtsBuild, listener);
+            // prepare containers to hold test metric report logs.
+            prepareReportLogContainers(getDevice(), mBuildInfo);
             preRebootIfNecessary(mTestPackageList);
 
             mPrevRebootTime = System.currentTimeMillis();
@@ -620,7 +623,8 @@
             }
 
             uninstallPrequisiteApks(uninstallPackages);
-
+            // Collect test metric report logs.
+            collectReportLogs(getDevice(), mBuildInfo);
         } catch (RuntimeException e) {
             CLog.e(e);
             throw e;
@@ -1099,6 +1103,20 @@
     }
 
     /**
+     * Prepares the report log directory on host to store test metric report logs.
+     */
+    void prepareReportLogContainers(ITestDevice device, IBuildInfo buildInfo) {
+        ReportLogUtil.prepareReportLogContainers(device, buildInfo);
+    }
+
+    /**
+     * Collects the test metric report logs written out by device-side and host-side tests.
+     */
+    void collectReportLogs(ITestDevice device, IBuildInfo buildInfo) {
+        ReportLogUtil.collectReportLogs(device, buildInfo);
+    }
+
+    /**
      * Factory method for creating a {@link ITestPackageRepo}.
      * <p/>
      * Exposed for unit testing
diff --git a/tools/tradefed-host/src/com/android/cts/tradefed/util/ReportLogUtil.java b/tools/tradefed-host/src/com/android/cts/tradefed/util/ReportLogUtil.java
new file mode 100644
index 0000000..6ab175f
--- /dev/null
+++ b/tools/tradefed-host/src/com/android/cts/tradefed/util/ReportLogUtil.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.tradefed.util;
+
+import com.android.cts.tradefed.result.CtsXmlResultReporter;
+import com.android.tradefed.build.IBuildInfo;
+import com.android.tradefed.device.ITestDevice;
+import com.android.tradefed.log.LogUtil.CLog;
+import com.android.tradefed.util.FileUtil;
+
+import java.io.File;
+
+/**
+ * Collects report logs from device and host after cts_v1 test runs.
+ */
+public class ReportLogUtil{
+
+    /**
+     * Directory values must match the src-dir, dest-dir and temp-dir values configured in
+     * ReportLogCollector target preparer in
+     * cts/tools/cts-tradefed/res/config/cts-preconditions.xml.
+     */
+    private static final String SRC_DIR = "/sdcard/report-log-files/";
+    private static final String DEST_DIR = "report-log-files/";
+    private static final String TEMP_REPORT_DIR= "temp-report-logs/";
+
+    public static void prepareReportLogContainers(ITestDevice device, IBuildInfo buildInfo) {
+        try {
+            // Delete earlier report logs if present on device.
+            String command = String.format("adb -s %s shell rm -rf %s", device.getSerialNumber(),
+                    SRC_DIR);
+            CLog.e(command);
+            if (device.doesFileExist(SRC_DIR)) {
+                Process process = Runtime.getRuntime().exec(new String[]{"/bin/bash", "-c",
+                        command});
+                if (process.waitFor() != 0) {
+                    CLog.e("Failed to run %s", command);
+                }
+            }
+            // Create folder in result directory to store report logs.
+            File resultDir = new File(buildInfo.getBuildAttributes().get(
+                    CtsXmlResultReporter.CTS_RESULT_DIR));
+            if (DEST_DIR != null) {
+                resultDir = new File(resultDir, DEST_DIR);
+            }
+            resultDir.mkdirs();
+            if (!resultDir.isDirectory()) {
+                CLog.e("%s is not a directory", resultDir.getAbsolutePath());
+                return;
+            }
+        } catch (Exception e) {
+            e.printStackTrace();
+        }
+    }
+
+    public static void collectReportLogs(ITestDevice device, IBuildInfo buildInfo) {
+        // Pull report log files from device and host.
+        try {
+            File resultDir = new File(buildInfo.getBuildAttributes().get(
+                    CtsXmlResultReporter.CTS_RESULT_DIR));
+            if (DEST_DIR != null) {
+                resultDir = new File(resultDir, DEST_DIR);
+            }
+            resultDir.mkdirs();
+            if (!resultDir.isDirectory()) {
+                CLog.e("%s is not a directory", resultDir.getAbsolutePath());
+                return;
+            }
+            final File hostReportDir = FileUtil.createNamedTempDir(TEMP_REPORT_DIR);
+            if (!hostReportDir.isDirectory()) {
+                CLog.e("%s is not a directory", hostReportDir.getAbsolutePath());
+                return;
+            }
+            pull(device, SRC_DIR, hostReportDir, resultDir);
+        } catch (Exception e) {
+            e.printStackTrace();
+        }
+    }
+
+    private static void pull(ITestDevice device, String deviceSrc, File hostDir, File destDir) {
+        String hostSrc = hostDir.getAbsolutePath();
+        String dest = destDir.getAbsolutePath();
+        String deviceSideCommand = String.format("adb -s %s pull %s %s", device.getSerialNumber(),
+                deviceSrc, dest);
+        CLog.e(deviceSideCommand);
+        try {
+            if (device.doesFileExist(deviceSrc)) {
+                Process deviceProcess = Runtime.getRuntime().exec(new String[]{"/bin/bash", "-c",
+                        deviceSideCommand});
+                if (deviceProcess.waitFor() != 0) {
+                    CLog.e("Failed to run %s", deviceSideCommand);
+                }
+            }
+            FileUtil.recursiveCopy(hostDir, destDir);
+            FileUtil.recursiveDelete(hostDir);
+        } catch (Exception e) {
+            CLog.e("Caught exception during pull.");
+            CLog.e(e);
+        }
+    }
+}