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);
+ }
+ }
+}