Merge "p2p: add group creation/join with band or freq tests"
diff --git a/Android.bp b/Android.bp
index 3eec2e6..2dce5de 100644
--- a/Android.bp
+++ b/Android.bp
@@ -49,3 +49,30 @@
],
},
}
+
+// Used with an android_test / android_test_helper_app, this is equivalent to
+// BUILD_CTS_SUPPORT_PACKAGE
+java_defaults {
+ name: "cts_support_defaults",
+ defaults: ["cts_error_prone_rules_tests"],
+ dex_preopt: {
+ enabled: false,
+ },
+ optimize: {
+ enabled: false,
+ },
+}
+
+// Used with different module types, this is equivalent to:
+// android_test: BUILD_CTS_PACKAGE
+// java_library: BUILD_CTS_TARGET_JAVA_LIBRARY
+// java_library_host: BUILD_CTS_HOST_JAVA_LIBRARY
+java_defaults {
+ name: "cts_defaults",
+ defaults: ["cts_support_defaults"],
+ target: {
+ android: {
+ static_libs: ["platform-test-annotations"],
+ },
+ },
+}
diff --git a/apps/CameraITS/tests/scene0/test_param_sensitivity_burst.py b/apps/CameraITS/tests/scene0/test_param_sensitivity_burst.py
index 97b12ab..7923f95 100644
--- a/apps/CameraITS/tests/scene0/test_param_sensitivity_burst.py
+++ b/apps/CameraITS/tests/scene0/test_param_sensitivity_burst.py
@@ -19,7 +19,7 @@
import its.target
NUM_STEPS = 3
-ERROR_TOLERANCE = 0.97 # Allow ISO to be rounded down by 3%
+ERROR_TOLERANCE = 0.96 # Allow ISO to be rounded down by 4%
def main():
diff --git a/apps/CameraITS/tests/sensor_fusion/test_sensor_fusion.py b/apps/CameraITS/tests/sensor_fusion/test_sensor_fusion.py
index 9f86553..c5e2d1b 100644
--- a/apps/CameraITS/tests/sensor_fusion/test_sensor_fusion.py
+++ b/apps/CameraITS/tests/sensor_fusion/test_sensor_fusion.py
@@ -343,12 +343,13 @@
p0_filtered = p0[mask]
num_features = len(p0_filtered)
if num_features < MIN_FEATURE_PTS:
- print "Not enough feature points in frame", i
+ print "Not enough feature points in frame %s" % str(i-1).zfill(3)
print "Need at least %d features, got %d" % (
MIN_FEATURE_PTS, num_features)
assert 0
else:
- print "Number of features in frame %d is %d" % (i, num_features)
+ print "Number of features in frame %s is %d" % (
+ str(i-1).zfill(3), num_features)
p1, st, _ = cv2.calcOpticalFlowPyrLK(gframe0, gframe1, p0_filtered,
None, **LK_PARAMS)
tform = procrustes_rotation(p0_filtered[st == 1], p1[st == 1])
diff --git a/apps/CtsVerifier/AndroidManifest.xml b/apps/CtsVerifier/AndroidManifest.xml
index 61dd69d..3f759ec 100644
--- a/apps/CtsVerifier/AndroidManifest.xml
+++ b/apps/CtsVerifier/AndroidManifest.xml
@@ -1285,7 +1285,6 @@
<meta-data android:name="test_category" android:value="@string/test_category_security" />
<meta-data android:name="test_excluded_features"
android:value="android.hardware.type.television:android.software.leanback:android.hardware.type.watch" />
- <meta-data android:name="test_required_features" android:value="android.hardware.fingerprint" />
</activity>
<activity android:name=".security.ScreenLockBoundKeysTest"
@@ -2137,6 +2136,16 @@
<category android:name="android.intent.category.DEFAULT"></category>
</intent-filter>
</activity>
+ <activity android:name=".wifi.TestListActivity"
+ android:label="@string/wifi_test"
+ android:configChanges="keyboardHidden|orientation|screenSize">
+ <intent-filter>
+ <action android:name="android.intent.action.MAIN" />
+ <category android:name="android.cts.intent.category.MANUAL_TEST" />
+ </intent-filter>
+ <meta-data android:name="test_category" android:value="@string/test_category_networking" />
+ <meta-data android:name="test_required_features" android:value="android.hardware.wifi" />
+ </activity>
<activity android:name=".wifiaware.TestListActivity"
android:label="@string/aware_test"
android:configChanges="keyboardHidden|orientation|screenSize">
@@ -2305,6 +2314,18 @@
android:value="android.hardware.type.watch:android.hardware.type.television:android.software.leanback" />
</activity>
+ <activity android:name=".wifi.NetworkRequestSpecificNetworkSpecifierTestActivity"
+ android:label="@string/wifi_test_network_request_specific"
+ android:configChanges="keyboardHidden|orientation|screenSize" />
+
+ <activity android:name=".wifi.NetworkRequestPatternNetworkSpecifierTestActivity"
+ android:label="@string/wifi_test_network_request_pattern"
+ android:configChanges="keyboardHidden|orientation|screenSize" />
+
+ <activity android:name=".wifi.NetworkRequestUnavailableNetworkSpecifierTestActivity"
+ android:label="@string/wifi_test_network_request_unavailable"
+ android:configChanges="keyboardHidden|orientation|screenSize" />
+
<activity android:name=".p2p.GoNegRequesterTestListActivity"
android:label="@string/p2p_go_neg_requester"
android:configChanges="keyboardHidden|orientation|screenSize" />
diff --git a/apps/CtsVerifier/res/layout/wifi_main.xml b/apps/CtsVerifier/res/layout/wifi_main.xml
new file mode 100644
index 0000000..fee710d
--- /dev/null
+++ b/apps/CtsVerifier/res/layout/wifi_main.xml
@@ -0,0 +1,51 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2017 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ android:orientation="vertical"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+>
+
+ <FrameLayout
+ android:layout_width="fill_parent"
+ android:layout_height="wrap_content"
+ android:layout_weight="1.0"
+ >
+
+ <ScrollView android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:layout_weight="1"
+ >
+ <TextView android:id="@+id/wifi_info"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ style="@style/InstructionsFont"
+ />
+ </ScrollView>
+
+ <ProgressBar
+ android:id="@+id/wifi_progress"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:indeterminate="true"
+ android:layout_gravity="center"
+ android:visibility="gone"
+ />
+ </FrameLayout>
+
+ <include layout="@layout/pass_fail_buttons" />
+
+</LinearLayout>
diff --git a/apps/CtsVerifier/res/values/strings.xml b/apps/CtsVerifier/res/values/strings.xml
index 60dd6f9..66c8f86 100755
--- a/apps/CtsVerifier/res/values/strings.xml
+++ b/apps/CtsVerifier/res/values/strings.xml
@@ -1431,6 +1431,44 @@
<string name="sv_failed_title">Test Failed</string>
<string name="sv_failed_message">Unable to play stream. See log for details.</string>
+ <!-- Strings for TestListActivity -->
+ <string name="wifi_test">Wi-Fi Test</string>
+ <string name="wifi_test_info">
+ The Wi-Fi tests requires an open (no security) access point along with the DUT.
+ </string>
+ <string name="wifi_location_not_enabled">Wi-Fi / Location Mode is not enabled</string>
+ <string name="wifi_location_not_enabled_message">These tests require Wi-Fi and Location Mode to be enabled.
+ Click the button below to go to system settings and enable Wi-Fi and Location Mode.</string>
+ <string name="wifi_settings">Wi-Fi Settings</string>
+ <string name="location_settings">Location Settings</string>
+ <string name="wifi_setup_error">
+ Test failed.\n\nSet up error. Check whether Wi-Fi is enabled.</string>
+ <string name="wifi_unexpected_error">
+ Test failed.\n\nUnexpected error. Check logcat.</string>
+
+ <string name="wifi_status_initiating_scan">Initiating scan.</string>
+ <string name="wifi_status_scan_failure">Unable to initiate scan.</string>
+ <string name="wifi_status_open_network_not_found">Unable to find any open network in scan results.</string>
+ <string name="wifi_status_initiating_network_request">Initiating network request.</string>
+ <string name="wifi_status_network_wait_for_available">Waiting for network connection. Please click the network in the dialog that pops up for approving the request.</string>
+ <string name="wifi_status_network_available">"Connected to network."</string>
+ <string name="wifi_status_network_wait_for_unavailable">"Ensuring device does not connect to any network. You should see an empty dialog that pops up for approving the request."</string>
+ <string name="wifi_status_network_unavailable">"Did not connect to any network."</string>
+ <string name="wifi_status_network_wait_for_lost">Ensuring device does not disconnect from the network until the request is released.</string>
+ <string name="wifi_status_network_lost">Disconnected from the network.</string>
+ <string name="wifi_status_network_cb_timeout">Network callback timed out.</string>
+
+ <string name="wifi_status_test_success">Test completed successfully!</string>
+ <string name="wifi_status_test_failed">Test failed!</string>
+
+ <string name="wifi_test_network_request">Network Request tests</string>
+ <string name="wifi_test_network_request_specific">Network Request with a specific SSID and BSSID.</string>
+ <string name="wifi_test_network_request_specific_info">Tests whether the API can be used to a connect to network with a specific SSID and BSSID specified in the request.</string>
+ <string name="wifi_test_network_request_pattern">Network Request with a SSID and BSSID pattern.</string>
+ <string name="wifi_test_network_request_pattern_info">Tests whether the API can be used to a connect to network with a SSID and BSSID pattern specified in the request.</string>
+ <string name="wifi_test_network_request_unavailable">Network Request with a specific network that is unavailable.</string>
+ <string name="wifi_test_network_request_unavailable_info">Tests that the API fails to connect when an unavailable network is specified in the request.</string>
+
<!-- Strings for P2pTestActivity -->
<string name="p2p_test">Wi-Fi Direct Test</string>
<string name="p2p_test_info">
@@ -1654,6 +1692,7 @@
<string name="aware_status_network_requested">Network requested ...</string>
<string name="aware_status_network_success">Network formed ...</string>
<string name="aware_status_network_failed">Network request failure - timed out!</string>
+ <string name="aware_status_network_failed_leak">Failure: Network request success - but leaked information!</string>
<string name="aware_status_sleeping_wait_for_responder">Pausing to let Responder time to set up ...</string>
<string name="aware_status_ranging_peer_failure">Ranging to PeerHandle failure: %1$d failures of %2$d attempts!</string>
<string name="aware_status_ranging_mac_failure">Ranging to MAC address failure: %1$d failures of %2$d attempts!</string>
@@ -3466,7 +3505,7 @@
<string name="disallow_remove_user">Disallow remove user</string>
<string name="device_owner_disallow_remove_user_info">
Please press \'Create uninitialized user\' to create a user that is not set up. Then press the
- \'Set restriction\' button to set the user restriction.
+ \'Set restriction\' button to set the user restriction.
Then press \'Go\' to open \'Multiple users\' setting. \n\n
Mark this test as passed if:\n\n
diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/biometrics/BiometricTest.java b/apps/CtsVerifier/src/com/android/cts/verifier/biometrics/BiometricTest.java
index 61abeae..31b43b4 100644
--- a/apps/CtsVerifier/src/com/android/cts/verifier/biometrics/BiometricTest.java
+++ b/apps/CtsVerifier/src/com/android/cts/verifier/biometrics/BiometricTest.java
@@ -39,7 +39,7 @@
/**
* Manual test for BiometricManager and BiometricPrompt. This tests two things currently.
* 1) When no biometrics are enrolled, BiometricManager and BiometricPrompt both return consistent
- * BIOMETRIC_ERROR_NO_BIOMETRICS errors).
+ * BIOMETRIC_ERROR_NONE_ENROLLED errors).
* 2) When biometrics are enrolled, BiometricManager returns BIOMETRIC_SUCCESS and BiometricPrompt
* authentication can be successfully completed.
*/
@@ -152,7 +152,7 @@
int result = mBiometricManager.canAuthenticate();
if (testType == TEST_NONE_ENROLLED) {
- if (result == BiometricManager.BIOMETRIC_ERROR_NO_BIOMETRICS) {
+ if (result == BiometricManager.BIOMETRIC_ERROR_NONE_ENROLLED) {
mExpectedError = BiometricPrompt.BIOMETRIC_ERROR_NO_BIOMETRICS;
showBiometricPrompt();
} else {
diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/camera/its/ItsService.java b/apps/CtsVerifier/src/com/android/cts/verifier/camera/its/ItsService.java
index 8f762c7..f3fe451 100644
--- a/apps/CtsVerifier/src/com/android/cts/verifier/camera/its/ItsService.java
+++ b/apps/CtsVerifier/src/com/android/cts/verifier/camera/its/ItsService.java
@@ -364,7 +364,8 @@
// Initialize memory quota on this device
for (String camId : devices) {
CameraCharacteristics chars = mCameraManager.getCameraCharacteristics(camId);
- Size maxYuvSize = ItsUtils.getYuvOutputSizes(chars)[0];
+ Size maxYuvSize = ItsUtils.getMaxOutputSize(
+ mCameraCharacteristics, ImageFormat.YUV_420_888);
// 4 bytes per pixel for RGBA8888 Bitmap and at least 3 Bitmaps per CDD
int quota = maxYuvSize.getWidth() * maxYuvSize.getHeight() * 4 * 3;
if (quota > mMemoryQuota) {
diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/nfc/NfcTestActivity.java b/apps/CtsVerifier/src/com/android/cts/verifier/nfc/NfcTestActivity.java
index eb84d1e..c710490 100644
--- a/apps/CtsVerifier/src/com/android/cts/verifier/nfc/NfcTestActivity.java
+++ b/apps/CtsVerifier/src/com/android/cts/verifier/nfc/NfcTestActivity.java
@@ -53,19 +53,22 @@
ArrayTestListAdapter adapter = new ArrayTestListAdapter(this);
- adapter.add(TestListItem.newCategory(this, R.string.nfc_pee_2_pee));
- adapter.add(TestListItem.newTest(this, R.string.nfc_ndef_push_sender,
- NdefPushSenderActivity.class.getName(),
- new Intent(this, NdefPushSenderActivity.class), null));
- adapter.add(TestListItem.newTest(this, R.string.nfc_ndef_push_receiver,
- NdefPushReceiverActivity.class.getName(),
- new Intent(this, NdefPushReceiverActivity.class), null));
+ if (getPackageManager().hasSystemFeature(PackageManager.FEATURE_NFC_BEAM)) {
+ adapter.add(TestListItem.newCategory(this, R.string.nfc_pee_2_pee));
+ adapter.add(TestListItem.newTest(this, R.string.nfc_ndef_push_sender,
+ NdefPushSenderActivity.class.getName(),
+ new Intent(this, NdefPushSenderActivity.class), null));
+ adapter.add(TestListItem.newTest(this, R.string.nfc_ndef_push_receiver,
+ NdefPushReceiverActivity.class.getName(),
+ new Intent(this, NdefPushReceiverActivity.class), null));
- if ("MNC".equals(Build.VERSION.CODENAME) || Build.VERSION.SDK_INT >= 23) {
- adapter.add(TestListItem.newTest(this, R.string.nfc_llcp_version_check,
- LlcpVersionActivity.class.getName(),
- new Intent(this, LlcpVersionActivity.class), null));
+ if ("MNC".equals(Build.VERSION.CODENAME) || Build.VERSION.SDK_INT >= 23) {
+ adapter.add(TestListItem.newTest(this, R.string.nfc_llcp_version_check,
+ LlcpVersionActivity.class.getName(),
+ new Intent(this, LlcpVersionActivity.class), null));
+ }
}
+
adapter.add(TestListItem.newCategory(this, R.string.nfc_tag_verification));
adapter.add(TestListItem.newTest(this, R.string.nfc_ndef,
NDEF_ID, getTagIntent(Ndef.class), null));
diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/security/BiometricPromptBoundKeysTest.java b/apps/CtsVerifier/src/com/android/cts/verifier/security/BiometricPromptBoundKeysTest.java
index 7fece23..d1a480d 100644
--- a/apps/CtsVerifier/src/com/android/cts/verifier/security/BiometricPromptBoundKeysTest.java
+++ b/apps/CtsVerifier/src/com/android/cts/verifier/security/BiometricPromptBoundKeysTest.java
@@ -17,20 +17,31 @@
package com.android.cts.verifier.security;
import android.content.DialogInterface;
+import android.hardware.biometrics.BiometricManager;
import android.hardware.biometrics.BiometricPrompt;
import android.os.CancellationSignal;
import android.os.Handler;
import android.os.Looper;
+import android.widget.Button;
import com.android.cts.verifier.R;
import java.util.concurrent.Executor;
+/**
+ * Test for {@link BiometricPrompt}. This test runs twice, once with confirmation required,
+ * once without. Both tests use crypto objects.
+ */
public class BiometricPromptBoundKeysTest extends FingerprintBoundKeysTest {
+ private static final int STATE_TEST_REQUIRE_CONFIRMATION = 1; // confirmation required
+ private static final int STATE_TEST_NO_CONFIRMATION = 2; // no confirmation required
+
private DialogCallback mDialogCallback;
private BiometricPrompt mBiometricPrompt;
private CancellationSignal mCancellationSignal;
+ private BiometricManager mBiometricManager;
+ private int mState = STATE_TEST_REQUIRE_CONFIRMATION;
private final Handler mHandler = new Handler(Looper.getMainLooper());
@@ -52,8 +63,15 @@
@Override
public void onAuthenticationSucceeded(BiometricPrompt.AuthenticationResult result) {
if (tryEncrypt()) {
- showToast("Test passed.");
- getPassButton().setEnabled(true);
+ if (mState == STATE_TEST_REQUIRE_CONFIRMATION) {
+ mState = STATE_TEST_NO_CONFIRMATION;
+ showToast("First test passed, run again to start the second test");
+ Button startButton = findViewById(R.id.sec_start_test_button);
+ startButton.setText("Run second test");
+ } else if (mState == STATE_TEST_NO_CONFIRMATION) {
+ showToast("Test passed.");
+ getPassButton().setEnabled(true);
+ }
} else {
showToast("Test failed. Key not accessible after auth");
}
@@ -61,9 +79,28 @@
}
@Override
+ protected void onPermissionsGranted() {
+ mBiometricManager = getSystemService(BiometricManager.class);
+ final int result = mBiometricManager.canAuthenticate();
+
+ if (result == BiometricManager.BIOMETRIC_ERROR_NO_HARDWARE) {
+ showToast("No biometric features, test passed.");
+ getPassButton().setEnabled(true);
+ } else if (result == BiometricManager.BIOMETRIC_ERROR_HW_UNAVAILABLE) {
+ showToast("Biometric unavailable, something is wrong with your device");
+ } else if (result == BiometricManager.BIOMETRIC_ERROR_NONE_ENROLLED) {
+ showToast("Error: " + result + " Please ensure you have a biometric enrolled");
+ Button startTestButton = findViewById(R.id.sec_start_test_button);
+ startTestButton.setEnabled(false);
+ }
+ }
+
+ @Override
protected void showAuthenticationScreen() {
mCancellationSignal = new CancellationSignal();
mDialogCallback = new DialogCallback();
+ final boolean requireConfirmation = mState == STATE_TEST_REQUIRE_CONFIRMATION
+ ? true : false;
mBiometricPrompt = new BiometricPrompt.Builder(getApplicationContext())
.setTitle("Authenticate with biometric")
.setNegativeButton("Cancel", mExecutor,
@@ -72,6 +109,7 @@
mHandler.post(mNegativeButtonRunnable);
}
})
+ .setRequireConfirmation(requireConfirmation)
.build();
mBiometricPrompt.authenticate(
new BiometricPrompt
diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/security/FingerprintBoundKeysTest.java b/apps/CtsVerifier/src/com/android/cts/verifier/security/FingerprintBoundKeysTest.java
index 1ae7a12..4ad8e09 100644
--- a/apps/CtsVerifier/src/com/android/cts/verifier/security/FingerprintBoundKeysTest.java
+++ b/apps/CtsVerifier/src/com/android/cts/verifier/security/FingerprintBoundKeysTest.java
@@ -66,7 +66,7 @@
private static final byte[] SECRET_BYTE_ARRAY = new byte[] {1, 2, 3, 4, 5, 6};
private static final int AUTHENTICATION_DURATION_SECONDS = 2;
private static final int CONFIRM_CREDENTIALS_REQUEST_CODE = 1;
- private static final int FINGERPRINT_PERMISSION_REQUEST_CODE = 0;
+ private static final int BIOMETRIC_REQUEST_PERMISSION_CODE = 0;
protected boolean useStrongBox;
@@ -90,17 +90,17 @@
setPassFailButtonClickListeners();
setInfoResources(getTitleRes(), getDescriptionRes(), -1);
getPassButton().setEnabled(false);
- requestPermissions(new String[]{Manifest.permission.USE_FINGERPRINT},
- FINGERPRINT_PERMISSION_REQUEST_CODE);
+ requestPermissions(new String[]{Manifest.permission.USE_BIOMETRIC},
+ BIOMETRIC_REQUEST_PERMISSION_CODE);
}
@Override
public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] state) {
- if (requestCode == FINGERPRINT_PERMISSION_REQUEST_CODE && state[0] == PackageManager.PERMISSION_GRANTED) {
+ if (requestCode == BIOMETRIC_REQUEST_PERMISSION_CODE && state[0] == PackageManager.PERMISSION_GRANTED) {
useStrongBox = false;
mFingerprintManager = (FingerprintManager) getSystemService(Context.FINGERPRINT_SERVICE);
- mKeyguardManager = (KeyguardManager) getSystemService(KeyguardManager.class);
- Button startTestButton = (Button) findViewById(R.id.sec_start_test_button);
+ mKeyguardManager = getSystemService(KeyguardManager.class);
+ Button startTestButton = findViewById(R.id.sec_start_test_button);
if (!mKeyguardManager.isKeyguardSecure()) {
// Show a message that the user hasn't set up a lock screen.
@@ -108,13 +108,10 @@
+ "Go to 'Settings -> Security -> Screen lock' to set up a lock screen");
startTestButton.setEnabled(false);
return;
- } else if (!mFingerprintManager.hasEnrolledFingerprints()) {
- showToast("No fingerprints enrolled.\n"
- + "Go to 'Settings -> Security -> Fingerprint' to set up a fingerprint");
- startTestButton.setEnabled(false);
- return;
}
+ onPermissionsGranted();
+
startTestButton.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
@@ -124,6 +121,19 @@
}
}
+ /**
+ * Fingerprint-specific check before allowing test to be started
+ */
+ protected void onPermissionsGranted() {
+ mFingerprintManager = getSystemService(FingerprintManager.class);
+ if (!mFingerprintManager.hasEnrolledFingerprints()) {
+ showToast("No fingerprints enrolled.\n"
+ + "Go to 'Settings -> Security -> Fingerprint' to set up a fingerprint");
+ Button startTestButton = findViewById(R.id.sec_start_test_button);
+ startTestButton.setEnabled(false);
+ }
+ }
+
protected void startTest() {
createKey(false /* hasValidityDuration */);
prepareEncrypt();
diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/sensors/RVCVXCheckTestActivity.java b/apps/CtsVerifier/src/com/android/cts/verifier/sensors/RVCVXCheckTestActivity.java
index 789de68..9fbeba2 100644
--- a/apps/CtsVerifier/src/com/android/cts/verifier/sensors/RVCVXCheckTestActivity.java
+++ b/apps/CtsVerifier/src/com/android/cts/verifier/sensors/RVCVXCheckTestActivity.java
@@ -167,7 +167,7 @@
// acquire a partial wake lock just in case CPU fall asleep
PowerManager pm = (PowerManager) getSystemService(Context.POWER_SERVICE);
- PowerManager.WakeLock wl = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK,
+ PowerManager.WakeLock wl = pm.newWakeLock(PowerManager.FULL_WAKE_LOCK,
"RVCVXCheckAnalyzer");
wl.acquire();
diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/wifi/BaseTestActivity.java b/apps/CtsVerifier/src/com/android/cts/verifier/wifi/BaseTestActivity.java
new file mode 100644
index 0000000..3d507cd
--- /dev/null
+++ b/apps/CtsVerifier/src/com/android/cts/verifier/wifi/BaseTestActivity.java
@@ -0,0 +1,129 @@
+/*
+ * Copyright (C) 2019 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.wifi;
+
+import android.content.Context;
+import android.os.Bundle;
+import android.os.Handler;
+import android.view.View;
+import android.view.WindowManager;
+import android.widget.ProgressBar;
+import android.widget.TextView;
+
+import com.android.cts.verifier.PassFailButtons;
+import com.android.cts.verifier.R;
+
+/**
+ * Base class for Wifi tests.
+ */
+public abstract class BaseTestActivity extends PassFailButtons.Activity implements
+ BaseTestCase.Listener {
+ /*
+ * Handles to GUI elements.
+ */
+ private TextView mWifiInfo;
+ private ProgressBar mWifiProgress;
+
+ /*
+ * Test case to be executed
+ */
+ private BaseTestCase mTestCase;
+
+ private Handler mHandler = new Handler();
+
+ protected abstract BaseTestCase getTestCase(Context context);
+
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ setContentView(R.layout.wifi_main);
+ setPassFailButtonClickListeners();
+ getPassButton().setEnabled(false);
+
+ // Get UI component.
+ mWifiInfo = (TextView) findViewById(R.id.wifi_info);
+ mWifiProgress = (ProgressBar) findViewById(R.id.wifi_progress);
+
+ // Initialize test components.
+ mTestCase = getTestCase(this);
+
+ // keep screen on while this activity is front view.
+ getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
+ }
+
+ @Override
+ protected void onStart() {
+ super.onStart();
+ mTestCase.start(this);
+ mWifiProgress.setVisibility(View.VISIBLE);
+ }
+
+ @Override
+ protected void onStop() {
+ super.onStop();
+ mTestCase.stop();
+ mWifiProgress.setVisibility(View.GONE);
+ }
+
+ @Override
+ public void onTestStarted() {
+ // nop
+ }
+
+ @Override
+ public void onTestMsgReceived(String msg) {
+ if (msg == null) {
+ return;
+ }
+ mHandler.post(new Runnable() {
+ @Override
+ public void run() {
+ mWifiInfo.append(msg);
+ mWifiInfo.append("\n");
+ }
+ });
+ }
+
+ @Override
+ public void onTestSuccess() {
+ mHandler.post(new Runnable() {
+ @Override
+ public void run() {
+ getPassButton().setEnabled(true);
+ mWifiInfo.append(getString(R.string.wifi_status_test_success));
+ mWifiInfo.append("\n");
+ mWifiProgress.setVisibility(View.GONE);
+ }
+ });
+ }
+
+ @Override
+ public void onTestFailed(String reason) {
+ mHandler.post(new Runnable() {
+ @Override
+ public void run() {
+ if (reason != null) {
+ mWifiInfo.append(reason);
+ }
+ getPassButton().setEnabled(false);
+ mWifiInfo.append(getString(R.string.wifi_status_test_failed));
+ mWifiInfo.append("\n");
+ mWifiProgress.setVisibility(View.GONE);
+ }
+ });
+ }
+}
diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/wifi/BaseTestCase.java b/apps/CtsVerifier/src/com/android/cts/verifier/wifi/BaseTestCase.java
new file mode 100644
index 0000000..8382903
--- /dev/null
+++ b/apps/CtsVerifier/src/com/android/cts/verifier/wifi/BaseTestCase.java
@@ -0,0 +1,158 @@
+/*
+ * Copyright (C) 2019 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.wifi;
+
+import android.content.Context;
+import android.content.res.Resources;
+import android.net.wifi.WifiManager;
+import android.os.Handler;
+import android.os.HandlerThread;
+
+import com.android.cts.verifier.R;
+
+/**
+ * Base class for all Wifi test cases.
+ */
+public abstract class BaseTestCase {
+ protected Context mContext;
+ protected Resources mResources;
+ protected Listener mListener;
+
+ private Thread mThread;
+ private HandlerThread mHandlerThread;
+ protected Handler mHandler;
+
+ protected WifiManager mWifiManager;
+
+ public BaseTestCase(Context context) {
+ mContext = context;
+ mResources = mContext.getResources();
+ }
+
+ /**
+ * Set up the test case. Executed once before test starts.
+ */
+ protected void setUp() {
+ mWifiManager = (WifiManager) mContext.getSystemService(Context.WIFI_SERVICE);
+ }
+
+ /**
+ * Tear down the test case. Executed after test finishes - whether on success or failure.
+ */
+ protected void tearDown() {
+ mWifiManager = null;
+ }
+
+ /**
+ * Execute test case.
+ *
+ * @return true on success, false on failure. In case of failure
+ */
+ protected abstract boolean executeTest() throws InterruptedException;
+
+ /**
+ * Returns a String describing the failure reason of the most recent test failure (not valid
+ * in other scenarios). Override to customize the failure string.
+ */
+ protected String getFailureReason() {
+ return mContext.getString(R.string.wifi_unexpected_error);
+ }
+
+ /**
+ * Start running the test case.
+ * <p>
+ * Test case is executed in another thread.
+ */
+ public void start(Listener listener) {
+ mListener = listener;
+
+ stop();
+ mHandlerThread = new HandlerThread("CtsVerifier-Wifi");
+ mHandlerThread.start();
+ mHandler = new Handler(mHandlerThread.getLooper());
+ mThread = new Thread(
+ new Runnable() {
+ @Override
+ public void run() {
+ mListener.onTestStarted();
+ try {
+ setUp();
+ } catch (Exception e) {
+ mListener.onTestFailed(mContext.getString(R.string.wifi_setup_error));
+ return;
+ }
+
+ try {
+ if (executeTest()) {
+ mListener.onTestSuccess();
+ } else {
+ mListener.onTestFailed(getFailureReason());
+ }
+ } catch (Exception e) {
+ e.printStackTrace();
+ mListener.onTestFailed(
+ mContext.getString(R.string.aware_unexpected_error));
+ } finally {
+ tearDown();
+ }
+ }
+ });
+ mThread.start();
+ }
+
+ /**
+ * Stop the currently running test case.
+ */
+ public void stop() {
+ if (mThread != null) {
+ mThread.interrupt();
+ mThread = null;
+ }
+ if (mHandlerThread != null) {
+ mHandlerThread.quitSafely();
+ mHandlerThread = null;
+ mHandler = null;
+ }
+ }
+
+ /**
+ * Listener interface used to communicate the state and status of the test case. It should
+ * be implemented by any activity encompassing a test case.
+ */
+ public interface Listener {
+ /**
+ * This function is invoked when the test case starts.
+ */
+ void onTestStarted();
+
+ /**
+ * This function is invoked by the test to send a message to listener.
+ */
+ void onTestMsgReceived(String msg);
+
+ /**
+ * This function is invoked when the test finished successfully.
+ */
+ void onTestSuccess();
+
+ /**
+ * This function is invoked when the test failed (test is done).
+ */
+ void onTestFailed(String reason);
+ }
+}
+
diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/wifi/CallbackUtils.java b/apps/CtsVerifier/src/com/android/cts/verifier/wifi/CallbackUtils.java
new file mode 100644
index 0000000..b486852
--- /dev/null
+++ b/apps/CtsVerifier/src/com/android/cts/verifier/wifi/CallbackUtils.java
@@ -0,0 +1,105 @@
+/*
+ * Copyright (C) 2019 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.wifi;
+
+import android.net.ConnectivityManager;
+import android.net.Network;
+import android.util.Pair;
+
+import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.TimeUnit;
+
+/**
+ * Blocking callbacks for Wi-Fi and Connectivity Manager.
+ */
+public class CallbackUtils {
+ public static final int DEFAULT_CALLBACK_TIMEOUT_MS = 15_000;
+
+ /**
+ * Utility NetworkCallback- provides mechanism to block execution with the
+ * waitForAttach method.
+ */
+ public static class NetworkCallback extends ConnectivityManager.NetworkCallback {
+ private final int mCallbackTimeoutInMs;
+
+ private CountDownLatch mBlocker = new CountDownLatch(1);
+ private CountDownLatch mOnLostBlocker = new CountDownLatch(1);
+ private Network mNetwork;
+
+ public NetworkCallback() {
+ mCallbackTimeoutInMs = DEFAULT_CALLBACK_TIMEOUT_MS;
+ }
+
+ public NetworkCallback(int callbackTimeoutInMs) {
+ mCallbackTimeoutInMs = callbackTimeoutInMs;
+ }
+
+ @Override
+ public void onAvailable(Network network) {
+ mNetwork = network;
+ mBlocker.countDown();
+ }
+
+ @Override
+ public void onUnavailable() {
+ mBlocker.countDown();
+ }
+
+ @Override
+ public void onLost(Network network) {
+ mNetwork = network;
+ mOnLostBlocker.countDown();
+ }
+
+ /**
+ * Wait (blocks) for {@link #onAvailable(Network)} or timeout.
+ *
+ * @return A pair of values: whether the callback was invoked and the Network object
+ * created when successful - null otherwise.
+ */
+ public Pair<Boolean, Network> waitForAvailable() throws InterruptedException {
+ if (mBlocker.await(mCallbackTimeoutInMs, TimeUnit.MILLISECONDS)) {
+ return Pair.create(true, mNetwork);
+ }
+ return Pair.create(false, null);
+ }
+
+ /**
+ * Wait (blocks) for {@link #onUnavailable()} or timeout.
+ *
+ * @return true whether the callback was invoked.
+ */
+ public boolean waitForUnavailable() throws InterruptedException {
+ if (mBlocker.await(mCallbackTimeoutInMs, TimeUnit.MILLISECONDS)) {
+ return true;
+ }
+ return false;
+ }
+
+ /**
+ * Wait (blocks) for {@link #onLost(Network)} or timeout.
+ *
+ * @return true whether the callback was invoked.
+ */
+ public boolean waitForLost() throws InterruptedException {
+ if (mOnLostBlocker.await(mCallbackTimeoutInMs, TimeUnit.MILLISECONDS)) {
+ return true;
+ }
+ return false;
+ }
+ }
+}
diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/wifi/NetworkRequestPatternNetworkSpecifierTestActivity.java b/apps/CtsVerifier/src/com/android/cts/verifier/wifi/NetworkRequestPatternNetworkSpecifierTestActivity.java
new file mode 100644
index 0000000..b49f11d
--- /dev/null
+++ b/apps/CtsVerifier/src/com/android/cts/verifier/wifi/NetworkRequestPatternNetworkSpecifierTestActivity.java
@@ -0,0 +1,42 @@
+/*
+ * Copyright (C) 2019 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.wifi;
+
+import static com.android.cts.verifier.wifi.testcase.NetworkRequestTestCase.NETWORK_SPECIFIER_PATTERN_SSID_BSSID;
+
+import android.content.Context;
+import android.os.Bundle;
+
+import com.android.cts.verifier.R;
+import com.android.cts.verifier.wifi.testcase.NetworkRequestTestCase;
+
+/**
+ * Test activity for specifier with ssid/bssid pattern.
+ */
+public class NetworkRequestPatternNetworkSpecifierTestActivity extends BaseTestActivity {
+ @Override
+ protected BaseTestCase getTestCase(Context context) {
+ return new NetworkRequestTestCase(context, NETWORK_SPECIFIER_PATTERN_SSID_BSSID);
+ }
+
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ setInfoResources(R.string.wifi_test_network_request_pattern,
+ R.string.wifi_test_network_request_pattern_info, 0);
+ }
+}
diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/wifi/NetworkRequestSpecificNetworkSpecifierTestActivity.java b/apps/CtsVerifier/src/com/android/cts/verifier/wifi/NetworkRequestSpecificNetworkSpecifierTestActivity.java
new file mode 100644
index 0000000..7d82e8d
--- /dev/null
+++ b/apps/CtsVerifier/src/com/android/cts/verifier/wifi/NetworkRequestSpecificNetworkSpecifierTestActivity.java
@@ -0,0 +1,42 @@
+/*
+ * Copyright (C) 2019 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.wifi;
+
+import static com.android.cts.verifier.wifi.testcase.NetworkRequestTestCase.NETWORK_SPECIFIER_SPECIFIC_SSID_BSSID;
+
+import android.content.Context;
+import android.os.Bundle;
+
+import com.android.cts.verifier.R;
+import com.android.cts.verifier.wifi.testcase.NetworkRequestTestCase;
+
+/**
+ * Test activity for specifier with specific ssid/bssid.
+ */
+public class NetworkRequestSpecificNetworkSpecifierTestActivity extends BaseTestActivity {
+ @Override
+ protected BaseTestCase getTestCase(Context context) {
+ return new NetworkRequestTestCase(context, NETWORK_SPECIFIER_SPECIFIC_SSID_BSSID);
+ }
+
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ setInfoResources(R.string.wifi_test_network_request_specific,
+ R.string.wifi_test_network_request_specific_info, 0);
+ }
+}
diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/wifi/NetworkRequestUnavailableNetworkSpecifierTestActivity.java b/apps/CtsVerifier/src/com/android/cts/verifier/wifi/NetworkRequestUnavailableNetworkSpecifierTestActivity.java
new file mode 100644
index 0000000..c02c429
--- /dev/null
+++ b/apps/CtsVerifier/src/com/android/cts/verifier/wifi/NetworkRequestUnavailableNetworkSpecifierTestActivity.java
@@ -0,0 +1,42 @@
+/*
+ * Copyright (C) 2019 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.wifi;
+
+import static com.android.cts.verifier.wifi.testcase.NetworkRequestTestCase.NETWORK_SPECIFIER_UNAVAILABLE_SSID_BSSID;
+
+import android.content.Context;
+import android.os.Bundle;
+
+import com.android.cts.verifier.R;
+import com.android.cts.verifier.wifi.testcase.NetworkRequestTestCase;
+
+/**
+ * Test activity for specifier with specific ssid/bssid not present in scan results.
+ */
+public class NetworkRequestUnavailableNetworkSpecifierTestActivity extends BaseTestActivity {
+ @Override
+ protected BaseTestCase getTestCase(Context context) {
+ return new NetworkRequestTestCase(context, NETWORK_SPECIFIER_UNAVAILABLE_SSID_BSSID);
+ }
+
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ setInfoResources(R.string.wifi_test_network_request_unavailable,
+ R.string.wifi_test_network_request_unavailable_info, 0);
+ }
+}
diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/wifi/OWNERS b/apps/CtsVerifier/src/com/android/cts/verifier/wifi/OWNERS
new file mode 100644
index 0000000..1848dfd
--- /dev/null
+++ b/apps/CtsVerifier/src/com/android/cts/verifier/wifi/OWNERS
@@ -0,0 +1,3 @@
+rpius@google.com
+etancohen@google.com
+satk@google.com
diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/wifi/TestListActivity.java b/apps/CtsVerifier/src/com/android/cts/verifier/wifi/TestListActivity.java
new file mode 100644
index 0000000..b4ccd3a
--- /dev/null
+++ b/apps/CtsVerifier/src/com/android/cts/verifier/wifi/TestListActivity.java
@@ -0,0 +1,128 @@
+/*
+ * Copyright (C) 2019 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.wifi;
+
+import android.app.AlertDialog;
+import android.content.Context;
+import android.content.DialogInterface;
+import android.content.Intent;
+import android.database.DataSetObserver;
+import android.location.LocationManager;
+import android.net.wifi.WifiManager;
+import android.os.Bundle;
+import android.provider.Settings;
+import android.util.Log;
+import android.view.View;
+import android.widget.ListView;
+
+import com.android.cts.verifier.ArrayTestListAdapter;
+import com.android.cts.verifier.PassFailButtons;
+import com.android.cts.verifier.R;
+import com.android.cts.verifier.TestListAdapter;
+
+/**
+ * Activity listing all Wi-Fi Wifi tests.
+ */
+public class TestListActivity extends PassFailButtons.TestListActivity {
+ private static final String TAG = "TestListActivity";
+
+ private WifiManager mWifiManager;
+
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+
+ mWifiManager = (WifiManager) getSystemService(Context.WIFI_SERVICE);
+ if (mWifiManager == null) {
+ Log.wtf(TAG,
+ "Can't get WIFI_SERVICE. Should be gated by 'test_required_features'!?");
+ return;
+ }
+ setContentView(R.layout.pass_fail_list);
+ setInfoResources(R.string.wifi_test, R.string.wifi_test_info, 0);
+ setPassFailButtonClickListeners();
+ getPassButton().setEnabled(false);
+
+ // Add the sub-test/categories
+ ArrayTestListAdapter adapter = new ArrayTestListAdapter(this);
+ adapter.add(TestListAdapter.TestListItem.newCategory(this,
+ R.string.wifi_test_network_request));
+ adapter.add(TestListAdapter.TestListItem.newTest(this,
+ R.string.wifi_test_network_request_specific,
+ NetworkRequestSpecificNetworkSpecifierTestActivity.class.getName(),
+ new Intent(this, NetworkRequestSpecificNetworkSpecifierTestActivity.class), null));
+ adapter.add(TestListAdapter.TestListItem.newTest(this,
+ R.string.wifi_test_network_request_pattern,
+ NetworkRequestPatternNetworkSpecifierTestActivity.class.getName(),
+ new Intent(this, NetworkRequestPatternNetworkSpecifierTestActivity.class), null));
+ adapter.add(TestListAdapter.TestListItem.newTest(this,
+ R.string.wifi_test_network_request_unavailable,
+ NetworkRequestUnavailableNetworkSpecifierTestActivity.class.getName(),
+ new Intent(this, NetworkRequestUnavailableNetworkSpecifierTestActivity.class),
+ null));
+
+ adapter.registerDataSetObserver(new DataSetObserver() {
+ @Override
+ public void onChanged() {
+ updatePassButton();
+ }
+
+ @Override
+ public void onInvalidated() {
+ updatePassButton();
+ }
+ });
+
+ setTestListAdapter(adapter);
+ }
+
+ @Override
+ protected void handleItemClick(ListView listView, View view, int position, long id) {
+ LocationManager locationManager =
+ (LocationManager) getSystemService(Context.LOCATION_SERVICE);
+ if (!mWifiManager.isWifiEnabled() || !locationManager.isLocationEnabled()) {
+ showWifiAndLocationEnableDialog();
+ return;
+ }
+ super.handleItemClick(listView, view, position, id);
+ }
+
+ /**
+ * Show the dialog to jump to system settings in order to enable WiFi & location.
+ */
+ private void showWifiAndLocationEnableDialog() {
+ AlertDialog.Builder builder = new AlertDialog.Builder(this);
+ builder.setIcon(android.R.drawable.ic_dialog_alert);
+ builder.setTitle(R.string.wifi_location_not_enabled);
+ builder.setMessage(R.string.wifi_location_not_enabled_message);
+ builder.setPositiveButton(R.string.wifi_settings,
+ new DialogInterface.OnClickListener() {
+ @Override
+ public void onClick(DialogInterface dialog, int which) {
+ startActivity(new Intent(Settings.ACTION_WIFI_SETTINGS));
+ }
+ });
+ builder.setPositiveButton(R.string.location_settings,
+ new DialogInterface.OnClickListener() {
+ @Override
+ public void onClick(DialogInterface dialog, int which) {
+ startActivity(new Intent(Settings.ACTION_LOCATION_SOURCE_SETTINGS));
+ }
+ });
+ builder.create().show();
+ }
+}
diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/wifi/testcase/NetworkRequestTestCase.java b/apps/CtsVerifier/src/com/android/cts/verifier/wifi/testcase/NetworkRequestTestCase.java
new file mode 100644
index 0000000..5760ed2
--- /dev/null
+++ b/apps/CtsVerifier/src/com/android/cts/verifier/wifi/testcase/NetworkRequestTestCase.java
@@ -0,0 +1,298 @@
+/*
+ * Copyright (C) 2019 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.wifi.testcase;
+
+import static android.net.NetworkCapabilities.NET_CAPABILITY_INTERNET;
+import static android.net.NetworkCapabilities.TRANSPORT_WIFI;
+
+import android.annotation.IntDef;
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+import android.content.BroadcastReceiver;
+import android.content.Context;
+import android.content.Intent;
+import android.content.IntentFilter;
+import android.net.ConnectivityManager;
+import android.net.MacAddress;
+import android.net.Network;
+import android.net.NetworkRequest;
+import android.net.NetworkSpecifier;
+import android.net.wifi.ScanResult;
+import android.net.wifi.WifiManager;
+import android.net.wifi.WifiNetworkConfigBuilder;
+import android.os.PatternMatcher;
+import android.text.TextUtils;
+import android.util.Log;
+import android.util.Pair;
+
+import com.android.cts.verifier.R;
+import com.android.cts.verifier.wifi.BaseTestCase;
+import com.android.cts.verifier.wifi.CallbackUtils;
+
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.util.List;
+import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.TimeUnit;
+
+/**
+ * Test case for all {@link NetworkRequest} requests with specifier built using
+ * {@link WifiNetworkConfigBuilder#buildNetworkSpecifier()}.
+ */
+public class NetworkRequestTestCase extends BaseTestCase {
+ private static final String TAG = "NetworkRequestTestCase";
+ private static final boolean DBG = true;
+
+ private static final String UNAVAILABLE_SSID = "blahblahblah";
+ private static final int NETWORK_REQUEST_TIMEOUT_MS = 30_000;
+ private static final int CALLBACK_TIMEOUT_MS = 40_000;
+ private static final int SCAN_TIMEOUT_MS = 30_000;
+
+ public static final int NETWORK_SPECIFIER_SPECIFIC_SSID_BSSID = 0;
+ public static final int NETWORK_SPECIFIER_PATTERN_SSID_BSSID = 1;
+ public static final int NETWORK_SPECIFIER_UNAVAILABLE_SSID_BSSID = 2;
+
+ @IntDef(prefix = { "NETWORK_SPECIFIER_" }, value = {
+ NETWORK_SPECIFIER_SPECIFIC_SSID_BSSID,
+ NETWORK_SPECIFIER_PATTERN_SSID_BSSID,
+ NETWORK_SPECIFIER_UNAVAILABLE_SSID_BSSID,
+ })
+ @Retention(RetentionPolicy.SOURCE)
+ public @interface NetworkSpecifierType{}
+
+ private final Object mLock = new Object();
+ private final @NetworkSpecifierType int mNetworkSpecifierType;
+
+ private ConnectivityManager mConnectivityManager;
+ private NetworkRequest mNetworkRequest;
+ private CallbackUtils.NetworkCallback mNetworkCallback;
+ private BroadcastReceiver mBroadcastReceiver;
+ private String mFailureReason;
+
+ public NetworkRequestTestCase(Context context, @NetworkSpecifierType int networkSpecifierType) {
+ super(context);
+ mNetworkSpecifierType = networkSpecifierType;
+ }
+
+ // Create a network specifier based on the test type.
+ private NetworkSpecifier createNetworkSpecifier(@NonNull ScanResult scanResult)
+ throws InterruptedException {
+ WifiNetworkConfigBuilder configBuilder = new WifiNetworkConfigBuilder();
+ switch (mNetworkSpecifierType) {
+ case NETWORK_SPECIFIER_SPECIFIC_SSID_BSSID:
+ configBuilder.setSsid(scanResult.SSID);
+ configBuilder.setBssid(MacAddress.fromString(scanResult.BSSID));
+ break;
+ case NETWORK_SPECIFIER_PATTERN_SSID_BSSID:
+ String ssidPrefix = scanResult.SSID.substring(0, scanResult.SSID.length() - 1);
+ MacAddress bssidMask = MacAddress.fromString("ff:ff:ff:ff:ff:00");
+ configBuilder.setSsidPattern(
+ new PatternMatcher(ssidPrefix, PatternMatcher.PATTERN_PREFIX));
+ configBuilder.setBssidPattern(MacAddress.fromString(scanResult.BSSID), bssidMask);
+ break;
+ case NETWORK_SPECIFIER_UNAVAILABLE_SSID_BSSID:
+ String ssid = UNAVAILABLE_SSID;
+ MacAddress bssid = MacAddress.createRandomUnicastAddress();
+ if (findNetworkInScanResultsResults(ssid, bssid.toString())) {
+ Log.e(TAG, "The specifiers chosen match a network in scan results."
+ + "Test will fail");
+ return null;
+ }
+ configBuilder.setSsid(UNAVAILABLE_SSID);
+ configBuilder.setBssid(bssid);
+ break;
+ default:
+ throw new IllegalStateException("Unknown specifier type specifier");
+ }
+ return configBuilder.buildNetworkSpecifier();
+ }
+
+ private boolean startScanAndWaitForResults() throws InterruptedException {
+ IntentFilter intentFilter = new IntentFilter(WifiManager.SCAN_RESULTS_AVAILABLE_ACTION);
+ final CountDownLatch countDownLatch = new CountDownLatch(1);
+ // Scan Results available broadcast receiver.
+ mBroadcastReceiver = new BroadcastReceiver() {
+ @Override
+ public void onReceive(Context context, Intent intent) {
+ if (DBG) Log.v(TAG, "Broadcast onReceive " + intent);
+ if (!intent.getAction().equals(WifiManager.SCAN_RESULTS_AVAILABLE_ACTION)) return;
+ if (!intent.getBooleanExtra(WifiManager.EXTRA_RESULTS_UPDATED, false)) return;
+ if (DBG) Log.v(TAG, "Scan results received");
+ countDownLatch.countDown();
+ }
+ };
+ // Register the receiver for scan results broadcast.
+ mContext.registerReceiver(mBroadcastReceiver, intentFilter);
+
+ // Start scan.
+ if (DBG) Log.v(TAG, "Starting scan");
+ mListener.onTestMsgReceived(mContext.getString(R.string.wifi_status_initiating_scan));
+ if (!mWifiManager.startScan()) {
+ Log.e(TAG, "Failed to start scan");
+ setFailureReason(mContext.getString(R.string.wifi_status_scan_failure));
+ return false;
+ }
+ // Wait for scan results.
+ if (DBG) Log.v(TAG, "Wait for scan results");
+ if (!countDownLatch.await(SCAN_TIMEOUT_MS, TimeUnit.MILLISECONDS)) {
+ Log.e(TAG, "No new scan results available");
+ setFailureReason(mContext.getString(R.string.wifi_status_scan_failure));
+ return false;
+ }
+ return true;
+ }
+
+ // Helper to check if the scan result corresponds to an open network.
+ private static boolean isScanResultForOpenNetwork(@NonNull ScanResult scanResult) {
+ String capabilities = scanResult.capabilities;
+ return !capabilities.contains("PSK") && !capabilities.contains("EAP")
+ && !capabilities.contains("WEP") && !capabilities.contains("SAE")
+ && !capabilities.contains("SUITE-B-192") && !capabilities.contains("OWE");
+ }
+
+ private @Nullable ScanResult startScanAndFindAnyOpenNetworkInResults()
+ throws InterruptedException {
+ // Start scan and wait for new results.
+ if (!startScanAndWaitForResults()) {
+ return null;
+ }
+ // Filter results to find an open network.
+ List<ScanResult> scanResults = mWifiManager.getScanResults();
+ for (ScanResult scanResult : scanResults) {
+ if (!TextUtils.isEmpty(scanResult.SSID)
+ && !TextUtils.isEmpty(scanResult.BSSID)
+ && isScanResultForOpenNetwork(scanResult)) {
+ if (DBG) Log.v(TAG, "Found open network " + scanResult);
+ return scanResult;
+ }
+ }
+ Log.e(TAG, "No open networks found in scan results");
+ setFailureReason(mContext.getString(R.string.wifi_status_open_network_not_found));
+ return null;
+ }
+
+ private boolean findNetworkInScanResultsResults(@NonNull String ssid, @NonNull String bssid)
+ throws InterruptedException {
+ List<ScanResult> scanResults = mWifiManager.getScanResults();
+ for (ScanResult scanResult : scanResults) {
+ if (TextUtils.equals(scanResult.SSID, ssid)
+ && TextUtils.equals(scanResult.BSSID, bssid)) {
+ if (DBG) Log.v(TAG, "Found network " + scanResult);
+ return true;
+ }
+ }
+ return false;
+ }
+
+ private void setFailureReason(String reason) {
+ synchronized (mLock) {
+ mFailureReason = reason;
+ }
+ }
+
+ @Override
+ protected boolean executeTest() throws InterruptedException {
+ // Step 1: Scan and find any open network around.
+ if (DBG) Log.v(TAG, "Scan and find an open network");
+ ScanResult openNetwork = startScanAndFindAnyOpenNetworkInResults();
+ if (openNetwork == null) return false;
+
+ // Step 2: Create a specifier for the chosen open network depending on the type of test.
+ NetworkSpecifier wns = createNetworkSpecifier(openNetwork);
+ if (wns == null) return false;
+
+ // Step 3: Create a network request with specifier.
+ mNetworkRequest = new NetworkRequest.Builder()
+ .addTransportType(TRANSPORT_WIFI)
+ .setNetworkSpecifier(wns)
+ .removeCapability(NET_CAPABILITY_INTERNET)
+ .build();
+
+ // Step 4: Send the network request
+ if (DBG) Log.v(TAG, "Request network using " + mNetworkRequest);
+ mNetworkCallback = new CallbackUtils.NetworkCallback(CALLBACK_TIMEOUT_MS);
+ mListener.onTestMsgReceived(
+ mContext.getString(R.string.wifi_status_initiating_network_request));
+ mConnectivityManager.requestNetwork(mNetworkRequest, mNetworkCallback,
+ NETWORK_REQUEST_TIMEOUT_MS);
+
+ // Step 5: Wait for the network available/unavailable callback.
+ if (mNetworkSpecifierType == NETWORK_SPECIFIER_UNAVAILABLE_SSID_BSSID) {
+ mListener.onTestMsgReceived(
+ mContext.getString(R.string.wifi_status_network_wait_for_unavailable));
+ if (DBG) Log.v(TAG, "Waiting for network unavailable callback");
+ boolean cbStatusForUnavailable = mNetworkCallback.waitForUnavailable();
+ if (!cbStatusForUnavailable) {
+ Log.e(TAG, "Failed to get network unavailable callback");
+ setFailureReason(mContext.getString(R.string.wifi_status_network_cb_timeout));
+ return false;
+ }
+ mListener.onTestMsgReceived(
+ mContext.getString(R.string.wifi_status_network_unavailable));
+ // All done!
+ return true;
+ }
+ mListener.onTestMsgReceived(
+ mContext.getString(R.string.wifi_status_network_wait_for_available));
+ if (DBG) Log.v(TAG, "Waiting for network available callback");
+ Pair<Boolean, Network> cbStatusForAvailable = mNetworkCallback.waitForAvailable();
+ if (!cbStatusForAvailable.first) {
+ Log.e(TAG, "Failed to get network available callback");
+ setFailureReason(mContext.getString(R.string.wifi_status_network_cb_timeout));
+ return false;
+ }
+ mListener.onTestMsgReceived(
+ mContext.getString(R.string.wifi_status_network_available));
+
+ mListener.onTestMsgReceived(
+ mContext.getString(R.string.wifi_status_network_wait_for_lost));
+ // Step 6: Ensure we don't disconnect from the network as long as the request is alive.
+ if (DBG) Log.v(TAG, "Ensuring network lost callback is not invoked");
+ boolean cbStatusForLost = mNetworkCallback.waitForLost();
+ if (cbStatusForLost) {
+ Log.e(TAG, "Disconnected from the network even though the request is active");
+ setFailureReason(mContext.getString(R.string.wifi_status_network_lost));
+ return false;
+ }
+ // All done!
+ return true;
+ }
+
+ @Override
+ protected String getFailureReason() {
+ synchronized (mLock) {
+ return mFailureReason;
+ }
+ }
+
+ @Override
+ protected void setUp() {
+ super.setUp();
+ mConnectivityManager = ConnectivityManager.from(mContext);
+ }
+
+ @Override
+ protected void tearDown() {
+ if (mBroadcastReceiver != null) {
+ mContext.unregisterReceiver(mBroadcastReceiver);
+ }
+ if (mNetworkCallback != null) {
+ mConnectivityManager.unregisterNetworkCallback(mNetworkCallback);
+ }
+ super.tearDown();
+ }
+}
diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/wifiaware/CallbackUtils.java b/apps/CtsVerifier/src/com/android/cts/verifier/wifiaware/CallbackUtils.java
index 2bf4614..b1bd228 100644
--- a/apps/CtsVerifier/src/com/android/cts/verifier/wifiaware/CallbackUtils.java
+++ b/apps/CtsVerifier/src/com/android/cts/verifier/wifiaware/CallbackUtils.java
@@ -18,6 +18,7 @@
import android.net.ConnectivityManager;
import android.net.Network;
+import android.net.NetworkCapabilities;
import android.net.wifi.aware.AttachCallback;
import android.net.wifi.aware.DiscoverySessionCallback;
import android.net.wifi.aware.IdentityChangedListener;
@@ -123,17 +124,18 @@
*/
public static class NetworkCb extends ConnectivityManager.NetworkCallback {
private CountDownLatch mBlocker = new CountDownLatch(1);
- private boolean mNetworkAvailable = false;
+ private NetworkCapabilities mNetworkCapabilities = null;
@Override
- public void onAvailable(Network network) {
- mNetworkAvailable = true;
+ public void onUnavailable() {
+ mNetworkCapabilities = null;
mBlocker.countDown();
}
@Override
- public void onUnavailable() {
- mNetworkAvailable = false;
+ public void onCapabilitiesChanged(Network network,
+ NetworkCapabilities networkCapabilities) {
+ mNetworkCapabilities = networkCapabilities;
mBlocker.countDown();
}
@@ -142,11 +144,11 @@
*
* @return true if Available, false otherwise (Unavailable or timeout).
*/
- public boolean waitForNetwork() throws InterruptedException {
+ public NetworkCapabilities waitForNetwork() throws InterruptedException {
if (mBlocker.await(CALLBACK_TIMEOUT_SEC, TimeUnit.SECONDS)) {
- return mNetworkAvailable;
+ return mNetworkCapabilities;
}
- return false;
+ return null;
}
}
diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/wifiaware/testcase/DataPathInBandTestCase.java b/apps/CtsVerifier/src/com/android/cts/verifier/wifiaware/testcase/DataPathInBandTestCase.java
index fc8a3ef..2f9bf4c 100644
--- a/apps/CtsVerifier/src/com/android/cts/verifier/wifiaware/testcase/DataPathInBandTestCase.java
+++ b/apps/CtsVerifier/src/com/android/cts/verifier/wifiaware/testcase/DataPathInBandTestCase.java
@@ -141,13 +141,18 @@
mListener.onTestMsgReceived(
mContext.getString(R.string.aware_status_network_requested));
if (DBG) Log.d(TAG, "executeTestSubscriber: requested network");
- boolean networkAvailable = networkCb.waitForNetwork();
+ NetworkCapabilities nc = networkCb.waitForNetwork();
cm.unregisterNetworkCallback(networkCb);
- if (!networkAvailable) {
+ if (nc == null) {
setFailureReason(mContext.getString(R.string.aware_status_network_failed));
Log.e(TAG, "executeTestSubscriber: network request rejected - ON_UNAVAILABLE");
return false;
}
+ if (nc.getNetworkSpecifier() != null) {
+ setFailureReason(mContext.getString(R.string.aware_status_network_failed_leak));
+ Log.e(TAG, "executeTestSubscriber: network request accepted - but leaks NS!");
+ return false;
+ }
mListener.onTestMsgReceived(mContext.getString(R.string.aware_status_network_success));
if (DBG) Log.d(TAG, "executeTestSubscriber: network request granted - AVAILABLE");
@@ -200,13 +205,18 @@
}
// 6. wait for network
- boolean networkAvailable = networkCb.waitForNetwork();
+ NetworkCapabilities nc = networkCb.waitForNetwork();
cm.unregisterNetworkCallback(networkCb);
- if (!networkAvailable) {
+ if (nc == null) {
setFailureReason(mContext.getString(R.string.aware_status_network_failed));
Log.e(TAG, "executeTestPublisher: request network rejected - ON_UNAVAILABLE");
return false;
}
+ if (nc.getNetworkSpecifier() != null) {
+ setFailureReason(mContext.getString(R.string.aware_status_network_failed_leak));
+ Log.e(TAG, "executeTestSubscriber: network request accepted - but leaks NS!");
+ return false;
+ }
mListener.onTestMsgReceived(mContext.getString(R.string.aware_status_network_success));
if (DBG) Log.d(TAG, "executeTestPublisher: network request granted - AVAILABLE");
diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/wifiaware/testcase/DataPathOutOfBandTestCase.java b/apps/CtsVerifier/src/com/android/cts/verifier/wifiaware/testcase/DataPathOutOfBandTestCase.java
index 0f81d2c..be198e1 100644
--- a/apps/CtsVerifier/src/com/android/cts/verifier/wifiaware/testcase/DataPathOutOfBandTestCase.java
+++ b/apps/CtsVerifier/src/com/android/cts/verifier/wifiaware/testcase/DataPathOutOfBandTestCase.java
@@ -284,13 +284,18 @@
cm.requestNetwork(nr, networkCb, CALLBACK_TIMEOUT_SEC * 1000);
mListener.onTestMsgReceived(mContext.getString(R.string.aware_status_network_requested));
if (DBG) Log.d(TAG, "executeTestResponder: requested network");
- boolean networkAvailable = networkCb.waitForNetwork();
+ NetworkCapabilities nc = networkCb.waitForNetwork();
cm.unregisterNetworkCallback(networkCb);
- if (!networkAvailable) {
+ if (nc == null) {
setFailureReason(mContext.getString(R.string.aware_status_network_failed));
Log.e(TAG, "executeTestResponder: network request rejected - ON_UNAVAILABLE");
return false;
}
+ if (nc.getNetworkSpecifier() != null) {
+ setFailureReason(mContext.getString(R.string.aware_status_network_failed_leak));
+ Log.e(TAG, "executeTestSubscriber: network request accepted - but leaks NS!");
+ return false;
+ }
mListener.onTestMsgReceived(mContext.getString(R.string.aware_status_network_success));
if (DBG) Log.d(TAG, "executeTestResponder: network request granted - AVAILABLE");
@@ -418,13 +423,18 @@
cm.requestNetwork(nr, networkCb, CALLBACK_TIMEOUT_SEC * 1000);
mListener.onTestMsgReceived(mContext.getString(R.string.aware_status_network_requested));
if (DBG) Log.d(TAG, "executeTestInitiator: requested network");
- boolean networkAvailable = networkCb.waitForNetwork();
+ NetworkCapabilities nc = networkCb.waitForNetwork();
cm.unregisterNetworkCallback(networkCb);
- if (!networkAvailable) {
+ if (nc == null) {
setFailureReason(mContext.getString(R.string.aware_status_network_failed));
Log.e(TAG, "executeTestInitiator: network request rejected - ON_UNAVAILABLE");
return false;
}
+ if (nc.getNetworkSpecifier() != null) {
+ setFailureReason(mContext.getString(R.string.aware_status_network_failed_leak));
+ Log.e(TAG, "executeTestSubscriber: network request accepted - but leaks NS!");
+ return false;
+ }
mListener.onTestMsgReceived(mContext.getString(R.string.aware_status_network_success));
if (DBG) Log.d(TAG, "executeTestInitiator: network request granted - AVAILABLE");
diff --git a/build/host_java_library.mk b/build/host_java_library.mk
index 303527e..6db1995 100644
--- a/build/host_java_library.mk
+++ b/build/host_java_library.mk
@@ -17,6 +17,8 @@
# Replace "include $(BUILD_HOST_JAVA_LIBRARY) with "include $(BUILD_CTS_HOST_JAVA_LIBRARY)
#
+# !!! Any changes to this file need to be reflected in cts/Android.bp "cts_defaults"
+
-include cts/error_prone_rules_tests.mk
include $(BUILD_HOST_JAVA_LIBRARY)
diff --git a/build/support_package.mk b/build/support_package.mk
index 83d7da9..6ab601f 100644
--- a/build/support_package.mk
+++ b/build/support_package.mk
@@ -18,6 +18,8 @@
# Replace "include $(BUILD_PACKAGE)" with "include $(BUILD_CTS_SUPPORT_PACKAGE)"
#
+# !!! Any changes to this file need to be reflected in cts/Android.bp "cts_support_defaults"
+
# Disable by default so "m cts" will work in emulator builds
LOCAL_DEX_PREOPT := false
LOCAL_PROGUARD_ENABLED := disabled
diff --git a/build/test_package.mk b/build/test_package.mk
index 2aa0852..e71a224 100644
--- a/build/test_package.mk
+++ b/build/test_package.mk
@@ -18,6 +18,8 @@
# Replace "include $(BUILD_PACKAGE)" with "include $(BUILD_CTS_PACKAGE)"
#
+# !!! Any changes to this file need to be reflected in cts/Android.bp "cts_defaults"
+
LOCAL_STATIC_JAVA_LIBRARIES += platform-test-annotations
-include cts/error_prone_rules_tests.mk
diff --git a/build/test_target_java_library.mk b/build/test_target_java_library.mk
index c932c30..0e36ca3 100644
--- a/build/test_target_java_library.mk
+++ b/build/test_target_java_library.mk
@@ -16,6 +16,8 @@
# Builds a Java library.
#
+# !!! Any changes to this file need to be reflected in cts/Android.bp "cts_defaults"
+
# Disable by default so "m cts" will work in emulator builds
LOCAL_DEX_PREOPT := false
LOCAL_STATIC_JAVA_LIBRARIES += platform-test-annotations
diff --git a/common/device-side/device-info/Android.bp b/common/device-side/device-info/Android.bp
index 583bc85..f4c80ba 100644
--- a/common/device-side/device-info/Android.bp
+++ b/common/device-side/device-info/Android.bp
@@ -25,17 +25,7 @@
libs: [
"android.test.base.stubs",
- "framework-stub-for-compatibility-device-info",
],
sdk_version: "test_current",
}
-
-java_library {
- // This stub library provides some internal APIs (SystemProperties, VintfObject, etc.)
- // to compatibility-device-info library.
- name: "framework-stub-for-compatibility-device-info",
- srcs: ["src_stub/**/*.java"],
-
- sdk_version: "current",
-}
diff --git a/common/device-side/device-info/src_stub/android/os/SystemProperties.java b/common/device-side/device-info/src_stub/android/os/SystemProperties.java
deleted file mode 100644
index 2f8a051..0000000
--- a/common/device-side/device-info/src_stub/android/os/SystemProperties.java
+++ /dev/null
@@ -1,9 +0,0 @@
-/**
- * This is a stub library for the runtime class at
- * frameworks/base/core/java/android/os/SystemProperties.java
- */
-package android.os;
-
-public class SystemProperties {
- public static String get(String key, String def) { return null; }
-}
diff --git a/common/device-side/device-info/src_stub/android/os/VintfObject.java b/common/device-side/device-info/src_stub/android/os/VintfObject.java
deleted file mode 100644
index b8da52e..0000000
--- a/common/device-side/device-info/src_stub/android/os/VintfObject.java
+++ /dev/null
@@ -1,16 +0,0 @@
-/**
- * This is a stub library for the runtime class at
- * frameworks/base/core/java/android/os/VintfObject.java
- */
-
-package android.os;
-
-import java.util.Map;
-
-public class VintfObject {
- public static Map<String, String[]> getVndkSnapshots() { return null; }
- public static String getSepolicyVersion() { return null; }
- public static String[] getHalNamesAndVersions() { return null; }
- public static String[] report() { return null; }
- public static Long getTargetFrameworkCompatibilityMatrixVersion() { return null; }
-}
diff --git a/common/device-side/device-info/src_stub/android/os/VintfRuntimeInfo.java b/common/device-side/device-info/src_stub/android/os/VintfRuntimeInfo.java
deleted file mode 100644
index 20fa94c..0000000
--- a/common/device-side/device-info/src_stub/android/os/VintfRuntimeInfo.java
+++ /dev/null
@@ -1,17 +0,0 @@
-/**
- * This is a stub library for the runtime class at
- * frameworks/base/core/java/android/os/VintfRuntimeInfo.java
- */
-package android.os;
-
-public class VintfRuntimeInfo {
- public static String getBootAvbVersion() { return null; }
- public static String getBootVbmetaAvbVersion() { return null; }
- public static String getCpuInfo() { return null; }
- public static String getHardwareId() { return null; }
- public static String getKernelVersion() { return null; }
- public static String getNodeName() { return null; }
- public static String getOsName() { return null; }
- public static String getOsRelease() { return null; }
- public static String getOsVersion() { return null; }
-}
diff --git a/common/device-side/util/src/com/android/compatibility/common/util/ColorUtils.java b/common/device-side/util/src/com/android/compatibility/common/util/ColorUtils.java
index a2439c7..cbb44c7 100644
--- a/common/device-side/util/src/com/android/compatibility/common/util/ColorUtils.java
+++ b/common/device-side/util/src/com/android/compatibility/common/util/ColorUtils.java
@@ -16,23 +16,59 @@
package com.android.compatibility.common.util;
-import static org.junit.Assert.assertEquals;
import static org.junit.Assert.fail;
import android.graphics.Color;
+import androidx.annotation.NonNull;
+
+import java.util.function.IntUnaryOperator;
+
public class ColorUtils {
public static void verifyColor(int expected, int observed) {
verifyColor(expected, observed, 0);
}
public static void verifyColor(int expected, int observed, int tolerance) {
- String s = "expected " + Integer.toHexString(expected)
- + ", observed " + Integer.toHexString(observed)
- + ", tolerated channel error " + tolerance;
- assertEquals(s, Color.red(expected), Color.red(observed), tolerance);
- assertEquals(s, Color.green(expected), Color.green(observed), tolerance);
- assertEquals(s, Color.blue(expected), Color.blue(observed), tolerance);
- assertEquals(s, Color.alpha(expected), Color.alpha(observed), tolerance);
+ verifyColor("", expected, observed, tolerance);
+ }
+
+ /**
+ * Verify that two colors match within a per-channel tolerance.
+ *
+ * @param s String with extra information about the test with an error.
+ * @param expected Expected color.
+ * @param observed Observed color.
+ * @param tolerance Per-channel tolerance by which the color can mismatch.
+ */
+ public static void verifyColor(@NonNull String s, int expected, int observed, int tolerance) {
+ s += " expected 0x" + Integer.toHexString(expected)
+ + ", observed 0x" + Integer.toHexString(observed)
+ + ", tolerated channel error 0x" + tolerance;
+ String red = verifyChannel("red", expected, observed, tolerance, (i) -> Color.red(i));
+ String green = verifyChannel("green", expected, observed, tolerance, (i) -> Color.green(i));
+ String blue = verifyChannel("blue", expected, observed, tolerance, (i) -> Color.blue(i));
+ String alpha = verifyChannel("alpha", expected, observed, tolerance, (i) -> Color.alpha(i));
+
+ String err = null;
+ for (String channel : new String[]{red, green, blue, alpha}) {
+ if (channel == null) continue;
+ if (err == null) err = s;
+ err += "\n\t\t" + channel;
+ }
+ if (err != null) {
+ fail(err);
+ }
+ }
+
+ private static String verifyChannel(String channelName, int expected, int observed,
+ int tolerance, IntUnaryOperator f) {
+ int e = f.applyAsInt(expected);
+ int o = f.applyAsInt(observed);
+ if (Math.abs(e - o) <= tolerance) {
+ return null;
+ }
+ return "Channel " + channelName + " mismatch: expected<0x" + Integer.toHexString(e)
+ + ">, observed: <0x" + Integer.toHexString(o) + ">";
}
}
diff --git a/common/device-side/util/src/com/android/compatibility/common/util/PackageUtil.java b/common/device-side/util/src/com/android/compatibility/common/util/PackageUtil.java
index a153a4b..e7b6976 100644
--- a/common/device-side/util/src/com/android/compatibility/common/util/PackageUtil.java
+++ b/common/device-side/util/src/com/android/compatibility/common/util/PackageUtil.java
@@ -114,4 +114,21 @@
private static PackageManager getPackageManager() {
return InstrumentationRegistry.getInstrumentation().getTargetContext().getPackageManager();
}
+
+ private static boolean hasDeviceFeature(final String requiredFeature) {
+ return InstrumentationRegistry.getContext()
+ .getPackageManager()
+ .hasSystemFeature(requiredFeature);
+ }
+
+ /**
+ * Rotation support is indicated by explicitly having both landscape and portrait
+ * features or not listing either at all.
+ */
+ public static boolean supportsRotation() {
+ final boolean supportsLandscape = hasDeviceFeature(PackageManager.FEATURE_SCREEN_LANDSCAPE);
+ final boolean supportsPortrait = hasDeviceFeature(PackageManager.FEATURE_SCREEN_PORTRAIT);
+ return (supportsLandscape && supportsPortrait)
+ || (!supportsLandscape && !supportsPortrait);
+ }
}
diff --git a/common/device-side/util/src/com/android/compatibility/common/util/ShellIdentityUtils.java b/common/device-side/util/src/com/android/compatibility/common/util/ShellIdentityUtils.java
index b858f5c..f3438ee 100644
--- a/common/device-side/util/src/com/android/compatibility/common/util/ShellIdentityUtils.java
+++ b/common/device-side/util/src/com/android/compatibility/common/util/ShellIdentityUtils.java
@@ -41,6 +41,20 @@
}
/**
+ * Utility interface to invoke a method against the target object.
+ *
+ * @param <U> the type of the object against which the method is invoked.
+ */
+ public interface ShellPermissionMethodHelperNoReturn<U> {
+ /**
+ * Invokes the method against the target object.
+ *
+ * @param targetObject the object against which the method should be invoked.
+ */
+ void callMethod(U targetObject);
+ }
+
+ /**
* Invokes the specified method on the targetObject as the shell user. The method can be invoked
* as follows:
*
@@ -60,6 +74,25 @@
}
/**
+ * Invokes the specified method on the targetObject as the shell user. The method can be invoked
+ * as follows:
+ *
+ * {@code ShellIdentityUtils.invokeMethodWithShellPermissions(mTelephonyManager,
+ * (tm) -> tm.getDeviceId());}
+ */
+ public static <U> void invokeMethodWithShellPermissionsNoReturn(
+ U targetObject, ShellPermissionMethodHelperNoReturn<U> methodHelper) {
+ final UiAutomation uiAutomation =
+ InstrumentationRegistry.getInstrumentation().getUiAutomation();
+ try {
+ uiAutomation.adoptShellPermissionIdentity();
+ methodHelper.callMethod(targetObject);
+ } finally {
+ uiAutomation.dropShellPermissionIdentity();
+ }
+ }
+
+ /**
* Utility interface to invoke a static method.
*
* @param <T> the type returned by the invoked method.
diff --git a/hostsidetests/angle/app/driverTest/Android.mk b/hostsidetests/angle/app/driverTest/Android.mk
index 9d8d629..37a1140 100644
--- a/hostsidetests/angle/app/driverTest/Android.mk
+++ b/hostsidetests/angle/app/driverTest/Android.mk
@@ -27,7 +27,7 @@
LOCAL_SDK_VERSION := current
# tag this module as a cts test artifact
-LOCAL_COMPATIBILITY_SUITE := cts
+LOCAL_COMPATIBILITY_SUITE := cts vts
LOCAL_MULTILIB := both
diff --git a/hostsidetests/angle/app/driverTest/AndroidManifest.xml b/hostsidetests/angle/app/driverTest/AndroidManifest.xml
index 03c3c53..be800a1 100755
--- a/hostsidetests/angle/app/driverTest/AndroidManifest.xml
+++ b/hostsidetests/angle/app/driverTest/AndroidManifest.xml
@@ -18,7 +18,7 @@
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.android.angleIntegrationTest.driverTest">
- <application>
+ <application android:debuggable="true">
<uses-library android:name="android.test.runner" />
<activity android:name="com.android.angleIntegrationTest.common.AngleIntegrationTestActivity" >
diff --git a/hostsidetests/angle/app/driverTestSecondary/Android.mk b/hostsidetests/angle/app/driverTestSecondary/Android.mk
index 87855e8..d361192 100644
--- a/hostsidetests/angle/app/driverTestSecondary/Android.mk
+++ b/hostsidetests/angle/app/driverTestSecondary/Android.mk
@@ -27,7 +27,7 @@
LOCAL_SDK_VERSION := current
# tag this module as a cts test artifact
-LOCAL_COMPATIBILITY_SUITE := cts
+LOCAL_COMPATIBILITY_SUITE := cts vts
LOCAL_MULTILIB := both
diff --git a/hostsidetests/angle/app/driverTestSecondary/AndroidManifest.xml b/hostsidetests/angle/app/driverTestSecondary/AndroidManifest.xml
index 1d8f1a7..bd2739d 100755
--- a/hostsidetests/angle/app/driverTestSecondary/AndroidManifest.xml
+++ b/hostsidetests/angle/app/driverTestSecondary/AndroidManifest.xml
@@ -18,7 +18,7 @@
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.android.angleIntegrationTest.driverTestSecondary">
- <application>
+ <application android:debuggable="true">
<uses-library android:name="android.test.runner" />
<activity android:name="com.android.angleIntegrationTest.common.AngleIntegrationTestActivity" >
diff --git a/hostsidetests/angle/src/android/angle/cts/CtsAngleCommon.java b/hostsidetests/angle/src/android/angle/cts/CtsAngleCommon.java
index 721de8f..a5d2262 100644
--- a/hostsidetests/angle/src/android/angle/cts/CtsAngleCommon.java
+++ b/hostsidetests/angle/src/android/angle/cts/CtsAngleCommon.java
@@ -26,13 +26,14 @@
static final String SETTINGS_GLOBAL_ALL_USE_ANGLE = "angle_gl_driver_all_angle";
static final String SETTINGS_GLOBAL_DRIVER_PKGS = "angle_gl_driver_selection_pkgs";
static final String SETTINGS_GLOBAL_DRIVER_VALUES = "angle_gl_driver_selection_values";
+ static final String SETTINGS_GLOBAL_WHITELIST = "angle_whitelist";
// System Properties
+ static final String PROPERTY_GFX_ANGLE_SUPPORTED = "ro.gfx.angle.supported";
static final String PROPERTY_BUILD_TYPE = "ro.build.type";
static final String PROPERTY_DISABLE_OPENGL_PRELOADING = "ro.zygote.disable_gl_preload";
static final String PROPERTY_GFX_DRIVER = "ro.gfx.driver.0";
static final String PROPERTY_TEMP_RULES_FILE = "debug.angle.rules";
- static final String PROPERTY_ENABLE_RULES_FILE = "debug.angle.enable";
// Rules File
static final String DEVICE_TEMP_RULES_FILE_DIRECTORY = "/data/local/tmp";
@@ -40,7 +41,6 @@
static final String DEVICE_TEMP_RULES_FILE_PATH = DEVICE_TEMP_RULES_FILE_DIRECTORY + "/" + DEVICE_TEMP_RULES_FILE_FILENAME;
// ANGLE
- static final String ANGLE_PKG = "com.google.android.angle";
static final String ANGLE_DRIVER_TEST_PKG = "com.android.angleIntegrationTest.driverTest";
static final String ANGLE_DRIVER_TEST_SEC_PKG = "com.android.angleIntegrationTest.driverTestSecondary";
static final String ANGLE_DRIVER_TEST_CLASS = "AngleDriverTestActivity";
@@ -85,17 +85,17 @@
device.setSetting("global", CtsAngleCommon.SETTINGS_GLOBAL_ALL_USE_ANGLE, "0");
device.setSetting("global", CtsAngleCommon.SETTINGS_GLOBAL_DRIVER_PKGS, "\"\"");
device.setSetting("global", CtsAngleCommon.SETTINGS_GLOBAL_DRIVER_VALUES, "\"\"");
+ device.setSetting("global", CtsAngleCommon.SETTINGS_GLOBAL_WHITELIST, "\"\"");
CtsAngleCommon.setProperty(device, CtsAngleCommon.PROPERTY_TEMP_RULES_FILE, "\"\"");
- CtsAngleCommon.setProperty(device, CtsAngleCommon.PROPERTY_ENABLE_RULES_FILE, "0");
}
static boolean isAngleLoadable(ITestDevice device) throws Exception {
- PackageInfo anglePkgInfo = device.getAppPackageInfo(ANGLE_PKG);
+ String angleSupported = device.getProperty(PROPERTY_GFX_ANGLE_SUPPORTED);
String propDisablePreloading = device.getProperty(PROPERTY_DISABLE_OPENGL_PRELOADING);
String propGfxDriver = device.getProperty(PROPERTY_GFX_DRIVER);
// Make sure ANGLE exists on the device
- if(anglePkgInfo == null) {
+ if((angleSupported == null) || (angleSupported.equals("false"))) {
return false;
}
diff --git a/hostsidetests/angle/src/android/angle/cts/CtsAngleDeveloperOptionHostTest.java b/hostsidetests/angle/src/android/angle/cts/CtsAngleDeveloperOptionHostTest.java
index cda98e3..385da2a 100644
--- a/hostsidetests/angle/src/android/angle/cts/CtsAngleDeveloperOptionHostTest.java
+++ b/hostsidetests/angle/src/android/angle/cts/CtsAngleDeveloperOptionHostTest.java
@@ -88,7 +88,6 @@
public void setUp() throws Exception {
CtsAngleCommon.clearSettings(getDevice());
- CtsAngleCommon.stopPackage(getDevice(), CtsAngleCommon.ANGLE_PKG);
CtsAngleCommon.stopPackage(getDevice(), CtsAngleCommon.ANGLE_DRIVER_TEST_PKG);
CtsAngleCommon.stopPackage(getDevice(), CtsAngleCommon.ANGLE_DRIVER_TEST_SEC_PKG);
}
diff --git a/hostsidetests/angle/src/android/angle/cts/CtsAngleRulesFileTest.java b/hostsidetests/angle/src/android/angle/cts/CtsAngleRulesFileTest.java
index f4f495a..87281b9 100644
--- a/hostsidetests/angle/src/android/angle/cts/CtsAngleRulesFileTest.java
+++ b/hostsidetests/angle/src/android/angle/cts/CtsAngleRulesFileTest.java
@@ -67,8 +67,10 @@
public void setUp() throws Exception {
CtsAngleCommon.clearSettings(getDevice());
- // Enable checking the rules file
- CtsAngleCommon.setProperty(getDevice(), CtsAngleCommon.PROPERTY_ENABLE_RULES_FILE, "1");
+ // Application must be whitelisted to load temp rules
+ getDevice().setSetting("global", CtsAngleCommon.SETTINGS_GLOBAL_WHITELIST,
+ CtsAngleCommon.ANGLE_DRIVER_TEST_PKG + "," +
+ CtsAngleCommon.ANGLE_DRIVER_TEST_SEC_PKG);
}
@After
@@ -117,4 +119,4 @@
CtsAngleCommon.ANGLE_DRIVER_TEST_SEC_PKG + "." + CtsAngleCommon.ANGLE_DRIVER_TEST_CLASS,
CtsAngleCommon.ANGLE_DRIVER_TEST_NATIVE_METHOD);
}
-}
\ No newline at end of file
+}
diff --git a/hostsidetests/appsecurity/src/android/appsecurity/cts/AdoptableHostTest.java b/hostsidetests/appsecurity/src/android/appsecurity/cts/AdoptableHostTest.java
index bbfc62f..d8a280e 100644
--- a/hostsidetests/appsecurity/src/android/appsecurity/cts/AdoptableHostTest.java
+++ b/hostsidetests/appsecurity/src/android/appsecurity/cts/AdoptableHostTest.java
@@ -117,6 +117,18 @@
// Unmount, remount and verify
getDevice().executeShellCommand("sm unmount " + vol.volId);
getDevice().executeShellCommand("sm mount " + vol.volId);
+
+ int attempt = 0;
+ String pkgPath = getDevice().executeShellCommand("pm path " + PKG);
+ while ((pkgPath == null || pkgPath.isEmpty()) && attempt++ < 15) {
+ Thread.sleep(1000);
+ pkgPath = getDevice().executeShellCommand("pm path " + PKG);
+ }
+
+ if (pkgPath == null || pkgPath.isEmpty()) {
+ throw new AssertionError("Package not ready yet");
+ }
+
runDeviceTests(PKG, CLASS, "testDataNotInternal");
runDeviceTests(PKG, CLASS, "testDataRead");
runDeviceTests(PKG, CLASS, "testNative");
diff --git a/hostsidetests/appsecurity/src/android/appsecurity/cts/BaseAppSecurityTest.java b/hostsidetests/appsecurity/src/android/appsecurity/cts/BaseAppSecurityTest.java
index 822edce..d7b812f 100644
--- a/hostsidetests/appsecurity/src/android/appsecurity/cts/BaseAppSecurityTest.java
+++ b/hostsidetests/appsecurity/src/android/appsecurity/cts/BaseAppSecurityTest.java
@@ -85,7 +85,8 @@
} else {
testArgs = null;
}
- Utils.runDeviceTests(getDevice(), packageName, testClassName, testMethodName, testArgs);
+ Utils.runDeviceTestsAsCurrentUser(getDevice(), packageName, testClassName, testMethodName,
+ testArgs);
}
protected boolean isAppVisibleForUser(String packageName, int userId,
diff --git a/hostsidetests/appsecurity/src/android/appsecurity/cts/ExternalStorageHostTest.java b/hostsidetests/appsecurity/src/android/appsecurity/cts/ExternalStorageHostTest.java
index 82c94cf..ec66cd1 100644
--- a/hostsidetests/appsecurity/src/android/appsecurity/cts/ExternalStorageHostTest.java
+++ b/hostsidetests/appsecurity/src/android/appsecurity/cts/ExternalStorageHostTest.java
@@ -551,7 +551,7 @@
}
private boolean hasIsolatedStorage() throws DeviceNotAvailableException {
- return getDevice().executeShellCommand("getprop persist.sys.isolated_storage")
+ return getDevice().executeShellCommand("getprop sys.isolated_storage_snapshot")
.contains("true");
}
diff --git a/hostsidetests/appsecurity/test-apps/DocumentClient/src/com/android/cts/documentclient/DocumentsClientTest.java b/hostsidetests/appsecurity/test-apps/DocumentClient/src/com/android/cts/documentclient/DocumentsClientTest.java
index 34f6100..2f503e3 100644
--- a/hostsidetests/appsecurity/test-apps/DocumentClient/src/com/android/cts/documentclient/DocumentsClientTest.java
+++ b/hostsidetests/appsecurity/test-apps/DocumentClient/src/com/android/cts/documentclient/DocumentsClientTest.java
@@ -276,6 +276,8 @@
findDocument("DIR2").click();
mDevice.waitForIdle();
findSaveButton().click();
+ mDevice.waitForIdle();
+ findPositiveButton().click();
final Result result = mActivity.getResult();
final Uri uri = result.data.getData();
@@ -397,6 +399,8 @@
findDocument("DIR2").click();
mDevice.waitForIdle();
findSaveButton().click();
+ mDevice.waitForIdle();
+ findPositiveButton().click();
final Result result = mActivity.getResult();
final Uri uri = result.data.getData();
@@ -504,6 +508,8 @@
findDocument("DIR2").click();
mDevice.waitForIdle();
findSaveButton().click();
+ mDevice.waitForIdle();
+ findPositiveButton().click();
final Result result = mActivity.getResult();
final Uri uri = result.data.getData();
diff --git a/hostsidetests/appsecurity/test-apps/ListeningPortsApp/src/android/appsecurity/cts/listeningports/ListeningPortsTest.java b/hostsidetests/appsecurity/test-apps/ListeningPortsApp/src/android/appsecurity/cts/listeningports/ListeningPortsTest.java
index cc70445..d0373e1 100644
--- a/hostsidetests/appsecurity/test-apps/ListeningPortsApp/src/android/appsecurity/cts/listeningports/ListeningPortsTest.java
+++ b/hostsidetests/appsecurity/test-apps/ListeningPortsApp/src/android/appsecurity/cts/listeningports/ListeningPortsTest.java
@@ -72,12 +72,14 @@
EXCEPTION_PATTERNS.add("127.0.0.1 10000"); // used by the cast receiver
EXCEPTION_PATTERNS.add(":: 1002"); // used by remote control
EXCEPTION_PATTERNS.add(":: 1020"); // used by remote control
+ EXCEPTION_PATTERNS.add("0.0.0.0:7275"); // used by supl
//no current patterns involve address, port and UID combinations
//Example for when necessary: EXCEPTION_PATTERNS.add("0.0.0.0:5555 10000")
// IPv6 exceptions
// TODO: this is not standard notation for IPv6. Use [$addr]:$port instead as per RFC 3986.
EXCEPTION_PATTERNS.add(":::5555"); // emulator port for adb
+ EXCEPTION_PATTERNS.add(":::7275"); // used by supl
}
/**
diff --git a/hostsidetests/appsecurity/test-apps/UsePermissionApp22/src/com/android/cts/usepermission/UsePermissionTest22.java b/hostsidetests/appsecurity/test-apps/UsePermissionApp22/src/com/android/cts/usepermission/UsePermissionTest22.java
index 1c2427a..20be2cc 100644
--- a/hostsidetests/appsecurity/test-apps/UsePermissionApp22/src/com/android/cts/usepermission/UsePermissionTest22.java
+++ b/hostsidetests/appsecurity/test-apps/UsePermissionApp22/src/com/android/cts/usepermission/UsePermissionTest22.java
@@ -16,13 +16,6 @@
package com.android.cts.usepermission;
-import static com.android.cts.externalstorageapp.CommonExternalStorageTest.assertDirNoAccess;
-import static com.android.cts.externalstorageapp.CommonExternalStorageTest.assertDirReadWriteAccess;
-import static com.android.cts.externalstorageapp.CommonExternalStorageTest.assertMediaNoAccess;
-import static com.android.cts.externalstorageapp.CommonExternalStorageTest.assertMediaReadWriteAccess;
-import static com.android.cts.externalstorageapp.CommonExternalStorageTest.getAllPackageSpecificPaths;
-import static com.android.cts.externalstorageapp.CommonExternalStorageTest.logCommand;
-
import static junit.framework.Assert.assertEquals;
import static junit.framework.Assert.assertTrue;
@@ -32,13 +25,11 @@
import android.content.pm.PackageManager;
import android.database.Cursor;
import android.net.Uri;
-import android.os.Environment;
import android.os.Process;
import android.provider.CalendarContract;
import org.junit.Test;
-import java.io.File;
import java.util.Arrays;
/**
@@ -51,61 +42,42 @@
@Test
public void testCompatDefault() throws Exception {
- logCommand("/system/bin/cat", "/proc/self/mountinfo");
+ // Legacy permission model appears granted
+ assertEquals(PackageManager.PERMISSION_GRANTED,
+ mContext.checkPermission(android.Manifest.permission.READ_CALENDAR,
+ Process.myPid(), Process.myUid()));
+ assertEquals(PackageManager.PERMISSION_GRANTED,
+ mContext.checkPermission(android.Manifest.permission.WRITE_CALENDAR,
+ Process.myPid(), Process.myUid()));
- // Legacy permission model is granted by default
- assertEquals(PackageManager.PERMISSION_GRANTED,
- mContext.checkPermission(android.Manifest.permission.READ_EXTERNAL_STORAGE,
- Process.myPid(), Process.myUid()));
- assertEquals(PackageManager.PERMISSION_GRANTED,
- mContext.checkPermission(android.Manifest.permission.WRITE_EXTERNAL_STORAGE,
- Process.myPid(), Process.myUid()));
- assertEquals(Environment.MEDIA_MOUNTED, Environment.getExternalStorageState());
- assertDirReadWriteAccess(Environment.getExternalStorageDirectory());
- for (File path : getAllPackageSpecificPaths(mContext)) {
- if (path != null) {
- assertDirReadWriteAccess(path);
- }
+ // Read/write access should be allowed
+ final Uri uri = insertCalendarItem();
+ try (Cursor c = mContext.getContentResolver().query(uri, null, null, null)) {
+ assertEquals(1, c.getCount());
}
- assertMediaReadWriteAccess(mContext.getContentResolver());
}
@Test
public void testCompatRevoked_part1() throws Exception {
// Revoke the permission
- revokePermissions(new String[]{android.Manifest.permission.READ_EXTERNAL_STORAGE}, true);
- }
-
- private void assertNoStorageAccess() throws Exception {
- assertEquals(Environment.MEDIA_UNMOUNTED, Environment.getExternalStorageState());
-
- assertDirNoAccess(Environment.getExternalStorageDirectory());
- for (File dir : getAllPackageSpecificPaths(mContext)) {
- if (dir != null) {
- assertDirNoAccess(dir);
- }
- }
- assertMediaNoAccess(mContext.getContentResolver(), true);
-
- // Just to be sure, poke explicit path
- assertDirNoAccess(new File(Environment.getExternalStorageDirectory(),
- "/Android/data/" + mContext.getPackageName()));
+ revokePermissions(new String[] {Manifest.permission.WRITE_CALENDAR}, true);
}
@Test
public void testCompatRevoked_part2() throws Exception {
- logCommand("/system/bin/cat", "/proc/self/mountinfo");
-
- // Legacy permission model appears granted, but storage looks and
- // behaves like it's ejected
+ // Legacy permission model appears granted
assertEquals(PackageManager.PERMISSION_GRANTED,
- mContext.checkPermission(android.Manifest.permission.READ_EXTERNAL_STORAGE,
+ mContext.checkPermission(android.Manifest.permission.READ_CALENDAR,
Process.myPid(), Process.myUid()));
assertEquals(PackageManager.PERMISSION_GRANTED,
- mContext.checkPermission(android.Manifest.permission.WRITE_EXTERNAL_STORAGE,
+ mContext.checkPermission(android.Manifest.permission.WRITE_CALENDAR,
Process.myPid(), Process.myUid()));
- assertNoStorageAccess();
+ // Read/write access should be ignored
+ final Uri uri = insertCalendarItem();
+ try (Cursor c = mContext.getContentResolver().query(uri, null, null, null)) {
+ assertEquals(0, c.getCount());
+ }
}
@Test
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 806c551..3e3f040 100755
--- 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
@@ -17,6 +17,7 @@
package com.android.cts.usepermission;
import static junit.framework.Assert.assertEquals;
+
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.fail;
@@ -34,6 +35,7 @@
import android.support.test.InstrumentationRegistry;
import android.support.test.runner.AndroidJUnit4;
import android.support.test.uiautomator.By;
+import android.support.test.uiautomator.Direction;
import android.support.test.uiautomator.UiDevice;
import android.support.test.uiautomator.UiObject;
import android.support.test.uiautomator.UiObject2;
@@ -47,13 +49,16 @@
import android.view.accessibility.AccessibilityNodeInfo.AccessibilityAction;
import android.widget.ScrollView;
import android.widget.Switch;
+
+import junit.framework.Assert;
+
+import org.junit.Before;
+import org.junit.runner.RunWith;
+
import java.util.List;
import java.util.Map;
import java.util.concurrent.Callable;
import java.util.concurrent.TimeoutException;
-import junit.framework.Assert;
-import org.junit.Before;
-import org.junit.runner.RunWith;
@RunWith(AndroidJUnit4.class)
public abstract class BasePermissionsTest {
@@ -62,7 +67,7 @@
private static final long IDLE_TIMEOUT_MILLIS = 500;
private static final long GLOBAL_TIMEOUT_MILLIS = 5000;
- private static final long RETRY_TIMEOUT = 3 * GLOBAL_TIMEOUT_MILLIS;
+ private static final long RETRY_TIMEOUT = 10 * GLOBAL_TIMEOUT_MILLIS;
private static final String LOG_TAG = "BasePermissionsTest";
private static Map<String, String> sPermissionToLabelResNameMap = new ArrayMap<>();
@@ -289,36 +294,47 @@
protected void clickAllowButton() throws Exception {
scrollToBottomIfWatch();
- getUiDevice().findObject(new UiSelector().resourceId(
- "com.android.permissioncontroller:id/permission_allow_button")).click();
+ waitForIdle();
+ getUiDevice().wait(Until.findObject(By.res(
+ "com.android.permissioncontroller:id/permission_allow_button")),
+ GLOBAL_TIMEOUT_MILLIS).click();
}
protected void clickAllowAlwaysButton() throws Exception {
- getUiDevice().findObject(new UiSelector().resourceId(
- "com.android.permissioncontroller:id/permission_allow_always_button")).click();
+ waitForIdle();
+ getUiDevice().wait(Until.findObject(By.res(
+ "com.android.permissioncontroller:id/permission_allow_always_button")),
+ GLOBAL_TIMEOUT_MILLIS).click();
}
protected void clickAllowForegroundButton() throws Exception {
- getUiDevice().findObject(new UiSelector().resourceId(
- "com.android.permissioncontroller:id/permission_allow_foreground_only_button")).click();
+ waitForIdle();
+ getUiDevice().wait(Until.findObject(By.res(
+ "com.android.permissioncontroller:id/permission_allow_foreground_only_button")),
+ GLOBAL_TIMEOUT_MILLIS).click();
}
protected void clickDenyButton() throws Exception {
scrollToBottomIfWatch();
- getUiDevice().findObject(new UiSelector().resourceId(
- "com.android.permissioncontroller:id/permission_deny_button")).click();
+ waitForIdle();
+ getUiDevice().wait(Until.findObject(By.res(
+ "com.android.permissioncontroller:id/permission_deny_button")),
+ GLOBAL_TIMEOUT_MILLIS).click();
}
protected void clickDenyAndDontAskAgainButton() throws Exception {
- getUiDevice().findObject(new UiSelector().resourceId(
- "com.android.permissioncontroller:id/permission_deny_and_dont_ask_again_button")).click();
+ waitForIdle();
+ getUiDevice().wait(Until.findObject(By.res(
+ "com.android.permissioncontroller:id/permission_deny_and_dont_ask_again_button")),
+ GLOBAL_TIMEOUT_MILLIS).click();
}
protected void clickDontAskAgainButton() throws Exception {
scrollToBottomIfWatch();
- getUiDevice().findObject(new UiSelector().resourceId(
- "com.android.permissioncontroller:id/permission_deny_dont_ask_again_button"))
- .click();
+ waitForIdle();
+ getUiDevice().wait(Until.findObject(By.res(
+ "com.android.permissioncontroller:id/permission_deny_dont_ask_again_button")),
+ GLOBAL_TIMEOUT_MILLIS).click();
}
protected void grantPermission(String permission) throws Exception {
@@ -377,7 +393,6 @@
Assert.assertNotNull("Permissions label should be present", permLabelView);
AccessibilityNodeInfo permItemView = findCollectionItem(permLabelView);
- Assert.assertNotNull("Permissions item should be present", permItemView);
click(permItemView);
@@ -387,36 +402,34 @@
// Find the permission screen
String permissionLabel = getPermissionLabel(permission);
- AccessibilityNodeInfo labelView = getNodeTimed(() -> findByText(permissionLabel), true);
- Assert.assertNotNull("Permission label should be present", labelView);
+ UiObject2 permissionView = null;
+ long start = System.currentTimeMillis();
+ while (permissionView == null && start + RETRY_TIMEOUT > System.currentTimeMillis()) {
+ permissionView = getUiDevice().wait(Until.findObject(By.text(permissionLabel)),
+ GLOBAL_TIMEOUT_MILLIS);
- AccessibilityNodeInfo itemView = findCollectionItem(labelView);
- Assert.assertNotNull("Permission item should be present", itemView);
+ if (permissionView == null) {
+ getUiDevice().findObject(By.res("android:id/list_container"))
+ .scroll(Direction.DOWN, 1);
+ }
+ }
- click(itemView);
+ permissionView.click();
+ waitForIdle();
String denyLabel = mContext.getResources().getString(R.string.Deny);
- AccessibilityNodeInfo denyView = getNodeTimed(() -> findByText(denyLabel), true);
- Assert.assertNotNull("Deny label should be present", denyView);
- final boolean wasGranted = !denyView.isChecked();
+ final boolean wasGranted = !getUiDevice().wait(Until.findObject(By.text(denyLabel)),
+ GLOBAL_TIMEOUT_MILLIS).isChecked();
if (granted != wasGranted) {
// Toggle the permission
if (granted) {
String allowLabel = mContext.getResources().getString(R.string.Allow);
- AccessibilityNodeInfo allowView = getNodeTimed(() -> findByText(allowLabel), false);
- if (allowView == null) {
- String allowAllLabel = mContext.getResources().getString(R.string.AllowAll);
- allowView = getNodeTimed(() -> findByText(allowAllLabel), true);
- }
- Assert.assertNotNull("Allow label should be present", allowView);
-
- click(allowView);
+ getUiDevice().findObject(By.text(allowLabel)).click();
} else {
- click(denyView);
+ getUiDevice().findObject(By.text(denyLabel)).click();
}
-
waitForIdle();
if (wasGranted && legacyApp) {
@@ -429,9 +442,8 @@
.createPackageContext(packageName, 0).getResources();
final int confirmResId = resources.getIdentifier(resIdName, null, null);
String confirmTitle = resources.getString(confirmResId);
- UiObject denyAnyway = getUiDevice().findObject(new UiSelector()
- .textStartsWith(confirmTitle));
- denyAnyway.click();
+ getUiDevice().wait(Until.findObject(By.textStartsWith(confirmTitle)),
+ GLOBAL_TIMEOUT_MILLIS).click();
waitForIdle();
}
@@ -585,27 +597,6 @@
return null;
}
- private static AccessibilityNodeInfo findSwitch(AccessibilityNodeInfo root) throws Exception {
- if (Switch.class.getName().equals(root.getClassName().toString())) {
- return root;
- }
- final int childCount = root.getChildCount();
- for (int i = 0; i < childCount; i++) {
- AccessibilityNodeInfo child = root.getChild(i);
- if (child == null) {
- continue;
- }
- if (Switch.class.getName().equals(child.getClassName().toString())) {
- return child;
- }
- AccessibilityNodeInfo result = findSwitch(child);
- if (result != null) {
- return result;
- }
- }
- return null;
- }
-
private static AccessibilityNodeInfo getNodeTimed(
Callable<AccessibilityNodeInfo> callable, boolean retry) throws Exception {
final long startTimeMillis = SystemClock.uptimeMillis();
diff --git a/hostsidetests/appsecurity/test-apps/UsePermissionApp23/src/com/android/cts/usepermission/UsePermissionTest23.java b/hostsidetests/appsecurity/test-apps/UsePermissionApp23/src/com/android/cts/usepermission/UsePermissionTest23.java
index 06c2b35..ed74947 100644
--- a/hostsidetests/appsecurity/test-apps/UsePermissionApp23/src/com/android/cts/usepermission/UsePermissionTest23.java
+++ b/hostsidetests/appsecurity/test-apps/UsePermissionApp23/src/com/android/cts/usepermission/UsePermissionTest23.java
@@ -20,15 +20,13 @@
import static org.junit.Assert.fail;
-import static com.android.cts.externalstorageapp.CommonExternalStorageTest.assertDirNoAccess;
-import static com.android.cts.externalstorageapp.CommonExternalStorageTest.assertDirReadWriteAccess;
-import static com.android.cts.externalstorageapp.CommonExternalStorageTest.assertMediaNoAccess;
-import static com.android.cts.externalstorageapp.CommonExternalStorageTest.assertMediaReadWriteAccess;
-import static com.android.cts.externalstorageapp.CommonExternalStorageTest.logCommand;
-
import android.Manifest;
+import android.content.ContentValues;
+import android.content.Context;
import android.content.pm.PackageManager;
-import android.os.Environment;
+import android.database.Cursor;
+import android.net.Uri;
+import android.provider.CalendarContract;
import android.support.test.InstrumentationRegistry;
import org.junit.Before;
@@ -40,6 +38,8 @@
public class UsePermissionTest23 extends BasePermissionsTest {
private static final int REQUEST_CODE_PERMISSIONS = 42;
+ private final Context mContext = getInstrumentation().getContext();
+
private boolean mLeanback;
private boolean mWatch;
@@ -62,49 +62,47 @@
@Test
public void testDefault() throws Exception {
- logCommand("/system/bin/cat", "/proc/self/mountinfo");
-
// New permission model is denied by default
assertAllPermissionsRevoked();
-
- assertEquals(Environment.MEDIA_MOUNTED, Environment.getExternalStorageState());
- assertDirNoAccess(Environment.getExternalStorageDirectory());
- assertDirReadWriteAccess(getInstrumentation().getContext().getExternalCacheDir());
- assertMediaNoAccess(getInstrumentation().getContext().getContentResolver(), false);
}
@Test
public void testGranted() throws Exception {
- logCommand("/system/bin/cat", "/proc/self/mountinfo");
- grantPermission(Manifest.permission.READ_EXTERNAL_STORAGE);
+ grantPermission(Manifest.permission.READ_CALENDAR);
+
+ // Read/write access should be allowed
assertEquals(PackageManager.PERMISSION_GRANTED, getInstrumentation().getContext()
- .checkSelfPermission(Manifest.permission.READ_EXTERNAL_STORAGE));
+ .checkSelfPermission(Manifest.permission.READ_CALENDAR));
assertEquals(PackageManager.PERMISSION_GRANTED, getInstrumentation().getContext()
- .checkSelfPermission(Manifest.permission.WRITE_EXTERNAL_STORAGE));
- assertEquals(Environment.MEDIA_MOUNTED, Environment.getExternalStorageState());
- assertDirReadWriteAccess(Environment.getExternalStorageDirectory());
- assertDirReadWriteAccess(getInstrumentation().getContext().getExternalCacheDir());
- assertMediaReadWriteAccess(getInstrumentation().getContext().getContentResolver());
+ .checkSelfPermission(Manifest.permission.WRITE_CALENDAR));
+ final Uri uri = insertCalendarItem();
+ try (Cursor c = mContext.getContentResolver().query(uri, null, null, null)) {
+ assertEquals(1, c.getCount());
+ }
}
@Test
public void testInteractiveGrant() throws Exception {
- logCommand("/system/bin/cat", "/proc/self/mountinfo");
-
// Start out without permission
assertEquals(PackageManager.PERMISSION_DENIED, getInstrumentation().getContext()
- .checkSelfPermission(Manifest.permission.READ_EXTERNAL_STORAGE));
+ .checkSelfPermission(Manifest.permission.READ_CALENDAR));
assertEquals(PackageManager.PERMISSION_DENIED, getInstrumentation().getContext()
- .checkSelfPermission(Manifest.permission.WRITE_EXTERNAL_STORAGE));
- assertEquals(Environment.MEDIA_MOUNTED, Environment.getExternalStorageState());
- assertDirNoAccess(Environment.getExternalStorageDirectory());
- assertDirReadWriteAccess(getInstrumentation().getContext().getExternalCacheDir());
- assertMediaNoAccess(getInstrumentation().getContext().getContentResolver(), false);
+ .checkSelfPermission(Manifest.permission.WRITE_CALENDAR));
+ try {
+ insertCalendarItem();
+ fail();
+ } catch (SecurityException expected) {
+ }
+ try (Cursor c = mContext.getContentResolver().query(
+ CalendarContract.Calendars.CONTENT_URI, null, null, null)) {
+ fail();
+ } catch (SecurityException expected) {
+ }
// Go through normal grant flow
BasePermissionActivity.Result result = requestPermissions(new String[] {
- Manifest.permission.READ_EXTERNAL_STORAGE,
- Manifest.permission.WRITE_EXTERNAL_STORAGE},
+ Manifest.permission.READ_CALENDAR,
+ Manifest.permission.WRITE_CALENDAR},
REQUEST_CODE_PERMISSIONS,
BasePermissionActivity.class,
() -> {
@@ -117,22 +115,20 @@
});
assertEquals(REQUEST_CODE_PERMISSIONS, result.requestCode);
- assertEquals(Manifest.permission.READ_EXTERNAL_STORAGE, result.permissions[0]);
- assertEquals(Manifest.permission.WRITE_EXTERNAL_STORAGE, result.permissions[1]);
+ assertEquals(Manifest.permission.READ_CALENDAR, result.permissions[0]);
+ assertEquals(Manifest.permission.WRITE_CALENDAR, result.permissions[1]);
assertEquals(PackageManager.PERMISSION_GRANTED, result.grantResults[0]);
assertEquals(PackageManager.PERMISSION_GRANTED, result.grantResults[1]);
- logCommand("/system/bin/cat", "/proc/self/mountinfo");
-
// We should have permission now!
assertEquals(PackageManager.PERMISSION_GRANTED, getInstrumentation().getContext()
- .checkSelfPermission(Manifest.permission.READ_EXTERNAL_STORAGE));
+ .checkSelfPermission(Manifest.permission.READ_CALENDAR));
assertEquals(PackageManager.PERMISSION_GRANTED, getInstrumentation().getContext()
- .checkSelfPermission(Manifest.permission.WRITE_EXTERNAL_STORAGE));
- assertEquals(Environment.MEDIA_MOUNTED, Environment.getExternalStorageState());
- assertDirReadWriteAccess(Environment.getExternalStorageDirectory());
- assertDirReadWriteAccess(getInstrumentation().getContext().getExternalCacheDir());
- assertMediaReadWriteAccess(getInstrumentation().getContext().getContentResolver());
+ .checkSelfPermission(Manifest.permission.WRITE_CALENDAR));
+ final Uri uri = insertCalendarItem();
+ try (Cursor c = mContext.getContentResolver().query(uri, null, null, null)) {
+ assertEquals(1, c.getCount());
+ }
}
@Test
@@ -680,4 +676,16 @@
clickDenyAndDontAskAgainButton();
}
}
+
+ /**
+ * Attempt to insert a new unique calendar item; this might be ignored if
+ * this legacy app has its permission revoked.
+ */
+ private Uri insertCalendarItem() {
+ final ContentValues values = new ContentValues();
+ values.put(CalendarContract.Calendars.NAME, "cts" + System.nanoTime());
+ values.put(CalendarContract.Calendars.CALENDAR_DISPLAY_NAME, "cts");
+ values.put(CalendarContract.Calendars.CALENDAR_COLOR, 0xffff0000);
+ return mContext.getContentResolver().insert(CalendarContract.Calendars.CONTENT_URI, values);
+ }
}
diff --git a/hostsidetests/backup/Android.mk b/hostsidetests/backup/Android.mk
index fd5b3c6..bbe7d47 100644
--- a/hostsidetests/backup/Android.mk
+++ b/hostsidetests/backup/Android.mk
@@ -25,7 +25,7 @@
LOCAL_MODULE := CtsBackupHostTestCases
-LOCAL_JAVA_LIBRARIES := cts-tradefed tradefed compatibility-host-util
+LOCAL_JAVA_LIBRARIES := cts-tradefed tradefed compatibility-host-util truth-prebuilt
include $(BUILD_HOST_JAVA_LIBRARY)
diff --git a/tests/libcore/simplemmodule/Android.mk b/hostsidetests/backup/ProfileFullBackupApp/Android.mk
similarity index 73%
copy from tests/libcore/simplemmodule/Android.mk
copy to hostsidetests/backup/ProfileFullBackupApp/Android.mk
index 2e6adc1..1451e97 100644
--- a/tests/libcore/simplemmodule/Android.mk
+++ b/hostsidetests/backup/ProfileFullBackupApp/Android.mk
@@ -1,4 +1,4 @@
-# Copyright (C) 2018 The Android Open Source Project
+# Copyright (C) 2019 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.
@@ -16,17 +16,8 @@
include $(CLEAR_VARS)
-LOCAL_PACKAGE_NAME := CtsLibcoreSimpleMModuleTestCases
-LOCAL_PRIVATE_PLATFORM_APIS := true
-
-LOCAL_STATIC_JAVA_LIBRARIES := \
- cts-core-test-runner \
- core-libart+oj-intra-test \
- core-simple-intra-test
-
# 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)
@@ -34,7 +25,18 @@
LOCAL_PROGUARD_ENABLED := disabled
-# Tag this module as a cts test artifact
+LOCAL_STATIC_JAVA_LIBRARIES := \
+ android-support-test \
+ platform-test-annotations \
+ truth-prebuilt
+
+LOCAL_SRC_FILES := $(call all-java-files-under, src)
+
+# tag this module as a cts test artifact
LOCAL_COMPATIBILITY_SUITE := cts vts general-tests
-include $(BUILD_CTS_SUPPORT_PACKAGE)
+LOCAL_PACKAGE_NAME := CtsProfileFullBackupApp
+
+LOCAL_SDK_VERSION := test_current
+
+include $(BUILD_PACKAGE)
diff --git a/hostsidetests/backup/ProfileFullBackupApp/AndroidManifest.xml b/hostsidetests/backup/ProfileFullBackupApp/AndroidManifest.xml
new file mode 100644
index 0000000..36111b0
--- /dev/null
+++ b/hostsidetests/backup/ProfileFullBackupApp/AndroidManifest.xml
@@ -0,0 +1,29 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ ~ Copyright (C) 2019 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.cts.backup.profilefullbackupapp">
+
+ <application android:label="ProfileFullBackupApp">
+ <uses-library android:name="android.test.runner" />
+ </application>
+
+ <instrumentation
+ android:name="android.support.test.runner.AndroidJUnitRunner"
+ android:targetPackage="android.cts.backup.profilefullbackupapp" />
+
+</manifest>
diff --git a/hostsidetests/backup/ProfileFullBackupApp/src/android/cts/backup/profilefullbackupapp/ProfileFullBackupRestoreTest.java b/hostsidetests/backup/ProfileFullBackupApp/src/android/cts/backup/profilefullbackupapp/ProfileFullBackupRestoreTest.java
new file mode 100644
index 0000000..198a180
--- /dev/null
+++ b/hostsidetests/backup/ProfileFullBackupApp/src/android/cts/backup/profilefullbackupapp/ProfileFullBackupRestoreTest.java
@@ -0,0 +1,87 @@
+/*
+ * Copyright (C) 2019 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.cts.backup.profilefullbackupapp;
+
+import static android.support.test.InstrumentationRegistry.getTargetContext;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import android.platform.test.annotations.AppModeFull;
+import android.support.test.runner.AndroidJUnit4;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import java.io.File;
+import java.io.IOException;
+import java.nio.file.Files;
+
+/** Device side test invoked by ProfileFullBackupRestoreHostSideTest. */
+@RunWith(AndroidJUnit4.class)
+@AppModeFull
+public class ProfileFullBackupRestoreTest {
+ private static final String FILE_ONE_CONTENT = "file1text";
+ private static final String FILE_TWO_CONTENT = "file2text";
+
+ private File mFile1;
+ private File mFile2;
+
+ @Before
+ public void setUp() throws Exception {
+ File dir = getTargetContext().getFilesDir();
+ dir.mkdirs();
+
+ mFile1 = new File(dir, "file1");
+ mFile2 = new File(dir, "file2");
+ }
+
+ @Test
+ public void assertFilesDontExist() throws Exception {
+ assertThat(mFile1.exists()).isFalse();
+ assertThat(mFile2.exists()).isFalse();
+ }
+
+ @Test
+ public void writeFilesAndAssertSuccess() throws Exception {
+ Files.write(mFile1.toPath(), FILE_ONE_CONTENT.getBytes());
+ assertFileContains(mFile1, FILE_ONE_CONTENT);
+
+ Files.write(mFile2.toPath(), FILE_TWO_CONTENT.getBytes());
+ assertFileContains(mFile2, FILE_TWO_CONTENT);
+ }
+
+ @Test
+ public void clearFilesAndAssertSuccess() throws Exception {
+ mFile1.delete();
+ mFile2.delete();
+ assertFilesDontExist();
+ }
+
+ @Test
+ public void assertFilesRestored() throws Exception {
+ assertThat(mFile1.exists()).isTrue();
+ assertFileContains(mFile1, FILE_ONE_CONTENT);
+
+ assertThat(mFile2.exists()).isTrue();
+ assertFileContains(mFile2, FILE_TWO_CONTENT);
+ }
+
+ private void assertFileContains(File file, String content) throws IOException {
+ assertThat(Files.readAllBytes(file.toPath())).isEqualTo(content.getBytes());
+ }
+}
diff --git a/tests/libcore/simplemmodule/Android.mk b/hostsidetests/backup/ProfileKeyValueApp/Android.mk
similarity index 73%
rename from tests/libcore/simplemmodule/Android.mk
rename to hostsidetests/backup/ProfileKeyValueApp/Android.mk
index 2e6adc1..89213f2 100644
--- a/tests/libcore/simplemmodule/Android.mk
+++ b/hostsidetests/backup/ProfileKeyValueApp/Android.mk
@@ -1,4 +1,4 @@
-# Copyright (C) 2018 The Android Open Source Project
+# Copyright (C) 2019 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.
@@ -16,17 +16,8 @@
include $(CLEAR_VARS)
-LOCAL_PACKAGE_NAME := CtsLibcoreSimpleMModuleTestCases
-LOCAL_PRIVATE_PLATFORM_APIS := true
-
-LOCAL_STATIC_JAVA_LIBRARIES := \
- cts-core-test-runner \
- core-libart+oj-intra-test \
- core-simple-intra-test
-
# 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)
@@ -34,7 +25,18 @@
LOCAL_PROGUARD_ENABLED := disabled
-# Tag this module as a cts test artifact
+LOCAL_STATIC_JAVA_LIBRARIES := \
+ android-support-test \
+ platform-test-annotations \
+ truth-prebuilt
+
+LOCAL_SRC_FILES := $(call all-java-files-under, src)
+
+# tag this module as a cts test artifact
LOCAL_COMPATIBILITY_SUITE := cts vts general-tests
-include $(BUILD_CTS_SUPPORT_PACKAGE)
+LOCAL_PACKAGE_NAME := CtsProfileKeyValueApp
+
+LOCAL_SDK_VERSION := test_current
+
+include $(BUILD_PACKAGE)
diff --git a/hostsidetests/backup/ProfileKeyValueApp/AndroidManifest.xml b/hostsidetests/backup/ProfileKeyValueApp/AndroidManifest.xml
new file mode 100644
index 0000000..fbc8602
--- /dev/null
+++ b/hostsidetests/backup/ProfileKeyValueApp/AndroidManifest.xml
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ ~ Copyright (C) 2019 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.cts.backup.profilekeyvalueapp">
+
+ <application
+ android:backupAgent=".ProfileKeyValueBackupAgent"
+ android:killAfterRestore="false" >
+
+ <uses-library android:name="android.test.runner" />
+ </application>
+
+ <instrumentation
+ android:name="android.support.test.runner.AndroidJUnitRunner"
+ android:targetPackage="android.cts.backup.profilekeyvalueapp" />
+
+</manifest>
diff --git a/hostsidetests/backup/ProfileKeyValueApp/src/android.cts.backup.profilekeyvalueapp/ProfileKeyValueBackupAgent.java b/hostsidetests/backup/ProfileKeyValueApp/src/android.cts.backup.profilekeyvalueapp/ProfileKeyValueBackupAgent.java
new file mode 100644
index 0000000..d4cd3a7
--- /dev/null
+++ b/hostsidetests/backup/ProfileKeyValueApp/src/android.cts.backup.profilekeyvalueapp/ProfileKeyValueBackupAgent.java
@@ -0,0 +1,37 @@
+/*
+ * Copyright (C) 2019 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.cts.backup.profilekeyvalueapp;
+
+import android.app.backup.BackupAgentHelper;
+import android.app.backup.SharedPreferencesBackupHelper;
+
+/**
+ * Backup agent that uses {@link SharedPreferencesBackupHelper} to backup/restore shared
+ * preferences.
+ */
+public class ProfileKeyValueBackupAgent extends BackupAgentHelper {
+ private static final String PREFS_PREFIX = "USER-KV";
+
+ @Override
+ public void onCreate() {
+ super.onCreate();
+ SharedPreferencesBackupHelper backupHelper =
+ new SharedPreferencesBackupHelper(
+ this, ProfileKeyValueBackupRestoreTest.TEST_PREFS_NAME);
+ addHelper(PREFS_PREFIX, backupHelper);
+ }
+}
diff --git a/hostsidetests/backup/ProfileKeyValueApp/src/android.cts.backup.profilekeyvalueapp/ProfileKeyValueBackupRestoreTest.java b/hostsidetests/backup/ProfileKeyValueApp/src/android.cts.backup.profilekeyvalueapp/ProfileKeyValueBackupRestoreTest.java
new file mode 100644
index 0000000..0081d15
--- /dev/null
+++ b/hostsidetests/backup/ProfileKeyValueApp/src/android.cts.backup.profilekeyvalueapp/ProfileKeyValueBackupRestoreTest.java
@@ -0,0 +1,68 @@
+/*
+ * Copyright (C) 2019 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.cts.backup.profilekeyvalueapp;
+
+import static android.support.test.InstrumentationRegistry.getTargetContext;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import android.content.Context;
+import android.content.SharedPreferences;
+import android.platform.test.annotations.AppModeFull;
+import android.support.test.runner.AndroidJUnit4;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+/** Device side test invoked by ProfileKeyValueBackupRestoreHostSideTest. */
+@RunWith(AndroidJUnit4.class)
+@AppModeFull
+public class ProfileKeyValueBackupRestoreTest {
+ static final String TEST_PREFS_NAME = "user-test-prefs";
+ private static final String PREFS_USER_KEY = "userId";
+ private static final int PREFS_USER_DEFAULT = -1000;
+
+ private int mUserId;
+ private SharedPreferences mPreferences;
+
+ @Before
+ public void setUp() {
+ Context context = getTargetContext();
+ mUserId = context.getUserId();
+ mPreferences = context.getSharedPreferences(TEST_PREFS_NAME, Context.MODE_PRIVATE);
+ }
+
+ @Test
+ public void assertSharedPrefsIsEmpty() {
+ int userIdPref = mPreferences.getInt(PREFS_USER_KEY, PREFS_USER_DEFAULT);
+ assertThat(userIdPref).isEqualTo(PREFS_USER_DEFAULT);
+ }
+
+ @Test
+ public void writeSharedPrefsAndAssertSuccess() {
+ SharedPreferences.Editor editor = mPreferences.edit();
+ editor.putInt(PREFS_USER_KEY, mUserId);
+ assertThat(editor.commit()).isTrue();
+ }
+
+ @Test
+ public void assertSharedPrefsRestored() {
+ int userIdPref = mPreferences.getInt(PREFS_USER_KEY, PREFS_USER_DEFAULT);
+ assertThat(userIdPref).isEqualTo(mUserId);
+ }
+}
diff --git a/hostsidetests/backup/src/android/cts/backup/BaseMultiUserBackupHostSideTest.java b/hostsidetests/backup/src/android/cts/backup/BaseMultiUserBackupHostSideTest.java
new file mode 100644
index 0000000..089faca
--- /dev/null
+++ b/hostsidetests/backup/src/android/cts/backup/BaseMultiUserBackupHostSideTest.java
@@ -0,0 +1,157 @@
+/*
+ * Copyright (C) 2019 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.cts.backup;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import static org.junit.Assume.assumeTrue;
+
+import android.platform.test.annotations.AppModeFull;
+
+import com.android.compatibility.common.util.BackupUtils;
+import com.android.tradefed.device.DeviceNotAvailableException;
+import com.android.tradefed.device.ITestDevice;
+import com.android.tradefed.log.LogUtil.CLog;
+import com.android.tradefed.testtype.DeviceJUnit4ClassRunner;
+
+import org.junit.After;
+import org.junit.Before;
+import org.junit.runner.RunWith;
+
+import java.io.IOException;
+import java.util.Optional;
+import java.util.concurrent.TimeUnit;
+
+/** Base class for CTS multi-user backup/restore host-side tests. */
+@RunWith(DeviceJUnit4ClassRunner.class)
+@AppModeFull
+public abstract class BaseMultiUserBackupHostSideTest extends BaseBackupHostSideTest {
+ private static final String USER_SETUP_COMPLETE_SETTING = "user_setup_complete";
+ private static final int BROADCAST_IDLE_TIMEOUT_MIN = 2;
+
+ private final BackupUtils mBackupUtils = getBackupUtils();
+ private ITestDevice mDevice;
+
+ // Store initial device state as Optional as tearDown() will execute even if we have assumption
+ // failures in setUp().
+ private Optional<Integer> mInitialUser = Optional.empty();
+
+ /** Check device features and keep track of pre-test device state. */
+ @Before
+ public void setUp() throws Exception {
+ super.setUp();
+ mDevice = getDevice();
+
+ // Check that backup and multi-user features are both supported.
+ assumeTrue("Backup feature not supported", mIsBackupSupported);
+ assumeTrue("Multi-user feature not supported", mDevice.isMultiUserSupported());
+
+ // Keep track of initial user state to restore in tearDown.
+ int currentUserId = mDevice.getCurrentUser();
+ mInitialUser = Optional.of(currentUserId);
+
+ // Switch to primary user.
+ int primaryUserId = mDevice.getPrimaryUserId();
+ if (currentUserId != primaryUserId) {
+ mDevice.switchUser(primaryUserId);
+ }
+ }
+
+ /** Restore pre-test device state. */
+ @After
+ public void tearDown() throws Exception {
+ if (mInitialUser.isPresent()) {
+ mDevice.switchUser(mInitialUser.get());
+ mInitialUser = Optional.empty();
+ }
+ }
+
+ /**
+ * Attempts to create a profile tied to the parent user {@code parentId}. Returns the user id of
+ * the profile if successful, otherwise throws a {@link RuntimeException}.
+ */
+ int createProfileUser(int parentId, String profileName) throws IOException {
+ String output =
+ mBackupUtils.executeShellCommandAndReturnOutput(
+ String.format("pm create-user --profileOf %d %s", parentId, profileName));
+ try {
+ // Expected output is "Success: created user id <id>"
+ String userId = output.substring(output.lastIndexOf(" ")).trim();
+ return Integer.parseInt(userId);
+ } catch (NumberFormatException e) {
+ CLog.d("Failed to parse user id when creating a profile user");
+ throw new RuntimeException();
+ }
+ }
+
+ /** Start the user and set necessary conditions for backup to be enabled in the user. */
+ void startUserAndInitializeForBackup(int userId) throws Exception {
+ // Turn on multi-user feature for this user.
+ mBackupUtils.executeShellCommandSync(
+ String.format("bmgr --user %d activate %b", userId, true));
+
+ mDevice.startUser(userId);
+ // Wait for user to be fully started.
+ mDevice.executeShellV2Command(
+ "am wait-for-broadcast-idle", BROADCAST_IDLE_TIMEOUT_MIN, TimeUnit.MINUTES);
+
+ mDevice.setSetting(userId, "secure", USER_SETUP_COMPLETE_SETTING, "1");
+ mBackupUtils.enableBackupForUser(true, userId);
+ assertThat(mBackupUtils.isBackupEnabledForUser(userId)).isTrue();
+ }
+
+ /**
+ * Selects the local transport as the current transport for user {@code userId}. Returns the
+ * {@link String} name of the local transport.
+ */
+ String switchUserToLocalTransportAndAssertSuccess(int userId) throws IOException {
+ // Make sure the user has the local transport.
+ String localTransport = mBackupUtils.getLocalTransportName();
+ assertThat(mBackupUtils.userHasBackupTransport(localTransport, userId)).isTrue();
+
+ // Switch to the local transport and assert success.
+ mBackupUtils.setBackupTransportForUser(localTransport, userId);
+ assertThat(mBackupUtils.isLocalTransportSelectedForUser(userId)).isTrue();
+
+ return localTransport;
+ }
+
+ /** Runs "bmgr --user <id> wipe <transport> <package>" to clear the backup data. */
+ void clearBackupDataInTransportForUser(String packageName, String transport, int userId)
+ throws DeviceNotAvailableException {
+ mDevice.executeShellCommand(
+ String.format("bmgr --user %d wipe %s %s", userId, transport, packageName));
+ }
+
+ /** Clears data of {@code packageName} for user {@code userId}. */
+ void clearPackageDataAsUser(String packageName, int userId) throws DeviceNotAvailableException {
+ mDevice.executeShellCommand(String.format("pm clear --user %d %s", userId, packageName));
+ }
+
+ /** Uninstalls {@code packageName} for user {@code userId}. */
+ void uninstallPackageAsUser(String packageName, int userId) throws DeviceNotAvailableException {
+ mDevice.executeShellCommand(
+ String.format("pm uninstall --user %d %s", userId, packageName));
+ }
+
+ /** Run device side test as user {@code userId}. */
+ void checkDeviceTestAsUser(String packageName, String className, String testName, int userId)
+ throws DeviceNotAvailableException {
+ boolean result = runDeviceTests(mDevice, packageName, className, testName, userId, null);
+ assertThat(result).isTrue();
+ }
+}
diff --git a/hostsidetests/backup/src/android/cts/backup/ProfileFullBackupRestoreHostSideTest.java b/hostsidetests/backup/src/android/cts/backup/ProfileFullBackupRestoreHostSideTest.java
new file mode 100644
index 0000000..56e2892
--- /dev/null
+++ b/hostsidetests/backup/src/android/cts/backup/ProfileFullBackupRestoreHostSideTest.java
@@ -0,0 +1,133 @@
+/*
+ * Copyright (C) 2019 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.cts.backup;
+
+import android.platform.test.annotations.AppModeFull;
+
+import com.android.compatibility.common.util.BackupUtils;
+import com.android.tradefed.device.DeviceNotAvailableException;
+import com.android.tradefed.device.ITestDevice;
+import com.android.tradefed.testtype.DeviceJUnit4ClassRunner;
+
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+/** Test the backup and restore flow for a full-backup app in a profile. */
+@RunWith(DeviceJUnit4ClassRunner.class)
+@AppModeFull
+public class ProfileFullBackupRestoreHostSideTest extends BaseMultiUserBackupHostSideTest {
+ private static final String TEST_APK = "CtsProfileFullBackupApp.apk";
+ private static final String TEST_FULL_BACKUP_PACKAGE =
+ "android.cts.backup.profilefullbackupapp";
+ private static final String DEVICE_TEST_NAME =
+ TEST_FULL_BACKUP_PACKAGE + ".ProfileFullBackupRestoreTest";
+
+ private final BackupUtils mBackupUtils = getBackupUtils();
+ private ITestDevice mDevice;
+ private int mProfileUserId;
+ private String mTransport;
+
+ /** Create the profile, switch to the local transport and setup the test package. */
+ @Before
+ @Override
+ public void setUp() throws Exception {
+ super.setUp();
+ mDevice = getDevice();
+
+ // Create profile user.
+ int parentUserId = mDevice.getCurrentUser();
+ mProfileUserId = createProfileUser(parentUserId, "Profile-Full");
+ startUserAndInitializeForBackup(mProfileUserId);
+
+ // Switch to local transport.
+ mTransport = switchUserToLocalTransportAndAssertSuccess(mProfileUserId);
+
+ // Setup test package.
+ installPackageAsUser(TEST_APK, true, mProfileUserId);
+ clearPackageDataAsUser(TEST_FULL_BACKUP_PACKAGE, mProfileUserId);
+ }
+
+ /** Uninstall the test package and remove the profile. */
+ @After
+ @Override
+ public void tearDown() throws Exception {
+ clearBackupDataInTransportForUser(TEST_FULL_BACKUP_PACKAGE, mTransport, mProfileUserId);
+ uninstallPackageAsUser(TEST_FULL_BACKUP_PACKAGE, mProfileUserId);
+ mDevice.removeUser(mProfileUserId);
+ super.tearDown();
+ }
+
+ /**
+ * Tests full-backup app backup and restore in the profile user using system restore.
+ *
+ * <ol>
+ * <li>App writes files to its directory.
+ * <li>Force a backup.
+ * <li>Clear the app's files.
+ * <li>Force a restore.
+ * <li>Check that the files and its contents are restored.
+ * </ol>
+ */
+ @Test
+ public void testFullBackupAndSystemRestore() throws Exception {
+ checkDeviceTest("assertFilesDontExist");
+ checkDeviceTest("writeFilesAndAssertSuccess");
+
+ mBackupUtils.backupNowAndAssertSuccessForUser(TEST_FULL_BACKUP_PACKAGE, mProfileUserId);
+
+ checkDeviceTest("clearFilesAndAssertSuccess");
+
+ mBackupUtils.restoreAndAssertSuccessForUser(
+ BackupUtils.LOCAL_TRANSPORT_TOKEN, TEST_FULL_BACKUP_PACKAGE, mProfileUserId);
+
+ checkDeviceTest("assertFilesRestored");
+ }
+
+ /**
+ * Tests full-backup app backup and restore in the profile user using restore at install.
+ *
+ * <ol>
+ * <li>App writes files to its directory.
+ * <li>Force a backup.
+ * <li>Uninstall the app.
+ * <li>Install the app to perform a restore-at-install operation.
+ * <li>Check that the files and its contents are restored.
+ * </ol>
+ */
+ @Test
+ public void testFullBackupAndRestoreAtInstall() throws Exception {
+ checkDeviceTest("assertFilesDontExist");
+ checkDeviceTest("writeFilesAndAssertSuccess");
+
+ mBackupUtils.backupNowAndAssertSuccessForUser(TEST_FULL_BACKUP_PACKAGE, mProfileUserId);
+
+ checkDeviceTest("clearFilesAndAssertSuccess");
+
+ uninstallPackageAsUser(TEST_FULL_BACKUP_PACKAGE, mProfileUserId);
+
+ installPackageAsUser(TEST_APK, true, mProfileUserId);
+
+ checkDeviceTest("assertFilesRestored");
+ }
+
+ private void checkDeviceTest(String methodName) throws DeviceNotAvailableException {
+ checkDeviceTestAsUser(
+ TEST_FULL_BACKUP_PACKAGE, DEVICE_TEST_NAME, methodName, mProfileUserId);
+ }
+}
diff --git a/hostsidetests/backup/src/android/cts/backup/ProfileKeyValueBackupRestoreHostSideTest.java b/hostsidetests/backup/src/android/cts/backup/ProfileKeyValueBackupRestoreHostSideTest.java
new file mode 100644
index 0000000..2ee45c4
--- /dev/null
+++ b/hostsidetests/backup/src/android/cts/backup/ProfileKeyValueBackupRestoreHostSideTest.java
@@ -0,0 +1,103 @@
+/*
+ * Copyright (C) 2019 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.cts.backup;
+
+import android.platform.test.annotations.AppModeFull;
+
+import com.android.compatibility.common.util.BackupUtils;
+import com.android.tradefed.device.DeviceNotAvailableException;
+import com.android.tradefed.device.ITestDevice;
+import com.android.tradefed.testtype.DeviceJUnit4ClassRunner;
+
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+/** Test the backup and restore flow for a key-value app in a profile. */
+@RunWith(DeviceJUnit4ClassRunner.class)
+@AppModeFull
+public class ProfileKeyValueBackupRestoreHostSideTest extends BaseMultiUserBackupHostSideTest {
+ private static final String TEST_APK = "CtsProfileKeyValueApp.apk";
+ private static final String TEST_PACKAGE = "android.cts.backup.profilekeyvalueapp";
+ private static final String DEVICE_TEST_NAME =
+ TEST_PACKAGE + ".ProfileKeyValueBackupRestoreTest";
+
+ private final BackupUtils mBackupUtils = getBackupUtils();
+ private ITestDevice mDevice;
+ private int mProfileUserId;
+ private String mTransport;
+
+ /** Create the profile, switch to the local transport and setup the test package. */
+ @Before
+ @Override
+ public void setUp() throws Exception {
+ super.setUp();
+ mDevice = getDevice();
+
+ // Create profile user.
+ int parentUserId = mDevice.getCurrentUser();
+ mProfileUserId = createProfileUser(parentUserId, "Profile-KV");
+ startUserAndInitializeForBackup(mProfileUserId);
+
+ // Switch to local transport.
+ mTransport = switchUserToLocalTransportAndAssertSuccess(mProfileUserId);
+
+ // Setup test package.
+ installPackageAsUser(TEST_APK, true, mProfileUserId);
+ clearPackageDataAsUser(TEST_PACKAGE, mProfileUserId);
+ }
+
+ /** Uninstall the test package and remove the profile. */
+ @After
+ @Override
+ public void tearDown() throws Exception {
+ clearBackupDataInTransportForUser(TEST_PACKAGE, mTransport, mProfileUserId);
+ uninstallPackageAsUser(TEST_PACKAGE, mProfileUserId);
+ mDevice.removeUser(mProfileUserId);
+ super.tearDown();
+ }
+
+ /**
+ * Tests key-value app backup and restore in the profile user.
+ *
+ * <ol>
+ * <li>App writes shared preferences.
+ * <li>Force a backup.
+ * <li>Uninstall the app.
+ * <li>Install the app to perform a restore-at-install operation.
+ * <li>Check that the shared preferences are restored.
+ * </ol>
+ */
+ @Test
+ public void testKeyValueBackupAndRestore() throws Exception {
+ checkDeviceTest("assertSharedPrefsIsEmpty");
+ checkDeviceTest("writeSharedPrefsAndAssertSuccess");
+
+ mBackupUtils.backupNowAndAssertSuccessForUser(TEST_PACKAGE, mProfileUserId);
+
+ uninstallPackageAsUser(TEST_PACKAGE, mProfileUserId);
+
+ installPackageAsUser(TEST_APK, true, mProfileUserId);
+
+ checkDeviceTest("assertSharedPrefsRestored");
+ }
+
+ private void checkDeviceTest(String methodName) throws DeviceNotAvailableException {
+ checkDeviceTestAsUser(TEST_PACKAGE, DEVICE_TEST_NAME, methodName, mProfileUserId);
+ }
+}
diff --git a/hostsidetests/devicepolicy/app/CertInstaller/src/com/android/cts/certinstaller/DelegatedDeviceIdAttestationTest.java b/hostsidetests/devicepolicy/app/CertInstaller/src/com/android/cts/certinstaller/DelegatedDeviceIdAttestationTest.java
index fffee81..e16aa42 100644
--- a/hostsidetests/devicepolicy/app/CertInstaller/src/com/android/cts/certinstaller/DelegatedDeviceIdAttestationTest.java
+++ b/hostsidetests/devicepolicy/app/CertInstaller/src/com/android/cts/certinstaller/DelegatedDeviceIdAttestationTest.java
@@ -31,7 +31,9 @@
// Test that a key generation request succeeds when device identifiers are requested.
public void testGenerateKeyPairWithDeviceIdAttestationExpectingSuccess() {
- KeyGenerationUtils.generateKeyWithDeviceIdAttestationExpectingSuccess(mDpm, null);
+ if (mDpm.isDeviceIdAttestationSupported()) {
+ KeyGenerationUtils.generateKeyWithDeviceIdAttestationExpectingSuccess(mDpm, null);
+ }
}
// Test that a key generation request fails when device identifiers are requested.
diff --git a/hostsidetests/devicepolicy/app/DeviceAdmin/src/com.android.cts.deviceadmin/BaseDeviceAdminTest.java b/hostsidetests/devicepolicy/app/DeviceAdmin/src/com.android.cts.deviceadmin/BaseDeviceAdminTest.java
index 22eab0b..4c10faa 100644
--- a/hostsidetests/devicepolicy/app/DeviceAdmin/src/com.android.cts.deviceadmin/BaseDeviceAdminTest.java
+++ b/hostsidetests/devicepolicy/app/DeviceAdmin/src/com.android.cts.deviceadmin/BaseDeviceAdminTest.java
@@ -18,6 +18,7 @@
import android.app.admin.DeviceAdminReceiver;
import android.app.admin.DevicePolicyManager;
import android.content.ComponentName;
+import android.content.pm.PackageManager;
import android.os.Build;
import android.test.AndroidTestCase;
@@ -28,6 +29,7 @@
protected String mPackageName;
protected ComponentName mAdminComponent;
+ protected boolean mHasSecureLockScreen;
public DevicePolicyManager dpm;
@@ -38,6 +40,8 @@
dpm = mContext.getSystemService(DevicePolicyManager.class);
mPackageName = mContext.getPackageName();
mAdminComponent = new ComponentName(mContext, AdminReceiver.class);
+ mHasSecureLockScreen = mContext.getPackageManager()
+ .hasSystemFeature(PackageManager.FEATURE_SECURE_LOCK_SCREEN);
}
/**
diff --git a/hostsidetests/devicepolicy/app/DeviceAdmin/src/com.android.cts.deviceadmin/DeviceAdminTest.java b/hostsidetests/devicepolicy/app/DeviceAdmin/src/com.android.cts.deviceadmin/DeviceAdminTest.java
index 90f24cb..2394a9a 100644
--- a/hostsidetests/devicepolicy/app/DeviceAdmin/src/com.android.cts.deviceadmin/DeviceAdminTest.java
+++ b/hostsidetests/devicepolicy/app/DeviceAdmin/src/com.android.cts.deviceadmin/DeviceAdminTest.java
@@ -41,6 +41,9 @@
}
public void testGetMaximumFailedPasswordsForWipe() {
+ if (!mHasSecureLockScreen) {
+ return;
+ }
dpm.setMaximumFailedPasswordsForWipe(mAdminComponent, 3);
assertEquals(3, dpm.getMaximumFailedPasswordsForWipe(mAdminComponent));
@@ -49,6 +52,9 @@
}
public void testPasswordHistoryLength() {
+ if (!mHasSecureLockScreen) {
+ return;
+ }
// Password history length restriction is only imposed if password quality is at least
// numeric.
dpm.setPasswordQuality(mAdminComponent,
@@ -66,6 +72,9 @@
}
public void testPasswordExpirationTimeout() {
+ if (!mHasSecureLockScreen) {
+ return;
+ }
long originalValue = dpm.getPasswordExpirationTimeout(mAdminComponent);
try {
for (long testLength : new long[] {
diff --git a/hostsidetests/devicepolicy/app/DeviceAdmin/src/com.android.cts.deviceadmin/DeviceAdminWithEnterprisePoliciesBlockedTest.java b/hostsidetests/devicepolicy/app/DeviceAdmin/src/com.android.cts.deviceadmin/DeviceAdminWithEnterprisePoliciesBlockedTest.java
index 3a123d9..402ca9f 100644
--- a/hostsidetests/devicepolicy/app/DeviceAdmin/src/com.android.cts.deviceadmin/DeviceAdminWithEnterprisePoliciesBlockedTest.java
+++ b/hostsidetests/devicepolicy/app/DeviceAdmin/src/com.android.cts.deviceadmin/DeviceAdminWithEnterprisePoliciesBlockedTest.java
@@ -42,6 +42,9 @@
@Override
public void testPasswordHistoryLength() {
+ if (!mHasSecureLockScreen) {
+ return;
+ }
int originalValue = dpm.getPasswordHistoryLength(mAdminComponent);
assertSecurityException(() -> dpm.setPasswordHistoryLength(mAdminComponent, 3));
assertEquals(originalValue, dpm.getPasswordHistoryLength(mAdminComponent));
@@ -98,6 +101,9 @@
@Override
public void testPasswordExpirationTimeout() {
+ if (!mHasSecureLockScreen) {
+ return;
+ }
long originalValue = dpm.getPasswordExpirationTimeout(mAdminComponent);
assertSecurityException(() -> dpm.setPasswordExpirationTimeout(mAdminComponent, 1234L));
assertEquals(originalValue, dpm.getPasswordExpirationTimeout(mAdminComponent));
diff --git a/hostsidetests/devicepolicy/app/DeviceAndProfileOwner/src/com/android/cts/deviceandprofileowner/DelegatedCertInstallerTest.java b/hostsidetests/devicepolicy/app/DeviceAndProfileOwner/src/com/android/cts/deviceandprofileowner/DelegatedCertInstallerTest.java
index 0fc8f48..bc33910 100644
--- a/hostsidetests/devicepolicy/app/DeviceAndProfileOwner/src/com/android/cts/deviceandprofileowner/DelegatedCertInstallerTest.java
+++ b/hostsidetests/devicepolicy/app/DeviceAndProfileOwner/src/com/android/cts/deviceandprofileowner/DelegatedCertInstallerTest.java
@@ -20,7 +20,6 @@
import static com.google.common.truth.Truth.assertThat;
-import android.app.KeyguardManager;
import android.app.admin.DevicePolicyManager;
import android.content.BroadcastReceiver;
import android.content.ComponentName;
@@ -249,7 +248,6 @@
mDpm.getCertInstallerPackage(ADMIN_RECEIVER_COMPONENT));
// Exercise installKeyPair()
- checkKeyguardPrecondition();
installKeyPair(TEST_KEY, TEST_CERT, alias);
assertResult("installKeyPair", true);
}
@@ -315,19 +313,6 @@
assertThat(mDpm.getCertInstallerPackage(ADMIN_RECEIVER_COMPONENT)).isNull();
}
- /**
- * installKeyPair() requires the system to have a lockscreen password, which should have been
- * set by the host side test.
- */
- private void checkKeyguardPrecondition() throws InterruptedException {
- KeyguardManager km = (KeyguardManager) mContext.getSystemService(Context.KEYGUARD_SERVICE);
- if (!km.isKeyguardSecure()) {
- Thread.sleep(5000);
- }
- assertTrue("A lockscreen password is required before keypair can be installed",
- km.isKeyguardSecure());
- }
-
private void installCaCert(byte[] cert) {
Intent intent = new Intent();
intent.setAction(ACTION_INSTALL_CERT);
diff --git a/hostsidetests/devicepolicy/app/DeviceAndProfileOwner/src/com/android/cts/deviceandprofileowner/DeviceIdAttestationTest.java b/hostsidetests/devicepolicy/app/DeviceAndProfileOwner/src/com/android/cts/deviceandprofileowner/DeviceIdAttestationTest.java
index 196000f..bce0a08 100755
--- a/hostsidetests/devicepolicy/app/DeviceAndProfileOwner/src/com/android/cts/deviceandprofileowner/DeviceIdAttestationTest.java
+++ b/hostsidetests/devicepolicy/app/DeviceAndProfileOwner/src/com/android/cts/deviceandprofileowner/DeviceIdAttestationTest.java
@@ -35,8 +35,10 @@
// Test that the same key generation request succeeds once the profile owner was granted
// access to device identifiers.
public void testSucceedsWithProfileOwnerIdsGrant() {
- KeyGenerationUtils.generateKeyWithDeviceIdAttestationExpectingSuccess(mDevicePolicyManager,
- getWho());
+ if (mDevicePolicyManager.isDeviceIdAttestationSupported()) {
+ KeyGenerationUtils.generateKeyWithDeviceIdAttestationExpectingSuccess(
+ mDevicePolicyManager, getWho());
+ }
}
protected ComponentName getWho() {
diff --git a/hostsidetests/devicepolicy/app/DeviceOwner/src/com/android/cts/deviceowner/BaseDeviceOwnerTest.java b/hostsidetests/devicepolicy/app/DeviceOwner/src/com/android/cts/deviceowner/BaseDeviceOwnerTest.java
index 9175d9b..9562a1f6 100644
--- a/hostsidetests/devicepolicy/app/DeviceOwner/src/com/android/cts/deviceowner/BaseDeviceOwnerTest.java
+++ b/hostsidetests/devicepolicy/app/DeviceOwner/src/com/android/cts/deviceowner/BaseDeviceOwnerTest.java
@@ -18,6 +18,7 @@
import android.app.Instrumentation;
import android.app.admin.DevicePolicyManager;
import android.content.ComponentName;
+import android.content.pm.PackageManager;
import android.support.test.InstrumentationRegistry;
import android.support.test.uiautomator.UiDevice;
import android.test.AndroidTestCase;
@@ -35,6 +36,8 @@
protected DevicePolicyManager mDevicePolicyManager;
protected Instrumentation mInstrumentation;
protected UiDevice mDevice;
+ protected boolean mHasSecureLockScreen;
+
@Override
protected void setUp() throws Exception {
super.setUp();
@@ -42,6 +45,8 @@
mInstrumentation = InstrumentationRegistry.getInstrumentation();
mDevice = UiDevice.getInstance(mInstrumentation);
mDevicePolicyManager = mContext.getSystemService(DevicePolicyManager.class);
+ mHasSecureLockScreen = mContext.getPackageManager().hasSystemFeature(
+ PackageManager.FEATURE_SECURE_LOCK_SCREEN);
assertDeviceOwner();
}
diff --git a/hostsidetests/devicepolicy/app/DeviceOwner/src/com/android/cts/deviceowner/InstallUpdateTest.java b/hostsidetests/devicepolicy/app/DeviceOwner/src/com/android/cts/deviceowner/InstallUpdateTest.java
index 6d38843..c6c62ee 100644
--- a/hostsidetests/devicepolicy/app/DeviceOwner/src/com/android/cts/deviceowner/InstallUpdateTest.java
+++ b/hostsidetests/devicepolicy/app/DeviceOwner/src/com/android/cts/deviceowner/InstallUpdateTest.java
@@ -17,7 +17,13 @@
package com.android.cts.deviceowner;
import android.app.admin.DevicePolicyManager;
+import android.content.Intent;
+import android.content.IntentFilter;
import android.net.Uri;
+import android.os.BatteryManager;
+import android.os.SystemClock;
+
+import com.android.compatibility.common.util.SystemUtil;
import java.io.File;
import java.util.concurrent.CountDownLatch;
@@ -27,6 +33,11 @@
* Test {@link android.app.admin.DevicePolicyManager#installSystemUpdate}
*/
public class InstallUpdateTest extends BaseDeviceOwnerTest {
+ private static final int BATTERY_STATE_CHANGE_TIMEOUT_MS = 5000;
+ private static final int BATTERY_STATE_CHANGE_SLEEP_PER_CHECK_MS = 50;
+ private static final int TEST_BATTERY_THRESHOLD = 10;
+ private static final IntentFilter BATTERY_CHANGED_FILTER =
+ new IntentFilter(Intent.ACTION_BATTERY_CHANGED);
public static final String TEST_SYSTEM_UPDATES_DIR =
"/data/local/tmp/cts/deviceowner/";
@@ -36,7 +47,6 @@
assertUpdateError(
"random",
DevicePolicyManager.InstallUpdateCallback.UPDATE_ERROR_FILE_NOT_FOUND);
-
}
public void testInstallUpdate_failWrongVersion() throws InterruptedException {
@@ -70,6 +80,58 @@
DevicePolicyManager.InstallUpdateCallback.UPDATE_ERROR_UPDATE_FILE_INVALID);
}
+ public void testInstallUpdate_notCharging_belowThreshold_failsBatteryCheck() throws Exception {
+ try {
+ setNonChargingBatteryThreshold(TEST_BATTERY_THRESHOLD);
+ setNonChargingBatteryLevelAndWait(TEST_BATTERY_THRESHOLD - 1);
+ assertUpdateError("wrongSize.zip",
+ DevicePolicyManager.InstallUpdateCallback.UPDATE_ERROR_BATTERY_LOW);
+ } finally {
+ resetBatteryState();
+ resetDevicePolicyConstants();
+ }
+ }
+
+ public void testInstallUpdate_notCharging_aboveThreshold_passesBatteryCheck() throws Exception {
+ try {
+ setNonChargingBatteryThreshold(TEST_BATTERY_THRESHOLD);
+ setNonChargingBatteryLevelAndWait(TEST_BATTERY_THRESHOLD);
+ // Positive CTS tests aren't possible, so we verify that we get the file-related error
+ // rather than the battery one.
+ assertUpdateError("wrongSize.zip",
+ DevicePolicyManager.InstallUpdateCallback.UPDATE_ERROR_UPDATE_FILE_INVALID);
+ } finally {
+ resetBatteryState();
+ resetDevicePolicyConstants();
+ }
+ }
+
+ public void testInstallUpdate_charging_belowThreshold_failsBatteryCheck() throws Exception {
+ try {
+ setChargingBatteryThreshold(TEST_BATTERY_THRESHOLD);
+ setChargingBatteryLevelAndWait(TEST_BATTERY_THRESHOLD - 1);
+ assertUpdateError("wrongSize.zip",
+ DevicePolicyManager.InstallUpdateCallback.UPDATE_ERROR_BATTERY_LOW);
+ } finally {
+ resetBatteryState();
+ resetDevicePolicyConstants();
+ }
+ }
+
+ public void testInstallUpdate_charging_aboveThreshold_passesBatteryCheck() throws Exception {
+ try {
+ setChargingBatteryThreshold(TEST_BATTERY_THRESHOLD);
+ setChargingBatteryLevelAndWait(TEST_BATTERY_THRESHOLD);
+ // Positive CTS tests aren't possible, so we verify that we get the file-related error
+ // rather than the battery one.
+ assertUpdateError("wrongSize.zip",
+ DevicePolicyManager.InstallUpdateCallback.UPDATE_ERROR_UPDATE_FILE_INVALID);
+ } finally {
+ resetBatteryState();
+ resetDevicePolicyConstants();
+ }
+ }
+
private void assertUpdateError(String fileName, int expectedErrorCode)
throws InterruptedException {
CountDownLatch latch = new CountDownLatch(1);
@@ -87,4 +149,60 @@
});
assertTrue(latch.await(TIMEOUT, TimeUnit.MINUTES));
}
-}
\ No newline at end of file
+
+ private void setNonChargingBatteryThreshold(int threshold) {
+ SystemUtil.runShellCommand(
+ "settings put global device_policy_constants battery_threshold_not_charging="
+ + threshold);
+ }
+
+ private void setNonChargingBatteryLevelAndWait(int level) throws Exception {
+ setBatteryStateAndWait(/* plugged= */ false, level);
+ }
+
+ private void setChargingBatteryThreshold(int threshold) {
+ SystemUtil.runShellCommand(
+ "settings put global device_policy_constants battery_threshold_charging="
+ + threshold);
+ }
+
+ private void setChargingBatteryLevelAndWait(int level) throws Exception {
+ setBatteryStateAndWait(/* plugged= */ true, level);
+ }
+
+ /** Should be paired with {@link #resetBatteryState()} in a {@code finally} block. */
+ private void setBatteryStateAndWait(boolean plugged, int level) throws Exception {
+ SystemUtil.runShellCommand(plugged ? "cmd battery set ac 1" : "cmd battery unplug");
+ SystemUtil.runShellCommand("cmd battery set -f level " + level);
+ long startTime = SystemClock.elapsedRealtime();
+ while (!isBatteryState(plugged, level)
+ && SystemClock.elapsedRealtime() <= startTime + BATTERY_STATE_CHANGE_TIMEOUT_MS) {
+ Thread.sleep(BATTERY_STATE_CHANGE_SLEEP_PER_CHECK_MS);
+ }
+ }
+
+ private boolean isBatteryState(boolean plugged, int level) {
+ final Intent batteryStatus =
+ mContext.registerReceiver(/* receiver= */ null, BATTERY_CHANGED_FILTER);
+ return isPluggedIn(batteryStatus) == plugged
+ && calculateBatteryPercentage(batteryStatus) == level;
+ }
+
+ private boolean isPluggedIn(Intent batteryStatus) {
+ return batteryStatus.getIntExtra(BatteryManager.EXTRA_PLUGGED, /* defaultValue= */ -1) > 0;
+ }
+
+ private float calculateBatteryPercentage(Intent batteryStatus) {
+ int level = batteryStatus.getIntExtra(BatteryManager.EXTRA_LEVEL, /* defaultValue= */ -1);
+ int scale = batteryStatus.getIntExtra(BatteryManager.EXTRA_SCALE, /* defaultValue= */ -1);
+ return 100 * level / (float) scale;
+ }
+
+ private void resetBatteryState() {
+ SystemUtil.runShellCommand("dumpsys battery reset");
+ }
+
+ private void resetDevicePolicyConstants() {
+ SystemUtil.runShellCommand("settings delete global device_policy_constants");
+ }
+}
diff --git a/hostsidetests/devicepolicy/app/DeviceOwner/src/com/android/cts/deviceowner/SecurityLoggingTest.java b/hostsidetests/devicepolicy/app/DeviceOwner/src/com/android/cts/deviceowner/SecurityLoggingTest.java
index 5118b83..4d4e306 100644
--- a/hostsidetests/devicepolicy/app/DeviceOwner/src/com/android/cts/deviceowner/SecurityLoggingTest.java
+++ b/hostsidetests/devicepolicy/app/DeviceOwner/src/com/android/cts/deviceowner/SecurityLoggingTest.java
@@ -253,9 +253,11 @@
}
private void verifyAdminEventsPresent(List<SecurityEvent> events) {
- verifyPasswordComplexityEventsPresent(events);
- verifyUserRestrictionEventsPresent(events);
+ if (mHasSecureLockScreen) {
+ verifyPasswordComplexityEventsPresent(events);
+ }
verifyLockingPolicyEventsPresent(events);
+ verifyUserRestrictionEventsPresent(events);
}
/**
@@ -280,9 +282,11 @@
}
private void generateAdminEvents() {
- generatePasswordComplexityEvents();
- generateUserRestrictionEvents();
+ if (mHasSecureLockScreen) {
+ generatePasswordComplexityEvents();
+ }
generateLockingPolicyEvents();
+ generateUserRestrictionEvents();
}
/**
@@ -606,9 +610,12 @@
}
private void generateLockingPolicyEvents() {
- mDevicePolicyManager.setPasswordExpirationTimeout(getWho(), TEST_PWD_EXPIRATION_TIMEOUT);
- mDevicePolicyManager.setPasswordHistoryLength(getWho(), TEST_PWD_HISTORY_LENGTH);
- mDevicePolicyManager.setMaximumFailedPasswordsForWipe(getWho(), TEST_PWD_MAX_ATTEMPTS);
+ if (mHasSecureLockScreen) {
+ mDevicePolicyManager.setPasswordExpirationTimeout(getWho(),
+ TEST_PWD_EXPIRATION_TIMEOUT);
+ mDevicePolicyManager.setPasswordHistoryLength(getWho(), TEST_PWD_HISTORY_LENGTH);
+ mDevicePolicyManager.setMaximumFailedPasswordsForWipe(getWho(), TEST_PWD_MAX_ATTEMPTS);
+ }
mDevicePolicyManager.setKeyguardDisabledFeatures(getWho(), KEYGUARD_DISABLE_FINGERPRINT);
mDevicePolicyManager.setMaximumTimeToLock(getWho(), TEST_MAX_TIME_TO_LOCK);
mDevicePolicyManager.lockNow();
@@ -617,26 +624,28 @@
private void verifyLockingPolicyEventsPresent(List<SecurityEvent> events) {
final int userId = Process.myUserHandle().getIdentifier();
- findEvent("set password expiration", events,
- e -> e.getTag() == TAG_PASSWORD_EXPIRATION_SET &&
- getString(e, ADMIN_PKG_INDEX).equals(getWho().getPackageName()) &&
- getInt(e, ADMIN_USER_INDEX) == userId &&
- getInt(e, TARGET_USER_INDEX) == userId &&
- getLong(e, PWD_EXPIRATION_INDEX) == TEST_PWD_EXPIRATION_TIMEOUT);
+ if (mHasSecureLockScreen) {
+ findEvent("set password expiration", events,
+ e -> e.getTag() == TAG_PASSWORD_EXPIRATION_SET &&
+ getString(e, ADMIN_PKG_INDEX).equals(getWho().getPackageName()) &&
+ getInt(e, ADMIN_USER_INDEX) == userId &&
+ getInt(e, TARGET_USER_INDEX) == userId &&
+ getLong(e, PWD_EXPIRATION_INDEX) == TEST_PWD_EXPIRATION_TIMEOUT);
- findEvent("set password history length", events,
- e -> e.getTag() == TAG_PASSWORD_HISTORY_LENGTH_SET &&
- getString(e, ADMIN_PKG_INDEX).equals(getWho().getPackageName()) &&
- getInt(e, ADMIN_USER_INDEX) == userId &&
- getInt(e, TARGET_USER_INDEX) == userId &&
- getInt(e, PWD_HIST_LEN_INDEX) == TEST_PWD_HISTORY_LENGTH);
+ findEvent("set password history length", events,
+ e -> e.getTag() == TAG_PASSWORD_HISTORY_LENGTH_SET &&
+ getString(e, ADMIN_PKG_INDEX).equals(getWho().getPackageName()) &&
+ getInt(e, ADMIN_USER_INDEX) == userId &&
+ getInt(e, TARGET_USER_INDEX) == userId &&
+ getInt(e, PWD_HIST_LEN_INDEX) == TEST_PWD_HISTORY_LENGTH);
- findEvent("set password attempts", events,
- e -> e.getTag() == TAG_MAX_PASSWORD_ATTEMPTS_SET &&
- getString(e, ADMIN_PKG_INDEX).equals(getWho().getPackageName()) &&
- getInt(e, ADMIN_USER_INDEX) == userId &&
- getInt(e, TARGET_USER_INDEX) == userId &&
- getInt(e, MAX_PWD_ATTEMPTS_INDEX) == TEST_PWD_MAX_ATTEMPTS);
+ findEvent("set password attempts", events,
+ e -> e.getTag() == TAG_MAX_PASSWORD_ATTEMPTS_SET &&
+ getString(e, ADMIN_PKG_INDEX).equals(getWho().getPackageName()) &&
+ getInt(e, ADMIN_USER_INDEX) == userId &&
+ getInt(e, TARGET_USER_INDEX) == userId &&
+ getInt(e, MAX_PWD_ATTEMPTS_INDEX) == TEST_PWD_MAX_ATTEMPTS);
+ }
findEvent("set keyguard disabled features", events,
e -> e.getTag() == TAG_KEYGUARD_DISABLED_FEATURES_SET &&
diff --git a/hostsidetests/devicepolicy/app/ManagedProfile/src/com/android/cts/managedprofile/BaseManagedProfileTest.java b/hostsidetests/devicepolicy/app/ManagedProfile/src/com/android/cts/managedprofile/BaseManagedProfileTest.java
index f10822c..ae530f3 100644
--- a/hostsidetests/devicepolicy/app/ManagedProfile/src/com/android/cts/managedprofile/BaseManagedProfileTest.java
+++ b/hostsidetests/devicepolicy/app/ManagedProfile/src/com/android/cts/managedprofile/BaseManagedProfileTest.java
@@ -19,6 +19,7 @@
import android.app.admin.DevicePolicyManager;
import android.content.ComponentName;
import android.content.Context;
+import android.content.pm.PackageManager;
import android.test.InstrumentationTestCase;
/**
@@ -38,6 +39,7 @@
protected DevicePolicyManager mDevicePolicyManager;
protected DevicePolicyManager mParentDevicePolicyManager;
protected Context mContext;
+ protected boolean mHasSecureLockScreen;
@Override
protected void setUp() throws Exception {
@@ -54,6 +56,9 @@
assertTrue(mDevicePolicyManager.isProfileOwnerApp(
ADMIN_RECEIVER_COMPONENT.getPackageName()));
assertTrue(mDevicePolicyManager.isManagedProfile(ADMIN_RECEIVER_COMPONENT));
+
+ mHasSecureLockScreen = mContext.getPackageManager().hasSystemFeature(
+ PackageManager.FEATURE_SECURE_LOCK_SCREEN);
}
protected DevicePolicyManager getDevicePolicyManager(boolean isParent) {
diff --git a/hostsidetests/devicepolicy/app/ManagedProfile/src/com/android/cts/managedprofile/CrossProfileCalendarTest.java b/hostsidetests/devicepolicy/app/ManagedProfile/src/com/android/cts/managedprofile/CrossProfileCalendarTest.java
index 879076a..522f048 100644
--- a/hostsidetests/devicepolicy/app/ManagedProfile/src/com/android/cts/managedprofile/CrossProfileCalendarTest.java
+++ b/hostsidetests/devicepolicy/app/ManagedProfile/src/com/android/cts/managedprofile/CrossProfileCalendarTest.java
@@ -41,7 +41,12 @@
import android.text.TextUtils;
import android.text.format.DateUtils;
import android.text.format.Time;
+import android.util.ArraySet;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.List;
import java.util.Set;
/**
@@ -132,15 +137,15 @@
ADMIN_RECEIVER_COMPONENT);
assertThat(whitelist).isEmpty();
- mDevicePolicyManager.addCrossProfileCalendarPackage(
- ADMIN_RECEIVER_COMPONENT, MANAGED_PROFILE_PKG);
+ mDevicePolicyManager.setCrossProfileCalendarPackages(
+ ADMIN_RECEIVER_COMPONENT, new ArraySet<String>(Arrays.asList(MANAGED_PROFILE_PKG)));
whitelist = mDevicePolicyManager.getCrossProfileCalendarPackages(
ADMIN_RECEIVER_COMPONENT);
assertThat(whitelist.size()).isEqualTo(1);
assertThat(whitelist.contains(MANAGED_PROFILE_PKG)).isTrue();
- assertThat(mDevicePolicyManager.removeCrossProfileCalendarPackage(
- ADMIN_RECEIVER_COMPONENT, MANAGED_PROFILE_PKG)).isTrue();
+ mDevicePolicyManager.setCrossProfileCalendarPackages(
+ ADMIN_RECEIVER_COMPONENT, Collections.emptySet());
whitelist = mDevicePolicyManager.getCrossProfileCalendarPackages(
ADMIN_RECEIVER_COMPONENT);
assertThat(whitelist).isEmpty();
@@ -392,15 +397,22 @@
// Utils method, not a actual test. Ran from ManagedProfileTest.java to set up for actual tests.
public void testWhitelistManagedProfilePackage() {
requireRunningOnManagedProfile();
- mDevicePolicyManager.addCrossProfileCalendarPackage(
- ADMIN_RECEIVER_COMPONENT, MANAGED_PROFILE_PKG);
+ mDevicePolicyManager.setCrossProfileCalendarPackages(
+ ADMIN_RECEIVER_COMPONENT, new ArraySet<String>(Arrays.asList(MANAGED_PROFILE_PKG)));
}
// Utils method, not a actual test. Ran from ManagedProfileTest.java to set up for actual tests.
- public void testRemoveManagedProfilePackageFromWhitelist() {
+ public void testWhitelistAllPackages() {
requireRunningOnManagedProfile();
- assertThat(mDevicePolicyManager.removeCrossProfileCalendarPackage(
- ADMIN_RECEIVER_COMPONENT, MANAGED_PROFILE_PKG)).isTrue();
+ mDevicePolicyManager.setCrossProfileCalendarPackages(
+ ADMIN_RECEIVER_COMPONENT, null);
+ }
+
+ // Utils method, not a actual test. Ran from ManagedProfileTest.java to set up for actual tests.
+ public void testCleanupWhitelist() {
+ requireRunningOnManagedProfile();
+ mDevicePolicyManager.setCrossProfileCalendarPackages(
+ ADMIN_RECEIVER_COMPONENT, Collections.emptySet());
}
// Utils method, not a actual test. Ran from ManagedProfileTest.java to set up for actual tests.
diff --git a/hostsidetests/devicepolicy/app/ManagedProfile/src/com/android/cts/managedprofile/DevicePolicyManagerParentSupportTest.java b/hostsidetests/devicepolicy/app/ManagedProfile/src/com/android/cts/managedprofile/DevicePolicyManagerParentSupportTest.java
index 9bd721f..c7f905a 100644
--- a/hostsidetests/devicepolicy/app/ManagedProfile/src/com/android/cts/managedprofile/DevicePolicyManagerParentSupportTest.java
+++ b/hostsidetests/devicepolicy/app/ManagedProfile/src/com/android/cts/managedprofile/DevicePolicyManagerParentSupportTest.java
@@ -31,6 +31,9 @@
}
public void testSetAndGetPasswordHistoryLength_onParent() {
+ if (!mHasSecureLockScreen) {
+ return;
+ }
final int passwordHistoryLength = 5;
mParentDevicePolicyManager.setPasswordHistoryLength(
@@ -42,6 +45,9 @@
}
public void testSetAndGetPasswordExpirationTimeout_onParent() {
+ if (!mHasSecureLockScreen) {
+ return;
+ }
final int passwordExpirationTimeout = 432000000;
mParentDevicePolicyManager.setPasswordExpirationTimeout(
@@ -53,6 +59,9 @@
}
public void testGetPasswordExpiration_onParent() {
+ if (!mHasSecureLockScreen) {
+ return;
+ }
final long passwordExpirationTimeout = 432000000;
final long currentTime = System.currentTimeMillis();
@@ -85,6 +94,9 @@
}
public void testSetAndGetMaximumFailedPasswordsForWipe_onParent() {
+ if (!mHasSecureLockScreen) {
+ return;
+ }
final int maximumFailedPasswordsForWipe = 15;
mParentDevicePolicyManager.setMaximumFailedPasswordsForWipe(
@@ -122,6 +134,9 @@
}
public void testSetAndGetTrustAgentConfiguration_onParent() {
+ if (!mHasSecureLockScreen) {
+ return;
+ }
final PersistableBundle configuration = new PersistableBundle();
final String key = "key";
final String value = "value";
@@ -137,6 +152,9 @@
}
public void testSetAndGetRequiredStrongAuthTimeout_onParent() {
+ if (!mHasSecureLockScreen) {
+ return;
+ }
final int requiredStrongAuthTimeout = 4600000;
mParentDevicePolicyManager.setRequiredStrongAuthTimeout(
diff --git a/hostsidetests/devicepolicy/app/ManagedProfile/src/com/android/cts/managedprofile/WipeDataReceiver.java b/hostsidetests/devicepolicy/app/ManagedProfile/src/com/android/cts/managedprofile/WipeDataReceiver.java
index 3f44008..9f65303 100644
--- a/hostsidetests/devicepolicy/app/ManagedProfile/src/com/android/cts/managedprofile/WipeDataReceiver.java
+++ b/hostsidetests/devicepolicy/app/ManagedProfile/src/com/android/cts/managedprofile/WipeDataReceiver.java
@@ -44,7 +44,7 @@
} else if (ACTION_WIPE_DATA_WITH_REASON.equals(intent.getAction())) {
dpm.wipeData(0, TEST_WIPE_DATA_REASON);
} else if (ACTION_WIPE_DATA_WITHOUT_REASON.equals(intent.getAction())) {
- dpm.wipeData(0, null);
+ dpm.wipeData(DevicePolicyManager.WIPE_SILENTLY);
}
}
}
diff --git a/hostsidetests/devicepolicy/app/TransferOwnerIncomingApp/src/com/android/cts/transferowner/DeviceAndProfileOwnerTransferIncomingTest.java b/hostsidetests/devicepolicy/app/TransferOwnerIncomingApp/src/com/android/cts/transferowner/DeviceAndProfileOwnerTransferIncomingTest.java
index 5d255e0e..7822e1a 100644
--- a/hostsidetests/devicepolicy/app/TransferOwnerIncomingApp/src/com/android/cts/transferowner/DeviceAndProfileOwnerTransferIncomingTest.java
+++ b/hostsidetests/devicepolicy/app/TransferOwnerIncomingApp/src/com/android/cts/transferowner/DeviceAndProfileOwnerTransferIncomingTest.java
@@ -25,6 +25,7 @@
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
+import android.content.pm.PackageManager;
import android.content.SharedPreferences;
import android.os.IBinder;
import android.os.PersistableBundle;
@@ -73,12 +74,15 @@
protected Context mContext;
protected ComponentName mIncomingComponentName;
protected DevicePolicyManager mDevicePolicyManager;
+ protected boolean mHasSecureLockScreen;
@Before
public void setUp() throws Exception {
mContext = InstrumentationRegistry.getTargetContext();
mDevicePolicyManager = mContext.getSystemService(DevicePolicyManager.class);
mIncomingComponentName = new ComponentName(mContext, BasicAdminReceiver.class.getName());
+ mHasSecureLockScreen = mContext.getPackageManager().hasSystemFeature(
+ PackageManager.FEATURE_SECURE_LOCK_SCREEN);
}
@Test
diff --git a/hostsidetests/devicepolicy/app/TransferOwnerIncomingApp/src/com/android/cts/transferowner/TransferProfileOwnerIncomingTest.java b/hostsidetests/devicepolicy/app/TransferOwnerIncomingApp/src/com/android/cts/transferowner/TransferProfileOwnerIncomingTest.java
index ef7e8ac..1d91237 100644
--- a/hostsidetests/devicepolicy/app/TransferOwnerIncomingApp/src/com/android/cts/transferowner/TransferProfileOwnerIncomingTest.java
+++ b/hostsidetests/devicepolicy/app/TransferOwnerIncomingApp/src/com/android/cts/transferowner/TransferProfileOwnerIncomingTest.java
@@ -40,8 +40,10 @@
DevicePolicyManager targetParentProfileInstance =
mDevicePolicyManager.getParentProfileInstance(mIncomingComponentName);
- assertEquals(
- passwordExpirationTimeout,
- targetParentProfileInstance.getPasswordExpirationTimeout(mIncomingComponentName));
+ if (mHasSecureLockScreen) {
+ assertEquals(
+ passwordExpirationTimeout,
+ targetParentProfileInstance.getPasswordExpirationTimeout(mIncomingComponentName));
+ }
}
}
diff --git a/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/BaseDeviceAdminHostSideTest.java b/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/BaseDeviceAdminHostSideTest.java
index 4425dcd..8141b11 100644
--- a/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/BaseDeviceAdminHostSideTest.java
+++ b/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/BaseDeviceAdminHostSideTest.java
@@ -91,7 +91,7 @@
}
public void testResetPassword_nycRestrictions() throws Exception {
- if (!mHasFeature) {
+ if (!mHasFeature || !mHasSecureLockScreen) {
return;
}
@@ -111,7 +111,7 @@
* Run the tests in DeviceOwnerPasswordTest.java (as device owner).
*/
public void testRunDeviceOwnerPasswordTest() throws Exception {
- if (!mHasFeature) {
+ if (!mHasFeature || !mHasSecureLockScreen) {
return;
}
diff --git a/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/BaseDevicePolicyTest.java b/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/BaseDevicePolicyTest.java
index 930e66d..53e45fc 100644
--- a/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/BaseDevicePolicyTest.java
+++ b/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/BaseDevicePolicyTest.java
@@ -133,6 +133,9 @@
/** Whether file-based encryption (FBE) is supported. */
protected boolean mSupportsFbe;
+ /** Whether the device has a lock screen.*/
+ protected boolean mHasSecureLockScreen;
+
/** Users we shouldn't delete in the tests */
private ArrayList<Integer> mFixedUsers;
@@ -156,6 +159,8 @@
mFixedPackages = getDevice().getInstalledPackageNames();
mBuildHelper = new CompatibilityBuildHelper(mCtsBuild);
+ mHasSecureLockScreen = hasDeviceFeature("android.software.secure_lock_screen");
+
// disable the package verifier to avoid the dialog when installing an app
mPackageVerifier = getDevice().executeShellCommand(
"settings get global package_verifier_enable");
diff --git a/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/DeviceAndProfileOwnerTest.java b/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/DeviceAndProfileOwnerTest.java
index bf94abb..c9c31f8 100644
--- a/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/DeviceAndProfileOwnerTest.java
+++ b/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/DeviceAndProfileOwnerTest.java
@@ -342,9 +342,6 @@
return;
}
- // Set a device lockscreen password (precondition for installing private key pairs).
- changeUserCredential("1234", null, mPrimaryUserId);
-
// Install relevant apps.
installAppAsUser(DELEGATE_APP_APK, mUserId);
installAppAsUser(TEST_APP_APK, mUserId);
@@ -370,8 +367,6 @@
executeDeviceTestClass(".DelegationTest");
} finally {
- // Clear lockscreen password previously set for installing private key pairs.
- changeUserCredential(null, "1234", mPrimaryUserId);
// Remove any remaining delegations.
setDelegatedScopes(DELEGATE_APP_PKG, null);
}
@@ -381,17 +376,11 @@
if (!mHasFeature) {
return;
}
- changeUserCredential("1234", null, mUserId);
- try {
- installAppAsUser(CERT_INSTALLER_APK, mUserId);
- setDelegatedScopes(CERT_INSTALLER_PKG, Arrays.asList(
- DELEGATION_CERT_INSTALL, DELEGATION_CERT_SELECTION));
- runDeviceTestsAsUser(CERT_INSTALLER_PKG, ".CertSelectionDelegateTest", mUserId);
- // Uninstall of test packages happen in tearDown.
- } finally {
- changeUserCredential(null, "1234", mUserId);
- }
+ installAppAsUser(CERT_INSTALLER_APK, mUserId);
+ setDelegatedScopes(CERT_INSTALLER_PKG, Arrays.asList(
+ DELEGATION_CERT_INSTALL, DELEGATION_CERT_SELECTION));
+ runDeviceTestsAsUser(CERT_INSTALLER_PKG, ".CertSelectionDelegateTest", mUserId);
}
public void testPermissionGrant() throws Exception {
@@ -450,7 +439,7 @@
// the same. However we're only testing the FBE case here as we need to set a device
// password during the test. This would cause FDE devices (e.g. angler) to prompt for the
// password during reboot, which we can't handle easily.
- if (!mHasFeature || !mSupportsFbe) {
+ if (!mHasFeature || !mSupportsFbe || !mHasSecureLockScreen) {
return;
}
@@ -462,6 +451,8 @@
installAppAsUser(VPN_APP_APK, mUserId);
executeDeviceTestMethod(".AlwaysOnVpnMultiStageTest", "testAlwaysOnSet");
rebootAndWaitUntilReady();
+ // Make sure profile user initialization is complete before proceeding.
+ waitForBroadcastIdle();
verifyUserCredential(testPassword, mUserId);
executeDeviceTestMethod(".AlwaysOnVpnMultiStageTest", "testAlwaysOnSetAfterReboot");
} finally {
@@ -786,25 +777,15 @@
boolean isManagedProfile = (mPrimaryUserId != mUserId);
- try {
- // Set a non-empty device lockscreen password, which is a precondition for installing
- // private key pairs.
- changeUserCredential("1234", null, mUserId);
- runDeviceTestsAsUser(DEVICE_ADMIN_PKG, ".DelegatedCertInstallerTest", mUserId);
- assertMetricsLogged(getDevice(), () -> {
+ runDeviceTestsAsUser(DEVICE_ADMIN_PKG, ".DelegatedCertInstallerTest", mUserId);
+ assertMetricsLogged(getDevice(), () -> {
runDeviceTestsAsUser(DEVICE_ADMIN_PKG, ".DelegatedCertInstallerTest",
"testInstallKeyPair", mUserId);
- }, new DevicePolicyEventWrapper.Builder(EventId.SET_CERT_INSTALLER_PACKAGE_VALUE)
- .setAdminPackageName(DEVICE_ADMIN_PKG)
- .setStrings(CERT_INSTALLER_PKG)
- .build());
- } finally {
- if (!isManagedProfile) {
- // Skip managed profile as dpm doesn't allow clear password
- changeUserCredential(null, "1234", mUserId);
- }
- }
+ }, new DevicePolicyEventWrapper.Builder(EventId.SET_CERT_INSTALLER_PACKAGE_VALUE)
+ .setAdminPackageName(DEVICE_ADMIN_PKG)
+ .setStrings(CERT_INSTALLER_PKG)
+ .build());
}
public interface DelegatedCertInstallerTestAction {
@@ -816,10 +797,6 @@
installAppAsUser(CERT_INSTALLER_APK, mUserId);
try {
- // Set a non-empty device lockscreen password, which is a precondition for installing
- // private key pairs.
- changeUserCredential("1234", null, mUserId);
-
runDeviceTestsAsUser(DEVICE_ADMIN_PKG, ".DelegatedCertInstallerHelper",
"testManualSetCertInstallerDelegate", mUserId);
@@ -827,8 +804,6 @@
} finally {
runDeviceTestsAsUser(DEVICE_ADMIN_PKG, ".DelegatedCertInstallerHelper",
"testManualClearCertInstallerDelegate", mUserId);
-
- changeUserCredential(null, "1234", mUserId);
}
}
@@ -1038,7 +1013,7 @@
}
public void testTrustAgentInfo() throws Exception {
- if (!mHasFeature) {
+ if (!mHasFeature || !mHasSecureLockScreen) {
return;
}
executeDeviceTestClass(".TrustAgentInfoTest");
@@ -1085,7 +1060,7 @@
}
public void testRequiredStrongAuthTimeout() throws Exception {
- if (!mHasFeature) {
+ if (!mHasFeature || !mHasSecureLockScreen) {
return;
}
executeDeviceTestClass(".RequiredStrongAuthTimeoutTest");
@@ -1115,7 +1090,7 @@
}
public void testResetPasswordWithToken() throws Exception {
- if (!mHasFeature) {
+ if (!mHasFeature || !mHasSecureLockScreen) {
return;
}
// If ResetPasswordWithTokenTest for managed profile is executed before device owner and
@@ -1136,7 +1111,7 @@
}
public void testGetCurrentFailedPasswordAttempts() throws Exception {
- if (!mHasFeature) {
+ if (!mHasFeature || !mHasSecureLockScreen) {
return;
}
final String testPassword = "1234";
@@ -1168,14 +1143,14 @@
}
public void testPasswordExpiration() throws Exception {
- if (!mHasFeature) {
+ if (!mHasFeature || !mHasSecureLockScreen) {
return;
}
executeDeviceTestClass(".PasswordExpirationTest");
}
public void testGetPasswordExpiration() throws Exception {
- if (!mHasFeature) {
+ if (!mHasFeature || !mHasSecureLockScreen) {
return;
}
executeDeviceTestMethod(".GetPasswordExpirationTest",
@@ -1252,16 +1227,7 @@
return;
}
- try {
- // Set a non-empty device lockscreen password, which is a precondition for installing
- // CA certificates.
- changeUserCredential("1234", null, mUserId);
- // Verify the credential immediately to unlock the work profile challenge
- verifyUserCredential("1234", mUserId);
- executeDeviceTestClass(".KeyManagementTest");
- } finally {
- changeUserCredential(null, "1234", mUserId);
- }
+ executeDeviceTestClass(".KeyManagementTest");
}
public void testInstallKeyPairLogged() throws Exception {
@@ -1269,26 +1235,16 @@
return;
}
- try {
- // Set a non-empty device lockscreen password, which is a precondition for installing
- // CA certificates.
- changeUserCredential("1234", null, mUserId);
- // Verify the credential immediately to unlock the work profile challenge
- verifyUserCredential("1234", mUserId);
- assertMetricsLogged(getDevice(), () -> {
+ assertMetricsLogged(getDevice(), () -> {
executeDeviceTestMethod(".KeyManagementTest", "testCanInstallCertChain");
- }, new DevicePolicyEventWrapper.Builder(EventId.INSTALL_KEY_PAIR_VALUE)
- .setAdminPackageName(DEVICE_ADMIN_PKG)
- .setBoolean(false)
- .build(),
+ }, new DevicePolicyEventWrapper.Builder(EventId.INSTALL_KEY_PAIR_VALUE)
+ .setAdminPackageName(DEVICE_ADMIN_PKG)
+ .setBoolean(false)
+ .build(),
new DevicePolicyEventWrapper.Builder(EventId.REMOVE_KEY_PAIR_VALUE)
- .setAdminPackageName(DEVICE_ADMIN_PKG)
- .setBoolean(false)
- .build());
-
- } finally {
- changeUserCredential(null, "1234", mUserId);
- }
+ .setAdminPackageName(DEVICE_ADMIN_PKG)
+ .setBoolean(false)
+ .build());
}
public void testGenerateKeyPairLogged() throws Exception {
@@ -1296,31 +1252,22 @@
return;
}
- try {
- // Set a non-empty device lockscreen password, which is a precondition for installing
- // CA certificates.
- changeUserCredential("1234", null, mUserId);
- // Verify the credential immediately to unlock the work profile challenge
- verifyUserCredential("1234", mUserId);
- assertMetricsLogged(getDevice(), () -> {
+ assertMetricsLogged(getDevice(), () -> {
executeDeviceTestMethod(
".KeyManagementTest", "testCanGenerateKeyPairWithKeyAttestation");
- }, new DevicePolicyEventWrapper.Builder(EventId.GENERATE_KEY_PAIR_VALUE)
- .setAdminPackageName(DEVICE_ADMIN_PKG)
- .setBoolean(false)
- .setInt(0)
- .setStrings("RSA")
- .build(),
+ }, new DevicePolicyEventWrapper.Builder(EventId.GENERATE_KEY_PAIR_VALUE)
+ .setAdminPackageName(DEVICE_ADMIN_PKG)
+ .setBoolean(false)
+ .setInt(0)
+ .setStrings("RSA")
+ .build(),
new DevicePolicyEventWrapper.Builder(EventId.GENERATE_KEY_PAIR_VALUE)
- .setAdminPackageName(DEVICE_ADMIN_PKG)
- .setBoolean(false)
- .setInt(0)
- .setStrings("EC")
- .build());
+ .setAdminPackageName(DEVICE_ADMIN_PKG)
+ .setBoolean(false)
+ .setInt(0)
+ .setStrings("EC")
+ .build());
- } finally {
- changeUserCredential(null, "1234", mUserId);
- }
}
public void testSetKeyPairCertificateLogged() throws Exception {
@@ -1328,22 +1275,12 @@
return;
}
- try {
- // Set a non-empty device lockscreen password, which is a precondition for installing
- // CA certificates.
- changeUserCredential("1234", null, mUserId);
- // Verify the credential immediately to unlock the work profile challenge
- verifyUserCredential("1234", mUserId);
- assertMetricsLogged(getDevice(), () -> {
+ assertMetricsLogged(getDevice(), () -> {
executeDeviceTestMethod(".KeyManagementTest", "testCanSetKeyPairCert");
- }, new DevicePolicyEventWrapper.Builder(EventId.SET_KEY_PAIR_CERTIFICATE_VALUE)
- .setAdminPackageName(DEVICE_ADMIN_PKG)
- .setBoolean(false)
- .build());
-
- } finally {
- changeUserCredential(null, "1234", mUserId);
- }
+ }, new DevicePolicyEventWrapper.Builder(EventId.SET_KEY_PAIR_CERTIFICATE_VALUE)
+ .setAdminPackageName(DEVICE_ADMIN_PKG)
+ .setBoolean(false)
+ .build());
}
public void testPermittedAccessibilityServices() throws Exception {
diff --git a/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/DeviceAndProfileOwnerTestApi25.java b/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/DeviceAndProfileOwnerTestApi25.java
index e4bf61c..fe3998d 100644
--- a/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/DeviceAndProfileOwnerTestApi25.java
+++ b/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/DeviceAndProfileOwnerTestApi25.java
@@ -64,7 +64,7 @@
/** Test for resetPassword for all devices. */
public void testResetPassword() throws Exception {
- if (!mHasFeature) {
+ if (!mHasFeature || !mHasSecureLockScreen) {
return;
}
executeDeviceTestMethod(RESET_PASSWORD_TEST_CLASS, "testResetPassword");
@@ -72,7 +72,7 @@
/** Additional test for resetPassword for FBE-enabled devices. */
public void testResetPasswordFbe() throws Exception {
- if (!mHasFeature || !mSupportsFbe) {
+ if (!mHasFeature || !mSupportsFbe || !mHasSecureLockScreen) {
return;
}
diff --git a/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/ManagedProfileTest.java b/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/ManagedProfileTest.java
index 555cfca..0d6225c 100644
--- a/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/ManagedProfileTest.java
+++ b/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/ManagedProfileTest.java
@@ -109,8 +109,7 @@
super.setUp();
// We need multi user to be supported in order to create a profile of the user owner.
- mHasFeature = mHasFeature && hasDeviceFeature(
- "android.software.managed_users");
+ mHasFeature = mHasFeature && hasDeviceFeature("android.software.managed_users");
mHasNfcFeature = hasDeviceFeature("android.hardware.nfc");
if (mHasFeature) {
@@ -151,6 +150,14 @@
super.tearDown();
}
+ public void testManagedProfilesSupportedWithLockScreenOnly() throws Exception {
+ if (mHasFeature) {
+ // Managed profiles should be only supported if the device supports the secure lock
+ // screen feature.
+ assertTrue(mHasSecureLockScreen);
+ }
+ }
+
public void testManagedProfileSetup() throws Exception {
if (!mHasFeature) {
return;
@@ -235,7 +242,7 @@
}
public void testLockNowWithKeyEviction() throws Exception {
- if (!mHasFeature || !mSupportsFbe) {
+ if (!mHasFeature || !mSupportsFbe || !mHasSecureLockScreen) {
return;
}
changeUserCredential("1234", null, mProfileUserId);
@@ -1225,7 +1232,7 @@
}
public void testTrustAgentInfo() throws Exception {
- if (!mHasFeature) {
+ if (!mHasFeature || !mHasSecureLockScreen) {
return;
}
// Set and get trust agent config using child dpm instance.
@@ -1300,7 +1307,7 @@
}
public void testResetPasswordWithTokenBeforeUnlock() throws Exception {
- if (!mHasFeature || !mSupportsFbe) {
+ if (!mHasFeature || !mSupportsFbe || !mHasSecureLockScreen) {
return;
}
@@ -1321,7 +1328,7 @@
* the device lock.
*/
public void testResetPasswordTokenUsableAfterClearingLock() throws Exception {
- if (!mHasFeature || !mSupportsFbe) {
+ if (!mHasFeature || !mSupportsFbe || !mHasSecureLockScreen) {
return;
}
final String devicePassword = "1234";
@@ -1348,7 +1355,7 @@
}
public void testIsUsingUnifiedPassword() throws Exception {
- if (!mHasFeature) {
+ if (!mHasFeature || !mHasSecureLockScreen) {
return;
}
@@ -1361,7 +1368,7 @@
}
public void testUnlockWorkProfile_deviceWidePassword() throws Exception {
- if (!mHasFeature || !mSupportsFbe) {
+ if (!mHasFeature || !mSupportsFbe || !mHasSecureLockScreen) {
return;
}
String password = "0000";
@@ -1383,7 +1390,7 @@
}
public void testRebootDevice_unifiedPassword() throws Exception {
- if (!mHasFeature) {
+ if (!mHasFeature || !mHasSecureLockScreen) {
return;
}
// Waiting before rebooting prevents flakiness.
@@ -1404,7 +1411,7 @@
}
public void testRebootDevice_separatePasswords() throws Exception {
- if (!mHasFeature) {
+ if (!mHasFeature || !mHasSecureLockScreen) {
return;
}
// Waiting before rebooting prevents flakiness.
@@ -1438,12 +1445,7 @@
assertMetricsLogged(getDevice(), () -> {
runDeviceTestsAsUser(MANAGED_PROFILE_PKG, ".CrossProfileCalendarTest",
"testCrossProfileCalendarPackage", mProfileUserId);
- }, new DevicePolicyEventWrapper.Builder(EventId.ADD_CROSS_PROFILE_CALENDAR_PACKAGE_VALUE)
- .setAdminPackageName(MANAGED_PROFILE_PKG)
- .setStrings(MANAGED_PROFILE_PKG)
- .build(),
- new DevicePolicyEventWrapper
- .Builder(EventId.REMOVE_CROSS_PROFILE_CALENDAR_PACKAGE_VALUE)
+ }, new DevicePolicyEventWrapper.Builder(EventId.SET_CROSS_PROFILE_CALENDAR_PACKAGES_VALUE)
.setAdminPackageName(MANAGED_PROFILE_PKG)
.setStrings(MANAGED_PROFILE_PKG)
.build());
@@ -1454,6 +1456,7 @@
return;
}
runCrossProfileCalendarTestsWhenWhitelistedAndEnabled();
+ runCrossProfileCalendarTestsWhenAllPackagesWhitelisted();
runCrossProfileCalendarTestsWhenDisabled();
runCrossProfileCalendarTestsWhenNotWhitelisted();
}
@@ -1492,7 +1495,50 @@
} finally {
// Cleanup.
runDeviceTestsAsUser(MANAGED_PROFILE_PKG, ".CrossProfileCalendarTest",
- "testRemoveManagedProfilePackageFromWhitelist", mProfileUserId);
+ "testCleanupWhitelist", mProfileUserId);
+ runDeviceTestsAsUser(MANAGED_PROFILE_PKG, ".CrossProfileCalendarTest",
+ "testCleanupTestCalendarDataForWorkProfile", mProfileUserId);
+ runDeviceTestsAsUser(MANAGED_PROFILE_PKG, ".CrossProfileCalendarTest",
+ "testDisableCrossProfileCalendarSettings", mProfileUserId);
+ }
+ }
+
+ private void runCrossProfileCalendarTestsWhenAllPackagesWhitelisted() throws Exception {
+ try {
+ // Setup. Allow all packages to access cross-profile calendar APIs by setting
+ // the whitelist to null, enable cross-profile calendar in settings,
+ // and insert test data into calendar provider.
+ // All setups should be done in managed profile.
+ runDeviceTestsAsUser(MANAGED_PROFILE_PKG, ".CrossProfileCalendarTest",
+ "testWhitelistAllPackages", mProfileUserId);
+ runDeviceTestsAsUser(MANAGED_PROFILE_PKG, ".CrossProfileCalendarTest",
+ "testAddTestCalendarDataForWorkProfile", mProfileUserId);
+ runDeviceTestsAsUser(MANAGED_PROFILE_PKG, ".CrossProfileCalendarTest",
+ "testEnableCrossProfileCalendarSettings", mProfileUserId);
+
+ // Testing.
+ runDeviceTestsAsUser(MANAGED_PROFILE_PKG, ".CrossProfileCalendarTest",
+ "testPrimaryProfile_getCorrectWorkCalendarsWhenEnabled", mParentUserId);
+ runDeviceTestsAsUser(MANAGED_PROFILE_PKG, ".CrossProfileCalendarTest",
+ "testPrimaryProfile_getCorrectWorkEventsWhenEnabled", mParentUserId);
+ runDeviceTestsAsUser(MANAGED_PROFILE_PKG, ".CrossProfileCalendarTest",
+ "testPrimaryProfile_getCorrectWorkInstancesWhenEnabled", mParentUserId);
+ runDeviceTestsAsUser(MANAGED_PROFILE_PKG, ".CrossProfileCalendarTest",
+ "testPrimaryProfile_getCorrectWorkInstancesByDayWhenEnabled", mParentUserId);
+ runDeviceTestsAsUser(MANAGED_PROFILE_PKG, ".CrossProfileCalendarTest",
+ "testPrimaryProfile_canAccessWorkInstancesSearch1", mParentUserId);
+ runDeviceTestsAsUser(MANAGED_PROFILE_PKG, ".CrossProfileCalendarTest",
+ "testPrimaryProfile_canAccessWorkInstancesSearch2", mParentUserId);
+ runDeviceTestsAsUser(MANAGED_PROFILE_PKG, ".CrossProfileCalendarTest",
+ "testPrimaryProfile_canAccessWorkInstancesSearchByDay", mParentUserId);
+ runDeviceTestsAsUser(MANAGED_PROFILE_PKG, ".CrossProfileCalendarTest",
+ "testPrimaryProfile_getExceptionWhenQueryNonWhitelistedColumns", mParentUserId);
+ runDeviceTestsAsUser(MANAGED_PROFILE_PKG, ".CrossProfileCalendarTest",
+ "testViewEventCrossProfile_intentReceivedWhenWhitelisted", mParentUserId);
+ } finally {
+ // Cleanup.
+ runDeviceTestsAsUser(MANAGED_PROFILE_PKG, ".CrossProfileCalendarTest",
+ "testCleanupWhitelist", mProfileUserId);
runDeviceTestsAsUser(MANAGED_PROFILE_PKG, ".CrossProfileCalendarTest",
"testCleanupTestCalendarDataForWorkProfile", mProfileUserId);
runDeviceTestsAsUser(MANAGED_PROFILE_PKG, ".CrossProfileCalendarTest",
@@ -1523,7 +1569,7 @@
} finally {
// Cleanup.
runDeviceTestsAsUser(MANAGED_PROFILE_PKG, ".CrossProfileCalendarTest",
- "testRemoveManagedProfilePackageFromWhitelist", mProfileUserId);
+ "testCleanupWhitelist", mProfileUserId);
runDeviceTestsAsUser(MANAGED_PROFILE_PKG, ".CrossProfileCalendarTest",
"testCleanupTestCalendarDataForWorkProfile", mProfileUserId);
}
@@ -1559,7 +1605,7 @@
}
public void testCreateSeparateChallengeChangedLogged() throws Exception {
- if (!mHasFeature) {
+ if (!mHasFeature || !mHasSecureLockScreen) {
return;
}
assertMetricsLogged(getDevice(), () -> {
diff --git a/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/MixedManagedProfileOwnerTest.java b/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/MixedManagedProfileOwnerTest.java
index 31d03fd..0417844 100644
--- a/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/MixedManagedProfileOwnerTest.java
+++ b/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/MixedManagedProfileOwnerTest.java
@@ -159,7 +159,7 @@
@Override
public void testResetPasswordWithToken() throws Exception {
- if (!mHasFeature) {
+ if (!mHasFeature || !mHasSecureLockScreen) {
return;
}
// Execute the test method that's guaranteed to succeed. See also test in base class
@@ -209,22 +209,15 @@
return;
}
- try {
- // Set a non-empty device lockscreen password, which is a precondition for interacting
- // with KeyStore.
- changeUserCredential("1234", null, mUserId);
- // Test that Device ID attestation for the profile owner does not work without grant.
- runDeviceTestsAsUser(DEVICE_ADMIN_PKG, ".DeviceIdAttestationTest",
- "testFailsWithoutProfileOwnerIdsGrant", mUserId);
+ // Test that Device ID attestation for the profile owner does not work without grant.
+ runDeviceTestsAsUser(DEVICE_ADMIN_PKG, ".DeviceIdAttestationTest",
+ "testFailsWithoutProfileOwnerIdsGrant", mUserId);
- // Test that Device ID attestation for the profile owner works with a grant.
- grantProfileOwnerDeviceIdsAccess();
+ // Test that Device ID attestation for the profile owner works with a grant.
+ grantProfileOwnerDeviceIdsAccess();
- runDeviceTestsAsUser(DEVICE_ADMIN_PKG, ".DeviceIdAttestationTest",
- "testSucceedsWithProfileOwnerIdsGrant", mUserId);
- } finally {
- changeUserCredential(null, "1234", mUserId);
- }
+ runDeviceTestsAsUser(DEVICE_ADMIN_PKG, ".DeviceIdAttestationTest",
+ "testSucceedsWithProfileOwnerIdsGrant", mUserId);
}
}
diff --git a/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/MixedManagedProfileOwnerTestApi25.java b/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/MixedManagedProfileOwnerTestApi25.java
index fd5b2bf..47b3539 100644
--- a/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/MixedManagedProfileOwnerTestApi25.java
+++ b/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/MixedManagedProfileOwnerTestApi25.java
@@ -62,7 +62,7 @@
*/
@Override
public void testResetPassword() throws Exception {
- if (!mHasFeature) {
+ if (!mHasFeature || !mHasSecureLockScreen) {
return;
}
@@ -75,7 +75,7 @@
*/
@Override
public void testResetPasswordFbe() throws Exception {
- if (!mHasFeature || !mSupportsFbe) {
+ if (!mHasFeature || !mSupportsFbe || !mHasSecureLockScreen) {
return;
}
diff --git a/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/PasswordComplexityTest.java b/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/PasswordComplexityTest.java
index 9be917e..958009f 100644
--- a/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/PasswordComplexityTest.java
+++ b/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/PasswordComplexityTest.java
@@ -11,6 +11,10 @@
protected void setUp() throws Exception {
super.setUp();
+ if (!mHasSecureLockScreen) {
+ return;
+ }
+
if (!getDevice().executeShellCommand("cmd lock_settings verify")
.startsWith("Lock credential verified successfully")) {
fail("Please remove the device screen lock before running this test");
@@ -21,12 +25,17 @@
@Override
protected void tearDown() throws Exception {
- getDevice().uninstallPackage(PKG);
+ if (mHasSecureLockScreen) {
+ getDevice().uninstallPackage(PKG);
+ }
super.tearDown();
}
public void testGetPasswordComplexity() throws Exception {
+ if (!mHasSecureLockScreen) {
+ return;
+ }
runDeviceTestsAsUser(PKG, CLS, mPrimaryUserId);
}
}
diff --git a/hostsidetests/dexmetadata/host/res/CtsDexMetadataSplitAppFeatureAWithVdex.apk b/hostsidetests/dexmetadata/host/res/CtsDexMetadataSplitAppFeatureAWithVdex.apk
new file mode 100644
index 0000000..875feb5
--- /dev/null
+++ b/hostsidetests/dexmetadata/host/res/CtsDexMetadataSplitAppFeatureAWithVdex.apk
Binary files differ
diff --git a/hostsidetests/dexmetadata/host/res/CtsDexMetadataSplitAppFeatureAWithVdex.dm b/hostsidetests/dexmetadata/host/res/CtsDexMetadataSplitAppFeatureAWithVdex.dm
new file mode 100644
index 0000000..bc79e55
--- /dev/null
+++ b/hostsidetests/dexmetadata/host/res/CtsDexMetadataSplitAppFeatureAWithVdex.dm
Binary files differ
diff --git a/hostsidetests/dexmetadata/host/res/CtsDexMetadataSplitAppWithVdex.apk b/hostsidetests/dexmetadata/host/res/CtsDexMetadataSplitAppWithVdex.apk
new file mode 100644
index 0000000..6760973
--- /dev/null
+++ b/hostsidetests/dexmetadata/host/res/CtsDexMetadataSplitAppWithVdex.apk
Binary files differ
diff --git a/hostsidetests/dexmetadata/host/res/CtsDexMetadataSplitAppWithVdex.dm b/hostsidetests/dexmetadata/host/res/CtsDexMetadataSplitAppWithVdex.dm
new file mode 100644
index 0000000..4471f69
--- /dev/null
+++ b/hostsidetests/dexmetadata/host/res/CtsDexMetadataSplitAppWithVdex.dm
Binary files differ
diff --git a/hostsidetests/dexmetadata/host/src/com/android/cts/dexmetadata/InstallDexMetadataHostTest.java b/hostsidetests/dexmetadata/host/src/com/android/cts/dexmetadata/InstallDexMetadataHostTest.java
index 766034a..15bb39b 100644
--- a/hostsidetests/dexmetadata/host/src/com/android/cts/dexmetadata/InstallDexMetadataHostTest.java
+++ b/hostsidetests/dexmetadata/host/src/com/android/cts/dexmetadata/InstallDexMetadataHostTest.java
@@ -13,6 +13,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
+
package com.android.cts.dexmetadata;
import static org.junit.Assert.assertArrayEquals;
@@ -24,9 +25,8 @@
import com.android.tradefed.testtype.DeviceJUnit4ClassRunner;
import com.android.tradefed.testtype.junit4.BaseHostJUnit4Test;
import com.android.tradefed.util.FileUtil;
-
-import java.io.ByteArrayOutputStream;
import java.io.BufferedOutputStream;
+import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
@@ -37,7 +37,6 @@
import java.nio.file.Paths;
import java.util.zip.ZipEntry;
import java.util.zip.ZipInputStream;
-
import org.junit.After;
import org.junit.Assume;
import org.junit.Before;
@@ -56,15 +55,25 @@
private static final String APK_BASE = "CtsDexMetadataSplitApp.apk";
private static final String APK_FEATURE_A = "CtsDexMetadataSplitAppFeatureA.apk";
+ private static final String APK_BASE_WITH_VDEX = "CtsDexMetadataSplitAppWithVdex.apk";
+ private static final String APK_FEATURE_A_WITH_VDEX
+ = "CtsDexMetadataSplitAppFeatureAWithVdex.apk";
private static final String DM_BASE = "CtsDexMetadataSplitApp.dm";
private static final String DM_FEATURE_A = "CtsDexMetadataSplitAppFeatureA.dm";
+ private static final String DM_BASE_WITH_VDEX = "CtsDexMetadataSplitAppWithVdex.dm";
+ private static final String DM_FEATURE_A_WITH_VDEX
+ = "CtsDexMetadataSplitAppFeatureAWithVdex.dm";
private File mTmpDir;
private File mApkBaseFile = null;
private File mApkFeatureAFile = null;
+ private File mApkBaseFileWithVdex = null;
+ private File mApkFeatureAFileWithVdex = null;
private File mDmBaseFile = null;
private File mDmFeatureAFile = null;
+ private File mDmBaseFileWithVdex = null;
+ private File mDmFeatureAFileWithVdex = null;
private boolean mShouldRunTests;
/**
@@ -83,8 +92,12 @@
mTmpDir = FileUtil.createTempDir("InstallDexMetadataHostTest");
mApkBaseFile = extractResource(APK_BASE, mTmpDir);
mApkFeatureAFile = extractResource(APK_FEATURE_A, mTmpDir);
+ mApkBaseFileWithVdex = extractResource(APK_BASE_WITH_VDEX, mTmpDir);
+ mApkFeatureAFileWithVdex = extractResource(APK_FEATURE_A_WITH_VDEX, mTmpDir);
mDmBaseFile = extractResource(DM_BASE, mTmpDir);
mDmFeatureAFile = extractResource(DM_FEATURE_A, mTmpDir);
+ mDmBaseFileWithVdex = extractResource(DM_BASE_WITH_VDEX, mTmpDir);
+ mDmFeatureAFileWithVdex = extractResource(DM_FEATURE_A_WITH_VDEX, mTmpDir);
}
}
@@ -204,6 +217,29 @@
assertArrayEquals(expectedProfileBytes, snapshotProfileBytes);
}
+ /**
+ * Verify .dm installation for stand-alone base (no splits) with vdex file.
+ */
+ @Test
+ public void testInstallDmForBaseWithVdex() throws Exception {
+ new InstallMultiple().addApk(mApkBaseFileWithVdex).addDm(mDmBaseFileWithVdex).run();
+ assertNotNull(getDevice().getAppPackageInfo(INSTALL_PACKAGE));
+
+ assertTrue(runDeviceTests(TEST_PACKAGE, TEST_CLASS, "testDmForBase"));
+ }
+
+ /**
+ * Verify .dm installation for base and splits with vdex files.
+ */
+ @Test
+ public void testInstallDmForBaseAndSplitWithVdex() throws Exception {
+ new InstallMultiple().addApk(mApkBaseFileWithVdex).addDm(mDmBaseFileWithVdex)
+ .addApk(mApkFeatureAFileWithVdex).addDm(mDmFeatureAFileWithVdex).run();
+ assertNotNull(getDevice().getAppPackageInfo(INSTALL_PACKAGE));
+
+ assertTrue(runDeviceTests(TEST_PACKAGE, TEST_CLASS, "testDmForBaseAndSplit"));
+ }
+
/** Verify that the use of profiles is enabled on the device. */
private void assumeProfilesAreEnabled() throws Exception {
String useProfiles = getDevice().executeShellCommand(
diff --git a/hostsidetests/gputools/apps/AndroidManifest.xml b/hostsidetests/gputools/apps/AndroidManifest.xml
index de8130f..fab44c3 100755
--- a/hostsidetests/gputools/apps/AndroidManifest.xml
+++ b/hostsidetests/gputools/apps/AndroidManifest.xml
@@ -18,7 +18,7 @@
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="android.rootlessgpudebug.app">>
- <application>
+ <application android:extractNativeLibs="true" >
<activity android:name=".RootlessGpuDebugDeviceActivity" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
diff --git a/hostsidetests/gputools/layers/AndroidManifest.xml b/hostsidetests/gputools/layers/AndroidManifest.xml
index 957b047..2b187ad 100755
--- a/hostsidetests/gputools/layers/AndroidManifest.xml
+++ b/hostsidetests/gputools/layers/AndroidManifest.xml
@@ -18,7 +18,8 @@
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="android.rootlessgpudebug.LAYERS.app">
- <application android:debuggable="false" android:hasCode="false">
+ <application android:extractNativeLibs="true" android:debuggable="false"
+ android:hasCode="false">
</application>
</manifest>
diff --git a/hostsidetests/jvmti/base/host/src/android/jvmti/cts/JvmtiHostTest.java b/hostsidetests/jvmti/base/host/src/android/jvmti/cts/JvmtiHostTest.java
index 68e9aab..7b04ff91 100644
--- a/hostsidetests/jvmti/base/host/src/android/jvmti/cts/JvmtiHostTest.java
+++ b/hostsidetests/jvmti/base/host/src/android/jvmti/cts/JvmtiHostTest.java
@@ -116,22 +116,24 @@
device.setSetting("global", "hidden_api_policy", "1");
}
- RemoteAndroidTestRunner runner = new RemoteAndroidTestRunner(mTestPackageName, RUNNER,
- device.getIDevice());
- // set a max deadline limit to avoid hanging forever
- runner.setMaxTimeToOutputResponse(2, TimeUnit.MINUTES);
+ try {
+ RemoteAndroidTestRunner runner = new RemoteAndroidTestRunner(mTestPackageName, RUNNER,
+ device.getIDevice());
+ // set a max deadline limit to avoid hanging forever
+ runner.setMaxTimeToOutputResponse(2, TimeUnit.MINUTES);
- AttachAgent aa = new AttachAgent(device, mTestPackageName, mTestApk);
- aa.prepare();
- TestResults tr = new TestResults(aa);
+ AttachAgent aa = new AttachAgent(device, mTestPackageName, mTestApk);
+ aa.prepare();
+ TestResults tr = new TestResults(aa);
- device.runInstrumentationTests(runner, tr);
+ device.runInstrumentationTests(runner, tr);
- assertTrue(tr.getErrors(), tr.hasStarted());
- assertFalse(tr.getErrors(), tr.hasFailed());
-
- if (disable_hidden_api) {
- device.setSetting("global", "hidden_api_policy", old_hiddenapi_setting);
+ assertTrue(tr.getErrors(), tr.hasStarted());
+ assertFalse(tr.getErrors(), tr.hasFailed());
+ } finally {
+ if (disable_hidden_api) {
+ device.setSetting("global", "hidden_api_policy", old_hiddenapi_setting);
+ }
}
}
diff --git a/hostsidetests/net/app/src/com/android/cts/net/hostside/MyVpnService.java b/hostsidetests/net/app/src/com/android/cts/net/hostside/MyVpnService.java
index 90a3ce4..c61b7d3 100644
--- a/hostsidetests/net/app/src/com/android/cts/net/hostside/MyVpnService.java
+++ b/hostsidetests/net/app/src/com/android/cts/net/hostside/MyVpnService.java
@@ -17,6 +17,7 @@
package com.android.cts.net.hostside;
import android.content.Intent;
+import android.net.ProxyInfo;
import android.net.VpnService;
import android.os.ParcelFileDescriptor;
import android.content.pm.PackageManager.NameNotFoundException;
@@ -113,6 +114,8 @@
}
}
+ ProxyInfo vpnProxy = intent.getParcelableExtra(packageName + ".httpProxy");
+ builder.setHttpProxy(vpnProxy);
builder.setMtu(MTU);
builder.setBlocking(true);
builder.setSession("MyVpnService");
diff --git a/hostsidetests/net/app/src/com/android/cts/net/hostside/VpnTest.java b/hostsidetests/net/app/src/com/android/cts/net/hostside/VpnTest.java
index 48f0afb..75fc6f1 100755
--- a/hostsidetests/net/app/src/com/android/cts/net/hostside/VpnTest.java
+++ b/hostsidetests/net/app/src/com/android/cts/net/hostside/VpnTest.java
@@ -19,6 +19,7 @@
import static android.os.Process.INVALID_UID;
import static android.system.OsConstants.*;
+import android.content.Context;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.net.ConnectivityManager;
@@ -27,6 +28,8 @@
import android.net.Network;
import android.net.NetworkCapabilities;
import android.net.NetworkRequest;
+import android.net.Proxy;
+import android.net.ProxyInfo;
import android.net.VpnService;
import android.os.ParcelFileDescriptor;
import android.os.Process;
@@ -45,6 +48,7 @@
import android.text.TextUtils;
import android.util.Log;
+import com.android.compatibility.common.util.BlockingBroadcastReceiver;
import com.android.cts.net.hostside.IRemoteSocketFactory;
import java.io.BufferedReader;
@@ -197,9 +201,8 @@
}
private void startVpn(
- String[] addresses, String[] routes,
- String allowedApplications, String disallowedApplications) throws Exception {
-
+ String[] addresses, String[] routes, String allowedApplications,
+ String disallowedApplications, ProxyInfo proxyInfo) throws Exception {
prepareVpn();
// Register a callback so we will be notified when our VPN comes up.
@@ -225,7 +228,8 @@
.putExtra(mPackageName + ".addresses", TextUtils.join(",", addresses))
.putExtra(mPackageName + ".routes", TextUtils.join(",", routes))
.putExtra(mPackageName + ".allowedapplications", allowedApplications)
- .putExtra(mPackageName + ".disallowedapplications", disallowedApplications);
+ .putExtra(mPackageName + ".disallowedapplications", disallowedApplications)
+ .putExtra(mPackageName + ".httpProxy", proxyInfo);
mActivity.startService(intent);
synchronized (mLock) {
if (mNetwork == null) {
@@ -573,7 +577,7 @@
startVpn(new String[] {"192.0.2.2/32", "2001:db8:1:2::ffe/128"},
new String[] {"0.0.0.0/0", "::/0"},
- "", "");
+ "", "", null);
assertSocketClosed(fd, TEST_HOST);
@@ -589,7 +593,7 @@
String allowedApps = mRemoteSocketFactoryClient.getPackageName() + "," + mPackageName;
startVpn(new String[] {"192.0.2.2/32", "2001:db8:1:2::ffe/128"},
new String[] {"192.0.2.0/24", "2001:db8::/32"},
- allowedApps, "");
+ allowedApps, "", null);
assertSocketClosed(fd, TEST_HOST);
@@ -611,7 +615,7 @@
Log.i(TAG, "Append shell app to disallowedApps: " + disallowedApps);
startVpn(new String[] {"192.0.2.2/32", "2001:db8:1:2::ffe/128"},
new String[] {"192.0.2.0/24", "2001:db8::/32"},
- "", disallowedApps);
+ "", disallowedApps, null);
assertSocketStillOpen(localFd, TEST_HOST);
assertSocketStillOpen(remoteFd, TEST_HOST);
@@ -620,7 +624,6 @@
}
public void testGetConnectionOwnerUidSecurity() throws Exception {
-
if (!supportedHardware()) return;
DatagramSocket s;
@@ -637,4 +640,155 @@
return;
}
}
+
+ public void testSetProxy() throws Exception {
+ if (!supportedHardware()) return;
+ ProxyInfo initialProxy = mCM.getDefaultProxy();
+ // Receiver for the proxy change broadcast.
+ BlockingBroadcastReceiver proxyBroadcastReceiver = new ProxyChangeBroadcastReceiver();
+ proxyBroadcastReceiver.register();
+
+ String allowedApps = mPackageName;
+ ProxyInfo testProxyInfo = ProxyInfo.buildDirectProxy("10.0.0.1", 8888);
+ startVpn(new String[] {"192.0.2.2/32", "2001:db8:1:2::ffe/128"},
+ new String[] {"0.0.0.0/0", "::/0"}, allowedApps, "",
+ testProxyInfo);
+
+ // Check that the proxy change broadcast is received
+ try {
+ assertNotNull("No proxy change was broadcast when VPN is connected.",
+ proxyBroadcastReceiver.awaitForBroadcast());
+ } finally {
+ proxyBroadcastReceiver.unregisterQuietly();
+ }
+
+ // Proxy is set correctly in network and in link properties.
+ assertNetworkHasExpectedProxy(testProxyInfo, mNetwork);
+ assertDefaultProxy(testProxyInfo);
+
+ proxyBroadcastReceiver = new ProxyChangeBroadcastReceiver();
+ proxyBroadcastReceiver.register();
+ stopVpn();
+ try {
+ assertNotNull("No proxy change was broadcast when VPN was disconnected.",
+ proxyBroadcastReceiver.awaitForBroadcast());
+ } finally {
+ proxyBroadcastReceiver.unregisterQuietly();
+ }
+
+ // After disconnecting from VPN, the proxy settings are the ones of the initial network.
+ assertDefaultProxy(initialProxy);
+ }
+
+ public void testSetProxyDisallowedApps() throws Exception {
+ if (!supportedHardware()) return;
+ ProxyInfo initialProxy = mCM.getDefaultProxy();
+
+ // If adb TCP port opened, this test may running by adb over TCP.
+ // Add com.android.shell appllication into blacklist to exclude adb socket for VPN test,
+ // see b/119382723.
+ // Note: The test don't support running adb over network for root device
+ String disallowedApps = mPackageName + ",com.android.shell";
+ ProxyInfo testProxyInfo = ProxyInfo.buildDirectProxy("10.0.0.1", 8888);
+ startVpn(new String[] {"192.0.2.2/32", "2001:db8:1:2::ffe/128"},
+ new String[] {"0.0.0.0/0", "::/0"}, "", disallowedApps,
+ testProxyInfo);
+
+ // The disallowed app does has the proxy configs of the default network.
+ assertNetworkHasExpectedProxy(initialProxy, mCM.getActiveNetwork());
+ assertDefaultProxy(initialProxy);
+ }
+
+ public void testNoProxy() throws Exception {
+ if (!supportedHardware()) return;
+ ProxyInfo initialProxy = mCM.getDefaultProxy();
+ BlockingBroadcastReceiver proxyBroadcastReceiver = new ProxyChangeBroadcastReceiver();
+ proxyBroadcastReceiver.register();
+ String allowedApps = mPackageName;
+ startVpn(new String[] {"192.0.2.2/32", "2001:db8:1:2::ffe/128"},
+ new String[] {"0.0.0.0/0", "::/0"}, allowedApps, "", null);
+
+ try {
+ assertNotNull("No proxy change was broadcast.",
+ proxyBroadcastReceiver.awaitForBroadcast());
+ } finally {
+ proxyBroadcastReceiver.unregisterQuietly();
+ }
+
+ // The VPN network has no proxy set.
+ assertNetworkHasExpectedProxy(null, mNetwork);
+
+ proxyBroadcastReceiver = new ProxyChangeBroadcastReceiver();
+ proxyBroadcastReceiver.register();
+ stopVpn();
+ try {
+ assertNotNull("No proxy change was broadcast.",
+ proxyBroadcastReceiver.awaitForBroadcast());
+ } finally {
+ proxyBroadcastReceiver.unregisterQuietly();
+ }
+ // After disconnecting from VPN, the proxy settings are the ones of the initial network.
+ assertDefaultProxy(initialProxy);
+ assertNetworkHasExpectedProxy(initialProxy, mCM.getActiveNetwork());
+ }
+
+ public void testBindToNetworkWithProxy() throws Exception {
+ if (!supportedHardware()) return;
+ String allowedApps = mPackageName;
+ Network initialNetwork = mCM.getActiveNetwork();
+ ProxyInfo initialProxy = mCM.getDefaultProxy();
+ ProxyInfo testProxyInfo = ProxyInfo.buildDirectProxy("10.0.0.1", 8888);
+ // Receiver for the proxy change broadcast.
+ BlockingBroadcastReceiver proxyBroadcastReceiver = new ProxyChangeBroadcastReceiver();
+ proxyBroadcastReceiver.register();
+ startVpn(new String[] {"192.0.2.2/32", "2001:db8:1:2::ffe/128"},
+ new String[] {"0.0.0.0/0", "::/0"}, allowedApps, "",
+ testProxyInfo);
+
+ assertDefaultProxy(testProxyInfo);
+ mCM.bindProcessToNetwork(initialNetwork);
+ try {
+ assertNotNull("No proxy change was broadcast.",
+ proxyBroadcastReceiver.awaitForBroadcast());
+ } finally {
+ proxyBroadcastReceiver.unregisterQuietly();
+ }
+ assertDefaultProxy(initialProxy);
+ }
+
+ private void assertDefaultProxy(ProxyInfo expected) {
+ assertEquals("Incorrect proxy config.", expected, mCM.getDefaultProxy());
+ String expectedHost = expected == null ? null : expected.getHost();
+ String expectedPort = expected == null ? null : String.valueOf(expected.getPort());
+ assertEquals("Incorrect proxy host system property.", expectedHost,
+ System.getProperty("http.proxyHost"));
+ assertEquals("Incorrect proxy port system property.", expectedPort,
+ System.getProperty("http.proxyPort"));
+ }
+
+ private void assertNetworkHasExpectedProxy(ProxyInfo expected, Network network) {
+ LinkProperties lp = mCM.getLinkProperties(network);
+ assertNotNull("The network link properties object is null.", lp);
+ assertEquals("Incorrect proxy config.", expected, lp.getHttpProxy());
+
+ assertEquals(expected, mCM.getProxyForNetwork(network));
+ }
+
+ class ProxyChangeBroadcastReceiver extends BlockingBroadcastReceiver {
+ private boolean received;
+
+ public ProxyChangeBroadcastReceiver() {
+ super(VpnTest.this.getInstrumentation().getContext(), Proxy.PROXY_CHANGE_ACTION);
+ received = false;
+ }
+
+ @Override
+ public void onReceive(Context context, Intent intent) {
+ if (!received) {
+ // Do not call onReceive() more than once.
+ super.onReceive(context, intent);
+ }
+ received = true;
+ }
+ }
}
diff --git a/hostsidetests/net/src/com/android/cts/net/HostsideVpnTests.java b/hostsidetests/net/src/com/android/cts/net/HostsideVpnTests.java
index 853668c..e34ee89 100644
--- a/hostsidetests/net/src/com/android/cts/net/HostsideVpnTests.java
+++ b/hostsidetests/net/src/com/android/cts/net/HostsideVpnTests.java
@@ -48,4 +48,20 @@
public void testGetConnectionOwnerUidSecurity() throws Exception {
runDeviceTests(TEST_PKG, TEST_PKG + ".VpnTest", "testGetConnectionOwnerUidSecurity");
}
+
+ public void testSetProxy() throws Exception {
+ runDeviceTests(TEST_PKG, TEST_PKG + ".VpnTest", "testSetProxy");
+ }
+
+ public void testSetProxyDisallowedApps() throws Exception {
+ runDeviceTests(TEST_PKG, TEST_PKG + ".VpnTest", "testSetProxyDisallowedApps");
+ }
+
+ public void testNoProxy() throws Exception {
+ runDeviceTests(TEST_PKG, TEST_PKG + ".VpnTest", "testNoProxy");
+ }
+
+ public void testBindToNetworkWithProxy() throws Exception {
+ runDeviceTests(TEST_PKG, TEST_PKG + ".VpnTest", "testBindToNetworkWithProxy");
+ }
}
diff --git a/hostsidetests/seccomp/app/Android.mk b/hostsidetests/seccomp/app/Android.mk
index 041d760..cf15eff 100644
--- a/hostsidetests/seccomp/app/Android.mk
+++ b/hostsidetests/seccomp/app/Android.mk
@@ -47,7 +47,7 @@
LOCAL_PACKAGE_NAME := CtsSeccompDeviceApp
-LOCAL_SDK_VERSION := current
+LOCAL_SDK_VERSION := test_current
include $(BUILD_PACKAGE)
diff --git a/hostsidetests/seccomp/app/AndroidManifest.xml b/hostsidetests/seccomp/app/AndroidManifest.xml
index b8e97e3..538149d 100644
--- a/hostsidetests/seccomp/app/AndroidManifest.xml
+++ b/hostsidetests/seccomp/app/AndroidManifest.xml
@@ -20,6 +20,12 @@
<application>
<uses-library android:name="android.test.runner" />
+ <service
+ android:name=".IsolatedService"
+ android:isolatedProcess="true"
+ android:exported="false"
+ android:useAppZygote="true">
+ </service>
</application>
<instrumentation
diff --git a/hostsidetests/seccomp/app/assets/syscalls_blocked.json b/hostsidetests/seccomp/app/assets/syscalls_blocked.json
index 441c8da..a53319b 100644
--- a/hostsidetests/seccomp/app/assets/syscalls_blocked.json
+++ b/hostsidetests/seccomp/app/assets/syscalls_blocked.json
@@ -13,8 +13,22 @@
"mount": 21,
"reboot": 88,
"setdomainname": 121,
+ "setfsgid": 139,
+ "setfsuid": 138,
+ "setgid": 46,
+ "setgid32": 214,
+ "setgroups": 81,
+ "setgroups32": 206,
"sethostname": 74,
+ "setregid": 71,
+ "setregid32": 204,
+ "setresgid": 170,
+ "setresgid32": 210,
+ "setreuid": 70,
+ "setreuid32": 203,
"settimeofday": 79,
+ "setuid": 23,
+ "setuid32": 213,
"swapoff": 115,
"swapon": 87,
"syslog": 103,
@@ -33,8 +47,16 @@
"mount": 40,
"reboot": 142,
"setdomainname": 162,
+ "setfsgid": 152,
+ "setfsuid": 151,
+ "setgid": 144,
+ "setgroups": 159,
"sethostname": 161,
+ "setregid": 143,
+ "setresgid": 149,
+ "setreuid": 145,
"settimeofday": 170,
+ "setuid": 146,
"swapoff": 225,
"swapon": 224,
"syslog": 116,
@@ -53,8 +75,16 @@
"mount": 4021,
"reboot": 4088,
"setdomainname": 4121,
+ "setfsgid": 4139,
+ "setfsuid": 4138,
+ "setgid": 4046,
+ "setgroups": 4081,
"sethostname": 4074,
+ "setregid": 4071,
+ "setresgid": 4190,
+ "setreuid": 4070,
"settimeofday": 4079,
+ "setuid": 4023,
"swapoff": 4115,
"swapon": 4087,
"syslog": 4103,
@@ -73,8 +103,16 @@
"mount": 5160,
"reboot": 5164,
"setdomainname": 5166,
+ "setfsgid": 5121,
+ "setfsuid": 5120,
+ "setgid": 5104,
+ "setgroups": 5114,
"sethostname": 5165,
+ "setregid": 5112,
+ "setresgid": 5117,
+ "setreuid": 5111,
"settimeofday": 5159,
+ "setuid": 5103,
"swapoff": 5163,
"swapon": 5162,
"syslog": 5101,
@@ -93,8 +131,22 @@
"mount": 21,
"reboot": 88,
"setdomainname": 121,
+ "setfsgid": 139,
+ "setfsuid": 138,
+ "setgid": 46,
+ "setgid32": 214,
+ "setgroups": 81,
+ "setgroups32": 206,
"sethostname": 74,
+ "setregid": 71,
+ "setregid32": 204,
+ "setresgid": 170,
+ "setresgid32": 210,
+ "setreuid": 70,
+ "setreuid32": 203,
"settimeofday": 79,
+ "setuid": 23,
+ "setuid32": 213,
"swapoff": 115,
"swapon": 87,
"syslog": 103,
@@ -113,8 +165,16 @@
"mount": 165,
"reboot": 169,
"setdomainname": 171,
+ "setfsgid": 123,
+ "setfsuid": 122,
+ "setgid": 106,
+ "setgroups": 116,
"sethostname": 170,
+ "setregid": 114,
+ "setresgid": 119,
+ "setreuid": 113,
"settimeofday": 164,
+ "setuid": 105,
"swapoff": 168,
"swapon": 167,
"syslog": 103,
diff --git a/hostsidetests/seccomp/app/gen_blacklist.py b/hostsidetests/seccomp/app/gen_blacklist.py
index cf36d11..e39fd9f 100755
--- a/hostsidetests/seccomp/app/gen_blacklist.py
+++ b/hostsidetests/seccomp/app/gen_blacklist.py
@@ -46,6 +46,20 @@
'setdomainname': 'all',
'sethostname': 'all',
'settimeofday': 'all',
+ 'setfsgid': 'all',
+ 'setfsuid': 'all',
+ 'setgid': 'all',
+ 'setgid32': 'x86,arm',
+ 'setgroups': 'all',
+ 'setgroups32': 'x86,arm',
+ 'setregid': 'all',
+ 'setregid32': 'x86,arm',
+ 'setresgid': 'all',
+ 'setresgid32': 'x86,arm',
+ 'setreuid': 'all',
+ 'setreuid32': 'x86,arm',
+ 'setuid': 'all',
+ 'setuid32': 'x86,arm',
'swapoff': 'all',
'swapoff': 'all',
'swapon': 'all',
diff --git a/hostsidetests/seccomp/app/jni/Android.mk b/hostsidetests/seccomp/app/jni/Android.mk
index 45fb135..3637f27 100644
--- a/hostsidetests/seccomp/app/jni/Android.mk
+++ b/hostsidetests/seccomp/app/jni/Android.mk
@@ -32,4 +32,5 @@
LOCAL_CFLAGS := -Wall -Werror
+LOCAL_NDK_STL_VARIANT := c++_static
include $(BUILD_SHARED_LIBRARY)
diff --git a/hostsidetests/seccomp/app/jni/android_seccomp_cts_app_SeccompDeviceTest.cpp b/hostsidetests/seccomp/app/jni/android_seccomp_cts_app_SeccompDeviceTest.cpp
index 2257232..1aac7239 100644
--- a/hostsidetests/seccomp/app/jni/android_seccomp_cts_app_SeccompDeviceTest.cpp
+++ b/hostsidetests/seccomp/app/jni/android_seccomp_cts_app_SeccompDeviceTest.cpp
@@ -18,6 +18,7 @@
#define LOG_TAG "SeccompTest"
+#include <functional>
#include <android/log.h>
#include <unistd.h>
#include <sys/types.h>
@@ -37,12 +38,11 @@
* 1 if blocked, else 0
* Exceptions: None
*/
-static jboolean testSyscallBlocked(JNIEnv *, jobject, int nr) {
+static jboolean doTestSyscallBlocked(std::function<void()> execSyscall) {
int pid = fork();
if (pid == 0) {
- ALOGI("Calling syscall %d", nr);
- syscall(nr);
- return false;
+ execSyscall();
+ exit(0);
} else {
int status;
int ret = waitpid(pid, &status, 0);
@@ -72,9 +72,25 @@
}
}
+static jboolean testSyscallBlocked(JNIEnv *, jobject, jint nr) {
+ return doTestSyscallBlocked([&](){ ALOGI("Calling syscall %d", nr); syscall(nr); });
+}
+
+static jboolean testSetresuidBlocked(JNIEnv *, jobject, jint ruid, jint euid, jint suid) {
+ return doTestSyscallBlocked([&] {ALOGE("Calling setresuid\n"); setresuid(ruid, euid, suid);});
+}
+
+static jboolean testSetresgidBlocked(JNIEnv *, jobject, jint rgid, jint egid, jint sgid) {
+ return doTestSyscallBlocked([&] {ALOGE("Calling setresgid\n"); setresgid(rgid, egid, sgid);});
+}
+
static JNINativeMethod gMethods[] = {
{ "testSyscallBlocked", "(I)Z",
(void*) testSyscallBlocked },
+ { "testSetresuidBlocked", "(III)Z",
+ (void*) testSetresuidBlocked },
+ { "testSetresgidBlocked", "(III)Z",
+ (void*) testSetresgidBlocked },
};
int register_android_seccomp_cts_app_SeccompTest(JNIEnv* env)
diff --git a/hostsidetests/seccomp/app/src/android/seccomp/cts/app/IsolatedService.java b/hostsidetests/seccomp/app/src/android/seccomp/cts/app/IsolatedService.java
new file mode 100644
index 0000000..2546c57
--- /dev/null
+++ b/hostsidetests/seccomp/app/src/android/seccomp/cts/app/IsolatedService.java
@@ -0,0 +1,57 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package android.seccomp.cts.app;
+
+import android.app.Service;
+import android.content.Intent;
+import android.os.Handler;
+import android.os.IBinder;
+import android.os.Message;
+import android.os.Messenger;
+import android.os.RemoteException;
+import android.util.Log;
+
+public class IsolatedService extends Service {
+ static final String TAG = "IsolatedService";
+
+ static final int MSG_GET_SECCOMP_RESULT = 1;
+
+ static final int MSG_SECCOMP_RESULT = 2;
+ final Messenger mMessenger = new Messenger(new ServiceHandler());
+
+ @Override
+ public IBinder onBind(Intent intent) {
+ return mMessenger.getBinder();
+ }
+
+ static class ServiceHandler extends Handler {
+ @Override
+ public void handleMessage(Message msg) {
+ switch (msg.what) {
+ case (MSG_GET_SECCOMP_RESULT):
+ int result = ZygotePreload.getSeccomptestResult() ? 1 : 0;
+ try {
+ msg.replyTo.send(Message.obtain(null, MSG_SECCOMP_RESULT, result, 0));
+ } catch (RemoteException e) {
+ Log.e(TAG, "Failed to send seccomp test result", e);
+ }
+ break;
+ default:
+ super.handleMessage(msg);
+ }
+ }
+ }
+}
diff --git a/hostsidetests/seccomp/app/src/android/seccomp/cts/app/SeccompDeviceTest.java b/hostsidetests/seccomp/app/src/android/seccomp/cts/app/SeccompDeviceTest.java
index 42ea6c2..1f066dc 100644
--- a/hostsidetests/seccomp/app/src/android/seccomp/cts/app/SeccompDeviceTest.java
+++ b/hostsidetests/seccomp/app/src/android/seccomp/cts/app/SeccompDeviceTest.java
@@ -20,10 +20,23 @@
import java.io.InputStream;
import java.util.Iterator;
+import android.content.ComponentName;
import android.content.Context;
+import android.content.Intent;
+import android.content.ServiceConnection;
import android.content.res.AssetManager;
+import android.os.ConditionVariable;
+import android.os.IBinder;
+import android.os.Handler;
+import android.os.HandlerThread;
+import android.os.Looper;
+import android.os.Message;
+import android.os.Messenger;
+import android.os.RemoteException;
import android.support.test.InstrumentationRegistry;
import android.support.test.runner.AndroidJUnit4;
+import android.util.Log;
+
import com.android.compatibility.common.util.CpuFeatures;
import org.json.JSONObject;
import org.json.JSONException;
@@ -44,19 +57,39 @@
System.loadLibrary("ctsseccomp_jni");
}
+ static final String TAG = "SeccompDeviceTest";
+
+ protected Context mContext;
+
+ // This is flagged whenever we have obtained the test result from the isolated
+ // service; it allows us to block the test until the results are in.
+ private final ConditionVariable mResultCondition = new ConditionVariable();
+
+ private boolean mAppZygoteResult;
+ private Messenger mMessenger;
+ private HandlerThread mHandlerThread;
+
+ // The service start can take a long time, because seccomp denials will
+ // cause process crashes and dumps, which we waitpid() for sequentially.
+ private static final int SERVICE_START_TIMEOUT_MS = 120000;
+
private JSONObject mAllowedSyscallMap;
private JSONObject mBlockedSyscallMap;
@Before
public void initializeSyscallMap() throws IOException, JSONException {
- final Context context = InstrumentationRegistry.getInstrumentation().getTargetContext();
- AssetManager manager = context.getAssets();
+ mContext = InstrumentationRegistry.getInstrumentation().getTargetContext();
+ AssetManager manager = mContext.getAssets();
try (InputStream is = manager.open("syscalls_allowed.json")) {
mAllowedSyscallMap = new JSONObject(readInputStreamFully(is));
}
try (InputStream is = manager.open("syscalls_blocked.json")) {
mBlockedSyscallMap = new JSONObject(readInputStreamFully(is));
}
+ mHandlerThread = new HandlerThread("HandlerThread");
+ mHandlerThread.start();
+ Looper looper = mHandlerThread.getLooper();
+ mMessenger = new Messenger(new IncomingHandler(looper));
}
@Test
@@ -79,6 +112,84 @@
}
}
+ class IncomingHandler extends Handler {
+ IncomingHandler(Looper looper) {
+ super(looper);
+ }
+
+ @Override
+ public void handleMessage(Message msg) {
+ switch (msg.what) {
+ case IsolatedService.MSG_SECCOMP_RESULT:
+ mAppZygoteResult = (msg.arg1 == 1);
+ mResultCondition.open();
+ default:
+ super.handleMessage(msg);
+ }
+ }
+ }
+
+ class IsolatedConnection implements ServiceConnection {
+ private final ConditionVariable mConnectedCondition = new ConditionVariable();
+ private Messenger mService;
+
+ public void onServiceConnected(ComponentName name, IBinder binder) {
+ mService = new Messenger(binder);
+ mConnectedCondition.open();
+ }
+
+ public void onServiceDisconnected(ComponentName name) {
+ mConnectedCondition.close();
+ }
+
+ public boolean getTestResult() {
+ boolean connected = mConnectedCondition.block(SERVICE_START_TIMEOUT_MS);
+ if (!connected) {
+ Log.e(TAG, "Failed to wait for IsolatedService to bind.");
+ return false;
+ }
+ Message msg = Message.obtain(null, IsolatedService.MSG_GET_SECCOMP_RESULT);
+ msg.replyTo = mMessenger;
+ try {
+ mService.send(msg);
+ } catch (RemoteException e) {
+ Log.e(TAG, "Failed to send message to IsolatedService to get test result.", e);
+ return false;
+ }
+
+ // Wait for result and return it
+ mResultCondition.block();
+
+ return mAppZygoteResult;
+ }
+ }
+
+ private IsolatedConnection bindService(Class<?> cls) {
+ Intent intent = new Intent();
+ intent.setClass(mContext, cls);
+ IsolatedConnection conn = new IsolatedConnection();
+ mContext.bindService(intent, conn, Context.BIND_AUTO_CREATE);
+
+ return conn;
+ }
+
+ @Test
+ public void testAppZygoteSyscalls() {
+ // Isolated services that spawn from the application Zygote are allowed
+ // to preload code in a security context that is allowed to use
+ // setresuid() / setresgid() in a limited range; this test enforces
+ // we allow calls within the range, and reject those outside them.
+ // This is done from the ZygotePreload class (which runs in the app zygote
+ // context); here we just wait for the service to come up, and ask it
+ // whether the tests were executed successfully. We have to ask the service
+ // because that is the only process that we can talk to that shares the
+ // same address space as the ZygotePreload class, which holds the test
+ // result.
+ IsolatedConnection conn = bindService(IsolatedService.class);
+ boolean testResult = conn.getTestResult();
+ Assert.assertTrue("seccomp tests in application zygote failed; see logs.", testResult);
+ }
+
private static String getCurrentArch() {
if (CpuFeatures.isArm64Cpu()) {
return "arm64";
@@ -120,4 +231,6 @@
}
private static final native boolean testSyscallBlocked(int nr);
+ protected static final native boolean testSetresuidBlocked(int ruid, int euid, int suid);
+ protected static final native boolean testSetresgidBlocked(int rgid, int egid, int sgid);
}
diff --git a/hostsidetests/seccomp/app/src/android/seccomp/cts/app/ZygotePreload.java b/hostsidetests/seccomp/app/src/android/seccomp/cts/app/ZygotePreload.java
new file mode 100644
index 0000000..270e558
--- /dev/null
+++ b/hostsidetests/seccomp/app/src/android/seccomp/cts/app/ZygotePreload.java
@@ -0,0 +1,126 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.seccomp.cts.app;
+
+import android.os.Process;
+import android.util.Log;
+
+public class ZygotePreload {
+ static final String TAG = "SeccompDeviceTest";
+
+ static boolean sResult = false;
+
+ static private boolean testSetResUidGidBlocked(int rid, int eid, int sid) {
+ if (!SeccompDeviceTest.testSetresuidBlocked(rid, eid, sid)) {
+ Log.e(TAG, "setresuid( " + Integer.toString(rid) + ","
+ + Integer.toString(eid) + "," + Integer.toString(sid) + ")"
+ + " is wrongly allowed.");
+ return false;
+ }
+ if (!SeccompDeviceTest.testSetresgidBlocked(rid, eid, sid)) {
+ Log.e(TAG, "setresguid( " + Integer.toString(rid) + ","
+ + Integer.toString(eid) + "," + Integer.toString(sid) + ")"
+ + " is wrongly allowed.");
+ return false;
+ }
+
+ return true;
+ }
+
+ static private boolean testSetResUidGidAllowed(int rid, int eid, int sid) {
+ if (SeccompDeviceTest.testSetresuidBlocked(rid, eid, sid)) {
+ Log.e(TAG, "setresuid( " + Integer.toString(rid) + ","
+ + Integer.toString(eid) + "," + Integer.toString(sid) + ")"
+ + " is wrongly blocked.");
+ return false;
+ }
+ if (SeccompDeviceTest.testSetresgidBlocked(rid, eid, sid)) {
+ Log.e(TAG, "setresguid( " + Integer.toString(rid) + ","
+ + Integer.toString(eid) + "," + Integer.toString(sid) + ")"
+ + " is wrongly blocked.");
+ return false;
+ }
+
+ return true;
+ }
+
+ static synchronized public boolean getSeccomptestResult() {
+ return sResult;
+ }
+
+ /*
+ * This is called from the app_zygote security context, which has two seccomp
+ * filters in place:
+ * 1) The regular app seccomp filter (which allows setresuid/setresgid)
+ * 2) A setresuid/setresgid limiting filter, which restricts the calls to
+ * setresuid/setresgid to be in a particular range.
+ *
+ * This test enforces 2) is in place.
+ */
+ static synchronized public void doPreload() {
+ boolean result = true;
+
+ // root uid
+ result &= testSetResUidGidBlocked(0, 0, 0);
+ // system uid
+ result &= testSetResUidGidBlocked(Process.SYSTEM_UID, Process.SYSTEM_UID,
+ Process.SYSTEM_UID);
+ // mix of uids
+ result &= testSetResUidGidBlocked(0, Process.SYSTEM_UID,
+ Process.SYSTEM_UID);
+
+ // an app uid
+ result &= testSetResUidGidBlocked(Process.FIRST_APPLICATION_UID,
+ Process.FIRST_APPLICATION_UID, Process.FIRST_APPLICATION_UID);
+ result &= testSetResUidGidBlocked(Process.LAST_APPLICATION_UID,
+ Process.LAST_APPLICATION_UID, Process.LAST_APPLICATION_UID);
+
+ // an isolated process uid
+ result &= testSetResUidGidBlocked(Process.FIRST_ISOLATED_UID,
+ Process.FIRST_ISOLATED_UID, Process.FIRST_ISOLATED_UID);
+ result &= testSetResUidGidBlocked(Process.LAST_ISOLATED_UID, Process.LAST_ISOLATED_UID,
+ Process.LAST_ISOLATED_UID);
+
+ // an allowed app zygote UID
+ // TODO this test assumes no other isolated app zygotes are currently running!
+ result &= testSetResUidGidAllowed(Process.FIRST_APP_ZYGOTE_ISOLATED_UID,
+ Process.FIRST_APP_ZYGOTE_ISOLATED_UID, Process.FIRST_APP_ZYGOTE_ISOLATED_UID);
+
+ // off-by-one
+ result &= testSetResUidGidBlocked(Process.FIRST_APP_ZYGOTE_ISOLATED_UID - 1,
+ Process.FIRST_APP_ZYGOTE_ISOLATED_UID - 1,
+ Process.FIRST_APP_ZYGOTE_ISOLATED_UID - 1);
+
+ // mixed allowed rgid with dis-allowed euid and suid (and variants)
+ result &= testSetResUidGidBlocked(Process.FIRST_APP_ZYGOTE_ISOLATED_UID, 0, 0);
+ result &= testSetResUidGidBlocked(Process.FIRST_APP_ZYGOTE_ISOLATED_UID,
+ Process.FIRST_APP_ZYGOTE_ISOLATED_UID, 0);
+ result &= testSetResUidGidBlocked(0, Process.FIRST_APP_ZYGOTE_ISOLATED_UID, 0);
+ result &= testSetResUidGidBlocked(0, Process.FIRST_APP_ZYGOTE_ISOLATED_UID,
+ Process.FIRST_APP_ZYGOTE_ISOLATED_UID);
+ result &= testSetResUidGidBlocked(0, 0, Process.FIRST_APP_ZYGOTE_ISOLATED_UID);
+ result &= testSetResUidGidBlocked(Process.FIRST_APP_ZYGOTE_ISOLATED_UID, 0,
+ Process.FIRST_APP_ZYGOTE_ISOLATED_UID);
+
+ // a disallowed app zygote UID
+ result &= testSetResUidGidBlocked(Process.LAST_APP_ZYGOTE_ISOLATED_UID,
+ Process.LAST_APP_ZYGOTE_ISOLATED_UID, Process.LAST_APP_ZYGOTE_ISOLATED_UID);
+
+ // Store result
+ sResult = result;
+ }
+}
diff --git a/hostsidetests/seccomp/src/android/seccomp/cts/SeccompHostJUnit4DeviceTest.java b/hostsidetests/seccomp/src/android/seccomp/cts/SeccompHostJUnit4DeviceTest.java
index 2a7242b..1d845f9 100644
--- a/hostsidetests/seccomp/src/android/seccomp/cts/SeccompHostJUnit4DeviceTest.java
+++ b/hostsidetests/seccomp/src/android/seccomp/cts/SeccompHostJUnit4DeviceTest.java
@@ -41,6 +41,7 @@
private static final String TEST_CTS_SYSCALL_BLOCKED = "testCTSSyscallBlocked";
private static final String TEST_CTS_SYSCALL_ALLOWED = "testCTSSyscallAllowed";
+ private static final String TEST_CTS_SYSCALL_APP_ZYGOTE = "testAppZygoteSyscalls";
@Before
public void setUp() throws Exception {
@@ -57,6 +58,11 @@
Assert.assertTrue(runDeviceTests(TEST_PKG, TEST_CLASS, TEST_CTS_SYSCALL_ALLOWED));
}
+ @Test
+ public void testAppZygoteSyscalls() throws Exception {
+ Assert.assertTrue(runDeviceTests(TEST_PKG, TEST_CLASS, TEST_CTS_SYSCALL_APP_ZYGOTE));
+ }
+
@After
public void tearDown() throws Exception {
uninstallPackage(getDevice(), TEST_PKG);
diff --git a/hostsidetests/securitybulletin/securityPatch/Bug-115739809/poc.cpp b/hostsidetests/securitybulletin/securityPatch/Bug-115739809/poc.cpp
index 5b40654..83227af 100755
--- a/hostsidetests/securitybulletin/securityPatch/Bug-115739809/poc.cpp
+++ b/hostsidetests/securitybulletin/securityPatch/Bug-115739809/poc.cpp
@@ -94,6 +94,8 @@
outMsg->body.motion.metaState = msg.body.motion.metaState;
// int32_t buttonState
outMsg->body.motion.buttonState = msg.body.motion.buttonState;
+ // MotionClassification classification
+ outMsg->body.motion.classification = msg.body.motion.classification;
// int32_t edgeFlags
outMsg->body.motion.edgeFlags = msg.body.motion.edgeFlags;
// nsecs_t downTime
diff --git a/hostsidetests/securitybulletin/securityPatch/CVE-2017-0477/Android.mk b/hostsidetests/securitybulletin/securityPatch/CVE-2017-0477/Android.mk
index 5561115..498e85f 100644
--- a/hostsidetests/securitybulletin/securityPatch/CVE-2017-0477/Android.mk
+++ b/hostsidetests/securitybulletin/securityPatch/CVE-2017-0477/Android.mk
@@ -22,7 +22,7 @@
LOCAL_MODULE_STEM_32 := $(LOCAL_MODULE)32
LOCAL_MODULE_STEM_64 := $(LOCAL_MODULE)64
-LOCAL_COMPATIBILITY_SUITE := cts sts
+LOCAL_COMPATIBILITY_SUITE := cts sts vts
LOCAL_CTS_TEST_PACKAGE := android.security.cts
LOCAL_ARM_MODE := arm
diff --git a/hostsidetests/securitybulletin/securityPatch/CVE-2018-9490/Android.mk b/hostsidetests/securitybulletin/securityPatch/CVE-2018-9490/Android.mk
index 4a4301f..a6a520f 100644
--- a/hostsidetests/securitybulletin/securityPatch/CVE-2018-9490/Android.mk
+++ b/hostsidetests/securitybulletin/securityPatch/CVE-2018-9490/Android.mk
@@ -25,7 +25,7 @@
libpac \
# Tag this module as a cts test artifact
-LOCAL_COMPATIBILITY_SUITE := cts sts
+LOCAL_COMPATIBILITY_SUITE := cts sts vts
LOCAL_CTS_TEST_PACKAGE := android.security.cts
LOCAL_ARM_MODE := arm
diff --git a/hostsidetests/securitybulletin/src/android/security/cts/Poc16_04.java b/hostsidetests/securitybulletin/src/android/security/cts/Poc16_04.java
index 4527c0c..9a7e62a 100644
--- a/hostsidetests/securitybulletin/src/android/security/cts/Poc16_04.java
+++ b/hostsidetests/securitybulletin/src/android/security/cts/Poc16_04.java
@@ -28,7 +28,7 @@
AdbUtils.runCommandLine("logcat -c" , getDevice());
AdbUtils.runPoc("CVE-2016-2419", getDevice(), 60);
String logcat = AdbUtils.runCommandLine("logcat -d", getDevice());
- assertNotMatches("[\\s\\n\\S]*IOMX_InfoLeak b26323455[\\s\\n\\S]*", logcat);
+ assertNotMatchesMultiLine("IOMX_InfoLeak b26323455", logcat);
}
/**
diff --git a/hostsidetests/securitybulletin/src/android/security/cts/Poc16_05.java b/hostsidetests/securitybulletin/src/android/security/cts/Poc16_05.java
index 886ebaf..d866a5a 100644
--- a/hostsidetests/securitybulletin/src/android/security/cts/Poc16_05.java
+++ b/hostsidetests/securitybulletin/src/android/security/cts/Poc16_05.java
@@ -29,7 +29,7 @@
AdbUtils.runPoc("CVE-2016-2460", getDevice(), 60);
String logcat = AdbUtils.runCommandLine("logcat -d", getDevice());
- assertNotMatches("[\\s\\n\\S]*IGraphicBufferProducer_Info is Leaked[\\s\\n\\S]*", logcat);
+ assertNotMatchesMultiLine("IGraphicBufferProducer_Info is Leaked", logcat);
}
/**
diff --git a/hostsidetests/securitybulletin/src/android/security/cts/Poc16_11.java b/hostsidetests/securitybulletin/src/android/security/cts/Poc16_11.java
index b6bb97b..bb18b0d 100644
--- a/hostsidetests/securitybulletin/src/android/security/cts/Poc16_11.java
+++ b/hostsidetests/securitybulletin/src/android/security/cts/Poc16_11.java
@@ -29,7 +29,7 @@
AdbUtils.runCommandLine("logcat -c", getDevice());
AdbUtils.runPoc("CVE-2012-6702", getDevice(), 60);
String logcat = AdbUtils.runCommandLine("logcat -d", getDevice());
- assertNotMatches("[\\s\\n\\S]*fail: encountered same random values![\\s\\n\\S]*", logcat);
+ assertNotMatchesMultiLine("fail: encountered same random values!", logcat);
}
/**
diff --git a/hostsidetests/securitybulletin/src/android/security/cts/Poc17_02.java b/hostsidetests/securitybulletin/src/android/security/cts/Poc17_02.java
index 27ded73..e2e5134 100644
--- a/hostsidetests/securitybulletin/src/android/security/cts/Poc17_02.java
+++ b/hostsidetests/securitybulletin/src/android/security/cts/Poc17_02.java
@@ -27,7 +27,7 @@
AdbUtils.runCommandLine("logcat -c", getDevice());
AdbUtils.runPoc("CVE-2017-0426", getDevice(), 60);
String logcatOut = AdbUtils.runCommandLine("logcat -d", getDevice());
- assertNotMatches("[\\s\\n\\S]*Bugreports file in wrong path[\\s\\n\\S]*", logcatOut);
+ assertNotMatchesMultiLine("Bugreports file in wrong path", logcatOut);
}
/**
diff --git a/hostsidetests/securitybulletin/src/android/security/cts/Poc17_11.java b/hostsidetests/securitybulletin/src/android/security/cts/Poc17_11.java
index cdeec39..e1c4977 100644
--- a/hostsidetests/securitybulletin/src/android/security/cts/Poc17_11.java
+++ b/hostsidetests/securitybulletin/src/android/security/cts/Poc17_11.java
@@ -34,8 +34,8 @@
// Wait for intent to be processed before checking logcat
Thread.sleep(5000);
String logcat = AdbUtils.runCommandLine("logcat -d", getDevice());
- assertNotMatches("[\\s\\n\\S]*Fatal signal 11 \\(SIGSEGV\\)" +
+ assertNotMatchesMultiLine("Fatal signal 11 \\(SIGSEGV\\)" +
"[\\s\\n\\S]*>>> /system/bin/" +
- "mediaserver <<<[\\s\\n\\S]*", logcat);
+ "mediaserver <<<", logcat);
}
}
diff --git a/hostsidetests/securitybulletin/src/android/security/cts/Poc18_02.java b/hostsidetests/securitybulletin/src/android/security/cts/Poc18_02.java
index a4eb539..c9f48f9 100644
--- a/hostsidetests/securitybulletin/src/android/security/cts/Poc18_02.java
+++ b/hostsidetests/securitybulletin/src/android/security/cts/Poc18_02.java
@@ -46,7 +46,7 @@
AdbUtils.runPoc("CVE-2017-13273", getDevice(), 60);
String dmesgOut = AdbUtils.runCommandLine("cat /sys/fs/pstore/console-ramoops",
getDevice());
- assertNotMatches("[\\s\\n\\S]*CVE-2017-132736 Tainted:" + "[\\s\\n\\S]*" +
+ assertNotMatchesMultiLine("CVE-2017-132736 Tainted:" + "[\\s\\n\\S]*" +
"Kernel panic - not syncing: Fatal exception in interrupt", dmesgOut);
}
AdbUtils.runCommandLine("setenforce 1",getDevice());
diff --git a/hostsidetests/securitybulletin/src/android/security/cts/Poc18_04.java b/hostsidetests/securitybulletin/src/android/security/cts/Poc18_04.java
new file mode 100644
index 0000000..02436e7
--- /dev/null
+++ b/hostsidetests/securitybulletin/src/android/security/cts/Poc18_04.java
@@ -0,0 +1,32 @@
+/**
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.security.cts;
+
+import android.platform.test.annotations.SecurityTest;
+import org.junit.runner.RunWith;
+
+public class Poc18_04 extends SecurityTestCase {
+ /**
+ * b/69683251
+ * Does not require root but must be a hostside test to avoid
+ * a race condition
+ */
+ @SecurityTest(minPatchLevel = "2018-04")
+ public void testPocCVE_2017_13286() throws Exception {
+ LaunchSomeWhere.launchSomeWhere("CVE_2017_13286", getDevice());
+ }
+}
diff --git a/hostsidetests/securitybulletin/src/android/security/cts/Poc18_07.java b/hostsidetests/securitybulletin/src/android/security/cts/Poc18_07.java
index 4d8d73b..9595d5a 100644
--- a/hostsidetests/securitybulletin/src/android/security/cts/Poc18_07.java
+++ b/hostsidetests/securitybulletin/src/android/security/cts/Poc18_07.java
@@ -30,6 +30,6 @@
AdbUtils.runCommandLine("logcat -c" , getDevice());
AdbUtils.runPoc("CVE-2018-9424", getDevice(), 60);
String result = AdbUtils.runCommandLine("logcat -d", getDevice());
- assertNotMatches("[\\s\\n\\S]*Fatal signal [\\s\\n\\S]*", result);
+ assertNotMatchesMultiLine("Fatal signal", result);
}
}
diff --git a/hostsidetests/securitybulletin/test-apps/launchanywhere/src/com/android/security/cts/launchanywhere/CVE_2017_13286.java b/hostsidetests/securitybulletin/test-apps/launchanywhere/src/com/android/security/cts/launchanywhere/CVE_2017_13286.java
new file mode 100644
index 0000000..752b06d
--- /dev/null
+++ b/hostsidetests/securitybulletin/test-apps/launchanywhere/src/com/android/security/cts/launchanywhere/CVE_2017_13286.java
@@ -0,0 +1,78 @@
+/**
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.security.cts.launchanywhere;
+
+import com.android.security.cts.launchanywhere.IGenerateMalformedParcel;
+import android.accounts.AccountManager;
+import android.content.Intent;
+import android.os.Parcel;
+
+public class CVE_2017_13286 implements IGenerateMalformedParcel {
+ @Override
+ public Parcel generate(Intent intent) {
+ Parcel data = Parcel.obtain();
+ data.writeInterfaceToken("android.accounts." +
+ "IAccountAuthenticatorResponse");
+ data.writeInt(1);
+ int bundleLenPos = data.dataPosition();
+ data.writeInt(0xffffffff);
+ data.writeInt(0x4C444E42);
+ int bundleStartPos = data.dataPosition();
+ data.writeInt(3);
+
+ data.writeString("launchanywhere");
+ data.writeInt(4);
+ data.writeString("android.hardware.camera2.params.OutputConfiguration");
+ data.writeInt(0);
+ data.writeInt(1);
+ data.writeInt(2);
+ data.writeInt(3);
+ data.writeInt(4);
+ data.writeInt(5);
+ data.writeInt(0);
+ data.writeInt(0);
+ data.writeInt(0);
+ data.writeInt(13);
+
+ int byteArrayLenPos = data.dataPosition();
+ data.writeInt(0xffffffff);
+ int byteArrayStartPos = data.dataPosition();
+ data.writeInt(0);
+ data.writeInt(0);
+ data.writeInt(0);
+ data.writeInt(0);
+ data.writeInt(0);
+ data.writeInt(0);
+ data.writeString(AccountManager.KEY_INTENT);
+ data.writeInt(4);
+ data.writeString("android.content.Intent");
+ intent.writeToParcel(data, 0);
+ int byteArrayEndPos = data.dataPosition();
+ data.setDataPosition(byteArrayLenPos);
+ int byteArrayLen = byteArrayEndPos - byteArrayStartPos;
+ data.writeInt(byteArrayLen);
+ data.setDataPosition(byteArrayEndPos);
+
+ int bundleEndPos = data.dataPosition();
+ data.setDataPosition(bundleLenPos);
+ int bundleLen = bundleEndPos - bundleStartPos;
+ data.writeInt(bundleLen);
+ data.setDataPosition(bundleEndPos);
+
+ return data;
+ }
+}
diff --git a/hostsidetests/signedconfig/app/Android.mk b/hostsidetests/signedconfig/app/Android.mk
index cc81b6f..1e9b142 100644
--- a/hostsidetests/signedconfig/app/Android.mk
+++ b/hostsidetests/signedconfig/app/Android.mk
@@ -54,3 +54,8 @@
LOCAL_PACKAGE_NAME := CtsSignedConfigTestAppV3_configv1
LOCAL_MANIFEST_FILE := version3_configv1_AndroidManifest.xml
include $(LOCAL_PATH)/build_signedconfig_apk.mk
+
+include $(CLEAR_VARS)
+LOCAL_PACKAGE_NAME := CtsSignedConfigTestAppV1_debug_key
+LOCAL_MANIFEST_FILE := version1_debug_key_AndroidManifest.xml
+include $(LOCAL_PATH)/build_signedconfig_apk.mk
diff --git a/hostsidetests/signedconfig/app/res/values/strings.xml b/hostsidetests/signedconfig/app/res/values/strings.xml
index e0300b5..454ddc6 100755
--- a/hostsidetests/signedconfig/app/res/values/strings.xml
+++ b/hostsidetests/signedconfig/app/res/values/strings.xml
@@ -15,8 +15,9 @@
-->
<resources>
<string name="signed_config_v1">eyJjb25maWciOiBbeyJ2YWx1ZXMiOiB7ImhpZGRlbl9hcGlfYmxhY2tsaXN0X2V4ZW1wdGlvbnMiOiAiTENsYXNzMTstPm1ldGhvZDEoLExDbGFzczE7LT5maWVsZDE6In0sICJtYXhfc2RrIjogOTksICJtaW5fc2RrIjogMH1dLCAidmVyc2lvbiI6IDF9</string>
- <string name="signed_config_signature_v1">MEUCIQDtx1a2H/xZV7IonZAGIFWZG3YGFo8AbQKIoL2COqpg9QIgA8aySPWgip3wJjXCCrGGFKViR1lIabbeQZ52QqhLZ/k=</string>
+ <string name="signed_config_signature_v1">MEUCIBx1XVpa8itMVos4oLSzb0zLsWT5mkbjSVrtRO6RnTjFAiEA+wI+G6YdxYdpolPliKXjUE6D0W9iRaqLeD29FZDb3Ic=</string>
+ <string name="signed_config_signature_v1_debug_key">MEQCIF7w8uUCYODYxYXyWvAnlPpLmn6Bv/OsW8fDqKfsGRPrAiA7t0jThzHkayAY841+UfKTA9gOH76Yu0e7BA1v9Fcx4g==</string>
<string name="signed_config_v2">eyJ2ZXJzaW9uIjogMiwgImNvbmZpZyI6IFt7InZhbHVlcyI6IHsiaGlkZGVuX2FwaV9ibGFja2xpc3RfZXhlbXB0aW9ucyI6ICJMQ2xhc3MyOy0+bWV0aG9kMigsTENsYXNzMjstPmZpZWxkMjoifSwgIm1heF9zZGsiOiA5OSwgIm1pbl9zZGsiOiAwfV19</string>
- <string name="signed_config_signature_v2">MEYCIQCW4j9khnDoCd7bXuPSw4G3SpNlMirFokO7W75W8HGxAgIhAOJDgSvIApTxoBkZXMhih7kyYxhtMJ777hDCBXR/QAPv</string>
+ <string name="signed_config_signature_v2">MEYCIQCj78TNHymjNlewEYic/yQ9efvwmzRtOVDgW5qhWW6FRwIhAPDiwO2gkoZaBTzIxHGoU2eHDFMb5ydeJjQBuWl/pn+I</string>
<string name="invalid_b64">invalidb64</string>
</resources>
diff --git a/hostsidetests/signedconfig/app/version1_debug_key_AndroidManifest.xml b/hostsidetests/signedconfig/app/version1_debug_key_AndroidManifest.xml
new file mode 100755
index 0000000..7a3462e
--- /dev/null
+++ b/hostsidetests/signedconfig/app/version1_debug_key_AndroidManifest.xml
@@ -0,0 +1,27 @@
+<?xml version="1.0" ?>
+<!-- Copyright (C) 2018 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<manifest
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ package="android.cts.signedconfig.app"
+ android:versionCode="1"
+ android:versionName="1">
+ <application>
+ <meta-data android:name="android.settings.global"
+ android:value="@string/signed_config_v1"/>
+ <meta-data android:name="android.settings.global.signature"
+ android:value="@string/signed_config_signature_v1_debug_key"/>
+ </application>
+</manifest>
diff --git a/hostsidetests/signedconfig/hostside/Android.mk b/hostsidetests/signedconfig/hostside/Android.mk
index fcf3046..b23fb0d 100644
--- a/hostsidetests/signedconfig/hostside/Android.mk
+++ b/hostsidetests/signedconfig/hostside/Android.mk
@@ -45,7 +45,8 @@
CtsSignedConfigTestAppV1_badsignature \
CtsSignedConfigTestAppV1_badb64_config \
CtsSignedConfigTestAppV1_badb64_signature \
- CtsSignedConfigTestAppV3_configv1
+ CtsSignedConfigTestAppV3_configv1 \
+ CtsSignedConfigTestAppV1_debug_key
include $(BUILD_CTS_HOST_JAVA_LIBRARY)
diff --git a/hostsidetests/signedconfig/hostside/src/com/android/cts/signedconfig/SignedConfigHostTest.java b/hostsidetests/signedconfig/hostside/src/com/android/cts/signedconfig/SignedConfigHostTest.java
index f68997b..0d57fda 100644
--- a/hostsidetests/signedconfig/hostside/src/com/android/cts/signedconfig/SignedConfigHostTest.java
+++ b/hostsidetests/signedconfig/hostside/src/com/android/cts/signedconfig/SignedConfigHostTest.java
@@ -54,6 +54,8 @@
"CtsSignedConfigTestAppV1_badb64_signature.apk";
private static final String TEST_APP_APK_NAME_V3_CONFIGV1 =
"CtsSignedConfigTestAppV3_configv1.apk";
+ private static final String TEST_APP_APK_NAME_V1_DEBUG_KEY =
+ "CtsSignedConfigTestAppV1_debug_key.apk";
private static final String SETTING_BLACKLIST_EXEMPTIONS = "hidden_api_blacklist_exemptions";
private static final String SETTING_SIGNED_CONFIG_VERSION = "signed_config_version";
@@ -112,7 +114,6 @@
public void setUp() throws Exception {
deleteConfig();
waitForDevice();
- Assume.assumeThat(getDevice().getBuildFlavor(), not(endsWith("-user")));
}
@After
@@ -213,4 +214,24 @@
assertThat(getDevice().getSetting("global", SETTING_SIGNED_CONFIG_VERSION))
.isEqualTo("null");
}
+
+ @Test
+ public void testDebugKeyValidOnDebugBuild() throws Exception {
+ Assume.assumeThat(getDevice().getBuildFlavor(), not(endsWith("-user")));
+ installPackage(TEST_APP_APK_NAME_V1_DEBUG_KEY);
+ waitUntilSettingMatches(SETTING_SIGNED_CONFIG_VERSION, "1");
+ assertThat(getDevice().getSetting("global", SETTING_BLACKLIST_EXEMPTIONS)).isEqualTo(
+ "LClass1;->method1(,LClass1;->field1:");
+ }
+
+ @Test
+ public void testDebugKeyNotValidOnUserBuild() throws Exception {
+ Assume.assumeThat(getDevice().getBuildFlavor(), endsWith("-user"));
+ installPackage(TEST_APP_APK_NAME_V1_DEBUG_KEY);
+ waitForDevice(5);
+ assertThat(getDevice().getSetting("global", SETTING_SIGNED_CONFIG_VERSION))
+ .isEqualTo("null");
+ assertThat(getDevice().getSetting("global", SETTING_BLACKLIST_EXEMPTIONS))
+ .isEqualTo("null");
+ }
}
diff --git a/hostsidetests/statsd/src/android/cts/statsd/atom/HostAtomTests.java b/hostsidetests/statsd/src/android/cts/statsd/atom/HostAtomTests.java
index e9996f1..8d5e523 100644
--- a/hostsidetests/statsd/src/android/cts/statsd/atom/HostAtomTests.java
+++ b/hostsidetests/statsd/src/android/cts/statsd/atom/HostAtomTests.java
@@ -417,6 +417,29 @@
assertTrue(atom.getBatteryLevel().getBatteryLevel() <= 100);
}
+ // This test is for the pulled battery charge count atom.
+ public void testBatteryCycleCount() throws Exception {
+ if (statsdDisabled()) {
+ return;
+ }
+ if (!hasFeature(FEATURE_WATCH, false)) return;
+ StatsdConfig.Builder config = getPulledConfig();
+ addGaugeAtomWithDimensions(config, Atom.BATTERY_CYCLE_COUNT_FIELD_NUMBER, null);
+
+ uploadConfig(config);
+
+ Thread.sleep(WAIT_TIME_LONG);
+ setAppBreadcrumbPredicate();
+ Thread.sleep(WAIT_TIME_LONG);
+
+ List<Atom> data = getGaugeMetricDataList();
+
+ assertTrue(data.size() > 0);
+ Atom atom = data.get(0);
+ assertTrue(atom.getBatteryCycleCount().hasCycleCount());
+ assertTrue(atom.getBatteryCycleCount().getCycleCount() > 0);
+ }
+
public void testKernelWakelock() throws Exception {
if (statsdDisabled() || !kernelWakelockStatsExist()) {
return;
diff --git a/hostsidetests/statsd/src/android/cts/statsd/validation/ProcStatsValidationTests.java b/hostsidetests/statsd/src/android/cts/statsd/validation/ProcStatsValidationTests.java
index 6a3c4a3..cfa0a37 100644
--- a/hostsidetests/statsd/src/android/cts/statsd/validation/ProcStatsValidationTests.java
+++ b/hostsidetests/statsd/src/android/cts/statsd/validation/ProcStatsValidationTests.java
@@ -390,6 +390,8 @@
Thread.sleep(WAIT_TIME_SHORT);
List<Atom> statsdData = getGaugeMetricDataList();
+ assertTrue(statsdData.size() > 0);
+ assertTrue(statsdData.get(0).getProcStatsPkgProc().getProcStatsSection().getAvailablePagesList().size() > 0);
List<ProcessStatsPackageProto> processStatsPackageProtoList = getAllProcStatsProto();
diff --git a/hostsidetests/theme/app/AndroidManifest.xml b/hostsidetests/theme/app/AndroidManifest.xml
index bb62742..9a8b7b2 100755
--- a/hostsidetests/theme/app/AndroidManifest.xml
+++ b/hostsidetests/theme/app/AndroidManifest.xml
@@ -18,7 +18,6 @@
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="android.theme.app">
- <uses-permission android:name="android.permission.DISABLE_KEYGUARD" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<application>
@@ -32,7 +31,7 @@
</activity>
<activity android:name=".GenerateImagesActivity"
android:screenOrientation="portrait"
- android:configChanges="screenSize|smallestScreenSize|screenLayout|orientation"
+ android:configChanges="screenSize|smallestScreenSize|screenLayout|orientation|uiMode"
android:exported="true" />
</application>
diff --git a/hostsidetests/theme/app/src/android/theme/app/GenerateImagesActivity.java b/hostsidetests/theme/app/src/android/theme/app/GenerateImagesActivity.java
index 1bf4da1..3591410 100644
--- a/hostsidetests/theme/app/src/android/theme/app/GenerateImagesActivity.java
+++ b/hostsidetests/theme/app/src/android/theme/app/GenerateImagesActivity.java
@@ -27,12 +27,16 @@
import android.os.Environment;
import android.os.Handler;
import android.util.Log;
+import android.util.Pair;
import android.view.WindowManager.LayoutParams;
import java.io.File;
import java.io.IOException;
+import java.util.ArrayList;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.TimeUnit;
+import java.util.function.Consumer;
+import java.util.function.Supplier;
/**
* Generates images by iterating through all themes and launching instances of
@@ -59,63 +63,65 @@
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
- getWindow().addFlags(LayoutParams.FLAG_KEEP_SCREEN_ON
- | LayoutParams.FLAG_TURN_SCREEN_ON
- | LayoutParams.FLAG_DISMISS_KEYGUARD);
+ // Useful for local testing. Not required for CTS harness.
+ getWindow().addFlags(LayoutParams.FLAG_KEEP_SCREEN_ON);
+ mOutputDir = setupOutputDirectory();
+ if (mOutputDir == null) {
+ finish("Failed to create output directory " + mOutputDir.getAbsolutePath(), false);
+ }
+
+ // The activity has been created, but we don't want to start image generation until various
+ // asynchronous conditions are satisfied.
+ new ConditionCheck(this, () -> generateNextImage(), message -> finish(message, false))
+ .addCondition("Device is unlocked",
+ () -> !getSystemService(KeyguardManager.class).isDeviceLocked())
+ .addCondition("Window is focused",
+ () -> hasWindowFocus())
+ .start();
+ }
+
+ private File setupOutputDirectory() {
mOutputDir = new File(Environment.getExternalStorageDirectory(), OUT_DIR);
ThemeTestUtils.deleteDirectory(mOutputDir);
mOutputDir.mkdirs();
- if (!mOutputDir.exists()) {
- finish("Failed to create output directory " + mOutputDir.getAbsolutePath(), false);
- return;
+ if (mOutputDir.exists()) {
+ return mOutputDir;
}
-
- final boolean canDisableKeyguard = checkCallingOrSelfPermission(
- permission.DISABLE_KEYGUARD) == PackageManager.PERMISSION_GRANTED;
- if (!canDisableKeyguard) {
- finish("Not granted permission to disable keyguard", false);
- return;
- }
-
- new KeyguardCheck(this) {
- @Override
- public void onSuccess() {
- generateNextImage();
- }
-
- @Override
- public void onFailure() {
- finish("Device is locked", false);
- }
- }.start();
+ return null;
}
- public boolean isFinishSuccess() {
- return mFinishSuccess;
- }
-
- public String getFinishReason() {
- return mFinishReason;
- }
-
- static abstract class KeyguardCheck implements Runnable {
+ /**
+ * Runnable that re-posts itself on a handler until either all of the conditions are satisfied
+ * or a retry threshold is exceeded.
+ */
+ class ConditionCheck implements Runnable {
private static final int MAX_RETRIES = 3;
private static final int RETRY_DELAY = 500;
private final Handler mHandler;
- private final KeyguardManager mKeyguard;
+ private final Runnable mOnSuccess;
+ private final Consumer<String> mOnFailure;
+ private final ArrayList<Pair<String, Supplier<Boolean>>> mConditions = new ArrayList<>();
- private int mRetries;
+ private ArrayList<Pair<String, Supplier<Boolean>>> mRemainingConditions = new ArrayList<>();
+ private int mRemainingRetries;
- public KeyguardCheck(Context context) {
+ ConditionCheck(Context context, Runnable onSuccess, Consumer<String> onFailure) {
mHandler = new Handler(context.getMainLooper());
- mKeyguard = (KeyguardManager) context.getSystemService(KEYGUARD_SERVICE);
+ mOnSuccess = onSuccess;
+ mOnFailure = onFailure;
+ }
+
+ public ConditionCheck addCondition(String summary, Supplier<Boolean> condition) {
+ mConditions.add(new Pair<>(summary, condition));
+ return this;
}
public void start() {
- mRetries = 0;
+ mRemainingConditions = new ArrayList<>(mConditions);
+ mRemainingRetries = 0;
mHandler.removeCallbacks(this);
mHandler.post(this);
@@ -127,19 +133,35 @@
@Override
public void run() {
- if (!mKeyguard.isKeyguardLocked()) {
- onSuccess();
- } else if (mRetries < MAX_RETRIES) {
- mRetries++;
+ mRemainingConditions.removeIf(condition -> condition.second.get());
+ if (mRemainingConditions.isEmpty()) {
+ mOnSuccess.run();
+ } else if (mRemainingRetries < MAX_RETRIES) {
+ mRemainingRetries++;
+ mHandler.removeCallbacks(this);
mHandler.postDelayed(this, RETRY_DELAY);
} else {
- onFailure();
+ final StringBuffer buffer = new StringBuffer("Failed conditions:");
+ mRemainingConditions.forEach(condition ->
+ buffer.append("\n").append(condition.first));
+ mOnFailure.accept(buffer.toString());
}
-
}
+ }
- public abstract void onSuccess();
- public abstract void onFailure();
+ /**
+ * @return whether the test finished successfully
+ */
+ public boolean isFinishSuccess() {
+ return mFinishSuccess;
+ }
+
+ /**
+ * @return user-visible string explaining why the test finished, may be {@code null} if the test
+ * finished unexpectedly
+ */
+ public String getFinishReason() {
+ return mFinishReason;
}
/**
diff --git a/hostsidetests/webkit/app/src/com/android/cts/webkit/WebViewDeviceSideStartupTest.java b/hostsidetests/webkit/app/src/com/android/cts/webkit/WebViewDeviceSideStartupTest.java
index bf113ff..80a8964 100644
--- a/hostsidetests/webkit/app/src/com/android/cts/webkit/WebViewDeviceSideStartupTest.java
+++ b/hostsidetests/webkit/app/src/com/android/cts/webkit/WebViewDeviceSideStartupTest.java
@@ -31,8 +31,9 @@
import android.webkit.SslErrorHandler;
import android.webkit.WebView;
import android.webkit.cts.CtsTestServer;
-import android.webkit.cts.WebViewOnUiThread;
-import android.webkit.cts.WebViewOnUiThread.WaitForLoadedClient;
+import android.webkit.cts.WebViewSyncLoader;
+import android.webkit.cts.WebViewSyncLoader.WaitForLoadedClient;
+import android.webkit.cts.WebkitUtils;
import android.webkit.WebView;
import com.android.compatibility.common.util.NullWebViewUtils;
@@ -100,16 +101,16 @@
// Now create WebView and test that setting the cookie beforehand really worked.
mActivity.createAndAttachWebView();
WebView webView = mActivity.getWebView();
- WebViewOnUiThread onUiThread = new WebViewOnUiThread(mActivity.getWebView());
- webView.setWebViewClient(new WaitForLoadedClient(onUiThread) {
+ WebViewSyncLoader syncLoader = new WebViewSyncLoader(webView);
+ webView.setWebViewClient(new WaitForLoadedClient(syncLoader) {
@Override
public void onReceivedSslError(WebView view, SslErrorHandler handler, SslError error) {
// Not intended to verify server certificate, ignore the error.
if (error.getPrimaryError() == SslError.SSL_IDMISMATCH) handler.proceed();
}
});
- onUiThread.loadUrlAndWaitForCompletion(url);
- assertEquals("1|count=41", onUiThread.getTitle()); // outgoing cookie
+ syncLoader.loadUrlAndWaitForCompletion(url);
+ assertEquals("1|count=41", webView.getTitle()); // outgoing cookie
CookieManager cookieManager = CookieManager.getInstance();
String cookie = cookieManager.getCookie(url);
assertNotNull(cookie);
@@ -117,6 +118,7 @@
Matcher m = pat.matcher(cookie);
assertTrue(m.matches());
assertEquals("42", m.group(1)); // value got incremented
+ syncLoader.detach();
}
@UiThreadTest
@@ -140,11 +142,8 @@
if (alreadyOnMainThread) {
mActivity.createAndAttachWebView();
} else {
- getInstrumentation().runOnMainSync(new Runnable() {
- @Override
- public void run() {
- mActivity.createAndAttachWebView();
- }
+ WebkitUtils.onMainThreadSync(() -> {
+ mActivity.createAndAttachWebView();
});
}
@@ -211,9 +210,10 @@
// WebView is available, so try to call some WebView APIs to ensure they don't cause
// strictmode violations
- WebViewOnUiThread onUiThread = new WebViewOnUiThread(mActivity.getWebView());
- onUiThread.loadUrlAndWaitForCompletion("about:blank");
- onUiThread.loadUrlAndWaitForCompletion("");
+ WebViewSyncLoader syncLoader = new WebViewSyncLoader(mActivity.getWebView());
+ syncLoader.loadUrlAndWaitForCompletion("about:blank");
+ syncLoader.loadUrlAndWaitForCompletion("");
+ syncLoader.detach();
}
@UiThreadTest
@@ -232,16 +232,12 @@
PackageManager pm = mActivity.getPackageManager();
if (!pm.hasSystemFeature(PackageManager.FEATURE_WEBVIEW)) return;
- WebView[] webviewHolder = new WebView[1];
// Create the WebView on the UI thread and then ensure webview.getWebViewLooper() returns
// the UI thread.
- getInstrumentation().runOnMainSync(new Runnable() {
- @Override
- public void run() {
- webviewHolder[0] = createAndCheckWebViewLooper();
- }
+ WebView webView = WebkitUtils.onMainThreadSync(() -> {
+ return createAndCheckWebViewLooper();
});
- assertEquals(Looper.getMainLooper(), webviewHolder[0].getWebViewLooper());
+ assertEquals(Looper.getMainLooper(), webView.getWebViewLooper());
}
/**
diff --git a/libs/deviceutillegacy/src/android/webkit/cts/WebViewOnUiThread.java b/libs/deviceutillegacy/src/android/webkit/cts/WebViewOnUiThread.java
index dbe7439..217e3d3 100644
--- a/libs/deviceutillegacy/src/android/webkit/cts/WebViewOnUiThread.java
+++ b/libs/deviceutillegacy/src/android/webkit/cts/WebViewOnUiThread.java
@@ -21,11 +21,8 @@
import android.graphics.Rect;
import android.net.Uri;
import android.net.http.SslCertificate;
-import android.os.Looper;
import android.os.Message;
-import android.os.SystemClock;
import android.print.PrintDocumentAdapter;
-import android.support.test.rule.ActivityTestRule;
import android.util.DisplayMetrics;
import android.view.View;
import android.view.ViewGroup;
@@ -48,10 +45,6 @@
import com.google.common.util.concurrent.SettableFuture;
-import junit.framework.Assert;
-
-import java.util.Map;
-import java.util.concurrent.Callable;
import java.util.concurrent.Future;
/**
@@ -64,107 +57,27 @@
* Modifications to this class should be reflected in that class as necessary. See
* http://go/modifying-webview-cts.
*/
-public class WebViewOnUiThread {
- /**
- * The maximum time, in milliseconds (10 seconds) to wait for a load
- * to be triggered.
- */
- private static final long LOAD_TIMEOUT = 10000;
-
- /**
- * Set to true after onPageFinished is called.
- */
- private boolean mLoaded;
-
- /**
- * Set to true after onNewPicture is called. Reset when onPageStarted
- * is called.
- */
- private boolean mNewPicture;
-
- /**
- * The progress, in percentage, of the page load. Valid values are between
- * 0 and 100.
- */
- private int mProgress;
-
+public class WebViewOnUiThread extends WebViewSyncLoader {
/**
* The WebView that calls will be made on.
*/
private WebView mWebView;
/**
- * Initializes the webView with a WebViewClient, WebChromeClient,
- * and PictureListener to prepare for loadUrlAndWaitForCompletion.
+ * Wraps a WebView to ensure that methods are run on the UI thread.
*
* A new WebViewOnUiThread should be called during setUp so as to
* reinitialize between calls.
*
- * @param test The test in which this is being run.
* @param webView The webView that the methods should call.
- * @see #loadDataAndWaitForCompletion(String, String, String)
- * @deprecated Use {@link WebViewOnUiThread#WebViewOnUiThread(ActivityTestRule, WebView)}
*/
- @Deprecated
public WebViewOnUiThread(WebView webView) {
+ super(webView);
mWebView = webView;
- final WebViewClient webViewClient = new WaitForLoadedClient(this);
- final WebChromeClient webChromeClient = new WaitForProgressClient(this);
- WebkitUtils.onMainThreadSync(() -> {
- mWebView.setWebViewClient(webViewClient);
- mWebView.setWebChromeClient(webChromeClient);
- mWebView.setPictureListener(new WaitForNewPicture());
- });
}
- /**
- * Called after a test is complete and the WebView should be disengaged from
- * the tests.
- */
public void cleanUp() {
- WebkitUtils.onMainThreadSync(() -> {
- mWebView.clearHistory();
- mWebView.clearCache(true);
- mWebView.setWebChromeClient(null);
- mWebView.setWebViewClient(null);
- mWebView.destroy();
- });
- }
-
- /**
- * Called from WaitForNewPicture, this is used to indicate that
- * the page has been drawn.
- */
- synchronized public void onNewPicture() {
- mNewPicture = true;
- this.notifyAll();
- }
-
- /**
- * Called from WaitForLoadedClient, this is used to clear the picture
- * draw state so that draws before the URL begins loading don't count.
- */
- synchronized public void onPageStarted() {
- mNewPicture = false; // Earlier paints won't count.
- }
-
- /**
- * Called from WaitForLoadedClient, this is used to indicate that
- * the page is loaded, but not drawn yet.
- */
- synchronized public void onPageFinished() {
- mLoaded = true;
- this.notifyAll();
- }
-
- /**
- * Called from the WebChrome client, this sets the current progress
- * for a page.
- * @param progress The progress made so far between 0 and 100.
- */
- synchronized public void onProgressChanged(int progress) {
- mProgress = progress;
- this.notifyAll();
+ super.destroy();
}
public void setWebViewClient(final WebViewClient webViewClient) {
@@ -216,7 +129,7 @@
}
public void requestFocus() {
- new PollingCheck(LOAD_TIMEOUT) {
+ new PollingCheck(WebkitUtils.TEST_TIMEOUT_MS) {
@Override
protected boolean check() {
requestFocusOnUiThread();
@@ -351,38 +264,6 @@
});
}
- /**
- * Calls loadUrl on the WebView and then waits onPageFinished,
- * onNewPicture and onProgressChange to reach 100.
- * Test fails if the load timeout elapses.
- * @param url The URL to load.
- */
- public void loadUrlAndWaitForCompletion(final String url) {
- callAndWait(new Runnable() {
- @Override
- public void run() {
- mWebView.loadUrl(url);
- }
- });
- }
-
- /**
- * Calls loadUrl on the WebView and then waits onPageFinished,
- * onNewPicture and onProgressChange to reach 100.
- * Test fails if the load timeout elapses.
- * @param url The URL to load.
- * @param extraHeaders The additional headers to be used in the HTTP request.
- */
- public void loadUrlAndWaitForCompletion(final String url,
- final Map<String, String> extraHeaders) {
- callAndWait(new Runnable() {
- @Override
- public void run() {
- mWebView.loadUrl(url, extraHeaders);
- }
- });
- }
-
public void loadUrl(final String url) {
WebkitUtils.onMainThreadSync(() -> {
mWebView.loadUrl(url);
@@ -395,55 +276,8 @@
});
}
- public void postUrlAndWaitForCompletion(final String url, final byte[] postData) {
- callAndWait(new Runnable() {
- @Override
- public void run() {
- mWebView.postUrl(url, postData);
- }
- });
- }
-
- public void loadDataAndWaitForCompletion(final String data,
- final String mimeType, final String encoding) {
- callAndWait(new Runnable() {
- @Override
- public void run() {
- mWebView.loadData(data, mimeType, encoding);
- }
- });
- }
-
- public void loadDataWithBaseURLAndWaitForCompletion(final String baseUrl,
- final String data, final String mimeType, final String encoding,
- final String historyUrl) {
- callAndWait(new Runnable() {
- @Override
- public void run() {
- mWebView.loadDataWithBaseURL(baseUrl, data, mimeType, encoding,
- historyUrl);
- }
- });
- }
-
/**
- * Reloads a page and waits for it to complete reloading. Use reload
- * if it is a form resubmission and the onFormResubmission responds
- * by telling WebView not to resubmit it.
- */
- public void reloadAndWaitForCompletion() {
- callAndWait(new Runnable() {
- @Override
- public void run() {
- mWebView.reload();
- }
- });
- }
-
- /**
- * Reload the previous URL. Use reloadAndWaitForCompletion unless
- * it is a form resubmission and the onFormResubmission responds
- * by telling WebView not to resubmit it.
+ * Reload the previous URL.
*/
public void reload() {
WebkitUtils.onMainThreadSync(() -> {
@@ -451,30 +285,6 @@
});
}
- /**
- * Use this only when JavaScript causes a page load to wait for the
- * page load to complete. Otherwise use loadUrlAndWaitForCompletion or
- * similar functions.
- */
- public void waitForLoadCompletion() {
- waitForCriteria(LOAD_TIMEOUT,
- new Callable<Boolean>() {
- @Override
- public Boolean call() {
- return isLoaded();
- }
- });
- clearLoad();
- }
-
- private void waitForCriteria(long timeout, Callable<Boolean> doneCriteria) {
- if (isUiThread()) {
- waitOnUiThread(timeout, doneCriteria);
- } else {
- waitOnTestThread(timeout, doneCriteria);
- }
- }
-
public String getTitle() {
return WebkitUtils.onMainThreadSync(() -> {
return mWebView.getTitle();
@@ -695,116 +505,6 @@
}
/**
- * Returns true if the current thread is the UI thread based on the
- * Looper.
- */
- private static boolean isUiThread() {
- return (Looper.myLooper() == Looper.getMainLooper());
- }
-
- /**
- * @return Whether or not the load has finished.
- */
- private synchronized boolean isLoaded() {
- return mLoaded && mNewPicture && mProgress == 100;
- }
-
- /**
- * Makes a WebView call, waits for completion and then resets the
- * load state in preparation for the next load call.
- *
- * <p>This method may be called on the UI thread.
- *
- * @param call The call to make on the UI thread prior to waiting.
- */
- private void callAndWait(Runnable call) {
- Assert.assertTrue("WebViewOnUiThread.load*AndWaitForCompletion calls "
- + "may not be mixed with load* calls directly on WebView "
- + "without calling waitForLoadCompletion after the load",
- !isLoaded());
- clearLoad(); // clear any extraneous signals from a previous load.
- if (isUiThread()) {
- call.run();
- } else {
- WebkitUtils.onMainThread(call);
- }
- waitForLoadCompletion();
- }
-
- /**
- * Called whenever a load has been completed so that a subsequent call to
- * waitForLoadCompletion doesn't return immediately.
- */
- synchronized private void clearLoad() {
- mLoaded = false;
- mNewPicture = false;
- mProgress = 0;
- }
-
- /**
- * Uses a polling mechanism, while pumping messages to check when the
- * criteria is met.
- */
- private void waitOnUiThread(long timeout, final Callable<Boolean> doneCriteria) {
- new PollingCheck(timeout) {
- @Override
- protected boolean check() {
- pumpMessages();
- try {
- return doneCriteria.call();
- } catch (Exception e) {
- Assert.fail("Unexpected error while checking the criteria: "
- + e.getMessage());
- return true;
- }
- }
- }.run();
- }
-
- /**
- * Uses a wait/notify to check when the criteria is met.
- */
- private synchronized void waitOnTestThread(long timeout, Callable<Boolean> doneCriteria) {
- try {
- long waitEnd = SystemClock.uptimeMillis() + timeout;
- long timeRemaining = timeout;
- while (!doneCriteria.call() && timeRemaining > 0) {
- this.wait(timeRemaining);
- timeRemaining = waitEnd - SystemClock.uptimeMillis();
- }
- Assert.assertTrue("Action failed to complete before timeout", doneCriteria.call());
- } catch (InterruptedException e) {
- // We'll just drop out of the loop and fail
- } catch (Exception e) {
- Assert.fail("Unexpected error while checking the criteria: "
- + e.getMessage());
- }
- }
-
- /**
- * Pumps all currently-queued messages in the UI thread and then exits.
- * This is useful to force processing while running tests in the UI thread.
- */
- private void pumpMessages() {
- class ExitLoopException extends RuntimeException {
- }
-
- // Force loop to exit when processing this. Loop.quit() doesn't
- // work because this is the main Loop.
- mWebView.getHandler().post(new Runnable() {
- @Override
- public void run() {
- throw new ExitLoopException(); // exit loop!
- }
- });
- try {
- // Pump messages until our message gets through.
- Looper.loop();
- } catch (ExitLoopException e) {
- }
- }
-
- /**
* Set LayoutParams to MATCH_PARENT.
*
* @param view Target view
@@ -815,65 +515,4 @@
params.width = ViewGroup.LayoutParams.MATCH_PARENT;
view.setLayoutParams(params);
}
-
- /**
- * A WebChromeClient used to capture the onProgressChanged for use
- * in waitFor functions. If a test must override the WebChromeClient,
- * it can derive from this class or call onProgressChanged
- * directly.
- */
- public static class WaitForProgressClient extends WebChromeClient {
- private WebViewOnUiThread mOnUiThread;
-
- public WaitForProgressClient(WebViewOnUiThread onUiThread) {
- mOnUiThread = onUiThread;
- }
-
- @Override
- public void onProgressChanged(WebView view, int newProgress) {
- super.onProgressChanged(view, newProgress);
- mOnUiThread.onProgressChanged(newProgress);
- }
- }
-
- /**
- * A WebViewClient that captures the onPageFinished for use in
- * waitFor functions. Using initializeWebView sets the WaitForLoadedClient
- * into the WebView. If a test needs to set a specific WebViewClient and
- * needs the waitForCompletion capability then it should derive from
- * WaitForLoadedClient or call WebViewOnUiThread.onPageFinished.
- */
- public static class WaitForLoadedClient extends WebViewClient {
- private WebViewOnUiThread mOnUiThread;
-
- public WaitForLoadedClient(WebViewOnUiThread onUiThread) {
- mOnUiThread = onUiThread;
- }
-
- @Override
- public void onPageFinished(WebView view, String url) {
- super.onPageFinished(view, url);
- mOnUiThread.onPageFinished();
- }
-
- @Override
- public void onPageStarted(WebView view, String url, Bitmap favicon) {
- super.onPageStarted(view, url, favicon);
- mOnUiThread.onPageStarted();
- }
- }
-
- /**
- * A PictureListener that captures the onNewPicture for use in
- * waitForLoadCompletion. Using initializeWebView sets the PictureListener
- * into the WebView. If a test needs to set a specific PictureListener and
- * needs the waitForCompletion capability then it should call
- * WebViewOnUiThread.onNewPicture.
- */
- private class WaitForNewPicture implements PictureListener {
- @Override
- public void onNewPicture(WebView view, Picture picture) {
- WebViewOnUiThread.this.onNewPicture();
- }
- }
}
diff --git a/libs/deviceutillegacy/src/android/webkit/cts/WebViewSyncLoader.java b/libs/deviceutillegacy/src/android/webkit/cts/WebViewSyncLoader.java
new file mode 100644
index 0000000..2b27b52
--- /dev/null
+++ b/libs/deviceutillegacy/src/android/webkit/cts/WebViewSyncLoader.java
@@ -0,0 +1,439 @@
+/*
+ * Copyright (C) 2011 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.webkit.cts;
+
+import android.graphics.Bitmap;
+import android.graphics.Picture;
+import android.os.Looper;
+import android.os.SystemClock;
+import android.webkit.WebChromeClient;
+import android.webkit.WebView;
+import android.webkit.WebView.PictureListener;
+import android.webkit.WebViewClient;
+
+import androidx.annotation.CallSuper;
+
+import com.android.compatibility.common.util.PollingCheck;
+
+import junit.framework.Assert;
+
+import java.util.Map;
+import java.util.concurrent.Callable;
+
+/**
+ * Utility class to simplify tests that need to load data into a WebView and wait for completion
+ * conditions.
+ *
+ * May be used from any thread.
+ */
+public class WebViewSyncLoader {
+ /**
+ * Set to true after onPageFinished is called.
+ */
+ private boolean mLoaded;
+
+ /**
+ * Set to true after onNewPicture is called. Reset when onPageStarted
+ * is called.
+ */
+ private boolean mNewPicture;
+
+ /**
+ * The progress, in percentage, of the page load. Valid values are between
+ * 0 and 100.
+ */
+ private int mProgress;
+
+ /**
+ * The WebView that calls will be made on.
+ */
+ private WebView mWebView;
+
+
+ public WebViewSyncLoader(WebView webView) {
+ init(webView, new WaitForLoadedClient(this), new WaitForProgressClient(this),
+ new WaitForNewPicture(this));
+ }
+
+ public WebViewSyncLoader(
+ WebView webView,
+ WaitForLoadedClient waitForLoadedClient,
+ WaitForProgressClient waitForProgressClient,
+ WaitForNewPicture waitForNewPicture) {
+ init(webView, waitForLoadedClient, waitForProgressClient, waitForNewPicture);
+ }
+
+ private void init(
+ final WebView webView,
+ final WaitForLoadedClient waitForLoadedClient,
+ final WaitForProgressClient waitForProgressClient,
+ final WaitForNewPicture waitForNewPicture) {
+ if (!isUiThread()) {
+ WebkitUtils.onMainThreadSync(() -> {
+ init(webView, waitForLoadedClient, waitForProgressClient, waitForNewPicture);
+ });
+ return;
+ }
+ mWebView = webView;
+ mWebView.setWebViewClient(waitForLoadedClient);
+ mWebView.setWebChromeClient(waitForProgressClient);
+ mWebView.setPictureListener(waitForNewPicture);
+ }
+
+ /**
+ * Detach listeners from this WebView, undoing the changes made to enable sync loading.
+ */
+ public void detach() {
+ if (!isUiThread()) {
+ WebkitUtils.onMainThreadSync(this::detach);
+ return;
+ }
+ mWebView.setWebChromeClient(null);
+ mWebView.setWebViewClient(null);
+ mWebView.setPictureListener(null);
+ mWebView = null;
+ }
+
+ /**
+ * Detach listeners, and destroy this webview.
+ */
+ public void destroy() {
+ if (!isUiThread()) {
+ WebkitUtils.onMainThreadSync(this::destroy);
+ return;
+ }
+ WebView webView = mWebView;
+ detach();
+ webView.clearHistory();
+ webView.clearCache(true);
+ webView.destroy();
+ }
+
+ /**
+ * Accessor for underlying WebView.
+ * @return The WebView being wrapped by this class.
+ */
+ public WebView getWebView() {
+ return mWebView;
+ }
+
+ /**
+ * Called from WaitForNewPicture, this is used to indicate that
+ * the page has been drawn.
+ */
+ public synchronized void onNewPicture() {
+ mNewPicture = true;
+ this.notifyAll();
+ }
+
+ /**
+ * Called from WaitForLoadedClient, this is used to clear the picture
+ * draw state so that draws before the URL begins loading don't count.
+ */
+ public synchronized void onPageStarted() {
+ mNewPicture = false; // Earlier paints won't count.
+ }
+
+ /**
+ * Called from WaitForLoadedClient, this is used to indicate that
+ * the page is loaded, but not drawn yet.
+ */
+ public synchronized void onPageFinished() {
+ mLoaded = true;
+ this.notifyAll();
+ }
+
+ /**
+ * Called from the WebChrome client, this sets the current progress
+ * for a page.
+ * @param progress The progress made so far between 0 and 100.
+ */
+ public synchronized void onProgressChanged(int progress) {
+ mProgress = progress;
+ this.notifyAll();
+ }
+
+ /**
+ * Calls {@link WebView#loadUrl} on the WebView and then waits for completion.
+ *
+ * <p>Test fails if the load timeout elapses.
+ */
+ public void loadUrlAndWaitForCompletion(final String url) {
+ callAndWait(() -> mWebView.loadUrl(url));
+ }
+
+ /**
+ * Calls {@link WebView#loadUrl(String,Map<String,String>)} on the WebView and waits for
+ * completion.
+ *
+ * <p>Test fails if the load timeout elapses.
+ */
+ public void loadUrlAndWaitForCompletion(final String url,
+ final Map<String, String> extraHeaders) {
+ callAndWait(() -> mWebView.loadUrl(url, extraHeaders));
+ }
+
+ /**
+ * Calls {@link WebView#postUrl(String,byte[])} on the WebView and then waits for completion.
+ *
+ * <p>Test fails if the load timeout elapses.
+ *
+ * @param url The URL to load.
+ * @param postData the data will be passed to "POST" request.
+ */
+ public void postUrlAndWaitForCompletion(final String url, final byte[] postData) {
+ callAndWait(() -> mWebView.postUrl(url, postData));
+ }
+
+ /**
+ * Calls {@link WebView#loadData(String,String,String)} on the WebView and then waits for
+ * completion.
+ *
+ * <p>Test fails if the load timeout elapses.
+ */
+ public void loadDataAndWaitForCompletion(final String data,
+ final String mimeType, final String encoding) {
+ callAndWait(() -> mWebView.loadData(data, mimeType, encoding));
+ }
+
+ /**
+ * Calls {@link WebView#loadDataWithBaseUrl(String,String,String,String,String)} on the WebView
+ * and then waits for completion.
+ *
+ * <p>Test fails if the load timeout elapses.
+ */
+ public void loadDataWithBaseURLAndWaitForCompletion(final String baseUrl,
+ final String data, final String mimeType, final String encoding,
+ final String historyUrl) {
+ callAndWait(
+ () -> mWebView.loadDataWithBaseURL(baseUrl, data, mimeType, encoding, historyUrl));
+ }
+
+ /**
+ * Reloads a page and waits for it to complete reloading. Use reload
+ * if it is a form resubmission and the onFormResubmission responds
+ * by telling WebView not to resubmit it.
+ */
+ public void reloadAndWaitForCompletion() {
+ callAndWait(() -> mWebView.reload());
+ }
+
+ /**
+ * Use this only when JavaScript causes a page load to wait for the
+ * page load to complete. Otherwise use loadUrlAndWaitForCompletion or
+ * similar functions.
+ */
+ public void waitForLoadCompletion() {
+ waitForCriteria(WebkitUtils.TEST_TIMEOUT_MS,
+ new Callable<Boolean>() {
+ @Override
+ public Boolean call() {
+ return isLoaded();
+ }
+ });
+ clearLoad();
+ }
+
+ private void waitForCriteria(long timeout, Callable<Boolean> doneCriteria) {
+ if (isUiThread()) {
+ waitOnUiThread(timeout, doneCriteria);
+ } else {
+ waitOnTestThread(timeout, doneCriteria);
+ }
+ }
+
+ /**
+ * @return Whether or not the load has finished.
+ */
+ private synchronized boolean isLoaded() {
+ return mLoaded && mNewPicture && mProgress == 100;
+ }
+
+ /**
+ * Makes a WebView call, waits for completion and then resets the
+ * load state in preparation for the next load call.
+ *
+ * <p>This method may be called on the UI thread.
+ *
+ * @param call The call to make on the UI thread prior to waiting.
+ */
+ private void callAndWait(Runnable call) {
+ Assert.assertTrue("WebViewSyncLoader.load*AndWaitForCompletion calls "
+ + "may not be mixed with load* calls directly on WebView "
+ + "without calling waitForLoadCompletion after the load",
+ !isLoaded());
+ clearLoad(); // clear any extraneous signals from a previous load.
+ if (isUiThread()) {
+ call.run();
+ } else {
+ WebkitUtils.onMainThread(call);
+ }
+ waitForLoadCompletion();
+ }
+
+ /**
+ * Called whenever a load has been completed so that a subsequent call to
+ * waitForLoadCompletion doesn't return immediately.
+ */
+ private synchronized void clearLoad() {
+ mLoaded = false;
+ mNewPicture = false;
+ mProgress = 0;
+ }
+
+ /**
+ * Uses a polling mechanism, while pumping messages to check when the
+ * criteria is met.
+ */
+ private void waitOnUiThread(long timeout, final Callable<Boolean> doneCriteria) {
+ new PollingCheck(timeout) {
+ @Override
+ protected boolean check() {
+ pumpMessages();
+ try {
+ return doneCriteria.call();
+ } catch (Exception e) {
+ Assert.fail("Unexpected error while checking the criteria: "
+ + e.getMessage());
+ return true;
+ }
+ }
+ }.run();
+ }
+
+ /**
+ * Uses a wait/notify to check when the criteria is met.
+ */
+ private synchronized void waitOnTestThread(long timeout, Callable<Boolean> doneCriteria) {
+ try {
+ long waitEnd = SystemClock.uptimeMillis() + timeout;
+ long timeRemaining = timeout;
+ while (!doneCriteria.call() && timeRemaining > 0) {
+ this.wait(timeRemaining);
+ timeRemaining = waitEnd - SystemClock.uptimeMillis();
+ }
+ Assert.assertTrue("Action failed to complete before timeout", doneCriteria.call());
+ } catch (InterruptedException e) {
+ // We'll just drop out of the loop and fail
+ } catch (Exception e) {
+ Assert.fail("Unexpected error while checking the criteria: "
+ + e.getMessage());
+ }
+ }
+
+ /**
+ * Pumps all currently-queued messages in the UI thread and then exits.
+ * This is useful to force processing while running tests in the UI thread.
+ */
+ private void pumpMessages() {
+ class ExitLoopException extends RuntimeException {
+ }
+
+ // Force loop to exit when processing this. Loop.quit() doesn't
+ // work because this is the main Loop.
+ mWebView.getHandler().post(new Runnable() {
+ @Override
+ public void run() {
+ throw new ExitLoopException(); // exit loop!
+ }
+ });
+ try {
+ // Pump messages until our message gets through.
+ Looper.loop();
+ } catch (ExitLoopException e) {
+ }
+ }
+
+ /**
+ * Returns true if the current thread is the UI thread based on the
+ * Looper.
+ */
+ private static boolean isUiThread() {
+ return (Looper.myLooper() == Looper.getMainLooper());
+ }
+
+ /**
+ * A WebChromeClient used to capture the onProgressChanged for use
+ * in waitFor functions. If a test must override the WebChromeClient,
+ * it can derive from this class or call onProgressChanged
+ * directly.
+ */
+ public static class WaitForProgressClient extends WebChromeClient {
+ private WebViewSyncLoader mWebViewSyncLoader;
+
+ public WaitForProgressClient(WebViewSyncLoader webViewSyncLoader) {
+ mWebViewSyncLoader = webViewSyncLoader;
+ }
+
+ @Override
+ @CallSuper
+ public void onProgressChanged(WebView view, int newProgress) {
+ super.onProgressChanged(view, newProgress);
+ mWebViewSyncLoader.onProgressChanged(newProgress);
+ }
+ }
+
+ /**
+ * A WebViewClient that captures the onPageFinished for use in
+ * waitFor functions. Using initializeWebView sets the WaitForLoadedClient
+ * into the WebView. If a test needs to set a specific WebViewClient and
+ * needs the waitForCompletion capability then it should derive from
+ * WaitForLoadedClient or call WebViewSyncLoader.onPageFinished.
+ */
+ public static class WaitForLoadedClient extends WebViewClient {
+ private WebViewSyncLoader mWebViewSyncLoader;
+
+ public WaitForLoadedClient(WebViewSyncLoader webViewSyncLoader) {
+ mWebViewSyncLoader = webViewSyncLoader;
+ }
+
+ @Override
+ @CallSuper
+ public void onPageFinished(WebView view, String url) {
+ super.onPageFinished(view, url);
+ mWebViewSyncLoader.onPageFinished();
+ }
+
+ @Override
+ @CallSuper
+ public void onPageStarted(WebView view, String url, Bitmap favicon) {
+ super.onPageStarted(view, url, favicon);
+ mWebViewSyncLoader.onPageStarted();
+ }
+ }
+
+ /**
+ * A PictureListener that captures the onNewPicture for use in
+ * waitForLoadCompletion. Using initializeWebView sets the PictureListener
+ * into the WebView. If a test needs to set a specific PictureListener and
+ * needs the waitForCompletion capability then it should call
+ * WebViewSyncLoader.onNewPicture.
+ */
+ public static class WaitForNewPicture implements PictureListener {
+ private WebViewSyncLoader mWebViewSyncLoader;
+
+ public WaitForNewPicture(WebViewSyncLoader webViewSyncLoader) {
+ mWebViewSyncLoader = webViewSyncLoader;
+ }
+
+ @Override
+ @CallSuper
+ public void onNewPicture(WebView view, Picture picture) {
+ mWebViewSyncLoader.onNewPicture();
+ }
+ }
+}
diff --git a/libs/deviceutillegacy/src/android/webkit/cts/WebkitUtils.java b/libs/deviceutillegacy/src/android/webkit/cts/WebkitUtils.java
index 419c633..eb9bdaa 100644
--- a/libs/deviceutillegacy/src/android/webkit/cts/WebkitUtils.java
+++ b/libs/deviceutillegacy/src/android/webkit/cts/WebkitUtils.java
@@ -38,7 +38,15 @@
*/
public final class WebkitUtils {
- private static final long TEST_TIMEOUT_MS = 20000L; // 20s.
+ /**
+ * Arbitrary timeout for tests. This is intended to be used with {@link TimeUnit#MILLISECONDS}
+ * so that this can represent 20 seconds.
+ *
+ * <p class=note><b>Note:</b> only use this timeout value for the unexpected case, not for the
+ * correct case, as this exceeds the time recommendation for {@link
+ * androidx.test.filters.MediumTest}.
+ */
+ public static final long TEST_TIMEOUT_MS = 20000L; // 20s.
// A handler for the main thread.
private static final Handler sMainHandler = new Handler(Looper.getMainLooper());
diff --git a/suite/audio_quality/lib/src/task/TaskGeneric.cpp b/suite/audio_quality/lib/src/task/TaskGeneric.cpp
index c0e4935..4a394e2 100644
--- a/suite/audio_quality/lib/src/task/TaskGeneric.cpp
+++ b/suite/audio_quality/lib/src/task/TaskGeneric.cpp
@@ -124,7 +124,7 @@
bool TaskGeneric::addStringAttribute(const android::String8& key, const android::String8& value)
{
- std::set<android::String8, android::String8>::iterator it = mAllowedStringAttributes.find(key);
+ auto it = mAllowedStringAttributes.find(key);
if (it == mAllowedStringAttributes.end()) {
return false; // not allowed
}
@@ -134,7 +134,7 @@
bool TaskGeneric::findStringAttribute(const android::String8& key, android::String8& value) const
{
- std::map<android::String8, android::String8>::const_iterator it = mStringAttributes.find(key);
+ auto it = mStringAttributes.find(key);
if (it == mStringAttributes.end()) {
return false; // not found
}
diff --git a/tests/AlarmManager/src/android/alarmmanager/cts/AppStandbyTests.java b/tests/AlarmManager/src/android/alarmmanager/cts/AppStandbyTests.java
index 36acd82..ecd9792 100644
--- a/tests/AlarmManager/src/android/alarmmanager/cts/AppStandbyTests.java
+++ b/tests/AlarmManager/src/android/alarmmanager/cts/AppStandbyTests.java
@@ -24,6 +24,7 @@
import android.alarmmanager.alarmtestapp.cts.TestAlarmReceiver;
import android.alarmmanager.alarmtestapp.cts.TestAlarmScheduler;
+import android.app.AlarmManager;
import android.content.BroadcastReceiver;
import android.content.ComponentName;
import android.content.Context;
@@ -36,6 +37,7 @@
import android.support.test.runner.AndroidJUnit4;
import android.support.test.uiautomator.UiDevice;
import android.util.Log;
+import android.util.LongArray;
import com.android.compatibility.common.util.AppStandbyUtils;
@@ -59,49 +61,93 @@
private static final String TEST_APP_PACKAGE = "android.alarmmanager.alarmtestapp.cts";
private static final String TEST_APP_RECEIVER = TEST_APP_PACKAGE + ".TestAlarmScheduler";
- private static final long DEFAULT_WAIT = 4_000;
+ private static final long DEFAULT_WAIT = 2_000;
private static final long POLL_INTERVAL = 200;
// Tweaked alarm manager constants to facilitate testing
- private static final long ALLOW_WHILE_IDLE_SHORT_TIME = 15_000;
- private static final long MIN_FUTURITY = 2_000;
- private static final long[] APP_STANDBY_DELAYS = {0, 10_000, 20_000, 30_000, 600_000};
+ private static final long ALLOW_WHILE_IDLE_SHORT_TIME = 10_000;
+ private static final long MIN_FUTURITY = 1_000;
+
+ // Not touching ACTIVE and RARE parameters for this test
+ private static final int WORKING_INDEX = 0;
+ private static final int FREQUENT_INDEX = 1;
+ private static final int RARE_INDEX = 2;
private static final String[] APP_BUCKET_TAGS = {
- "active",
"working_set",
"frequent",
"rare",
- "never"
};
- private static final String[] APP_BUCKET_KEYS = {
- "standby_active_delay",
+ private static final String[] APP_BUCKET_DELAY_KEYS = {
"standby_working_delay",
"standby_frequent_delay",
"standby_rare_delay",
- "standby_never_delay",
};
+ private static final long[] APP_STANDBY_DELAYS = {
+ 5_000, // Working set
+ 10_000, // Frequent
+ 15_000, // Rare
+ };
+ private static final long APP_STANDBY_WINDOW = 10_000;
+ private static final String[] APP_BUCKET_QUOTA_KEYS = {
+ "standby_working_quota",
+ "standby_frequent_quota",
+ "standby_rare_quota",
+ };
+ private static final int[] APP_STANDBY_QUOTAS = {
+ 5, // Working set
+ 3, // Frequent
+ 1, // Rare
+ };
+
+ // Settings common for all tests
+ private static final String COMMON_SETTINGS;
+
+ static {
+ final StringBuilder settings = new StringBuilder();
+ settings.append("min_futurity=");
+ settings.append(MIN_FUTURITY);
+ settings.append(",allow_while_idle_short_time=");
+ settings.append(ALLOW_WHILE_IDLE_SHORT_TIME);
+ for (int i = 0; i < APP_STANDBY_DELAYS.length; i++) {
+ settings.append(",");
+ settings.append(APP_BUCKET_DELAY_KEYS[i]);
+ settings.append("=");
+ settings.append(APP_STANDBY_DELAYS[i]);
+ }
+ settings.append(",app_standby_window=");
+ settings.append(APP_STANDBY_WINDOW);
+ for (int i = 0; i < APP_STANDBY_QUOTAS.length; i++) {
+ settings.append(",");
+ settings.append(APP_BUCKET_QUOTA_KEYS[i]);
+ settings.append("=");
+ settings.append(APP_STANDBY_QUOTAS[i]);
+ }
+ COMMON_SETTINGS = settings.toString();
+ }
// Save the state before running tests to restore it after we finish testing.
private static boolean sOrigAppStandbyEnabled;
+ // Test app's alarm history to help predict when a subsequent alarm is going to get deferred.
+ private static TestAlarmHistory sAlarmHistory;
private Context mContext;
private ComponentName mAlarmScheduler;
private UiDevice mUiDevice;
private AtomicInteger mAlarmCount;
- private volatile long mLastAlarmTime;
private final BroadcastReceiver mAlarmStateReceiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
mAlarmCount.getAndAdd(intent.getIntExtra(TestAlarmReceiver.EXTRA_ALARM_COUNT, 1));
- mLastAlarmTime = SystemClock.elapsedRealtime();
- Log.d(TAG, "No. of expirations: " + mAlarmCount
- + " elapsed: " + SystemClock.elapsedRealtime());
+ final long nowElapsed = SystemClock.elapsedRealtime();
+ sAlarmHistory.addTime(nowElapsed);
+ Log.d(TAG, "No. of expirations: " + mAlarmCount + " elapsed: " + nowElapsed);
}
};
@BeforeClass
public static void setUpTests() throws Exception {
+ sAlarmHistory = new TestAlarmHistory();
sOrigAppStandbyEnabled = AppStandbyUtils.isAppStandbyEnabledAtRuntime();
if (!sOrigAppStandbyEnabled) {
AppStandbyUtils.setAppStandbyEnabledAtRuntime(true);
@@ -117,16 +163,12 @@
mUiDevice = UiDevice.getInstance(InstrumentationRegistry.getInstrumentation());
mAlarmScheduler = new ComponentName(TEST_APP_PACKAGE, TEST_APP_RECEIVER);
mAlarmCount = new AtomicInteger(0);
- updateAlarmManagerConstants();
+ updateAlarmManagerConstants(true);
setBatteryCharging(false);
final IntentFilter intentFilter = new IntentFilter();
intentFilter.addAction(TestAlarmReceiver.ACTION_REPORT_ALARM_EXPIRED);
mContext.registerReceiver(mAlarmStateReceiver, intentFilter);
assumeTrue("App Standby not enabled on device", AppStandbyUtils.isAppStandbyEnabled());
- setAppStandbyBucket("active");
- scheduleAlarm(SystemClock.elapsedRealtime(), false, 0);
- Thread.sleep(MIN_FUTURITY);
- assertTrue("Alarm not sent when app in active", waitForAlarms(1));
}
private void scheduleAlarm(long triggerMillis, boolean allowWhileIdle, long interval) {
@@ -140,50 +182,99 @@
mContext.sendBroadcast(setAlarmIntent);
}
+ private void scheduleAlarmClock(long triggerRTC) {
+ AlarmManager.AlarmClockInfo alarmInfo = new AlarmManager.AlarmClockInfo(triggerRTC, null);
+
+ final Intent setAlarmClockIntent = new Intent(TestAlarmScheduler.ACTION_SET_ALARM_CLOCK);
+ setAlarmClockIntent.setComponent(mAlarmScheduler);
+ setAlarmClockIntent.putExtra(TestAlarmScheduler.EXTRA_ALARM_CLOCK_INFO, alarmInfo);
+ mContext.sendBroadcast(setAlarmClockIntent);
+ }
+
+
private void testBucketDelay(int bucketIndex) throws Exception {
- setAppStandbyBucket(APP_BUCKET_TAGS[bucketIndex]);
- final long triggerTime = SystemClock.elapsedRealtime() + MIN_FUTURITY;
- final long minTriggerTime = mLastAlarmTime + APP_STANDBY_DELAYS[bucketIndex];
- scheduleAlarm(triggerTime, false, 0);
+ setAppStandbyBucket("active");
+ final long firstTrigger = SystemClock.elapsedRealtime() + MIN_FUTURITY;
+ scheduleAlarm(firstTrigger, false, 0);
Thread.sleep(MIN_FUTURITY);
- if (triggerTime + DEFAULT_WAIT < minTriggerTime) {
+ assertTrue("Alarm did not fire when app in active", waitForAlarm());
+
+ setAppStandbyBucket(APP_BUCKET_TAGS[bucketIndex]);
+ final long nextTriggerTime = SystemClock.elapsedRealtime() + MIN_FUTURITY;
+ final long minTriggerTime = sAlarmHistory.getLast(1) + APP_STANDBY_DELAYS[bucketIndex];
+ scheduleAlarm(nextTriggerTime, false, 0);
+ Thread.sleep(MIN_FUTURITY);
+ if (nextTriggerTime + DEFAULT_WAIT < minTriggerTime) {
assertFalse("Alarm went off before " + APP_BUCKET_TAGS[bucketIndex] + " delay",
- waitForAlarms(1));
- Thread.sleep(minTriggerTime - SystemClock.elapsedRealtime());
+ waitForAlarm());
}
+ Thread.sleep(minTriggerTime - SystemClock.elapsedRealtime());
assertTrue("Deferred alarm did not go off after " + APP_BUCKET_TAGS[bucketIndex] + " delay",
- waitForAlarms(1));
+ waitForAlarm());
+ }
+
+ @Test
+ public void testActiveDelay() throws Exception {
+ updateAlarmManagerConstants(false);
+ setAppStandbyBucket("active");
+ long nextTrigger = SystemClock.elapsedRealtime() + MIN_FUTURITY;
+ for (int i = 0; i < 3; i++) {
+ scheduleAlarm(nextTrigger, false, 0);
+ Thread.sleep(MIN_FUTURITY);
+ assertTrue("Alarm not received as expected when app is in active", waitForAlarm());
+ nextTrigger += MIN_FUTURITY;
+ }
}
@Test
public void testWorkingSetDelay() throws Exception {
- testBucketDelay(1);
+ updateAlarmManagerConstants(false);
+ testBucketDelay(WORKING_INDEX);
}
@Test
public void testFrequentDelay() throws Exception {
- testBucketDelay(2);
+ updateAlarmManagerConstants(false);
+ testBucketDelay(FREQUENT_INDEX);
}
@Test
public void testRareDelay() throws Exception {
- testBucketDelay(3);
+ updateAlarmManagerConstants(false);
+ testBucketDelay(RARE_INDEX);
+ }
+
+ @Test
+ public void testNeverDelay() throws Exception {
+ updateAlarmManagerConstants(false);
+ setAppStandbyBucket("never");
+ final long expectedTrigger = SystemClock.elapsedRealtime() + MIN_FUTURITY;
+ scheduleAlarm(expectedTrigger, true, 0);
+ Thread.sleep(10_000);
+ assertFalse("Alarm received when app was in never bucket", waitForAlarm());
}
@Test
public void testBucketUpgradeToSmallerDelay() throws Exception {
- setAppStandbyBucket(APP_BUCKET_TAGS[2]);
+ updateAlarmManagerConstants(false);
+ setAppStandbyBucket("active");
+ final long firstTrigger = SystemClock.elapsedRealtime() + MIN_FUTURITY;
+ scheduleAlarm(firstTrigger, false, 0);
+ Thread.sleep(MIN_FUTURITY);
+ assertTrue("Alarm did not fire when app in active", waitForAlarm());
+
+ setAppStandbyBucket(APP_BUCKET_TAGS[FREQUENT_INDEX]);
final long triggerTime = SystemClock.elapsedRealtime() + MIN_FUTURITY;
- final long workingSetExpectedTrigger = mLastAlarmTime + APP_STANDBY_DELAYS[1];
+ final long workingSetExpectedTrigger = sAlarmHistory.getLast(1)
+ + APP_STANDBY_DELAYS[WORKING_INDEX];
scheduleAlarm(triggerTime, false, 0);
Thread.sleep(workingSetExpectedTrigger - SystemClock.elapsedRealtime());
- assertFalse("The alarm went off before frequent delay", waitForAlarms(1));
- setAppStandbyBucket(APP_BUCKET_TAGS[1]);
+ assertFalse("The alarm went off before frequent delay", waitForAlarm());
+ setAppStandbyBucket(APP_BUCKET_TAGS[WORKING_INDEX]);
assertTrue("The alarm did not go off when app bucket upgraded to working_set",
- waitForAlarms(1));
+ waitForAlarm());
}
-
/**
* This is different to {@link #testBucketUpgradeToSmallerDelay()} in the sense that the bucket
* upgrade shifts eligibility to a point earlier than when the alarm is scheduled for.
@@ -192,61 +283,148 @@
*/
@Test
public void testBucketUpgradeToNoDelay() throws Exception {
- setAppStandbyBucket(APP_BUCKET_TAGS[3]);
- final long triggerTime1 = mLastAlarmTime + APP_STANDBY_DELAYS[2];
+ updateAlarmManagerConstants(false);
+
+ setAppStandbyBucket("active");
+ final long firstTrigger = SystemClock.elapsedRealtime() + MIN_FUTURITY;
+ scheduleAlarm(firstTrigger, false, 0);
+ Thread.sleep(MIN_FUTURITY);
+ assertTrue("Alarm did not fire when app in active", waitForAlarm());
+
+ setAppStandbyBucket(APP_BUCKET_TAGS[RARE_INDEX]);
+ final long triggerTime1 = sAlarmHistory.getLast(1) + APP_STANDBY_DELAYS[FREQUENT_INDEX];
scheduleAlarm(triggerTime1, false, 0);
Thread.sleep(triggerTime1 - SystemClock.elapsedRealtime());
assertFalse("The alarm went off after frequent delay when app in rare bucket",
- waitForAlarms(1));
- setAppStandbyBucket(APP_BUCKET_TAGS[1]);
+ waitForAlarm());
+ setAppStandbyBucket(APP_BUCKET_TAGS[WORKING_INDEX]);
assertTrue("The alarm did not go off when app bucket upgraded to working_set",
- waitForAlarms(1));
+ waitForAlarm());
// Once more
- setAppStandbyBucket(APP_BUCKET_TAGS[3]);
- final long triggerTime2 = mLastAlarmTime + APP_STANDBY_DELAYS[2];
+ setAppStandbyBucket(APP_BUCKET_TAGS[RARE_INDEX]);
+ final long triggerTime2 = sAlarmHistory.getLast(1) + APP_STANDBY_DELAYS[FREQUENT_INDEX];
scheduleAlarm(triggerTime2, false, 0);
- setAppStandbyBucket(APP_BUCKET_TAGS[0]);
+ setAppStandbyBucket("active");
Thread.sleep(triggerTime2 - SystemClock.elapsedRealtime());
assertTrue("The alarm did not go off as scheduled when the app was in active",
- waitForAlarms(1));
+ waitForAlarm());
+ }
+
+ public void testSimpleQuotaDeferral(int bucketIndex) throws Exception {
+ setAppStandbyBucket(APP_BUCKET_TAGS[bucketIndex]);
+ final int quota = APP_STANDBY_QUOTAS[bucketIndex];
+
+ long startElapsed = SystemClock.elapsedRealtime();
+ final long freshWindowPoint = sAlarmHistory.getLast(1) + APP_STANDBY_WINDOW + 1;
+ if (freshWindowPoint > startElapsed) {
+ Thread.sleep(freshWindowPoint - startElapsed);
+ startElapsed = freshWindowPoint;
+ // Now we should have no alarms in the past APP_STANDBY_WINDOW
+ }
+ final long desiredTrigger = startElapsed + APP_STANDBY_WINDOW;
+ final long firstTrigger = startElapsed + 4_000;
+ assertTrue("Quota too large for test",
+ firstTrigger + ((quota - 1) * MIN_FUTURITY) < desiredTrigger);
+ for (int i = 0; i < quota; i++) {
+ final long trigger = firstTrigger + (i * MIN_FUTURITY);
+ scheduleAlarm(trigger, false, 0);
+ Thread.sleep(trigger - SystemClock.elapsedRealtime());
+ assertTrue("Alarm within quota not firing as expected", waitForAlarm());
+ }
+
+ // Now quota is reached, any subsequent alarm should get deferred.
+ scheduleAlarm(desiredTrigger, false, 0);
+ Thread.sleep(desiredTrigger - SystemClock.elapsedRealtime());
+ assertFalse("Alarm exceeding quota not deferred", waitForAlarm());
+ final long minTrigger = firstTrigger + 1 + APP_STANDBY_WINDOW;
+ Thread.sleep(minTrigger - SystemClock.elapsedRealtime());
+ assertTrue("Alarm exceeding quota not delivered after expected delay", waitForAlarm());
+ }
+
+ @Test
+ public void testActiveQuota() throws Exception {
+ setAppStandbyBucket("active");
+ long nextTrigger = SystemClock.elapsedRealtime() + MIN_FUTURITY;
+ for (int i = 0; i < 3; i++) {
+ scheduleAlarm(nextTrigger, false, 0);
+ Thread.sleep(MIN_FUTURITY);
+ assertTrue("Alarm not received as expected when app is in active", waitForAlarm());
+ nextTrigger += MIN_FUTURITY;
+ }
+ }
+
+ @Test
+ public void testWorkingQuota() throws Exception {
+ testSimpleQuotaDeferral(WORKING_INDEX);
+ }
+
+ @Test
+ public void testFrequentQuota() throws Exception {
+ testSimpleQuotaDeferral(FREQUENT_INDEX);
+ }
+
+ @Test
+ public void testRareQuota() throws Exception {
+ testSimpleQuotaDeferral(RARE_INDEX);
+ }
+
+ @Test
+ public void testNeverQuota() throws Exception {
+ setAppStandbyBucket("never");
+ final long expectedTrigger = SystemClock.elapsedRealtime() + MIN_FUTURITY;
+ scheduleAlarm(expectedTrigger, true, 0);
+ Thread.sleep(10_000);
+ assertFalse("Alarm received when app was in never bucket", waitForAlarm());
+ }
+
+ @Test
+ public void testAlarmClockUnaffected() throws Exception {
+ setAppStandbyBucket("never");
+ final long trigger = System.currentTimeMillis() + MIN_FUTURITY;
+ scheduleAlarmClock(trigger);
+ Thread.sleep(MIN_FUTURITY);
+ assertTrue("Alarm clock not received as expected", waitForAlarm());
}
@Test
public void testAllowWhileIdleAlarms() throws Exception {
+ updateAlarmManagerConstants(false);
+ setAppStandbyBucket("active");
final long firstTrigger = SystemClock.elapsedRealtime() + MIN_FUTURITY;
scheduleAlarm(firstTrigger, true, 0);
Thread.sleep(MIN_FUTURITY);
- assertTrue("first allow_while_idle alarm did not go off as scheduled", waitForAlarms(1));
- scheduleAlarm(mLastAlarmTime + 9_000, true, 0);
+ assertTrue("first allow_while_idle alarm did not go off as scheduled", waitForAlarm());
+ scheduleAlarm(sAlarmHistory.getLast(1) + 7_000, true, 0);
// First check for the case where allow_while_idle delay should supersede app standby
- setAppStandbyBucket(APP_BUCKET_TAGS[1]);
- Thread.sleep(APP_STANDBY_DELAYS[1]);
- assertFalse("allow_while_idle alarm went off before short time", waitForAlarms(1));
- long expectedTriggerTime = mLastAlarmTime + ALLOW_WHILE_IDLE_SHORT_TIME;
+ setAppStandbyBucket(APP_BUCKET_TAGS[WORKING_INDEX]);
+ Thread.sleep(APP_STANDBY_DELAYS[WORKING_INDEX]);
+ assertFalse("allow_while_idle alarm went off before short time", waitForAlarm());
+ long expectedTriggerTime = sAlarmHistory.getLast(1) + ALLOW_WHILE_IDLE_SHORT_TIME;
Thread.sleep(expectedTriggerTime - SystemClock.elapsedRealtime());
- assertTrue("allow_while_idle alarm did not go off after short time", waitForAlarms(1));
+ assertTrue("allow_while_idle alarm did not go off after short time", waitForAlarm());
// Now the other case, app standby delay supersedes the allow_while_idle delay
- scheduleAlarm(mLastAlarmTime + 12_000, true, 0);
- setAppStandbyBucket(APP_BUCKET_TAGS[2]);
+ scheduleAlarm(sAlarmHistory.getLast(1) + 7_000, true, 0);
+ setAppStandbyBucket(APP_BUCKET_TAGS[RARE_INDEX]);
Thread.sleep(ALLOW_WHILE_IDLE_SHORT_TIME);
- assertFalse("allow_while_idle alarm went off before " + APP_STANDBY_DELAYS[2]
- + "ms, when in bucket " + APP_BUCKET_TAGS[2], waitForAlarms(1));
- expectedTriggerTime = mLastAlarmTime + APP_STANDBY_DELAYS[2];
+ assertFalse("allow_while_idle alarm went off before " + APP_STANDBY_DELAYS[RARE_INDEX]
+ + "ms, when in bucket " + APP_BUCKET_TAGS[RARE_INDEX], waitForAlarm());
+ expectedTriggerTime = sAlarmHistory.getLast(1) + APP_STANDBY_DELAYS[RARE_INDEX];
Thread.sleep(expectedTriggerTime - SystemClock.elapsedRealtime());
- assertTrue("allow_while_idle alarm did not go off even after " + APP_STANDBY_DELAYS[2]
- + "ms, when in bucket " + APP_BUCKET_TAGS[2], waitForAlarms(1));
+ assertTrue("allow_while_idle alarm did not go off even after "
+ + APP_STANDBY_DELAYS[RARE_INDEX]
+ + "ms, when in bucket " + APP_BUCKET_TAGS[RARE_INDEX], waitForAlarm());
}
@Test
public void testPowerWhitelistedAlarmNotBlocked() throws Exception {
- setAppStandbyBucket(APP_BUCKET_TAGS[3]);
+ setAppStandbyBucket(APP_BUCKET_TAGS[RARE_INDEX]);
setPowerWhitelisted(true);
final long triggerTime = SystemClock.elapsedRealtime() + MIN_FUTURITY;
scheduleAlarm(triggerTime, false, 0);
Thread.sleep(MIN_FUTURITY);
- assertTrue("Alarm did not go off for whitelisted app in rare bucket", waitForAlarms(1));
+ assertTrue("Alarm did not go off for whitelisted app in rare bucket", waitForAlarm());
setPowerWhitelisted(false);
}
@@ -270,13 +448,11 @@
}
}
- private void updateAlarmManagerConstants() throws IOException {
+ private void updateAlarmManagerConstants(boolean enableQuota) throws IOException {
final StringBuffer cmd = new StringBuffer("settings put global alarm_manager_constants ");
- cmd.append("min_futurity="); cmd.append(MIN_FUTURITY);
- cmd.append(",allow_while_idle_short_time="); cmd.append(ALLOW_WHILE_IDLE_SHORT_TIME);
- for (int i = 0; i < APP_STANDBY_DELAYS.length; i++) {
- cmd.append(",");
- cmd.append(APP_BUCKET_KEYS[i]); cmd.append("="); cmd.append(APP_STANDBY_DELAYS[i]);
+ cmd.append(COMMON_SETTINGS);
+ if (!enableQuota) {
+ cmd.append(",app_standby_quotas_enabled=false");
}
executeAndLog(cmd.toString());
}
@@ -311,8 +487,8 @@
return output;
}
- private boolean waitForAlarms(final int numAlarms) throws InterruptedException {
- final boolean success = waitUntil(() -> (mAlarmCount.get() == numAlarms), DEFAULT_WAIT);
+ private boolean waitForAlarm() throws InterruptedException {
+ final boolean success = waitUntil(() -> (mAlarmCount.get() == 1), DEFAULT_WAIT);
mAlarmCount.set(0);
return success;
}
@@ -325,6 +501,24 @@
return condition.isMet();
}
+ private static final class TestAlarmHistory {
+ private LongArray mHistory = new LongArray();
+
+ private synchronized void addTime(long timestamp) {
+ mHistory.add(timestamp);
+ }
+
+ /**
+ * Get the xth alarm time from the end.
+ */
+ private synchronized long getLast(int x) {
+ if (x == 0 || x > mHistory.size()) {
+ return 0;
+ }
+ return mHistory.get(mHistory.size() - x);
+ }
+ }
+
@FunctionalInterface
interface Condition {
boolean isMet();
diff --git a/tests/AlarmManager/src/android/alarmmanager/cts/BackgroundRestrictedAlarmsTest.java b/tests/AlarmManager/src/android/alarmmanager/cts/BackgroundRestrictedAlarmsTest.java
index a981e5a..f36b07f 100644
--- a/tests/AlarmManager/src/android/alarmmanager/cts/BackgroundRestrictedAlarmsTest.java
+++ b/tests/AlarmManager/src/android/alarmmanager/cts/BackgroundRestrictedAlarmsTest.java
@@ -136,7 +136,7 @@
@Test
public void testAlarmClockNotBlocked() throws Exception {
final long nowRTC = System.currentTimeMillis();
- final long waitInterval = 10_000;
+ final long waitInterval = 3_000;
final long triggerRTC = nowRTC + waitInterval;
scheduleAlarmClock(triggerRTC);
Thread.sleep(waitInterval);
diff --git a/tests/accessibilityservice/src/android/accessibilityservice/cts/utils/ActivityLaunchUtils.java b/tests/accessibilityservice/src/android/accessibilityservice/cts/utils/ActivityLaunchUtils.java
index 3fbccc7..5e7745a 100644
--- a/tests/accessibilityservice/src/android/accessibilityservice/cts/utils/ActivityLaunchUtils.java
+++ b/tests/accessibilityservice/src/android/accessibilityservice/cts/utils/ActivityLaunchUtils.java
@@ -119,6 +119,7 @@
public static void homeScreenOrBust(Context context, UiAutomation uiAutomation) {
wakeUpOrBust(context, uiAutomation);
+ if (context.getPackageManager().isInstantApp()) return;
if (isHomeScreenShowing(context, uiAutomation)) return;
try {
executeAndWaitOn(
diff --git a/tests/admin/src/android/admin/cts/DevicePolicyManagerTest.java b/tests/admin/src/android/admin/cts/DevicePolicyManagerTest.java
index ad1fd91..8bd83e2 100644
--- a/tests/admin/src/android/admin/cts/DevicePolicyManagerTest.java
+++ b/tests/admin/src/android/admin/cts/DevicePolicyManagerTest.java
@@ -46,6 +46,7 @@
import java.security.cert.CertificateException;
import java.security.cert.CertificateFactory;
import java.util.ArrayList;
+import java.util.Collections;
import java.util.List;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.TimeUnit;
@@ -66,6 +67,7 @@
private boolean mManagedProfiles;
private PackageManager mPackageManager;
private NotificationManager mNotificationManager;
+ private boolean mHasSecureLockScreen;
private static final String TEST_CA_STRING1 =
"-----BEGIN CERTIFICATE-----\n" +
@@ -98,6 +100,8 @@
mDeviceAdmin = mPackageManager.hasSystemFeature(PackageManager.FEATURE_DEVICE_ADMIN);
mManagedProfiles = mDeviceAdmin
&& mPackageManager.hasSystemFeature(PackageManager.FEATURE_MANAGED_USERS);
+ mHasSecureLockScreen =
+ mPackageManager.hasSystemFeature(PackageManager.FEATURE_SECURE_LOCK_SCREEN);
}
public void testGetActiveAdmins() {
@@ -870,7 +874,7 @@
}
public void testSetResetPasswordToken_failIfNotDeviceOrProfileOwner() {
- if (!mDeviceAdmin) {
+ if (!mDeviceAdmin || !mHasSecureLockScreen) {
Log.w(TAG, "Skipping testSetResetPasswordToken_failIfNotDeviceOwner");
return;
}
@@ -883,7 +887,7 @@
}
public void testClearResetPasswordToken_failIfNotDeviceOrProfileOwner() {
- if (!mDeviceAdmin) {
+ if (!mDeviceAdmin || !mHasSecureLockScreen) {
Log.w(TAG, "Skipping testClearResetPasswordToken_failIfNotDeviceOwner");
return;
}
@@ -896,7 +900,7 @@
}
public void testIsResetPasswordTokenActive_failIfNotDeviceOrProfileOwner() {
- if (!mDeviceAdmin) {
+ if (!mDeviceAdmin || !mHasSecureLockScreen) {
Log.w(TAG, "Skipping testIsResetPasswordTokenActive_failIfNotDeviceOwner");
return;
}
@@ -909,7 +913,7 @@
}
public void testResetPasswordWithToken_failIfNotDeviceOrProfileOwner() {
- if (!mDeviceAdmin) {
+ if (!mDeviceAdmin || !mHasSecureLockScreen) {
Log.w(TAG, "Skipping testResetPasswordWithToken_failIfNotDeviceOwner");
return;
}
@@ -922,7 +926,7 @@
}
public void testIsUsingUnifiedPassword_failIfNotProfileOwner() {
- if (!mDeviceAdmin) {
+ if (!mDeviceAdmin || !mHasSecureLockScreen) {
Log.w(TAG, "Skipping testIsUsingUnifiedPassword_failIfNotProfileOwner");
return;
}
@@ -1058,14 +1062,9 @@
return;
}
try {
- mDevicePolicyManager.addCrossProfileCalendarPackage(mComponent, TEST_PACKAGE_NAME);
- fail("addCrossProfileCalendarPackage did not throw expected SecurityException");
- } catch (SecurityException e) {
- assertProfileOwnerMessage(e.getMessage());
- }
- try {
- mDevicePolicyManager.removeCrossProfileCalendarPackage(mComponent, TEST_PACKAGE_NAME);
- fail("removeCrossProfileCalendarPackage did not throw expected SecurityException");
+ mDevicePolicyManager.setCrossProfileCalendarPackages(mComponent,
+ Collections.singleton(TEST_PACKAGE_NAME));
+ fail("setCrossProfileCalendarPackages did not throw expected SecurityException");
} catch (SecurityException e) {
assertProfileOwnerMessage(e.getMessage());
}
diff --git a/tests/app/app/AndroidManifest.xml b/tests/app/app/AndroidManifest.xml
index fb20e53..fef8625 100644
--- a/tests/app/app/AndroidManifest.xml
+++ b/tests/app/app/AndroidManifest.xml
@@ -152,7 +152,7 @@
</intent-filter>
</service>
- <service android:name="android.app.stubs.IsolatedService" android:isolatedProcess="true">
+ <service android:name="android.app.stubs.IsolatedService" android:isolatedProcess="true" android:useAppZygote="true">
</service>
<activity android:name="android.app.stubs.TestedScreen"
diff --git a/tests/app/app/res/xml/wallpaper.xml b/tests/app/app/res/xml/wallpaper.xml
index bce8793..e86c9b9 100644
--- a/tests/app/app/res/xml/wallpaper.xml
+++ b/tests/app/app/res/xml/wallpaper.xml
@@ -20,6 +20,7 @@
android:author="@string/wallpaper_collection"
android:description="@string/wallpaper_description"
android:showMetadataInPreview="true"
+ android:supportsMultipleDisplays="true"
android:contextDescription="@string/wallpaper_context"
android:contextUri="@string/wallpaper_context_uri"
android:settingsSliceUri="@string/wallpaper_slice_uri"
diff --git a/tests/app/app/src/android/app/stubs/LocalService.java b/tests/app/app/src/android/app/stubs/LocalService.java
index 6120a77..f914cdf 100644
--- a/tests/app/app/src/android/app/stubs/LocalService.java
+++ b/tests/app/app/src/android/app/stubs/LocalService.java
@@ -46,6 +46,8 @@
public static final int SET_VALUE_CODE = 7;
public static final int GET_PID_CODE = 8;
public static final int GET_UID_CODE = 9;
+ public static final int GET_PPID_CODE = 10;
+ public static final int GET_ZYGOTE_PRELOAD_CALLED = 11;
public static Context sServiceContext = null;
@@ -78,6 +80,14 @@
data.enforceInterface(SERVICE_LOCAL);
reply.writeInt(Process.myUid());
return true;
+ case GET_PPID_CODE:
+ data.enforceInterface(SERVICE_LOCAL);
+ reply.writeInt(Process.myPpid());
+ return true;
+ case GET_ZYGOTE_PRELOAD_CALLED:
+ data.enforceInterface(SERVICE_LOCAL);
+ reply.writeBoolean(ZygotePreload.preloadCalled());
+ return true;
default:
return super.onTransact(code, data, reply, flags);
}
diff --git a/tests/app/app/src/android/app/stubs/ZygotePreload.java b/tests/app/app/src/android/app/stubs/ZygotePreload.java
new file mode 100644
index 0000000..1faef7c
--- /dev/null
+++ b/tests/app/app/src/android/app/stubs/ZygotePreload.java
@@ -0,0 +1,34 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.app.stubs;
+
+import android.os.Process;
+import android.util.Log;
+
+public class ZygotePreload {
+ static final String TAG = "ZygotePreload";
+
+ static boolean sPreloadCalled = false;
+
+ static synchronized public boolean preloadCalled() {
+ return sPreloadCalled;
+ }
+
+ static synchronized public void doPreload() {
+ sPreloadCalled = true;
+ }
+}
diff --git a/tests/app/src/android/app/cts/DisplayTest.java b/tests/app/src/android/app/cts/DisplayTest.java
index f845bb7..4bb6c40 100644
--- a/tests/app/src/android/app/cts/DisplayTest.java
+++ b/tests/app/src/android/app/cts/DisplayTest.java
@@ -22,6 +22,7 @@
import android.graphics.Point;
import android.test.ActivityInstrumentationTestCase2;
import android.view.Display;
+import static com.android.compatibility.common.util.PackageUtil.supportsRotation;
/**
* Tests to verify functionality of {@link Display}.
@@ -48,6 +49,11 @@
* updated adjustments after a rotation.
*/
public void testRotation() throws Throwable {
+ if (!supportsRotation()) {
+ // Skip rotation test if device doesn't support it.
+ return;
+ }
+
// Get a {@link Display} instance before rotation.
final Display origDisplay = mActivity.getDisplay();
diff --git a/tests/app/src/android/app/cts/DownloadManagerTest.java b/tests/app/src/android/app/cts/DownloadManagerTest.java
index fa5e8064..76cd58c 100644
--- a/tests/app/src/android/app/cts/DownloadManagerTest.java
+++ b/tests/app/src/android/app/cts/DownloadManagerTest.java
@@ -45,6 +45,7 @@
import android.provider.MediaStore;
import android.support.test.InstrumentationRegistry;
import android.support.test.runner.AndroidJUnit4;
+import android.text.TextUtils;
import android.text.format.DateUtils;
import android.util.Log;
import android.webkit.cts.CtsTestServer;
@@ -485,7 +486,7 @@
* updates to this entry in DownlaodProvider are reflected in MediaProvider as well.
*/
@Test
- public void testDownloadManager_mediaStoreUpdates() throws Exception {
+ public void testDownloadManagerUpdates() throws Exception {
final File dataDir = mContext.getExternalFilesDir(Environment.DIRECTORY_DOCUMENTS);
dataDir.mkdir();
final File downloadFile = new File(dataDir, "colors.txt");
@@ -531,6 +532,48 @@
}
}
+ @Test
+ public void testDownloadManager_mediaStoreUpdates() throws Exception {
+ final File dataDir = mContext.getExternalFilesDir(Environment.DIRECTORY_DOCUMENTS);
+ dataDir.mkdir();
+ final File downloadFile = new File(dataDir, "colors.txt");
+ downloadFile.createNewFile();
+ final String fileContents = "RED;GREEN;BLUE";
+ try (final PrintWriter pw = new PrintWriter(downloadFile)) {
+ pw.print(fileContents);
+ }
+
+ // Insert into DownloadProvider and verify it's added to MediaProvider as well
+ final String testTitle = "Test_title";
+ final long downloadId = mDownloadManager.addCompletedDownload(testTitle, "Test desc", true,
+ "text/plain", downloadFile.getPath(), fileContents.getBytes().length, true);
+ assertTrue(downloadId >= 0);
+ final Uri downloadUri = mDownloadManager.getUriForDownloadedFile(downloadId);
+ try (Cursor cursor = mContext.getContentResolver().query(downloadUri,
+ new String[] { DownloadManager.COLUMN_TITLE }, null, null)) {
+ cursor.moveToNext();
+ assertEquals(testTitle, cursor.getString(0));
+ }
+
+ final Uri mediaStoreUri = getMediaStoreUri(downloadUri);
+ final String newTitle = "New_title";
+ updateUri(mediaStoreUri, "_display_name", newTitle);
+ try (Cursor cursor = mContext.getContentResolver().query(downloadUri,
+ new String[] { DownloadManager.COLUMN_TITLE }, null, null)) {
+ cursor.moveToNext();
+ assertEquals(newTitle, cursor.getString(0));
+ }
+
+ assertRemoveDownload(downloadId, 0);
+ }
+
+ private void updateUri(Uri uri, String column, String value) throws Exception {
+ final String cmd = String.format("content update --uri %s --bind %s:s:%s",
+ uri, column, value);
+ final String res = runShellCommand(cmd).trim();
+ assertTrue(res, TextUtils.isEmpty(res));
+ }
+
private static byte[] hash(InputStream in) throws Exception {
try (DigestInputStream digestIn = new DigestInputStream(in,
MessageDigest.getInstance("SHA-1"));
diff --git a/tests/app/src/android/app/cts/NotificationChannelTest.java b/tests/app/src/android/app/cts/NotificationChannelTest.java
index b369703..f8fe35c1 100644
--- a/tests/app/src/android/app/cts/NotificationChannelTest.java
+++ b/tests/app/src/android/app/cts/NotificationChannelTest.java
@@ -21,7 +21,6 @@
import android.app.Notification;
import android.app.NotificationChannel;
-import android.app.NotificationManager;
import android.graphics.Color;
import android.media.AudioAttributes;
import android.net.Uri;
@@ -59,7 +58,7 @@
assertEquals(Notification.AUDIO_ATTRIBUTES_DEFAULT, channel.getAudioAttributes());
assertEquals(null, channel.getGroup());
assertTrue(channel.getLightColor() == 0);
- assertTrue(channel.canOverlayApps());
+ assertTrue(channel.canBubble());
}
public void testWriteToParcel() {
@@ -155,18 +154,18 @@
assertEquals("banana", channel.getGroup());
}
- public void testAppOverlay() {
+ public void testBubble() {
NotificationChannel channel =
new NotificationChannel("1", "one", IMPORTANCE_DEFAULT);
- channel.setAllowAppOverlay(true);
- assertEquals("Only HIGH channels can have app overlays", false, channel.canOverlayApps());
+ channel.setAllowBubbles(true);
+ assertEquals("Only HIGH channels can have bubbles", false, channel.canBubble());
channel = new NotificationChannel("1", "one", IMPORTANCE_HIGH);
- channel.setAllowAppOverlay(false);
- assertEquals(false, channel.canOverlayApps());
+ channel.setAllowBubbles(false);
+ assertEquals(false, channel.canBubble());
channel = new NotificationChannel("1", "one", IMPORTANCE_HIGH);
- channel.setAllowAppOverlay(true);
- assertEquals(true, channel.canOverlayApps());
+ channel.setAllowBubbles(true);
+ assertEquals(true, channel.canBubble());
}
}
diff --git a/tests/app/src/android/app/cts/NotificationManagerTest.java b/tests/app/src/android/app/cts/NotificationManagerTest.java
index ec1d91f..d99cb11 100644
--- a/tests/app/src/android/app/cts/NotificationManagerTest.java
+++ b/tests/app/src/android/app/cts/NotificationManagerTest.java
@@ -1510,8 +1510,8 @@
}
}
- public void testAreAppOverlaysAllowed() {
- assertTrue(mNotificationManager.areAppOverlaysAllowed());
+ public void testAreBubblesAllowed() {
+ assertTrue(mNotificationManager.areBubblesAllowed());
}
public void testNotificationIcon() {
diff --git a/tests/app/src/android/app/cts/NotificationTest.java b/tests/app/src/android/app/cts/NotificationTest.java
index 1f25528..18a8776 100644
--- a/tests/app/src/android/app/cts/NotificationTest.java
+++ b/tests/app/src/android/app/cts/NotificationTest.java
@@ -25,7 +25,6 @@
import android.app.PendingIntent;
import android.app.Person;
import android.app.RemoteInput;
-import android.app.stubs.R;
import android.content.Context;
import android.content.Intent;
import android.graphics.drawable.Icon;
@@ -56,6 +55,8 @@
private static final String CONTENT_TEXT = "contentText";
private static final String URI_STRING = "uriString";
private static final String ACTION_TITLE = "actionTitle";
+ private static final String BUBBLE_TITLE = "bubbleTitle";
+ private static final int BUBBLE_HEIGHT = 300;
private static final int TOLERANCE = 200;
private static final long TIMEOUT = 4000;
private static final NotificationChannel CHANNEL = new NotificationChannel("id", "name",
@@ -121,14 +122,14 @@
}
public void testWriteToParcel() {
- PendingIntent overlayIntent = PendingIntent.getActivity(mContext, 0, new Intent(), 0);
+ Notification.BubbleMetadata bubble = makeBubbleMetadata();
mNotification = new Notification.Builder(mContext, CHANNEL.getId())
.setBadgeIconType(Notification.BADGE_ICON_SMALL)
.setShortcutId(SHORTCUT_ID)
.setTimeoutAfter(TIMEOUT)
.setSettingsText(SETTING_TEXT)
.setGroupAlertBehavior(Notification.GROUP_ALERT_CHILDREN)
- .setAppOverlayIntent(overlayIntent)
+ .setBubbleMetadata(bubble)
.setAllowSystemGeneratedContextualActions(ALLOW_SYS_GEN_CONTEXTUAL_ACTIONS)
.build();
mNotification.icon = 0;
@@ -186,7 +187,7 @@
assertEquals(mNotification.getChannelId(), result.getChannelId());
assertEquals(mNotification.getSettingsText(), result.getSettingsText());
assertEquals(mNotification.getGroupAlertBehavior(), result.getGroupAlertBehavior());
- assertEquals(overlayIntent, result.getAppOverlayIntent());
+ assertNotNull(result.getBubbleMetadata());
assertEquals(mNotification.getAllowSystemGeneratedContextualActions(),
result.getAllowSystemGeneratedContextualActions());
@@ -239,7 +240,7 @@
public void testBuilder() {
final Intent intent = new Intent();
final PendingIntent contentIntent = PendingIntent.getBroadcast(mContext, 0, intent, 0);
- PendingIntent overlayIntent = PendingIntent.getActivity(mContext, 0, intent, 0);
+ Notification.BubbleMetadata bubble = makeBubbleMetadata();
mNotification = new Notification.Builder(mContext, CHANNEL.getId())
.setSmallIcon(1)
.setContentTitle(CONTENT_TITLE)
@@ -250,7 +251,7 @@
.setTimeoutAfter(TIMEOUT)
.setSettingsText(SETTING_TEXT)
.setGroupAlertBehavior(Notification.GROUP_ALERT_SUMMARY)
- .setAppOverlayIntent(overlayIntent)
+ .setBubbleMetadata(bubble)
.setAllowSystemGeneratedContextualActions(ALLOW_SYS_GEN_CONTEXTUAL_ACTIONS)
.build();
assertEquals(CONTENT_TEXT, mNotification.extras.getString(Notification.EXTRA_TEXT));
@@ -263,7 +264,7 @@
assertEquals(TIMEOUT, mNotification.getTimeoutAfter());
assertEquals(SETTING_TEXT, mNotification.getSettingsText());
assertEquals(Notification.GROUP_ALERT_SUMMARY, mNotification.getGroupAlertBehavior());
- assertEquals(overlayIntent, mNotification.getAppOverlayIntent());
+ assertEquals(bubble, mNotification.getBubbleMetadata());
assertEquals(ALLOW_SYS_GEN_CONTEXTUAL_ACTIONS,
mNotification.getAllowSystemGeneratedContextualActions());
}
@@ -572,6 +573,94 @@
assertFalse(notification.getAllowSystemGeneratedContextualActions());
}
+ public void testBubbleMetadataBuilder() {
+ PendingIntent bubbleIntent = PendingIntent.getActivity(mContext, 0, new Intent(), 0);
+ Icon icon = Icon.createWithResource(mContext, 1);
+ Notification.BubbleMetadata.Builder metadataBuilder =
+ new Notification.BubbleMetadata.Builder()
+ .setDesiredHeight(BUBBLE_HEIGHT)
+ .setTitle(BUBBLE_TITLE)
+ .setIcon(icon)
+ .setIntent(bubbleIntent);
+
+ Notification.BubbleMetadata data = metadataBuilder.build();
+ assertEquals(BUBBLE_HEIGHT, data.getDesiredHeight());
+ assertEquals(BUBBLE_TITLE, data.getTitle());
+ assertEquals(icon, data.getIcon());
+ assertEquals(bubbleIntent, data.getIntent());
+ assertFalse(data.getSuppressInitialNotification());
+ assertFalse(data.getAutoExpandBubble());
+ }
+
+ public void testBubbleMetadata_parcel() {
+ PendingIntent bubbleIntent = PendingIntent.getActivity(mContext, 0, new Intent(), 0);
+ Icon icon = Icon.createWithResource(mContext, 1);
+ Notification.BubbleMetadata metadata =
+ new Notification.BubbleMetadata.Builder()
+ .setDesiredHeight(BUBBLE_HEIGHT)
+ .setTitle(BUBBLE_TITLE)
+ .setAutoExpandBubble(true)
+ .setSuppressInitialNotification(true)
+ .setIcon(icon)
+ .setIntent(bubbleIntent)
+ .build();
+
+ writeAndReadParcelable(metadata);
+ assertEquals(BUBBLE_TITLE, metadata.getTitle());
+ assertEquals(BUBBLE_HEIGHT, metadata.getDesiredHeight());
+ assertEquals(icon, metadata.getIcon());
+ assertEquals(bubbleIntent, metadata.getIntent());
+ assertTrue(metadata.getAutoExpandBubble());
+ assertTrue(metadata.getSuppressInitialNotification());
+
+ }
+
+ public void testBubbleMetadataBuilder_throwForNoIntent() {
+ Icon icon = Icon.createWithResource(mContext, 1);
+ Notification.BubbleMetadata.Builder metadataBuilder =
+ new Notification.BubbleMetadata.Builder()
+ .setDesiredHeight(BUBBLE_HEIGHT)
+ .setTitle(BUBBLE_TITLE)
+ .setIcon(icon);
+ try {
+ metadataBuilder.build();
+ fail("Should have thrown IllegalStateException, no pending intent");
+ } catch (IllegalStateException e) {
+ // expected
+ }
+ }
+
+ public void testBubbleMetadataBuilder_throwForNoTitle() {
+ PendingIntent bubbleIntent = PendingIntent.getActivity(mContext, 0, new Intent(), 0);
+ Icon icon = Icon.createWithResource(mContext, 1);
+ Notification.BubbleMetadata.Builder metadataBuilder =
+ new Notification.BubbleMetadata.Builder()
+ .setDesiredHeight(BUBBLE_HEIGHT)
+ .setIcon(icon)
+ .setIntent(bubbleIntent);
+ try {
+ metadataBuilder.build();
+ fail("Should have thrown IllegalStateException, no title");
+ } catch (IllegalStateException e) {
+ // expected
+ }
+ }
+
+ public void testBubbleMetadataBuilder_throwForNoIcon() {
+ PendingIntent bubbleIntent = PendingIntent.getActivity(mContext, 0, new Intent(), 0);
+ Notification.BubbleMetadata.Builder metadataBuilder =
+ new Notification.BubbleMetadata.Builder()
+ .setDesiredHeight(BUBBLE_HEIGHT)
+ .setTitle(BUBBLE_TITLE)
+ .setIntent(bubbleIntent);
+ try {
+ metadataBuilder.build();
+ fail("Should have thrown IllegalStateException, no icon");
+ } catch (IllegalStateException e) {
+ // expected
+ }
+ }
+
private static RemoteInput newDataOnlyRemoteInput() {
return new RemoteInput.Builder(DATA_RESULT_KEY)
.setAllowFreeFormInput(false)
@@ -623,4 +712,14 @@
}
return actionBuilder.build();
}
+
+ private Notification.BubbleMetadata makeBubbleMetadata() {
+ PendingIntent bubbleIntent = PendingIntent.getActivity(mContext, 0, new Intent(), 0);
+ return new Notification.BubbleMetadata.Builder()
+ .setIntent(bubbleIntent)
+ .setTitle(BUBBLE_TITLE)
+ .setIcon(Icon.createWithResource(mContext, 1))
+ .setDesiredHeight(BUBBLE_HEIGHT)
+ .build();
+ }
}
diff --git a/tests/app/src/android/app/cts/ServiceTest.java b/tests/app/src/android/app/cts/ServiceTest.java
index 3f32a86..720ec4a 100644
--- a/tests/app/src/android/app/cts/ServiceTest.java
+++ b/tests/app/src/android/app/cts/ServiceTest.java
@@ -79,6 +79,7 @@
private static final String EXTERNAL_SERVICE_PACKAGE = "com.android.app2";
private static final String EXTERNAL_SERVICE_COMPONENT =
EXTERNAL_SERVICE_PACKAGE + "/android.app.stubs.LocalService";
+ private static final String APP_ZYGOTE_PROCESS_NAME = "android.app.stubs_zygote";
private int mExpectedServiceState;
private Context mContext;
private Intent mLocalService;
@@ -209,6 +210,7 @@
private IBinder mService;
private int mUid;
private int mPid;
+ private int mPpid;
public IsolatedConnection() {
mUid = mPid = -1;
@@ -247,6 +249,25 @@
return mPid;
}
+ public int getPpid() {
+ return mPpid;
+ }
+
+ public boolean zygotePreloadCalled() {
+ Parcel data = Parcel.obtain();
+ Parcel reply = Parcel.obtain();
+ data.writeInterfaceToken(LocalService.SERVICE_LOCAL);
+ try {
+ mService.transact(LocalService.GET_ZYGOTE_PRELOAD_CALLED, data, reply, 0);
+ } catch (RemoteException e) {
+ finishBad("DeadObjectException when sending reporting object");
+ }
+ boolean value = reply.readBoolean();
+ reply.recycle();
+ data.recycle();
+ return value;
+ }
+
public void setValue(int value) {
Parcel data = Parcel.obtain();
data.writeInterfaceToken(LocalService.SERVICE_LOCAL);
@@ -289,6 +310,21 @@
return value;
}
+ public int getPpidIpc() {
+ Parcel data = Parcel.obtain();
+ Parcel reply = Parcel.obtain();
+ data.writeInterfaceToken(LocalService.SERVICE_LOCAL);
+ try {
+ mService.transact(LocalService.GET_PPID_CODE, data, reply, 0);
+ } catch (RemoteException e) {
+ finishBad("DeadObjectException when sending reporting object");
+ }
+ int value = reply.readInt();
+ reply.recycle();
+ data.recycle();
+ return value;
+ }
+
public int getUidIpc() {
Parcel data = Parcel.obtain();
Parcel reply = Parcel.obtain();
@@ -310,6 +346,7 @@
mService = service;
mUid = getUidIpc();
mPid = getPidIpc();
+ mPpid = getPpidIpc();
notifyAll();
}
}
@@ -1344,6 +1381,92 @@
}
}
+ @MediumTest
+ public void testAppZygotePreload() throws Exception {
+ IsolatedConnection conn = new IsolatedConnection();
+ try {
+ mContext.bindIsolatedService(
+ mIsolatedService, conn, Context.BIND_AUTO_CREATE, "1");
+
+ conn.waitForService(DELAY);
+
+ // Verify application preload was done
+ assertTrue(conn.zygotePreloadCalled());
+ } finally {
+ if (conn != null) {
+ mContext.unbindService(conn);
+ }
+ }
+ }
+
+ @MediumTest
+ public void testAppZygoteServices() throws Exception {
+ IsolatedConnection conn1a = null;
+ IsolatedConnection conn1b = null;
+ IsolatedConnection conn2 = null;
+ int appZygotePid;
+ try {
+ conn1a = new IsolatedConnection();
+ mContext.bindIsolatedService(
+ mIsolatedService, conn1a, Context.BIND_AUTO_CREATE, "1");
+ conn1b = new IsolatedConnection();
+ mContext.bindIsolatedService(
+ mIsolatedService, conn1b, Context.BIND_AUTO_CREATE, "1");
+ conn2 = new IsolatedConnection();
+ mContext.bindIsolatedService(
+ mIsolatedService, conn2, Context.BIND_AUTO_CREATE, "2");
+
+ conn1a.waitForService(DELAY);
+ conn1b.waitForService(DELAY);
+ conn2.waitForService(DELAY);
+
+ // Get PPID of each service, and verify they're identical
+ int ppid1a = conn1a.getPpid();
+ int ppid1b = conn1b.getPpid();
+ int ppid2 = conn2.getPpid();
+
+ assertEquals(ppid1a, ppid1b);
+ assertEquals(ppid1b, ppid2);
+ // Find the app zygote process hosting these
+ String result = SystemUtil.runShellCommand(InstrumentationRegistry.getInstrumentation(),
+ "ps -p " + Integer.toString(ppid1a) + " -o NAME=");
+ result = result.replaceAll("\\s+", "");
+ assertEquals(result, APP_ZYGOTE_PROCESS_NAME);
+ appZygotePid = ppid1a;
+ } finally {
+ if (conn2 != null) {
+ mContext.unbindService(conn2);
+ }
+ if (conn1b != null) {
+ mContext.unbindService(conn1b);
+ }
+ if (conn1a != null) {
+ mContext.unbindService(conn1a);
+ }
+ }
+ // Sleep for 2 seconds and bind a service again, see it uses the same Zygote
+ try {
+ conn1a = new IsolatedConnection();
+ mContext.bindIsolatedService(
+ mIsolatedService, conn1a, Context.BIND_AUTO_CREATE, "1");
+
+ conn1a.waitForService(DELAY);
+
+ int ppid1a = conn1a.getPpid();
+ assertEquals(appZygotePid, ppid1a);
+ } finally {
+ if (conn1a != null) {
+ mContext.unbindService(conn1a);
+ }
+ }
+ // Sleep for 10 seconds, verify the app_zygote is gone
+ Thread.sleep(10000);
+ String result = SystemUtil.runShellCommand(InstrumentationRegistry.getInstrumentation(),
+ "ps -p " + Integer.toString(appZygotePid) + " -o NAME=");
+ result = result.replaceAll("\\s+", "");
+ assertEquals("", result);
+ }
+
/**
* Test that the system properly orders processes bound by an activity within the
* LRU list.
diff --git a/tests/app/src/android/app/cts/WallpaperInfoTest.java b/tests/app/src/android/app/cts/WallpaperInfoTest.java
index 7cff609..123a9cd 100644
--- a/tests/app/src/android/app/cts/WallpaperInfoTest.java
+++ b/tests/app/src/android/app/cts/WallpaperInfoTest.java
@@ -59,6 +59,7 @@
assertEquals(context.getString(R.string.wallpaper_slice_uri),
wallpaperInfo.getSettingsSliceUri().toString());
assertEquals(true, wallpaperInfo.getShowMetadataInPreview());
+ assertEquals(true, wallpaperInfo.supportsMultipleDisplays());
assertNotNull(wallpaperInfo.loadIcon(pm));
assertNotNull(wallpaperInfo.loadThumbnail(pm));
}
diff --git a/tests/autofillservice/AndroidManifest.xml b/tests/autofillservice/AndroidManifest.xml
index f27e663..5955274 100644
--- a/tests/autofillservice/AndroidManifest.xml
+++ b/tests/autofillservice/AndroidManifest.xml
@@ -156,6 +156,16 @@
<action android:name="android.service.autofill.AutofillService" />
</intent-filter>
</service>
+
+ <service
+ android:name=".augmented.CtsAugmentedAutofillService"
+ android:label="CtsAugmentedAutofillService"
+ android:permission="android.permission.BIND_AUGMENTED_AUTOFILL_SERVICE" >
+ <intent-filter>
+ <action android:name="android.service.autofill.AutofillService" />
+ </intent-filter>
+ </service>
+
</application>
<instrumentation
diff --git a/tests/autofillservice/res/layout/augmented_autofill_ui.xml b/tests/autofillservice/res/layout/augmented_autofill_ui.xml
new file mode 100644
index 0000000..e6f5a28
--- /dev/null
+++ b/tests/autofillservice/res/layout/augmented_autofill_ui.xml
@@ -0,0 +1,20 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2019 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.
+-->
+
+<TextView xmlns:android="http://schemas.android.com/apk/res/android"
+ android:id="@+id/augmentedAutofillUi"
+ android:layout_width="fill_parent"
+ android:layout_height="fill_parent"/>
diff --git a/tests/autofillservice/src/android/autofillservice/cts/AbstractAutoFillActivity.java b/tests/autofillservice/src/android/autofillservice/cts/AbstractAutoFillActivity.java
index 3ee3e79..bc7e7c1 100644
--- a/tests/autofillservice/src/android/autofillservice/cts/AbstractAutoFillActivity.java
+++ b/tests/autofillservice/src/android/autofillservice/cts/AbstractAutoFillActivity.java
@@ -37,7 +37,7 @@
/**
* Base class for all activities in this test suite
*/
-abstract class AbstractAutoFillActivity extends Activity {
+public abstract class AbstractAutoFillActivity extends Activity {
private final CountDownLatch mDestroyedLatch = new CountDownLatch(1);
private MyAutofillCallback mCallback;
diff --git a/tests/autofillservice/src/android/autofillservice/cts/AbstractLoginActivityTestCase.java b/tests/autofillservice/src/android/autofillservice/cts/AbstractLoginActivityTestCase.java
index 00135d4..c0b2994 100644
--- a/tests/autofillservice/src/android/autofillservice/cts/AbstractLoginActivityTestCase.java
+++ b/tests/autofillservice/src/android/autofillservice/cts/AbstractLoginActivityTestCase.java
@@ -24,7 +24,7 @@
/**
* Base class for test cases using {@link LoginActivity}.
*/
-abstract class AbstractLoginActivityTestCase
+public abstract class AbstractLoginActivityTestCase
extends AutoFillServiceTestCase.AutoActivityLaunch<LoginActivity> {
protected LoginActivity mActivity;
diff --git a/tests/autofillservice/src/android/autofillservice/cts/AutoFillServiceTestCase.java b/tests/autofillservice/src/android/autofillservice/cts/AutoFillServiceTestCase.java
index ef5170af..1e1e740 100644
--- a/tests/autofillservice/src/android/autofillservice/cts/AutoFillServiceTestCase.java
+++ b/tests/autofillservice/src/android/autofillservice/cts/AutoFillServiceTestCase.java
@@ -65,7 +65,7 @@
* <li>Launching the activity used by the test.
* </ul>
*/
-final class AutoFillServiceTestCase {
+public final class AutoFillServiceTestCase {
/**
* Base class for all test cases that use an {@link AutofillActivityTestRule} to
diff --git a/tests/autofillservice/src/android/autofillservice/cts/CannedFillResponse.java b/tests/autofillservice/src/android/autofillservice/cts/CannedFillResponse.java
index c03ba04..d68cacf 100644
--- a/tests/autofillservice/src/android/autofillservice/cts/CannedFillResponse.java
+++ b/tests/autofillservice/src/android/autofillservice/cts/CannedFillResponse.java
@@ -59,7 +59,7 @@
* .build());
* </pre class="prettyprint">
*/
-final class CannedFillResponse {
+public final class CannedFillResponse {
private final ResponseType mResponseType;
private final List<CannedDataset> mDatasets;
@@ -125,27 +125,27 @@
* Constant used to pass a {@code null} response to the
* {@link FillCallback#onSuccess(FillResponse)} method.
*/
- static final CannedFillResponse NO_RESPONSE =
+ public static final CannedFillResponse NO_RESPONSE =
new Builder(ResponseType.NULL).build();
/**
* Constant used to emulate a timeout by not calling any method on {@link FillCallback}.
*/
- static final CannedFillResponse DO_NOT_REPLY_RESPONSE =
+ public static final CannedFillResponse DO_NOT_REPLY_RESPONSE =
new Builder(ResponseType.TIMEOUT).build();
/**
* Constant used to call {@link FillCallback#onFailure(CharSequence)} method.
*/
- static final CannedFillResponse FAIL =
+ public static final CannedFillResponse FAIL =
new Builder(ResponseType.FAILURE).build();
- String getFailureMessage() {
+ public String getFailureMessage() {
return mFailureMessage;
}
- ResponseType getResponseType() {
+ public ResponseType getResponseType() {
return mResponseType;
}
@@ -153,7 +153,7 @@
* Creates a new response, replacing the dataset field ids by the real ids from the assist
* structure.
*/
- FillResponse asFillResponse(Function<String, ViewNode> nodeResolver) {
+ public FillResponse asFillResponse(Function<String, ViewNode> nodeResolver) {
final FillResponse.Builder builder = new FillResponse.Builder()
.setFlags(mFillResponseFlags);
if (mDatasets != null) {
@@ -275,14 +275,14 @@
+ "]";
}
- enum ResponseType {
+ public enum ResponseType {
NORMAL,
NULL,
TIMEOUT,
FAILURE
}
- static class Builder {
+ public static final class Builder {
private final List<CannedDataset> mDatasets = new ArrayList<>();
private final ArrayList<Pair<Sanitizer, AutofillId[]>> mSanitizers = new ArrayList<>();
private final ResponseType mResponseType;
@@ -527,7 +527,7 @@
* .build());
* </pre class="prettyprint">
*/
- static class CannedDataset {
+ public static class CannedDataset {
private final Map<String, AutofillValue> mFieldValues;
private final Map<AutofillId, AutofillValue> mFieldValuesById;
private final Map<AutofillId, RemoteViews> mFieldPresentationsById;
@@ -611,7 +611,7 @@
+ ", fieldFilters=" + mFieldFilters + "]";
}
- static class Builder {
+ public static class Builder {
private final Map<String, AutofillValue> mFieldValues = new HashMap<>();
private final Map<AutofillId, AutofillValue> mFieldValuesById = new HashMap<>();
private final Map<String, RemoteViews> mFieldPresentations = new HashMap<>();
diff --git a/tests/autofillservice/src/android/autofillservice/cts/Helper.java b/tests/autofillservice/src/android/autofillservice/cts/Helper.java
index b6ebd7a..69da062 100644
--- a/tests/autofillservice/src/android/autofillservice/cts/Helper.java
+++ b/tests/autofillservice/src/android/autofillservice/cts/Helper.java
@@ -35,9 +35,11 @@
import android.app.assist.AssistStructure.WindowNode;
import android.autofillservice.cts.common.OneTimeSettingsListener;
import android.autofillservice.cts.common.SettingsHelper;
+import android.autofillservice.cts.common.ShellHelper;
import android.content.ComponentName;
import android.content.Context;
import android.content.pm.PackageManager;
+import android.content.res.Resources;
import android.graphics.Bitmap;
import android.icu.util.Calendar;
import android.os.Bundle;
@@ -75,35 +77,35 @@
/**
* Helper for common funcionalities.
*/
-final class Helper {
+public final class Helper {
- static final String TAG = "AutoFillCtsHelper";
+ public static final String TAG = "AutoFillCtsHelper";
- static final boolean VERBOSE = false;
+ public static final boolean VERBOSE = false;
- static final String MY_PACKAGE = "android.autofillservice.cts";
+ public static final String MY_PACKAGE = "android.autofillservice.cts";
- static final String ID_USERNAME_LABEL = "username_label";
- static final String ID_USERNAME = "username";
- static final String ID_PASSWORD_LABEL = "password_label";
- static final String ID_PASSWORD = "password";
- static final String ID_LOGIN = "login";
- static final String ID_OUTPUT = "output";
- static final String ID_STATIC_TEXT = "static_text";
+ public static final String ID_USERNAME_LABEL = "username_label";
+ public static final String ID_USERNAME = "username";
+ public static final String ID_PASSWORD_LABEL = "password_label";
+ public static final String ID_PASSWORD = "password";
+ public static final String ID_LOGIN = "login";
+ public static final String ID_OUTPUT = "output";
+ public static final String ID_STATIC_TEXT = "static_text";
- static final String NULL_DATASET_ID = null;
+ public static final String NULL_DATASET_ID = null;
- static final char LARGE_STRING_CHAR = '6';
+ public static final char LARGE_STRING_CHAR = '6';
// NOTE: cannot be much large as it could ANR and fail the test.
- static final int LARGE_STRING_SIZE = 100_000;
- static final String LARGE_STRING = com.android.compatibility.common.util.TextUtils
+ public static final int LARGE_STRING_SIZE = 100_000;
+ public static final String LARGE_STRING = com.android.compatibility.common.util.TextUtils
.repeat(LARGE_STRING_CHAR, LARGE_STRING_SIZE);
/**
* Can be used in cases where the autofill values is required by irrelevant (like adding a
* value to an authenticated dataset).
*/
- static final String UNUSED_AUTOFILL_VALUE = null;
+ public static final String UNUSED_AUTOFILL_VALUE = null;
private static final String ACCELLEROMETER_CHANGE =
"content insert --uri content://settings/system --bind name:s:accelerometer_rotation "
@@ -116,6 +118,9 @@
"SETTINGS_SHELL_CMD_TIMEOUT", OneTimeSettingsListener.DEFAULT_TIMEOUT_MS / 2, 2,
OneTimeSettingsListener.DEFAULT_TIMEOUT_MS);
+ private static final String RESOURCE_BOOLEAN_CONFIG_FORCE_DEFAULT_ORIENTATION =
+ "config_forceDefaultOrientation";
+
/**
* Helper interface used to filter nodes.
*
@@ -176,12 +181,12 @@
}
@NonNull
- static String toString(@NonNull AssistStructure structure) {
+ public static String toString(@NonNull AssistStructure structure) {
return toString(structure, new StringBuilder());
}
@Nullable
- static String toString(@Nullable AutofillValue value) {
+ public static String toString(@Nullable AutofillValue value) {
if (value == null) return null;
if (value.isText()) {
// We don't care about PII...
@@ -194,14 +199,14 @@
/**
* Dump the assist structure on logcat.
*/
- static void dumpStructure(String message, AssistStructure structure) {
+ public static void dumpStructure(String message, AssistStructure structure) {
Log.i(TAG, toString(structure, new StringBuilder(message)));
}
/**
* Dump the contexts on logcat.
*/
- static void dumpStructure(String message, List<FillContext> contexts) {
+ public static void dumpStructure(String message, List<FillContext> contexts) {
for (FillContext context : contexts) {
dumpStructure(message, context.getStructure());
}
@@ -210,14 +215,14 @@
/**
* Dumps the state of the autofill service on logcat.
*/
- static void dumpAutofillService() {
+ public static void dumpAutofillService() {
Log.i(TAG, "dumpsys autofill\n\n" + runShellCommand("dumpsys autofill"));
}
/**
* Sets whether the user completed the initial setup.
*/
- static void setUserComplete(Context context, boolean complete) {
+ public static void setUserComplete(Context context, boolean complete) {
SettingsHelper.syncSet(context, USER_SETUP_COMPLETE, complete ? "1" : null);
}
@@ -255,7 +260,7 @@
* Appends a field value to a {@link StringBuilder} when it's not {@code null}.
*/
@NonNull
- static StringBuilder append(@NonNull StringBuilder builder, @NonNull String field,
+ public static StringBuilder append(@NonNull StringBuilder builder, @NonNull String field,
@Nullable Object value) {
if (value == null) return builder;
@@ -275,7 +280,7 @@
* Appends a field value to a {@link StringBuilder} when it's {@code true}.
*/
@NonNull
- static StringBuilder append(@NonNull StringBuilder builder, @NonNull String field,
+ public static StringBuilder append(@NonNull StringBuilder builder, @NonNull String field,
boolean value) {
if (value) {
builder.append(", ").append(field);
@@ -286,7 +291,7 @@
/**
* Gets a node if it matches the filter criteria for the given id.
*/
- static ViewNode findNodeByFilter(@NonNull AssistStructure structure, @NonNull Object id,
+ public static ViewNode findNodeByFilter(@NonNull AssistStructure structure, @NonNull Object id,
@NonNull NodeFilter<ViewNode> filter) {
Log.v(TAG, "Parsing request for activity " + structure.getActivityComponent());
final int nodes = structure.getWindowNodeCount();
@@ -304,7 +309,7 @@
/**
* Gets a node if it matches the filter criteria for the given id.
*/
- static ViewNode findNodeByFilter(@NonNull List<FillContext> contexts, @NonNull Object id,
+ public static ViewNode findNodeByFilter(@NonNull List<FillContext> contexts, @NonNull Object id,
@NonNull NodeFilter<ViewNode> filter) {
for (FillContext context : contexts) {
ViewNode node = findNodeByFilter(context.getStructure(), id, filter);
@@ -318,7 +323,7 @@
/**
* Gets a node if it matches the filter criteria for the given id.
*/
- static ViewNode findNodeByFilter(@NonNull ViewNode node, @NonNull Object id,
+ public static ViewNode findNodeByFilter(@NonNull ViewNode node, @NonNull Object id,
@NonNull NodeFilter<ViewNode> filter) {
if (filter.matches(node, id)) {
return node;
@@ -338,42 +343,42 @@
/**
* Gets a node given its Android resource id, or {@code null} if not found.
*/
- static ViewNode findNodeByResourceId(AssistStructure structure, String resourceId) {
+ public static ViewNode findNodeByResourceId(AssistStructure structure, String resourceId) {
return findNodeByFilter(structure, resourceId, RESOURCE_ID_FILTER);
}
/**
* Gets a node given its Android resource id, or {@code null} if not found.
*/
- static ViewNode findNodeByResourceId(List<FillContext> contexts, String resourceId) {
+ public static ViewNode findNodeByResourceId(List<FillContext> contexts, String resourceId) {
return findNodeByFilter(contexts, resourceId, RESOURCE_ID_FILTER);
}
/**
* Gets a node given its Android resource id, or {@code null} if not found.
*/
- static ViewNode findNodeByResourceId(ViewNode node, String resourceId) {
+ public static ViewNode findNodeByResourceId(ViewNode node, String resourceId) {
return findNodeByFilter(node, resourceId, RESOURCE_ID_FILTER);
}
/**
* Gets a node given the name of its HTML INPUT tag, or {@code null} if not found.
*/
- static ViewNode findNodeByHtmlName(AssistStructure structure, String htmlName) {
+ public static ViewNode findNodeByHtmlName(AssistStructure structure, String htmlName) {
return findNodeByFilter(structure, htmlName, HTML_NAME_FILTER);
}
/**
* Gets a node given the name of its HTML INPUT tag, or {@code null} if not found.
*/
- static ViewNode findNodeByHtmlName(List<FillContext> contexts, String htmlName) {
+ public static ViewNode findNodeByHtmlName(List<FillContext> contexts, String htmlName) {
return findNodeByFilter(contexts, htmlName, HTML_NAME_FILTER);
}
/**
* Gets a node given the name of its HTML INPUT tag, or {@code null} if not found.
*/
- static ViewNode findNodeByHtmlName(ViewNode node, String htmlName) {
+ public static ViewNode findNodeByHtmlName(ViewNode node, String htmlName) {
return findNodeByFilter(node, htmlName, HTML_NAME_FILTER);
}
@@ -381,7 +386,7 @@
* Gets a node given the value of its (single) autofill hint property, or {@code null} if not
* found.
*/
- static ViewNode findNodeByAutofillHint(ViewNode node, String hint) {
+ public static ViewNode findNodeByAutofillHint(ViewNode node, String hint) {
return findNodeByFilter(node, hint, AUTOFILL_HINT_FILTER);
}
@@ -389,7 +394,7 @@
* Gets a node given the name of its HTML INPUT tag or Android resoirce id, or {@code null} if
* not found.
*/
- static ViewNode findNodeByHtmlNameOrResourceId(List<FillContext> contexts, String id) {
+ public static ViewNode findNodeByHtmlNameOrResourceId(List<FillContext> contexts, String id) {
return findNodeByFilter(contexts, id, HTML_NAME_OR_RESOURCE_ID_FILTER);
}
@@ -397,7 +402,7 @@
* Gets the {@code name} attribute of a node representing an HTML input tag.
*/
@Nullable
- static String getHtmlName(@NonNull ViewNode node) {
+ public static String getHtmlName(@NonNull ViewNode node) {
final HtmlInfo htmlInfo = node.getHtmlInfo();
if (htmlInfo == null) {
return null;
@@ -419,21 +424,21 @@
/**
* Gets a node given its expected text, or {@code null} if not found.
*/
- static ViewNode findNodeByText(AssistStructure structure, String text) {
+ public static ViewNode findNodeByText(AssistStructure structure, String text) {
return findNodeByFilter(structure, text, TEXT_FILTER);
}
/**
* Gets a node given its expected text, or {@code null} if not found.
*/
- static ViewNode findNodeByText(ViewNode node, String text) {
+ public static ViewNode findNodeByText(ViewNode node, String text) {
return findNodeByFilter(node, text, TEXT_FILTER);
}
/**
* Gets a view that contains the an autofill hint, or {@code null} if not found.
*/
- static View findViewByAutofillHint(Activity activity, String hint) {
+ public static View findViewByAutofillHint(Activity activity, String hint) {
final View rootView = activity.getWindow().getDecorView().getRootView();
return findViewByAutofillHint(rootView, hint);
}
@@ -442,7 +447,7 @@
* Gets a view (or a descendant of it) that contains the an autofill hint, or {@code null} if
* not found.
*/
- static View findViewByAutofillHint(View view, String hint) {
+ public static View findViewByAutofillHint(View view, String hint) {
if (AUTOFILL_HINT_VIEW_FILTER.matches(view, hint)) return view;
if ((view instanceof ViewGroup)) {
final ViewGroup group = (ViewGroup) view;
@@ -458,14 +463,14 @@
* Gets a view (or a descendant of it) that has the given {@code id}, or {@code null} if
* not found.
*/
- static ViewNode findNodeByAutofillId(AssistStructure structure, AutofillId id) {
+ public static ViewNode findNodeByAutofillId(AssistStructure structure, AutofillId id) {
return findNodeByFilter(structure, id, AUTOFILL_ID_FILTER);
}
/**
* Asserts a text-based node is sanitized.
*/
- static void assertTextIsSanitized(ViewNode node) {
+ public static void assertTextIsSanitized(ViewNode node) {
final CharSequence text = node.getText();
final String resourceId = node.getIdEntry();
if (!TextUtils.isEmpty(text)) {
@@ -480,7 +485,7 @@
assertThat(node.getTextIdEntry()).isNull();
}
- static void assertNodeHasNoAutofillValue(ViewNode node) {
+ public static void assertNodeHasNoAutofillValue(ViewNode node) {
final AutofillValue value = node.getAutofillValue();
if (value != null) {
final String text = value.isText() ? value.getTextValue().toString() : "N/A";
@@ -491,7 +496,7 @@
/**
* Asserts the contents of a text-based node that is also auto-fillable.
*/
- static void assertTextOnly(ViewNode node, String expectedValue) {
+ public static void assertTextOnly(ViewNode node, String expectedValue) {
assertText(node, expectedValue, false);
assertNotFromResources(node);
}
@@ -499,7 +504,8 @@
/**
* Asserts the contents of a text-based node that is also auto-fillable.
*/
- static void assertTextOnly(AssistStructure structure, String resourceId, String expectedValue) {
+ public static void assertTextOnly(AssistStructure structure, String resourceId,
+ String expectedValue) {
final ViewNode node = findNodeByResourceId(structure, resourceId);
assertText(node, expectedValue, false);
assertNotFromResources(node);
@@ -508,7 +514,7 @@
/**
* Asserts the contents of a text-based node that is also auto-fillable.
*/
- static void assertTextAndValue(ViewNode node, String expectedValue) {
+ public static void assertTextAndValue(ViewNode node, String expectedValue) {
assertText(node, expectedValue, true);
assertNotFromResources(node);
}
@@ -516,7 +522,7 @@
/**
* Asserts a text-based node exists and verify its values.
*/
- static ViewNode assertTextAndValue(AssistStructure structure, String resourceId,
+ public static ViewNode assertTextAndValue(AssistStructure structure, String resourceId,
String expectedValue) {
final ViewNode node = findNodeByResourceId(structure, resourceId);
assertTextAndValue(node, expectedValue);
@@ -526,7 +532,7 @@
/**
* Asserts a text-based node exists and is sanitized.
*/
- static ViewNode assertValue(AssistStructure structure, String resourceId,
+ public static ViewNode assertValue(AssistStructure structure, String resourceId,
String expectedValue) {
final ViewNode node = findNodeByResourceId(structure, resourceId);
assertTextValue(node, expectedValue);
@@ -536,7 +542,7 @@
/**
* Asserts the values of a text-based node whose string come from resoruces.
*/
- static ViewNode assertTextFromResouces(AssistStructure structure, String resourceId,
+ public static ViewNode assertTextFromResouces(AssistStructure structure, String resourceId,
String expectedValue, boolean isAutofillable, String expectedTextIdEntry) {
final ViewNode node = findNodeByResourceId(structure, resourceId);
assertText(node, expectedValue, isAutofillable);
@@ -561,7 +567,7 @@
/**
* Asserts the auto-fill value of a text-based node.
*/
- static ViewNode assertTextValue(ViewNode node, String expectedText) {
+ public static ViewNode assertTextValue(ViewNode node, String expectedText) {
final AutofillValue value = node.getAutofillValue();
final AutofillId id = node.getAutofillId();
assertWithMessage("null autofill value on %s", id).that(value).isNotNull();
@@ -574,7 +580,7 @@
/**
* Asserts the auto-fill value of a list-based node.
*/
- static ViewNode assertListValue(ViewNode node, int expectedIndex) {
+ public static ViewNode assertListValue(ViewNode node, int expectedIndex) {
final AutofillValue value = node.getAutofillValue();
final AutofillId id = node.getAutofillId();
assertWithMessage("null autofill value on %s", id).that(value).isNotNull();
@@ -587,7 +593,7 @@
/**
* Asserts the auto-fill value of a toggle-based node.
*/
- static void assertToggleValue(ViewNode node, boolean expectedToggle) {
+ public static void assertToggleValue(ViewNode node, boolean expectedToggle) {
final AutofillValue value = node.getAutofillValue();
final AutofillId id = node.getAutofillId();
assertWithMessage("null autofill value on %s", id).that(value).isNotNull();
@@ -599,7 +605,8 @@
/**
* Asserts the auto-fill value of a date-based node.
*/
- static void assertDateValue(Object object, AutofillValue value, int year, int month, int day) {
+ public static void assertDateValue(Object object, AutofillValue value, int year, int month,
+ int day) {
assertWithMessage("null autofill value on %s", object).that(value).isNotNull();
assertWithMessage("wrong autofill type on %s", object).that(value.isDate()).isTrue();
@@ -617,14 +624,14 @@
/**
* Asserts the auto-fill value of a date-based node.
*/
- static void assertDateValue(ViewNode node, int year, int month, int day) {
+ public static void assertDateValue(ViewNode node, int year, int month, int day) {
assertDateValue(node, node.getAutofillValue(), year, month, day);
}
/**
* Asserts the auto-fill value of a date-based view.
*/
- static void assertDateValue(View view, int year, int month, int day) {
+ public static void assertDateValue(View view, int year, int month, int day) {
assertDateValue(view, view.getAutofillValue(), year, month, day);
}
@@ -647,21 +654,21 @@
/**
* Asserts the auto-fill value of a time-based node.
*/
- static void assertTimeValue(ViewNode node, int hour, int minute) {
+ public static void assertTimeValue(ViewNode node, int hour, int minute) {
assertTimeValue(node, node.getAutofillValue(), hour, minute);
}
/**
* Asserts the auto-fill value of a time-based view.
*/
- static void assertTimeValue(View view, int hour, int minute) {
+ public static void assertTimeValue(View view, int hour, int minute) {
assertTimeValue(view, view.getAutofillValue(), hour, minute);
}
/**
* Asserts a text-based node exists and is sanitized.
*/
- static ViewNode assertTextIsSanitized(AssistStructure structure, String resourceId) {
+ public static ViewNode assertTextIsSanitized(AssistStructure structure, String resourceId) {
final ViewNode node = findNodeByResourceId(structure, resourceId);
assertWithMessage("no ViewNode with id %s", resourceId).that(node).isNotNull();
assertTextIsSanitized(node);
@@ -671,7 +678,7 @@
/**
* Asserts a list-based node exists and is sanitized.
*/
- static void assertListValueIsSanitized(AssistStructure structure, String resourceId) {
+ public static void assertListValueIsSanitized(AssistStructure structure, String resourceId) {
final ViewNode node = findNodeByResourceId(structure, resourceId);
assertWithMessage("no ViewNode with id %s", resourceId).that(node).isNotNull();
assertTextIsSanitized(node);
@@ -680,7 +687,7 @@
/**
* Asserts a toggle node exists and is sanitized.
*/
- static void assertToggleIsSanitized(AssistStructure structure, String resourceId) {
+ public static void assertToggleIsSanitized(AssistStructure structure, String resourceId) {
final ViewNode node = findNodeByResourceId(structure, resourceId);
assertNodeHasNoAutofillValue(node);
assertWithMessage("ViewNode %s should not be checked", resourceId).that(node.isChecked())
@@ -690,7 +697,8 @@
/**
* Asserts a node exists and has the {@code expected} number of children.
*/
- static void assertNumberOfChildren(AssistStructure structure, String resourceId, int expected) {
+ public static void assertNumberOfChildren(AssistStructure structure, String resourceId,
+ int expected) {
final ViewNode node = findNodeByResourceId(structure, resourceId);
final int actual = node.getChildCount();
if (actual != expected) {
@@ -703,7 +711,7 @@
/**
* Asserts the number of children in the Assist structure.
*/
- static void assertNumberOfChildren(AssistStructure structure, int expected) {
+ public static void assertNumberOfChildren(AssistStructure structure, int expected) {
assertWithMessage("wrong number of nodes").that(structure.getWindowNodeCount())
.isEqualTo(1);
final int actual = getNumberNodes(structure);
@@ -717,7 +725,7 @@
/**
* Gets the total number of nodes in an structure.
*/
- static int getNumberNodes(AssistStructure structure) {
+ public static int getNumberNodes(AssistStructure structure) {
int count = 0;
final int nodes = structure.getWindowNodeCount();
for (int i = 0; i < nodes; i++) {
@@ -731,7 +739,7 @@
/**
* Gets the total number of nodes in an node, including all descendants and the node itself.
*/
- static int getNumberNodes(ViewNode node) {
+ public static int getNumberNodes(ViewNode node) {
int count = 1;
final int childrenSize = node.getChildCount();
if (childrenSize > 0) {
@@ -746,7 +754,7 @@
* Creates an array of {@link AutofillId} mapped from the {@code structure} nodes with the given
* {@code resourceIds}.
*/
- static AutofillId[] getAutofillIds(Function<String, ViewNode> nodeResolver,
+ public static AutofillId[] getAutofillIds(Function<String, ViewNode> nodeResolver,
String[] resourceIds) {
if (resourceIds == null) return null;
@@ -767,7 +775,8 @@
* Get an {@link AutofillId} mapped from the {@code structure} node with the given
* {@code resourceId}.
*/
- static AutofillId getAutofillId(Function<String, ViewNode> nodeResolver, String resourceId) {
+ public static AutofillId getAutofillId(Function<String, ViewNode> nodeResolver,
+ String resourceId) {
if (resourceId == null) return null;
final ViewNode node = nodeResolver.apply(resourceId);
@@ -837,7 +846,35 @@
* Checks if screen orientation can be changed.
*/
public static boolean isRotationSupported(Context context) {
- return !context.getPackageManager().hasSystemFeature(PackageManager.FEATURE_LEANBACK);
+ if (!isScreenRotationSupported(context)) {
+ Log.v(TAG, "isRotationSupported(): screen rotation not supported");
+ return false;
+ }
+ if (context.getPackageManager().hasSystemFeature(PackageManager.FEATURE_LEANBACK)) {
+ Log.v(TAG, "isRotationSupported(): has leanback feature");
+ return false;
+ }
+ return true;
+ }
+
+ /**
+ * Returns {@code true} if display rotation is supported, {@code false} otherwise.
+ */
+ private static boolean isScreenRotationSupported(Context context) {
+ try {
+ return !getBoolean(context, RESOURCE_BOOLEAN_CONFIG_FORCE_DEFAULT_ORIENTATION);
+ } catch (Resources.NotFoundException e) {
+ Log.d(TAG, "Resource not found: "
+ + RESOURCE_BOOLEAN_CONFIG_FORCE_DEFAULT_ORIENTATION
+ + ". Assume rotation supported");
+ return true;
+ }
+ }
+
+ private static boolean getBoolean(Context context, String id) {
+ final Resources resources = context.getResources();
+ final int booleanId = resources.getIdentifier(id, "bool", "android");
+ return resources.getBoolean(booleanId);
}
/**
@@ -1288,7 +1325,7 @@
}
@Nullable
- public static File dumpBitmap(@NonNull Bitmap bitmap, @NonNull File file) throws IOException {
+ public static File dumpBitmap(@NonNull Bitmap bitmap, @NonNull File file) {
Log.i(TAG, "Dumping bitmap at " + file);
BitmapUtils.saveBitmap(bitmap, file.getParent(), file.getName());
return file;
@@ -1340,6 +1377,24 @@
assertThat(string.charAt(LARGE_STRING_SIZE - 1)).isEqualTo(LARGE_STRING_CHAR);
}
+ /**
+ * Allows the test to draw overlaid windows.
+ *
+ * <p>Should call {@link #disallowOverlays()} afterwards.
+ */
+ public static void allowOverlays() {
+ ShellHelper.setOverlayPermissions(MY_PACKAGE, true);
+ }
+
+ /**
+ * Disallow the test to draw overlaid windows.
+ *
+ * <p>Should call {@link #disallowOverlays()} afterwards.
+ */
+ public static void disallowOverlays() {
+ ShellHelper.setOverlayPermissions(MY_PACKAGE, false);
+ }
+
private Helper() {
throw new UnsupportedOperationException("contain static methods only");
}
diff --git a/tests/autofillservice/src/android/autofillservice/cts/InstrumentedAutoFillService.java b/tests/autofillservice/src/android/autofillservice/cts/InstrumentedAutoFillService.java
index 7309db6..4062817 100644
--- a/tests/autofillservice/src/android/autofillservice/cts/InstrumentedAutoFillService.java
+++ b/tests/autofillservice/src/android/autofillservice/cts/InstrumentedAutoFillService.java
@@ -259,7 +259,7 @@
* was replied with a {@code null} response) - if a text needs to block until the service
* receives a callback, it should use {@link Replier#getNextFillRequest()} instead.
*/
- static void waitUntilConnected() throws Exception {
+ public static void waitUntilConnected() throws Exception {
waitConnectionState(CONNECTION_TIMEOUT, true);
}
@@ -269,7 +269,7 @@
* <p>This method is useful on tests that explicitly verifies the connection, but should be
* avoided in other tests, as it adds extra time to the test execution.
*/
- static void waitUntilDisconnected() throws Exception {
+ public static void waitUntilDisconnected() throws Exception {
waitConnectionState(IDLE_UNBIND_TIMEOUT, false);
}
@@ -297,7 +297,7 @@
* {@link AutofillService#onFillRequest(android.service.autofill.FillRequest,
* CancellationSignal, FillCallback)} that can be asserted at the end of a test case.
*/
- static final class FillRequest {
+ public static final class FillRequest {
final AssistStructure structure;
final List<FillContext> contexts;
final Bundle data;
@@ -327,7 +327,7 @@
* {@link AutofillService#onSaveRequest(android.service.autofill.SaveRequest, SaveCallback)}
* that can be asserted at the end of a test case.
*/
- static final class SaveRequest {
+ public static final class SaveRequest {
public final List<FillContext> contexts;
public final AssistStructure structure;
public final Bundle data;
@@ -359,7 +359,7 @@
* CancellationSignal, FillCallback)}
* on behalf of a unit test method.
*/
- static final class Replier {
+ public static final class Replier {
private final BlockingQueue<CannedFillResponse> mResponses = new LinkedBlockingQueue<>();
private final BlockingQueue<FillRequest> mFillRequests = new LinkedBlockingQueue<>();
@@ -388,7 +388,8 @@
/**
* Gets the exceptions thrown asynchronously, if any.
*/
- @Nullable List<Throwable> getExceptions() {
+ @Nullable
+ public List<Throwable> getExceptions() {
return mExceptions;
}
@@ -405,7 +406,7 @@
* Sets the expectation for the next {@code onFillRequest} as {@link FillResponse} with just
* one {@link Dataset}.
*/
- Replier addResponse(CannedDataset dataset) {
+ public Replier addResponse(CannedDataset dataset) {
return addResponse(new CannedFillResponse.Builder()
.addDataset(dataset)
.build());
@@ -414,7 +415,7 @@
/**
* Sets the expectation for the next {@code onFillRequest}.
*/
- Replier addResponse(CannedFillResponse response) {
+ public Replier addResponse(CannedFillResponse response) {
if (response == null) {
throw new IllegalArgumentException("Cannot be null - use NO_RESPONSE instead");
}
@@ -426,17 +427,15 @@
* Sets the {@link IntentSender} that is passed to
* {@link SaveCallback#onSuccess(IntentSender)}.
*/
- Replier setOnSave(IntentSender intentSender) {
+ public Replier setOnSave(IntentSender intentSender) {
mOnSaveIntentSender = intentSender;
return this;
}
/**
* Gets the next fill request, in the order received.
- *
- * <p>Typically called at the end of a test case, to assert the initial request.
*/
- FillRequest getNextFillRequest() {
+ public FillRequest getNextFillRequest() {
FillRequest request;
try {
request = mFillRequests.poll(FILL_TIMEOUT.ms(), TimeUnit.MILLISECONDS);
@@ -457,7 +456,7 @@
* <p>Should only be called in cases where it's not expected to be called, as it will
* sleep for a few ms.
*/
- void assertOnFillRequestNotCalled() {
+ public void assertOnFillRequestNotCalled() {
SystemClock.sleep(FILL_TIMEOUT.getMaxValue());
assertThat(mFillRequests).isEmpty();
}
@@ -468,7 +467,7 @@
* received by the service were properly {@link #getNextFillRequest() handled} by the test
* case.
*/
- void assertNoUnhandledFillRequests() {
+ public void assertNoUnhandledFillRequests() {
if (mFillRequests.isEmpty()) return; // Good job, test case!
if (!mReportUnhandledFillRequest) {
@@ -486,7 +485,7 @@
/**
* Gets the current number of unhandled requests.
*/
- int getNumberUnhandledFillRequests() {
+ public int getNumberUnhandledFillRequests() {
return mFillRequests.size();
}
@@ -495,7 +494,7 @@
*
* <p>Typically called at the end of a test case, to assert the initial request.
*/
- SaveRequest getNextSaveRequest() {
+ public SaveRequest getNextSaveRequest() {
SaveRequest request;
try {
request = mSaveRequests.poll(SAVE_TIMEOUT.ms(), TimeUnit.MILLISECONDS);
@@ -515,7 +514,7 @@
* save requests} received by the service were properly
* {@link #getNextFillRequest() handled} by the test case.
*/
- void assertNoUnhandledSaveRequests() {
+ public void assertNoUnhandledSaveRequests() {
if (mSaveRequests.isEmpty()) return; // Good job, test case!
if (!mReportUnhandledSaveRequest) {
@@ -533,7 +532,7 @@
/**
* Resets its internal state.
*/
- void reset() {
+ public void reset() {
mResponses.clear();
mFillRequests.clear();
mSaveRequests.clear();
diff --git a/tests/autofillservice/src/android/autofillservice/cts/LoginActivity.java b/tests/autofillservice/src/android/autofillservice/cts/LoginActivity.java
index 8690204..939792c 100644
--- a/tests/autofillservice/src/android/autofillservice/cts/LoginActivity.java
+++ b/tests/autofillservice/src/android/autofillservice/cts/LoginActivity.java
@@ -50,10 +50,10 @@
private static String WELCOME_TEMPLATE = "Welcome to the new activity, %s!";
private static final long LOGIN_TIMEOUT_MS = 1000;
- static final String ID_USERNAME_CONTAINER = "username_container";
- static final String AUTHENTICATION_MESSAGE = "Authentication failed. D'OH!";
- static final String BACKDOOR_USERNAME = "LemmeIn";
- static final String BACKDOOR_PASSWORD_SUBSTRING = "pass";
+ public static final String ID_USERNAME_CONTAINER = "username_container";
+ public static final String AUTHENTICATION_MESSAGE = "Authentication failed. D'OH!";
+ public static final String BACKDOOR_USERNAME = "LemmeIn";
+ public static final String BACKDOOR_PASSWORD_SUBSTRING = "pass";
private LinearLayout mUsernameContainer;
private TextView mUsernameLabel;
@@ -74,7 +74,7 @@
/**
* Gets the expected welcome message for a given username.
*/
- static String getWelcomeMessage(String username) {
+ public static String getWelcomeMessage(String username) {
return String.format(WELCOME_TEMPLATE, username);
}
@@ -157,7 +157,7 @@
* Sets the expectation for an autofill request (for all fields), so it can be asserted through
* {@link #assertAutoFilled()} later.
*/
- void expectAutoFill(String username, String password) {
+ public void expectAutoFill(String username, String password) {
mExpectation = new FillExpectation(username, password);
mUsernameEditText.addTextChangedListener(mExpectation.ccUsernameWatcher);
mPasswordEditText.addTextChangedListener(mExpectation.ccPasswordWatcher);
@@ -167,7 +167,7 @@
* Sets the expectation for an autofill request (for username only), so it can be asserted
* through {@link #assertAutoFilled()} later.
*/
- void expectAutoFill(String username) {
+ public void expectAutoFill(String username) {
mExpectation = new FillExpectation(username);
mUsernameEditText.addTextChangedListener(mExpectation.ccUsernameWatcher);
}
@@ -176,7 +176,7 @@
* Sets the expectation for an autofill request (for password only), so it can be asserted
* through {@link #assertAutoFilled()} later.
*/
- void expectPasswordAutoFill(String password) {
+ public void expectPasswordAutoFill(String password) {
mExpectation = new FillExpectation(null, password);
mPasswordEditText.addTextChangedListener(mExpectation.ccPasswordWatcher);
}
@@ -185,7 +185,7 @@
* Asserts the activity was auto-filled with the values passed to
* {@link #expectAutoFill(String, String)}.
*/
- void assertAutoFilled() throws Exception {
+ public void assertAutoFilled() throws Exception {
assertWithMessage("expectAutoFill() not called").that(mExpectation).isNotNull();
if (mExpectation.ccUsernameWatcher != null) {
mExpectation.ccUsernameWatcher.assertAutoFilled();
@@ -195,25 +195,25 @@
}
}
- void forceAutofillOnUsername() {
+ public void forceAutofillOnUsername() {
syncRunOnUiThread(() -> getAutofillManager().requestAutofill(mUsernameEditText));
}
- void forceAutofillOnPassword() {
+ public void forceAutofillOnPassword() {
syncRunOnUiThread(() -> getAutofillManager().requestAutofill(mPasswordEditText));
}
/**
* Visits the {@code username_label} in the UiThread.
*/
- void onUsernameLabel(Visitor<TextView> v) {
+ public void onUsernameLabel(Visitor<TextView> v) {
syncRunOnUiThread(() -> v.visit(mUsernameLabel));
}
/**
* Visits the {@code username} in the UiThread.
*/
- void onUsername(Visitor<EditText> v) {
+ public void onUsername(Visitor<EditText> v) {
syncRunOnUiThread(() -> v.visit(mUsernameEditText));
}
@@ -227,42 +227,42 @@
/**
* Gets the {@code username_label} view.
*/
- TextView getUsernameLabel() {
+ public TextView getUsernameLabel() {
return mUsernameLabel;
}
/**
* Gets the {@code username} view.
*/
- EditText getUsername() {
+ public EditText getUsername() {
return mUsernameEditText;
}
/**
* Visits the {@code password_label} in the UiThread.
*/
- void onPasswordLabel(Visitor<TextView> v) {
+ public void onPasswordLabel(Visitor<TextView> v) {
syncRunOnUiThread(() -> v.visit(mPasswordLabel));
}
/**
* Visits the {@code password} in the UiThread.
*/
- void onPassword(Visitor<EditText> v) {
+ public void onPassword(Visitor<EditText> v) {
syncRunOnUiThread(() -> v.visit(mPasswordEditText));
}
/**
* Gets the {@code password} view.
*/
- EditText getPassword() {
+ public EditText getPassword() {
return mPasswordEditText;
}
/**
* Taps the login button in the UI thread.
*/
- String tapLogin() throws Exception {
+ public String tapLogin() throws Exception {
mLoginLatch = new CountDownLatch(1);
syncRunOnUiThread(() -> mLoginButton.performClick());
boolean called = mLoginLatch.await(LOGIN_TIMEOUT_MS, TimeUnit.MILLISECONDS);
@@ -274,7 +274,7 @@
/**
* Taps the save button in the UI thread.
*/
- void tapSave() throws Exception {
+ public void tapSave() throws Exception {
syncRunOnUiThread(() -> mSaveButton.performClick());
}
@@ -288,7 +288,7 @@
/**
* Sets the window flags.
*/
- void setFlags(int flags) {
+ public void setFlags(int flags) {
Log.d(TAG, "setFlags():" + flags);
syncRunOnUiThread(() -> getWindow().setFlags(flags, flags));
}
diff --git a/tests/autofillservice/src/android/autofillservice/cts/LoginActivityTest.java b/tests/autofillservice/src/android/autofillservice/cts/LoginActivityTest.java
index 5b42ad8..5edfb53 100644
--- a/tests/autofillservice/src/android/autofillservice/cts/LoginActivityTest.java
+++ b/tests/autofillservice/src/android/autofillservice/cts/LoginActivityTest.java
@@ -23,12 +23,14 @@
import static android.autofillservice.cts.Helper.ID_PASSWORD_LABEL;
import static android.autofillservice.cts.Helper.ID_USERNAME;
import static android.autofillservice.cts.Helper.ID_USERNAME_LABEL;
+import static android.autofillservice.cts.Helper.allowOverlays;
import static android.autofillservice.cts.Helper.assertHasFlags;
import static android.autofillservice.cts.Helper.assertNumberOfChildren;
import static android.autofillservice.cts.Helper.assertTextAndValue;
import static android.autofillservice.cts.Helper.assertTextIsSanitized;
import static android.autofillservice.cts.Helper.assertTextOnly;
import static android.autofillservice.cts.Helper.assertValue;
+import static android.autofillservice.cts.Helper.disallowOverlays;
import static android.autofillservice.cts.Helper.dumpStructure;
import static android.autofillservice.cts.Helper.findNodeByResourceId;
import static android.autofillservice.cts.Helper.isAutofillWindowFullScreen;
@@ -41,7 +43,6 @@
import static android.autofillservice.cts.LoginActivity.BACKDOOR_USERNAME;
import static android.autofillservice.cts.LoginActivity.ID_USERNAME_CONTAINER;
import static android.autofillservice.cts.LoginActivity.getWelcomeMessage;
-import static android.autofillservice.cts.common.ShellHelper.runShellCommand;
import static android.autofillservice.cts.common.ShellHelper.sendKeyEvent;
import static android.autofillservice.cts.common.ShellHelper.tap;
import static android.content.Context.CLIPBOARD_SERVICE;
@@ -943,7 +944,7 @@
final View[] overlay = new View[1];
try {
// Allow ourselves to add overlays
- runShellCommand("appops set %s SYSTEM_ALERT_WINDOW allow", mPackageName);
+ allowOverlays();
// Make sure the fill UI is shown.
mUiBot.assertDatasets("The Dude");
@@ -1013,7 +1014,7 @@
} finally {
try {
// Make sure we can no longer add overlays
- runShellCommand("appops set %s SYSTEM_ALERT_WINDOW ignore", mPackageName);
+ disallowOverlays();
// Make sure the overlay is removed
mActivity.runOnUiThread(() -> {
WindowManager windowManager = mContext.getSystemService(WindowManager.class);
diff --git a/tests/autofillservice/src/android/autofillservice/cts/OneTimeCancellationSignalListener.java b/tests/autofillservice/src/android/autofillservice/cts/OneTimeCancellationSignalListener.java
index 0b055e0..9ba3f6b 100644
--- a/tests/autofillservice/src/android/autofillservice/cts/OneTimeCancellationSignalListener.java
+++ b/tests/autofillservice/src/android/autofillservice/cts/OneTimeCancellationSignalListener.java
@@ -27,15 +27,16 @@
* Custom {@link android.os.CancellationSignal.OnCancelListener} used to assert that
* {@link android.os.CancellationSignal.OnCancelListener} was called, and just once.
*/
-final class OneTimeCancellationSignalListener implements CancellationSignal.OnCancelListener {
+public final class OneTimeCancellationSignalListener
+ implements CancellationSignal.OnCancelListener {
private final CountDownLatch mLatch = new CountDownLatch(1);
private final long mTimeoutMs;
- OneTimeCancellationSignalListener(long timeoutMs) {
+ public OneTimeCancellationSignalListener(long timeoutMs) {
mTimeoutMs = timeoutMs;
}
- void assertOnCancelCalled() throws Exception {
+ public void assertOnCancelCalled() throws Exception {
final boolean called = mLatch.await(mTimeoutMs, TimeUnit.MILLISECONDS);
assertWithMessage("Timeout (%s ms) waiting for onCancel()", mTimeoutMs)
.that(called).isTrue();
diff --git a/tests/autofillservice/src/android/autofillservice/cts/UiBot.java b/tests/autofillservice/src/android/autofillservice/cts/UiBot.java
index 3c520bc..85e8983 100644
--- a/tests/autofillservice/src/android/autofillservice/cts/UiBot.java
+++ b/tests/autofillservice/src/android/autofillservice/cts/UiBot.java
@@ -67,7 +67,7 @@
/**
* Helper for UI-related needs.
*/
-final class UiBot {
+public final class UiBot {
private static final String TAG = "AutoFillCtsUiBot";
@@ -130,11 +130,11 @@
private boolean mOkToCallAssertNoDatasets;
- UiBot() {
+ public UiBot() {
this(UI_TIMEOUT);
}
- UiBot(Timeout defaultTimeout) {
+ public UiBot(Timeout defaultTimeout) {
mDefaultTimeout = defaultTimeout;
final Instrumentation instrumentation = InstrumentationRegistry.getInstrumentation();
mDevice = UiDevice.getInstance(instrumentation);
@@ -143,14 +143,14 @@
mAutoman = instrumentation.getUiAutomation();
}
- void waitForIdle() {
+ public void waitForIdle() {
final long before = SystemClock.elapsedRealtimeNanos();
mDevice.waitForIdle();
final float delta = ((float) (SystemClock.elapsedRealtimeNanos() - before)) / 1_000_000;
Log.v(TAG, "device idle in " + delta + "ms");
}
- void reset() {
+ public void reset() {
mOkToCallAssertNoDatasets = false;
}
@@ -159,7 +159,7 @@
* {@code AssumptionViolatedException} if it doesn't (so the test is skiped by the JUnit
* Runner).
*/
- void assumeMinimumResolution(int minSize) {
+ public void assumeMinimumResolution(int minSize) {
final int width = mDevice.getDisplayWidth();
final int heigth = mDevice.getDisplayHeight();
final int min = Math.min(width, heigth);
@@ -174,7 +174,7 @@
*
* When called, test must call <p>{@link #resetScreenResolution()} in a {@code finally} block.
*/
- void setScreenResolution() {
+ public void setScreenResolution() {
assumeMinimumResolution(500);
runShellCommand("wm size 1080x1920");
@@ -186,7 +186,7 @@
*
* <p>Should always be called after {@link #setScreenResolution()}.
*/
- void resetScreenResolution() {
+ public void resetScreenResolution() {
runShellCommand("wm density reset");
runShellCommand("wm size reset");
}
@@ -198,7 +198,7 @@
* dataset picker is shown - if that's not the case, call
* {@link #assertNoDatasetsEver()} instead.
*/
- void assertNoDatasets() throws Exception {
+ public void assertNoDatasets() throws Exception {
if (!mOkToCallAssertNoDatasets) {
throw new IllegalStateException(
"Cannot call assertNoDatasets() without calling assertDatasets first");
@@ -213,7 +213,7 @@
* <p>This method is slower than {@link #assertNoDatasets()} and should only be called in the
* cases where the dataset picker was not previous shown.
*/
- void assertNoDatasetsEver() throws Exception {
+ public void assertNoDatasetsEver() throws Exception {
assertNeverShown("dataset picker", DATASET_PICKER_SELECTOR,
DATASET_PICKER_NOT_SHOWN_NAPTIME_MS);
}
@@ -223,7 +223,7 @@
*
* @return the dataset picker object.
*/
- UiObject2 assertDatasets(String...names) throws Exception {
+ public UiObject2 assertDatasets(String...names) throws Exception {
// TODO: change run() so it can rethrow the original message
return UI_DATASET_PICKER_TIMEOUT.run("assertDatasets: " + Arrays.toString(names), () -> {
final UiObject2 picker = findDatasetPicker(UI_DATASET_PICKER_TIMEOUT);
@@ -245,7 +245,7 @@
*
* @return the dataset picker object.
*/
- UiObject2 assertDatasetsContains(String...names) throws Exception {
+ public UiObject2 assertDatasetsContains(String...names) throws Exception {
// TODO: change run() so it can rethrow the original message
return UI_DATASET_PICKER_TIMEOUT.run("assertDatasets: " + Arrays.toString(names), () -> {
final UiObject2 picker = findDatasetPicker(UI_DATASET_PICKER_TIMEOUT);
@@ -268,7 +268,7 @@
*
* @return the dataset picker object.
*/
- UiObject2 assertDatasetsWithBorders(String header, String footer, String...names)
+ public UiObject2 assertDatasetsWithBorders(String header, String footer, String...names)
throws Exception {
final UiObject2 picker = findDatasetPicker(UI_DATASET_PICKER_TIMEOUT);
final List<String> expectedChild = new ArrayList<>();
@@ -295,7 +295,7 @@
/**
* Gets the text of this object children.
*/
- List<String> getChildrenAsText(UiObject2 object) {
+ public List<String> getChildrenAsText(UiObject2 object) {
final List<String> list = new ArrayList<>();
getChildrenAsText(object, list);
return list;
@@ -314,7 +314,7 @@
/**
* Selects a dataset that should be visible in the floating UI.
*/
- void selectDataset(String name) throws Exception {
+ public void selectDataset(String name) throws Exception {
final UiObject2 picker = findDatasetPicker(UI_DATASET_PICKER_TIMEOUT);
selectDataset(picker, name);
}
@@ -322,7 +322,7 @@
/**
* Selects a dataset that should be visible in the floating UI.
*/
- void selectDataset(UiObject2 picker, String name) {
+ public void selectDataset(UiObject2 picker, String name) {
final UiObject2 dataset = picker.findObject(By.text(name));
if (dataset == null) {
throw new AssertionError("no dataset " + name + " in " + getChildrenAsText(picker));
@@ -336,7 +336,7 @@
* <p><b>NOTE:</b> when selecting an option in dataset picker is shown, prefer
* {@link #selectDataset(String)}.
*/
- void selectByText(String name) throws Exception {
+ public void selectByText(String name) throws Exception {
Log.v(TAG, "selectByText(): " + name);
final UiObject2 object = waitForObject(By.text(name));
@@ -394,7 +394,7 @@
/**
* Checks if a View with a certain text exists.
*/
- boolean hasViewWithText(String name) {
+ public boolean hasViewWithText(String name) {
Log.v(TAG, "hasViewWithText(): " + name);
return mDevice.findObject(By.text(name)) != null;
@@ -403,7 +403,7 @@
/**
* Selects a view by id.
*/
- UiObject2 selectByRelativeId(String id) throws Exception {
+ public UiObject2 selectByRelativeId(String id) throws Exception {
Log.v(TAG, "selectByRelativeId(): " + id);
UiObject2 object = waitForObject(By.res(mPackageName, id));
object.click();
@@ -413,7 +413,7 @@
/**
* Asserts the id is shown on the screen.
*/
- UiObject2 assertShownById(String id) throws Exception {
+ public UiObject2 assertShownById(String id) throws Exception {
final UiObject2 object = waitForObject(By.res(id));
assertThat(object).isNotNull();
return object;
@@ -422,11 +422,11 @@
/**
* Asserts the id is shown on the screen, using a resource id from the test package.
*/
- UiObject2 assertShownByRelativeId(String id) throws Exception {
+ public UiObject2 assertShownByRelativeId(String id) throws Exception {
return assertShownByRelativeId(id, mDefaultTimeout);
}
- UiObject2 assertShownByRelativeId(String id, Timeout timeout) throws Exception {
+ public UiObject2 assertShownByRelativeId(String id, Timeout timeout) throws Exception {
final UiObject2 obj = waitForObject(By.res(mPackageName, id), timeout);
assertThat(obj).isNotNull();
return obj;
@@ -438,17 +438,25 @@
* <p><b>Note:</b> this method should only called AFTER the id was previously shown, otherwise
* it might pass without really asserting anything.
*/
- void assertGoneByRelativeId(@NonNull String id, @NonNull Timeout timeout) {
+ public void assertGoneByRelativeId(@NonNull String id, @NonNull Timeout timeout) {
assertGoneByRelativeId(/* parent = */ null, id, timeout);
}
+ public void assertGoneByRelativeId(int resId, @NonNull Timeout timeout) {
+ assertGoneByRelativeId(/* parent = */ null, getIdName(resId), timeout);
+ }
+
+ private String getIdName(int resId) {
+ return mContext.getResources().getResourceEntryName(resId);
+ }
+
/**
* Asserts the id is not shown on the parent anymore, using a resource id from the test package.
*
* <p><b>Note:</b> this method should only called AFTER the id was previously shown, otherwise
* it might pass without really asserting anything.
*/
- void assertGoneByRelativeId(@Nullable UiObject2 parent, @NonNull String id,
+ public void assertGoneByRelativeId(@Nullable UiObject2 parent, @NonNull String id,
@NonNull Timeout timeout) {
final SearchCondition<Boolean> condition = Until.gone(By.res(mPackageName, id));
final boolean gone = parent != null
@@ -462,6 +470,16 @@
}
}
+ public UiObject2 assertShownByRelativeId(int resId) throws Exception {
+ return assertShownByRelativeId(getIdName(resId));
+ }
+
+ public void assertNeverShownByRelativeId(@NonNull String description, int resId, long timeout)
+ throws Exception {
+ final BySelector selector = By.res(Helper.MY_PACKAGE, getIdName(resId));
+ assertNeverShown(description, selector, timeout);
+ }
+
/**
* Asserts that a {@code selector} is not showing after {@code timeout} milliseconds.
*/
@@ -479,42 +497,42 @@
/**
* Gets the text set on a view.
*/
- String getTextByRelativeId(String id) throws Exception {
+ public String getTextByRelativeId(String id) throws Exception {
return waitForObject(By.res(mPackageName, id)).getText();
}
/**
* Focus in the view with the given resource id.
*/
- void focusByRelativeId(String id) throws Exception {
+ public void focusByRelativeId(String id) throws Exception {
waitForObject(By.res(mPackageName, id)).click();
}
/**
* Sets a new text on a view.
*/
- void setTextByRelativeId(String id, String newText) throws Exception {
+ public void setTextByRelativeId(String id, String newText) throws Exception {
waitForObject(By.res(mPackageName, id)).setText(newText);
}
/**
* Asserts the save snackbar is showing and returns it.
*/
- UiObject2 assertSaveShowing(int type) throws Exception {
+ public UiObject2 assertSaveShowing(int type) throws Exception {
return assertSaveShowing(SAVE_TIMEOUT, type);
}
/**
* Asserts the save snackbar is showing and returns it.
*/
- UiObject2 assertSaveShowing(Timeout timeout, int type) throws Exception {
+ public UiObject2 assertSaveShowing(Timeout timeout, int type) throws Exception {
return assertSaveShowing(null, timeout, type);
}
/**
* Asserts the save snackbar is showing with the Update message and returns it.
*/
- UiObject2 assertUpdateShowing(int... types) throws Exception {
+ public UiObject2 assertUpdateShowing(int... types) throws Exception {
return assertSaveOrUpdateShowing(/* update= */ true, SaveInfo.NEGATIVE_BUTTON_STYLE_CANCEL,
null, SAVE_TIMEOUT, types);
}
@@ -522,7 +540,7 @@
/**
* Presses the Back button.
*/
- void pressBack() {
+ public void pressBack() {
Log.d(TAG, "pressBack()");
mDevice.pressBack();
}
@@ -530,7 +548,7 @@
/**
* Presses the Home button.
*/
- void pressHome() {
+ public void pressHome() {
Log.d(TAG, "pressHome()");
mDevice.pressHome();
}
@@ -538,11 +556,11 @@
/**
* Asserts the save snackbar is not showing.
*/
- void assertSaveNotShowing(int type) throws Exception {
+ public void assertSaveNotShowing(int type) throws Exception {
assertNeverShown("save UI for type " + type, SAVE_UI_SELECTOR, SAVE_NOT_SHOWN_NAPTIME_MS);
}
- void assertSaveNotShowing() throws Exception {
+ public void assertSaveNotShowing() throws Exception {
assertNeverShown("save UI", SAVE_UI_SELECTOR, SAVE_NOT_SHOWN_NAPTIME_MS);
}
@@ -570,26 +588,26 @@
return getString(typeResourceName);
}
- UiObject2 assertSaveShowing(String description, int... types) throws Exception {
+ public UiObject2 assertSaveShowing(String description, int... types) throws Exception {
return assertSaveOrUpdateShowing(/* update= */ false, SaveInfo.NEGATIVE_BUTTON_STYLE_CANCEL,
description, SAVE_TIMEOUT, types);
}
- UiObject2 assertSaveShowing(String description, Timeout timeout, int... types)
+ public UiObject2 assertSaveShowing(String description, Timeout timeout, int... types)
throws Exception {
return assertSaveOrUpdateShowing(/* update= */ false, SaveInfo.NEGATIVE_BUTTON_STYLE_CANCEL,
description, timeout, types);
}
- UiObject2 assertSaveShowing(int negativeButtonStyle, String description,
+ public UiObject2 assertSaveShowing(int negativeButtonStyle, String description,
int... types) throws Exception {
return assertSaveOrUpdateShowing(/* update= */ false, negativeButtonStyle, description,
SAVE_TIMEOUT, types);
}
- UiObject2 assertSaveOrUpdateShowing(boolean update, int negativeButtonStyle, String description,
- Timeout timeout, int... types) throws Exception {
+ public UiObject2 assertSaveOrUpdateShowing(boolean update, int negativeButtonStyle,
+ String description, Timeout timeout, int... types) throws Exception {
final UiObject2 snackbar = waitForObject(SAVE_UI_SELECTOR, timeout);
final UiObject2 titleView =
@@ -674,7 +692,7 @@
* @param yesDoIt {@code true} for 'YES', {@code false} for 'NO THANKS'.
* @param types expected types of save info.
*/
- void saveForAutofill(boolean yesDoIt, int... types) throws Exception {
+ public void saveForAutofill(boolean yesDoIt, int... types) throws Exception {
final UiObject2 saveSnackBar = assertSaveShowing(
SaveInfo.NEGATIVE_BUTTON_STYLE_CANCEL, null, types);
saveForAutofill(saveSnackBar, yesDoIt);
@@ -691,7 +709,8 @@
* @param yesDoIt {@code true} for 'YES', {@code false} for 'NO THANKS'.
* @param types expected types of save info.
*/
- void saveForAutofill(int negativeButtonStyle, boolean yesDoIt, int... types) throws Exception {
+ public void saveForAutofill(int negativeButtonStyle, boolean yesDoIt, int... types)
+ throws Exception {
final UiObject2 saveSnackBar = assertSaveShowing(negativeButtonStyle,null, types);
saveForAutofill(saveSnackBar, yesDoIt);
}
@@ -703,7 +722,7 @@
* {@link #assertSaveShowing(int)}.
* @param yesDoIt {@code true} for 'YES', {@code false} for 'NO THANKS'.
*/
- void saveForAutofill(UiObject2 saveSnackBar, boolean yesDoIt) {
+ public void saveForAutofill(UiObject2 saveSnackBar, boolean yesDoIt) {
final String id = yesDoIt ? "autofill_save_yes" : "autofill_save_no";
final UiObject2 button = saveSnackBar.findObject(By.res("android", id));
@@ -722,7 +741,7 @@
* @param id resource id of the field.
* @param expectOverflow whether overflow menu should be shown (when clipboard contains text)
*/
- UiObject2 getAutofillMenuOption(String id, boolean expectOverflow) throws Exception {
+ public UiObject2 getAutofillMenuOption(String id, boolean expectOverflow) throws Exception {
final UiObject2 field = waitForObject(By.res(mPackageName, id));
// TODO: figure out why obj.longClick() doesn't always work
field.click(3000);
diff --git a/tests/autofillservice/src/android/autofillservice/cts/Visitor.java b/tests/autofillservice/src/android/autofillservice/cts/Visitor.java
index a8e0314..26e62e3 100644
--- a/tests/autofillservice/src/android/autofillservice/cts/Visitor.java
+++ b/tests/autofillservice/src/android/autofillservice/cts/Visitor.java
@@ -22,13 +22,12 @@
* the UI thread. Example:
* <pre><code>
* void onUsername(ViewVisitor<EditText> v) {
- * runOnUiThread(() -> {
- * v.visit(mUsername);
- * });
+ * runOnUiThread(() -> v.visit(mUsername));
* }
* </code></pre>
*/
-interface Visitor<T> {
+// TODO: move to common code
+public interface Visitor<T> {
void visit(T view);
}
\ No newline at end of file
diff --git a/tests/autofillservice/src/android/autofillservice/cts/augmented/AugmentedAutofillAutoActivityLaunchTestCase.java b/tests/autofillservice/src/android/autofillservice/cts/augmented/AugmentedAutofillAutoActivityLaunchTestCase.java
new file mode 100644
index 0000000..c7e55fa
--- /dev/null
+++ b/tests/autofillservice/src/android/autofillservice/cts/augmented/AugmentedAutofillAutoActivityLaunchTestCase.java
@@ -0,0 +1,75 @@
+/*
+ * Copyright (C) 2019 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.autofillservice.cts.augmented;
+
+import static android.autofillservice.cts.Helper.allowOverlays;
+import static android.autofillservice.cts.Helper.disallowOverlays;
+import static android.provider.Settings.Global.AUTOFILL_SMART_SUGGESTION_EMULATION_FLAGS;
+
+import android.autofillservice.cts.AbstractAutoFillActivity;
+import android.autofillservice.cts.AutoFillServiceTestCase;
+import android.autofillservice.cts.augmented.CtsAugmentedAutofillService.AugmentedReplier;
+import android.autofillservice.cts.common.SettingsHelper;
+import android.autofillservice.cts.common.SettingsStateChangerRule;
+import android.view.autofill.AutofillManager;
+
+import org.junit.After;
+import org.junit.AfterClass;
+import org.junit.Before;
+import org.junit.BeforeClass;
+import org.junit.ClassRule;
+
+// Must be public because of the @ClassRule
+public abstract class AugmentedAutofillAutoActivityLaunchTestCase
+ <A extends AbstractAutoFillActivity> extends AutoFillServiceTestCase.AutoActivityLaunch<A> {
+
+ @ClassRule
+ public static final SettingsStateChangerRule sFeatureEnabler = new SettingsStateChangerRule(
+ sContext, SettingsHelper.NAMESPACE_GLOBAL, AUTOFILL_SMART_SUGGESTION_EMULATION_FLAGS,
+ Integer.toString(AutofillManager.FLAG_SMART_SUGGESTION_SYSTEM));
+
+ protected static AugmentedReplier sAugmentedReplier;
+ protected AugmentedUiBot mAugmentedUiBot;
+
+ @BeforeClass
+ public static void allowAugmentedAutofillWindow() {
+ allowOverlays();
+ }
+
+ @AfterClass
+ public static void disallowAugmentedAutofillWindow() {
+ disallowOverlays();
+ }
+
+ @Before
+ public void setFixtures() {
+ sAugmentedReplier = CtsAugmentedAutofillService.getAugmentedReplier();
+ sAugmentedReplier.reset();
+ mAugmentedUiBot = new AugmentedUiBot(mUiBot);
+ mSafeCleanerRule
+ .run(() -> sAugmentedReplier.assertNoUnhandledFillRequests())
+ .add(() -> { return sAugmentedReplier.getExceptions(); });
+ }
+
+ @After
+ public void resetService() {
+ AugmentedHelper.resetAugmentedService();
+ }
+
+ protected void enableAugmentedService() {
+ AugmentedHelper.setAugmentedService(CtsAugmentedAutofillService.SERVICE_NAME);
+ }
+}
diff --git a/tests/autofillservice/src/android/autofillservice/cts/augmented/AugmentedHelper.java b/tests/autofillservice/src/android/autofillservice/cts/augmented/AugmentedHelper.java
new file mode 100644
index 0000000..626b835
--- /dev/null
+++ b/tests/autofillservice/src/android/autofillservice/cts/augmented/AugmentedHelper.java
@@ -0,0 +1,161 @@
+/*
+ * Copyright (C) 2019 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.autofillservice.cts.augmented;
+
+import static android.autofillservice.cts.common.ShellHelper.runShellCommand;
+import static android.view.autofill.AutofillManager.MAX_TEMP_AUGMENTED_SERVICE_DURATION_MS;
+
+import static com.google.common.truth.Truth.assertWithMessage;
+
+import android.app.Activity;
+import android.autofillservice.cts.Helper;
+import android.autofillservice.cts.augmented.CtsAugmentedAutofillService.AugmentedFillRequest;
+import android.content.ComponentName;
+import android.service.autofill.augmented.FillRequest;
+import android.util.Log;
+import android.util.Pair;
+import android.view.autofill.AutofillId;
+import android.view.autofill.AutofillValue;
+
+import androidx.annotation.NonNull;
+import androidx.annotation.Nullable;
+
+import com.google.common.base.Preconditions;
+
+import java.util.List;
+
+/**
+ * Helper for common funcionalities.
+ */
+public final class AugmentedHelper {
+
+ private static final String TAG = AugmentedHelper.class.getSimpleName();
+
+ @NonNull
+ public static String getActivityName(@Nullable FillRequest request) {
+ if (request == null) return "N/A (null request)";
+
+ final ComponentName componentName = request.getActivityComponent();
+ if (componentName == null) return "N/A (no component name)";
+
+ return componentName.flattenToShortString();
+ }
+
+ /**
+ * Sets the augmented capture service.
+ */
+ public static void setAugmentedService(@NonNull String service) {
+ Log.d(TAG, "Setting service to " + service);
+ runShellCommand("cmd autofill set temporary-augmented-service 0 %s %d", service,
+ MAX_TEMP_AUGMENTED_SERVICE_DURATION_MS);
+ }
+
+ /**
+ * Resets the content capture service.
+ */
+ public static void resetAugmentedService() {
+ Log.d(TAG, "Resetting back to default service");
+ runShellCommand("cmd autofill set temporary-augmented-service 0");
+ }
+
+ public static void assertBasicRequestInfo(@NonNull AugmentedFillRequest request,
+ @NonNull Activity activity, @NonNull AutofillId expectedFocusedId,
+ @NonNull AutofillValue expectedFocusedValue) {
+ Preconditions.checkNotNull(activity);
+ Preconditions.checkNotNull(expectedFocusedId);
+ assertWithMessage("no AugmentedFillRequest").that(request).isNotNull();
+ assertWithMessage("no FillRequest on %s", request).that(request.request).isNotNull();
+ assertWithMessage("no FillController on %s", request).that(request.controller).isNotNull();
+ assertWithMessage("no FillCallback on %s", request).that(request.callback).isNotNull();
+ // TODO(b/122728762): re-add when set
+// assertWithMessage("no CancellationSignal on %s", request).that(request.cancellationSignal)
+// .isNotNull();
+ // NOTE: task id can change, we might need to set it in the activity's onCreate()
+ assertWithMessage("wrong task id on %s", request).that(request.request.getTaskId())
+ .isEqualTo(activity.getTaskId());
+
+ final ComponentName actualComponentName = request.request.getActivityComponent();
+ assertWithMessage("no activity name on %s", request).that(actualComponentName).isNotNull();
+ assertWithMessage("wrong activity name on %s", request).that(actualComponentName)
+ .isEqualTo(activity.getComponentName());
+ final AutofillId actualFocusedId = request.request.getFocusedId();
+ assertWithMessage("no focused id on %s", request).that(actualFocusedId).isNotNull();
+ assertWithMessage("wrong focused id on %s", request).that(actualFocusedId)
+ .isEqualTo(expectedFocusedId);
+ final AutofillValue actualFocusedValue = request.request.getFocusedValue();
+ assertWithMessage("no focused value on %s", request).that(actualFocusedValue).isNotNull();
+ assertAutofillValue(expectedFocusedValue, actualFocusedValue);
+ }
+
+ public static void assertAutofillValue(final AutofillValue expectedValue,
+ final AutofillValue actualValue) {
+ // It only supports text values for now...
+ assertWithMessage("expected value is not text: %s", expectedValue)
+ .that(expectedValue.isText()).isTrue();
+ assertWithMessage("actual value is not text: %s", actualValue)
+ .that(actualValue.isText()).isTrue();
+
+ assertWithMessage("wrong autofill value").that(actualValue.getTextValue())
+ .isEqualTo(expectedValue.getTextValue());
+ }
+
+ @NonNull
+ public static String toString(@Nullable List<Pair<AutofillId, AutofillValue>> values) {
+ if (values == null) return "null";
+ final StringBuilder string = new StringBuilder("[");
+ final int size = values.size();
+ for (int i = 0; i < size; i++) {
+ final Pair<AutofillId, AutofillValue> value = values.get(i);
+ string.append(i).append(':').append(value.first).append('=')
+ .append(Helper.toString(value.second));
+ if (i < size - 1) {
+ string.append(", ");
+ }
+
+ }
+ return string.append(']').toString();
+ }
+
+ @NonNull
+ public static String toString(@Nullable FillRequest request) {
+ if (request == null) return "(null request)";
+
+ final StringBuilder string =
+ new StringBuilder("FillRequest[act=").append(getActivityName(request))
+ .append(", taskId=").append(request.getTaskId());
+
+ final AutofillId focusedId = request.getFocusedId();
+ if (focusedId != null) {
+ string.append(", focusedId=").append(focusedId);
+ }
+ final AutofillValue focusedValue = request.getFocusedValue();
+ if (focusedValue != null) {
+ string.append(", focusedValue=").append(focusedValue);
+ }
+
+ return string.append(']').toString();
+ }
+
+ // Used internally by UiBot to assert the UI
+ static String getContentDescriptionForUi(@NonNull AutofillId focusedId) {
+ return "ui_for_" + focusedId;
+ }
+
+ private AugmentedHelper() {
+ throw new UnsupportedOperationException("contain static methods only");
+ }
+}
diff --git a/tests/autofillservice/src/android/autofillservice/cts/augmented/AugmentedLoginActivityTest.java b/tests/autofillservice/src/android/autofillservice/cts/augmented/AugmentedLoginActivityTest.java
new file mode 100644
index 0000000..cbf2671
--- /dev/null
+++ b/tests/autofillservice/src/android/autofillservice/cts/augmented/AugmentedLoginActivityTest.java
@@ -0,0 +1,200 @@
+/*
+ * Copyright (C) 2019 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.autofillservice.cts.augmented;
+
+import static android.autofillservice.cts.CannedFillResponse.NO_RESPONSE;
+import static android.autofillservice.cts.augmented.AugmentedHelper.assertBasicRequestInfo;
+import static android.autofillservice.cts.augmented.AugmentedTimeouts.AUGMENTED_FILL_TIMEOUT;
+import static android.autofillservice.cts.augmented.CannedAugmentedFillResponse.DO_NOT_REPLY_AUGMENTED_RESPONSE;
+import static android.autofillservice.cts.augmented.CannedAugmentedFillResponse.NO_AUGMENTED_RESPONSE;
+
+import android.autofillservice.cts.AutofillActivityTestRule;
+import android.autofillservice.cts.LoginActivity;
+import android.autofillservice.cts.OneTimeCancellationSignalListener;
+import android.autofillservice.cts.augmented.CtsAugmentedAutofillService.AugmentedFillRequest;
+import android.support.test.uiautomator.UiObject2;
+import android.view.View;
+import android.view.autofill.AutofillId;
+import android.view.autofill.AutofillValue;
+import android.widget.EditText;
+
+import org.junit.Ignore;
+import org.junit.Test;
+
+public class AugmentedLoginActivityTest
+ extends AugmentedAutofillAutoActivityLaunchTestCase<LoginActivity> {
+
+ protected LoginActivity mActivity;
+
+ @Override
+ protected AutofillActivityTestRule<LoginActivity> getActivityRule() {
+ return new AutofillActivityTestRule<LoginActivity>(
+ LoginActivity.class) {
+ @Override
+ protected void afterActivityLaunched() {
+ mActivity = getActivity();
+ }
+ };
+ }
+
+ @Test
+ public void testAutoFill_neitherServiceCanAutofill() throws Exception {
+ // Set services
+ enableService();
+ enableAugmentedService();
+
+ // Set expectations
+ final EditText username = mActivity.getUsername();
+ final AutofillValue expectedFocusedValue = username.getAutofillValue();
+ final AutofillId expectedFocusedId = username.getAutofillId();
+ sReplier.addResponse(NO_RESPONSE);
+ sAugmentedReplier.addResponse(NO_AUGMENTED_RESPONSE);
+
+ // Trigger autofill
+ mActivity.onUsername(View::requestFocus);
+ sReplier.getNextFillRequest();
+ final AugmentedFillRequest request = sAugmentedReplier.getNextFillRequest();
+
+ // Assert request
+ assertBasicRequestInfo(request, mActivity, expectedFocusedId, expectedFocusedValue);
+
+ // Make sure standard Autofill UI is not shown.
+ mUiBot.assertNoDatasetsEver();
+
+ // Make sure Augmented Autofill UI is not shown.
+ mAugmentedUiBot.assertUiNeverShown();
+ }
+
+ @Test
+ public void testAutoFill_mainServiceReturnedNull_augmentedAutofillOneField() throws Exception {
+ // Set services
+ enableService();
+ enableAugmentedService();
+
+ // Set expectations
+ final EditText username = mActivity.getUsername();
+ final AutofillId usernameId = username.getAutofillId();
+ final AutofillValue expectedFocusedValue = username.getAutofillValue();
+ sReplier.addResponse(NO_RESPONSE);
+ sAugmentedReplier.addResponse(new CannedAugmentedFillResponse.Builder()
+ .setDataset(new CannedAugmentedFillResponse.Dataset.Builder("Augment Me")
+ .setField(usernameId, "dude")
+ .build(), usernameId)
+ .build());
+ mActivity.expectAutoFill("dude");
+
+ // Trigger autofill
+ mActivity.onUsername(View::requestFocus);
+ sReplier.getNextFillRequest();
+ final AugmentedFillRequest request = sAugmentedReplier.getNextFillRequest();
+
+ // Assert request
+ assertBasicRequestInfo(request, mActivity, usernameId, expectedFocusedValue);
+
+ // Make sure standard Autofill UI is not shown.
+ mUiBot.assertNoDatasetsEver();
+
+ // Make sure Augmented Autofill UI is shown.
+ final UiObject2 ui = mAugmentedUiBot.assertUiShown(usernameId, "Augment Me");
+
+ // Autofill
+ ui.click();
+ mActivity.assertAutoFilled();
+ mAugmentedUiBot.assertUiGone();
+ }
+
+ @Test
+ public void testAutoFill_mainServiceReturnedNull_augmentedAutofillTwoFields() throws Exception {
+ // Set services
+ enableService();
+ enableAugmentedService();
+
+ // Set expectations
+ final EditText username = mActivity.getUsername();
+ final AutofillId usernameId = username.getAutofillId();
+ final AutofillValue expectedFocusedValue = username.getAutofillValue();
+ sReplier.addResponse(NO_RESPONSE);
+ sAugmentedReplier.addResponse(new CannedAugmentedFillResponse.Builder()
+ .setDataset(new CannedAugmentedFillResponse.Dataset.Builder("Augment Me")
+ .setField(usernameId, "dude")
+ .setField(mActivity.getPassword().getAutofillId(), "sweet")
+ .build(), usernameId)
+ .build());
+ mActivity.expectAutoFill("dude", "sweet");
+
+ // Trigger autofill
+ mActivity.onUsername(View::requestFocus);
+ sReplier.getNextFillRequest();
+ final AugmentedFillRequest request = sAugmentedReplier.getNextFillRequest();
+
+ // Assert request
+ assertBasicRequestInfo(request, mActivity, usernameId, expectedFocusedValue);
+
+ // Make sure standard Autofill UI is not shown.
+ mUiBot.assertNoDatasetsEver();
+
+ // Make sure Augmented Autofill UI is shown.
+ final UiObject2 ui = mAugmentedUiBot.assertUiShown(usernameId, "Augment Me");
+
+ // Autofill
+ ui.click();
+ mActivity.assertAutoFilled();
+ mAugmentedUiBot.assertUiGone();
+ }
+
+ @Ignore("blocked on b/122728762")
+ @Test
+ public void testCancellationSignalCalledAfterTimeout() throws Exception {
+ // Set services
+ enableService();
+ enableAugmentedService();
+
+ // Set expectations
+ sReplier.addResponse(NO_RESPONSE);
+ sAugmentedReplier.addResponse(DO_NOT_REPLY_AUGMENTED_RESPONSE);
+ final OneTimeCancellationSignalListener listener =
+ new OneTimeCancellationSignalListener(AUGMENTED_FILL_TIMEOUT.ms() + 2000);
+
+ // Trigger autofill
+ mActivity.onUsername(View::requestFocus);
+ sReplier.getNextFillRequest();
+
+ // TODO(b/122728762): might need to wait until connected
+ sAugmentedReplier.getNextFillRequest().cancellationSignal.setOnCancelListener(listener);
+
+ // Assert results
+ listener.assertOnCancelCalled();
+ }
+
+ /*
+ * TODO(b/119638958) - add moarrrr tests:
+ *
+ * - Augmented service returned null
+ * - Focus back and forth between username and passwod
+ * - When Augmented service shows UI on one field (like username) but not other.
+ * - When Augmented service shows UI on one field (like username) on both.
+ * - Tap back
+ * - Tap home (then bring activity back)
+ * - Acitivy is killed (and restored)
+ * - Main service returns non-null response that doesn't show UI (for example, has just
+ * SaveInfo)
+ * - Augmented autofill show UI, user fills, Save UI is shown
+ * - etc ...
+ * - No augmented autofill calls when the main service is not set.
+ * - etc...
+ */
+}
diff --git a/tests/autofillservice/src/android/autofillservice/cts/augmented/AugmentedTimeouts.java b/tests/autofillservice/src/android/autofillservice/cts/augmented/AugmentedTimeouts.java
new file mode 100644
index 0000000..730b0d4
--- /dev/null
+++ b/tests/autofillservice/src/android/autofillservice/cts/augmented/AugmentedTimeouts.java
@@ -0,0 +1,50 @@
+/*
+ * Copyright (C) 2019 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.autofillservice.cts.augmented;
+
+import android.autofillservice.cts.Timeout;
+
+/**
+ * Timeouts for common tasks.
+ */
+final class AugmentedTimeouts {
+
+ private static final long ONE_TIMEOUT_TO_RULE_THEN_ALL_MS = 1_000;
+ private static final long ONE_NAPTIME_TO_RULE_THEN_ALL_MS = 3_000;
+
+ /**
+ * Timeout for expected augmented autofill requests.
+ */
+ static final Timeout AUGMENTED_FILL_TIMEOUT = new Timeout("AUGMENTED_FILL_TIMEOUT",
+ ONE_TIMEOUT_TO_RULE_THEN_ALL_MS, 2F, ONE_TIMEOUT_TO_RULE_THEN_ALL_MS);
+
+ /**
+ * Timeout until framework binds / unbinds from service.
+ */
+ static final Timeout AUGMENTED_CONNECTION_TIMEOUT = new Timeout("AUGMENTED_CONNECTION_TIMEOUT",
+ ONE_TIMEOUT_TO_RULE_THEN_ALL_MS, 2F, ONE_TIMEOUT_TO_RULE_THEN_ALL_MS);
+
+ /**
+ * Timeout used when the augmented autofill UI not expected to be shown - test will sleep for
+ * that amount of time as there is no callback that be received to assert it's not shown.
+ */
+ static final long AUGMENTED_UI_NOT_SHOWN_NAPTIME_MS = ONE_NAPTIME_TO_RULE_THEN_ALL_MS;
+
+ private AugmentedTimeouts() {
+ throw new UnsupportedOperationException("contain static methods only");
+ }
+}
diff --git a/tests/autofillservice/src/android/autofillservice/cts/augmented/AugmentedUiBot.java b/tests/autofillservice/src/android/autofillservice/cts/augmented/AugmentedUiBot.java
new file mode 100644
index 0000000..ed00223
--- /dev/null
+++ b/tests/autofillservice/src/android/autofillservice/cts/augmented/AugmentedUiBot.java
@@ -0,0 +1,91 @@
+/*
+ * Copyright (C) 2019 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.autofillservice.cts.augmented;
+
+import static android.autofillservice.cts.augmented.AugmentedHelper.getContentDescriptionForUi;
+import static android.autofillservice.cts.augmented.AugmentedTimeouts.AUGMENTED_FILL_TIMEOUT;
+import static android.autofillservice.cts.augmented.AugmentedTimeouts.AUGMENTED_UI_NOT_SHOWN_NAPTIME_MS;
+
+import static com.google.common.truth.Truth.assertWithMessage;
+
+import android.autofillservice.cts.R;
+import android.autofillservice.cts.UiBot;
+import android.support.test.uiautomator.UiObject2;
+import android.view.autofill.AutofillId;
+
+import androidx.annotation.NonNull;
+
+import com.google.common.base.Preconditions;
+
+/**
+ * Helper for UI-related needs.
+ */
+public final class AugmentedUiBot {
+
+ private final UiBot mUiBot;
+ private boolean mOkToCallAssertUiGone;
+
+ public AugmentedUiBot(@NonNull UiBot uiBot) {
+ mUiBot = uiBot;
+ }
+
+ /**
+ * Asserts the augmented autofill UI was never shown.
+ *
+ * <p>This method is slower than {@link #assertUiGone()} and should only be called in the
+ * cases where the dataset picker was not previous shown.
+ */
+ public void assertUiNeverShown() throws Exception {
+ mUiBot.assertNeverShownByRelativeId("augmented autofil UI", R.id.augmentedAutofillUi,
+ AUGMENTED_UI_NOT_SHOWN_NAPTIME_MS);
+ }
+
+ /**
+ * Asserts the augmented autofill UI was shown.
+ *
+ * @param focusedId where it should have been shown
+ * @param expectedText the expected text in the UI
+ */
+ public UiObject2 assertUiShown(@NonNull AutofillId focusedId,
+ @NonNull String expectedText) throws Exception {
+ Preconditions.checkNotNull(focusedId);
+ Preconditions.checkNotNull(expectedText);
+
+ final UiObject2 ui = mUiBot.assertShownByRelativeId(R.id.augmentedAutofillUi);
+
+ assertWithMessage("Wrong text on UI").that(ui.getText()).isEqualTo(expectedText);
+
+ final String expectedContentDescription = getContentDescriptionForUi(focusedId);
+ assertWithMessage("Wrong content description on UI")
+ .that(ui.getContentDescription()).isEqualTo(expectedContentDescription);
+
+ mOkToCallAssertUiGone = true;
+
+ return ui;
+ }
+
+ /**
+ * Asserts the augmented autofill UI is gone AFTER it was previously shown.
+ *
+ * @throws IllegalStateException if this method is called without calling
+ * {@link #assertUiShown(AutofillId, String)} before.
+ */
+ public void assertUiGone() {
+ Preconditions.checkState(mOkToCallAssertUiGone, "must call assertUiShown() first");
+ mUiBot.assertGoneByRelativeId(R.id.augmentedAutofillUi, AUGMENTED_FILL_TIMEOUT);
+ }
+}
diff --git a/tests/autofillservice/src/android/autofillservice/cts/augmented/CannedAugmentedFillResponse.java b/tests/autofillservice/src/android/autofillservice/cts/augmented/CannedAugmentedFillResponse.java
new file mode 100644
index 0000000..8aada3f
--- /dev/null
+++ b/tests/autofillservice/src/android/autofillservice/cts/augmented/CannedAugmentedFillResponse.java
@@ -0,0 +1,216 @@
+/*
+ * Copyright (C) 2019 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.autofillservice.cts.augmented;
+
+import static android.autofillservice.cts.augmented.AugmentedHelper.getContentDescriptionForUi;
+
+import android.autofillservice.cts.R;
+import android.content.Context;
+import android.service.autofill.augmented.FillCallback;
+import android.service.autofill.augmented.FillController;
+import android.service.autofill.augmented.FillRequest;
+import android.service.autofill.augmented.FillResponse;
+import android.service.autofill.augmented.FillWindow;
+import android.service.autofill.augmented.PresentationParams;
+import android.service.autofill.augmented.PresentationParams.Area;
+import android.util.ArrayMap;
+import android.util.Log;
+import android.util.Pair;
+import android.view.LayoutInflater;
+import android.view.autofill.AutofillId;
+import android.view.autofill.AutofillValue;
+import android.widget.TextView;
+
+import androidx.annotation.NonNull;
+
+import com.google.common.base.Preconditions;
+
+import java.util.List;
+import java.util.Map;
+import java.util.stream.Collectors;
+
+/**
+ * Helper class used to produce a {@link FillResponse}.
+ */
+public final class CannedAugmentedFillResponse {
+
+ private static final String TAG = CannedAugmentedFillResponse.class.getSimpleName();
+
+ private final AugmentedResponseType mResponseType;
+ private final Map<AutofillId, Dataset> mDatasets;
+
+ private CannedAugmentedFillResponse(@NonNull Builder builder) {
+ mResponseType = builder.mResponseType;
+ mDatasets = builder.mDatasets;
+ }
+
+ /**
+ * Constant used to pass a {@code null} response to the
+ * {@link FillCallback#onSuccess(FillResponse)} method.
+ */
+ public static final CannedAugmentedFillResponse NO_AUGMENTED_RESPONSE =
+ new Builder(AugmentedResponseType.NULL).build();
+
+ /**
+ * Constant used to emulate a timeout by not calling any method on {@link FillCallback}.
+ */
+ public static final CannedAugmentedFillResponse DO_NOT_REPLY_AUGMENTED_RESPONSE =
+ new Builder(AugmentedResponseType.TIMEOUT).build();
+
+ public AugmentedResponseType getResponseType() {
+ return mResponseType;
+ }
+
+ /**
+ * Creates the "real" response.
+ */
+ public FillResponse asFillResponse(@NonNull Context context, @NonNull FillRequest request,
+ @NonNull FillController controller) {
+ final AutofillId focusedId = request.getFocusedId();
+
+ final Dataset dataset = mDatasets.get(focusedId);
+ if (dataset == null) {
+ Log.d(TAG, "no dataset for field " + focusedId);
+ return null;
+ }
+
+ Log.d(TAG, "asFillResponse: id=" + focusedId + ", dataset=" + dataset);
+
+ final PresentationParams presentationParams = request.getPresentationParams();
+ if (presentationParams == null) {
+ Log.w(TAG, "No PresentationParams");
+ return null;
+ }
+
+ final Area strip = presentationParams.getSuggestionArea();
+ if (strip == null) {
+ Log.w(TAG, "No suggestion strip");
+ return null;
+ }
+
+ final LayoutInflater inflater = LayoutInflater.from(context);
+ final TextView rootView = (TextView) inflater.inflate(R.layout.augmented_autofill_ui, null);
+
+ rootView.setText(dataset.mPresentation);
+
+ rootView.setContentDescription(getContentDescriptionForUi(focusedId));
+ final FillWindow fillWindow = new FillWindow();
+ rootView.setOnClickListener((v) -> {
+ Log.d(TAG, "Destroying window first");
+ fillWindow.destroy();
+ final List<Pair<AutofillId, AutofillValue>> values = dataset.getValues();
+ Log.i(TAG, "Autofilling: " + AugmentedHelper.toString(values));
+ controller.autofill(values);
+ });
+
+ boolean ok = fillWindow.update(strip, rootView, 0);
+ if (!ok) {
+ Log.w(TAG, "FillWindow.update() failed for " + strip + " and " + rootView);
+ return null;
+ }
+
+ return new FillResponse.Builder().setFillWindow(fillWindow).build();
+ }
+
+ @Override
+ public String toString() {
+ return "CannedAugmentedFillResponse: [type=" + mResponseType
+ + ",datasets=" + mDatasets
+ + "]";
+ }
+ public enum AugmentedResponseType {
+ NORMAL,
+ NULL,
+ TIMEOUT,
+ }
+
+ public static final class Builder {
+ private final Map<AutofillId, Dataset> mDatasets = new ArrayMap<>();
+ private final AugmentedResponseType mResponseType;
+
+ public Builder(@NonNull AugmentedResponseType type) {
+ mResponseType = type;
+ }
+
+ public Builder() {
+ this(AugmentedResponseType.NORMAL);
+ }
+
+ /**
+ * Sets the {@link Dataset} that will be filled when the given {@code ids} is focused and
+ * the UI is tapped.
+ */
+ public Builder setDataset(@NonNull Dataset dataset, @NonNull AutofillId... ids) {
+ for (AutofillId id : ids) {
+ mDatasets.put(id, dataset);
+ }
+ return this;
+ }
+
+ public CannedAugmentedFillResponse build() {
+ return new CannedAugmentedFillResponse(this);
+ }
+ } // CannedAugmentedFillResponse.Builder
+
+
+ /**
+ * Helper class used to define which fields will be autofilled when the user taps the Augmented
+ * Autofill UI.
+ */
+ public static class Dataset {
+ private final Map<AutofillId, AutofillValue> mFieldValuesById;
+ private final String mPresentation;
+
+ private Dataset(@NonNull Builder builder) {
+ mFieldValuesById = builder.mFieldValuesById;
+ mPresentation = builder.mPresentation;
+ }
+
+ public List<Pair<AutofillId, AutofillValue>> getValues() {
+ return mFieldValuesById.entrySet().stream()
+ .map((entry) -> (new Pair<>(entry.getKey(), entry.getValue())))
+ .collect(Collectors.toList());
+ }
+
+ @Override
+ public String toString() {
+ return "Dataset: [presentation=" + mPresentation
+ + ", fields=" + mFieldValuesById
+ + "]";
+ }
+
+ public static class Builder {
+ private final Map<AutofillId, AutofillValue> mFieldValuesById = new ArrayMap<>();
+
+ private final String mPresentation;
+
+ public Builder(@NonNull String presentation) {
+ mPresentation = Preconditions.checkNotNull(presentation);
+ }
+
+ /**
+ * Sets the value that will be autofilled on the field with {@code id}.
+ */
+ public Builder setField(@NonNull AutofillId id, String text) {
+ mFieldValuesById.put(id, AutofillValue.forText(text));
+ return this;
+ }
+ public Dataset build() {
+ return new Dataset(this);
+ }
+ } // Dataset.Builder
+ } // Dataset
+} // CannedAugmentedFillResponse
diff --git a/tests/autofillservice/src/android/autofillservice/cts/augmented/CtsAugmentedAutofillService.java b/tests/autofillservice/src/android/autofillservice/cts/augmented/CtsAugmentedAutofillService.java
new file mode 100644
index 0000000..8fb17a2
--- /dev/null
+++ b/tests/autofillservice/src/android/autofillservice/cts/augmented/CtsAugmentedAutofillService.java
@@ -0,0 +1,268 @@
+/*
+ * Copyright (C) 2019 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.autofillservice.cts.augmented;
+
+import static android.autofillservice.cts.augmented.AugmentedHelper.getActivityName;
+import static android.autofillservice.cts.augmented.AugmentedTimeouts.AUGMENTED_CONNECTION_TIMEOUT;
+import static android.autofillservice.cts.augmented.AugmentedTimeouts.AUGMENTED_FILL_TIMEOUT;
+import static android.autofillservice.cts.augmented.CannedAugmentedFillResponse.AugmentedResponseType.NULL;
+import static android.autofillservice.cts.augmented.CannedAugmentedFillResponse.AugmentedResponseType.TIMEOUT;
+
+import android.autofillservice.cts.Helper;
+import android.autofillservice.cts.JUnitHelper;
+import android.autofillservice.cts.RetryableException;
+import android.content.ComponentName;
+import android.content.Context;
+import android.os.CancellationSignal;
+import android.os.Handler;
+import android.os.HandlerThread;
+import android.service.autofill.augmented.AugmentedAutofillService;
+import android.service.autofill.augmented.FillCallback;
+import android.service.autofill.augmented.FillController;
+import android.service.autofill.augmented.FillRequest;
+import android.service.autofill.augmented.FillResponse;
+import android.util.Log;
+
+import androidx.annotation.NonNull;
+import androidx.annotation.Nullable;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.concurrent.BlockingQueue;
+import java.util.concurrent.LinkedBlockingQueue;
+import java.util.concurrent.TimeUnit;
+
+/**
+ * Implementation of {@link AugmentedAutofillService} used in the tests.
+ */
+public class CtsAugmentedAutofillService extends AugmentedAutofillService {
+
+ private static final String TAG = CtsAugmentedAutofillService.class.getSimpleName();
+
+ public static final String SERVICE_PACKAGE = Helper.MY_PACKAGE;
+ public static final String SERVICE_CLASS = CtsAugmentedAutofillService.class.getSimpleName();
+
+ public static final String SERVICE_NAME = SERVICE_PACKAGE + "/.augmented." + SERVICE_CLASS;
+
+ private static final AugmentedReplier sAugmentedReplier = new AugmentedReplier();
+
+ // We must handle all requests in a separate thread as the service's main thread is the also
+ // the UI thread of the test process and we don't want to hose it in case of failures here
+ private static final HandlerThread sMyThread = new HandlerThread("MyAugmentedServiceThread");
+ private final Handler mHandler;
+
+ static {
+ Log.i(TAG, "Starting thread " + sMyThread);
+ sMyThread.start();
+ }
+
+ public CtsAugmentedAutofillService() {
+ mHandler = Handler.createAsync(sMyThread.getLooper());
+ }
+
+ @Override
+ public void onFillRequest(FillRequest request, CancellationSignal cancellationSignal,
+ FillController controller, FillCallback callback) {
+ Log.i(TAG, "onFillRequest(): " + AugmentedHelper.toString(request));
+
+ final ComponentName component = request.getActivityComponent();
+
+ if (!JUnitHelper.isRunningTest()) {
+ Log.e(TAG, "onFillRequest(" + component + ") called after tests finished");
+ return;
+ }
+ mHandler.post(() -> sAugmentedReplier.handleOnFillRequest(getApplicationContext(), request,
+ cancellationSignal, controller, callback));
+ }
+
+ /**
+ * Gets the {@link AugmentedReplier} singleton.
+ */
+ static AugmentedReplier getAugmentedReplier() {
+ return sAugmentedReplier;
+ }
+
+ /**
+ * POJO representation of the contents of a {@link FillRequest}
+ * that can be asserted at the end of a test case.
+ */
+ public static final class AugmentedFillRequest {
+ public final FillRequest request;
+ public final CancellationSignal cancellationSignal;
+ public final FillController controller;
+ public final FillCallback callback;
+
+ private AugmentedFillRequest(FillRequest request, CancellationSignal cancellationSignal,
+ FillController controller, FillCallback callback) {
+ this.request = request;
+ this.cancellationSignal = cancellationSignal;
+ this.controller = controller;
+ this.callback = callback;
+ }
+
+ @Override
+ public String toString() {
+ return "AugmentedFillRequest[activity=" + getActivityName(request) + ", request="
+ + AugmentedHelper.toString(request) + "]";
+ }
+ }
+
+ /**
+ * Object used to answer a
+ * {@link AugmentedAutofillService#onFillRequest(FillRequest, CancellationSignal,
+ * FillController, FillCallback)} on behalf of a unit test method.
+ */
+ public static final class AugmentedReplier {
+
+ private final BlockingQueue<CannedAugmentedFillResponse> mResponses =
+ new LinkedBlockingQueue<>();
+ private final BlockingQueue<AugmentedFillRequest> mFillRequests =
+ new LinkedBlockingQueue<>();
+
+ private List<Throwable> mExceptions;
+ private boolean mReportUnhandledFillRequest = true;
+
+ private AugmentedReplier() {
+ }
+
+ /**
+ * Gets the exceptions thrown asynchronously, if any.
+ */
+ @Nullable
+ public List<Throwable> getExceptions() {
+ return mExceptions;
+ }
+
+ private void addException(@Nullable Throwable e) {
+ if (e == null) return;
+
+ if (mExceptions == null) {
+ mExceptions = new ArrayList<>();
+ }
+ mExceptions.add(e);
+ }
+
+ /**
+ * Sets the expectation for the next {@code onFillRequest}.
+ */
+ public AugmentedReplier addResponse(@NonNull CannedAugmentedFillResponse response) {
+ if (response == null) {
+ throw new IllegalArgumentException("Cannot be null - use NO_RESPONSE instead");
+ }
+ mResponses.add(response);
+ return this;
+ }
+ /**
+ * Gets the next fill request, in the order received.
+ */
+ public AugmentedFillRequest getNextFillRequest() {
+ AugmentedFillRequest request;
+ try {
+ request = mFillRequests.poll(AUGMENTED_FILL_TIMEOUT.ms(), TimeUnit.MILLISECONDS);
+ } catch (InterruptedException e) {
+ Thread.currentThread().interrupt();
+ throw new IllegalStateException("Interrupted", e);
+ }
+ if (request == null) {
+ throw new RetryableException(AUGMENTED_FILL_TIMEOUT, "onFillRequest() not called");
+ }
+ return request;
+ }
+
+ /**
+ * Asserts all {@link AugmentedAutofillService#onFillRequest(FillRequest,
+ * CancellationSignal, FillController, FillCallback)} received by the service were properly
+ * {@link #getNextFillRequest() handled} by the test case.
+ */
+ public void assertNoUnhandledFillRequests() {
+ if (mFillRequests.isEmpty()) return; // Good job, test case!
+
+ if (!mReportUnhandledFillRequest) {
+ // Just log, so it's not thrown again on @After if already thrown on main body
+ Log.d(TAG, "assertNoUnhandledFillRequests(): already reported, "
+ + "but logging just in case: " + mFillRequests);
+ return;
+ }
+
+ mReportUnhandledFillRequest = false;
+ throw new AssertionError(mFillRequests.size() + " unhandled fill requests: "
+ + mFillRequests);
+ }
+
+ /**
+ * Gets the current number of unhandled requests.
+ */
+ public int getNumberUnhandledFillRequests() {
+ return mFillRequests.size();
+ }
+
+ /**
+ * Resets its internal state.
+ */
+ public void reset() {
+ mResponses.clear();
+ mFillRequests.clear();
+ mExceptions = null;
+ mReportUnhandledFillRequest = true;
+ }
+
+ private void handleOnFillRequest(@NonNull Context context, @NonNull FillRequest request,
+ @NonNull CancellationSignal cancellationSignal, @NonNull FillController controller,
+ @NonNull FillCallback callback) {
+ try {
+ final CannedAugmentedFillResponse response;
+ try {
+ response = mResponses.poll(AUGMENTED_CONNECTION_TIMEOUT.ms(),
+ TimeUnit.MILLISECONDS);
+ } catch (InterruptedException e) {
+ Log.w(TAG, "Interrupted getting CannedAugmentedFillResponse: " + e);
+ Thread.currentThread().interrupt();
+ addException(e);
+ return;
+ }
+ if (response == null) {
+ Log.w(TAG, "onFillRequest() for " + getActivityName(request)
+ + " received when no canned response was set.");
+ return;
+ }
+ if (response.getResponseType() == NULL) {
+ Log.d(TAG, "onFillRequest(): replying with null");
+ callback.onSuccess(null);
+ return;
+ }
+
+ if (response.getResponseType() == TIMEOUT) {
+ Log.d(TAG, "onFillRequest(): not replying at all");
+ return;
+ }
+
+ Log.v(TAG, "onFillRequest(): response = " + response);
+ final FillResponse fillResponse = response.asFillResponse(context, request,
+ controller);
+ Log.v(TAG, "onFillRequest(): fillResponse = " + fillResponse);
+ callback.onSuccess(fillResponse);
+ } catch (Throwable t) {
+ addException(t);
+ } finally {
+ final AugmentedFillRequest myRequest = new AugmentedFillRequest(request,
+ cancellationSignal, controller, callback);
+ Log.d(TAG, "offering " + myRequest);
+ Helper.offer(mFillRequests, myRequest, AUGMENTED_CONNECTION_TIMEOUT.ms());
+ }
+ }
+ }
+}
diff --git a/tests/autofillservice/src/android/autofillservice/cts/common/ShellHelper.java b/tests/autofillservice/src/android/autofillservice/cts/common/ShellHelper.java
index 2a97aee..117c755 100644
--- a/tests/autofillservice/src/android/autofillservice/cts/common/ShellHelper.java
+++ b/tests/autofillservice/src/android/autofillservice/cts/common/ShellHelper.java
@@ -16,6 +16,8 @@
package android.autofillservice.cts.common;
+import static android.autofillservice.cts.common.ShellHelper.runShellCommand;
+
import android.support.test.InstrumentationRegistry;
import android.text.TextUtils;
import android.util.Log;
@@ -75,4 +77,12 @@
public static void sendKeyEvent(String keyCode) {
runShellCommand("input keyevent " + keyCode);
}
+
+ /**
+ * Allows an app to draw overlaid windows.
+ */
+ public static void setOverlayPermissions(@NonNull String packageName, boolean allowed) {
+ final String action = allowed ? "allow" : "ignore";
+ runShellCommand("appops set %s SYSTEM_ALERT_WINDOW %s", packageName, action);
+ }
}
diff --git a/tests/camera/libctscamera2jni/Android.mk b/tests/camera/libctscamera2jni/Android.mk
index 7d71676..2cd4f64 100644
--- a/tests/camera/libctscamera2jni/Android.mk
+++ b/tests/camera/libctscamera2jni/Android.mk
@@ -47,7 +47,4 @@
LOCAL_SDK_VERSION := current
LOCAL_NDK_STL_VARIANT := c++_shared
-# Remove when libjpeg_static_ndk is XOM compatible.
-LOCAL_XOM := false
-
include $(BUILD_SHARED_LIBRARY)
diff --git a/tests/camera/src/android/hardware/camera2/cts/CaptureResultTest.java b/tests/camera/src/android/hardware/camera2/cts/CaptureResultTest.java
index 0b9f9c3..ab65015 100644
--- a/tests/camera/src/android/hardware/camera2/cts/CaptureResultTest.java
+++ b/tests/camera/src/android/hardware/camera2/cts/CaptureResultTest.java
@@ -555,6 +555,12 @@
// Only present in reprocessing capture result.
waiverKeys.add(CaptureResult.REPROCESS_EFFECTIVE_EXPOSURE_FACTOR);
+ // LOGICAL_MULTI_CAMERA_ACTIVE_PHYSICAL_ID not required if key is not supported.
+ if (!staticInfo.isLogicalMultiCamera() ||
+ !staticInfo.isActivePhysicalCameraIdSupported()) {
+ waiverKeys.add(CaptureResult.LOGICAL_MULTI_CAMERA_ACTIVE_PHYSICAL_ID);
+ }
+
//Keys not required if RAW is not supported
if (!staticInfo.isCapabilitySupported(
CameraCharacteristics.REQUEST_AVAILABLE_CAPABILITIES_RAW)) {
@@ -968,6 +974,7 @@
resultKeys.add(CaptureResult.TONEMAP_PRESET_CURVE);
resultKeys.add(CaptureResult.BLACK_LEVEL_LOCK);
resultKeys.add(CaptureResult.REPROCESS_EFFECTIVE_EXPOSURE_FACTOR);
+ resultKeys.add(CaptureResult.LOGICAL_MULTI_CAMERA_ACTIVE_PHYSICAL_ID);
resultKeys.add(CaptureResult.DISTORTION_CORRECTION_MODE);
return resultKeys;
diff --git a/tests/camera/src/android/hardware/camera2/cts/ExtendedCameraCharacteristicsTest.java b/tests/camera/src/android/hardware/camera2/cts/ExtendedCameraCharacteristicsTest.java
index 42f2f58..e433ad8 100644
--- a/tests/camera/src/android/hardware/camera2/cts/ExtendedCameraCharacteristicsTest.java
+++ b/tests/camera/src/android/hardware/camera2/cts/ExtendedCameraCharacteristicsTest.java
@@ -1968,6 +1968,19 @@
"timestamp source", timestampSource, timestampSourcePhysical);
}
}
+
+ // Verify that if multiple focal lengths or apertures are supported, they are in
+ // ascending order.
+ float[] focalLengths = c.get(CameraCharacteristics.LENS_INFO_AVAILABLE_FOCAL_LENGTHS);
+ for (int i = 0; i < focalLengths.length-1; i++) {
+ mCollector.expectTrue("Camera's available focal lengths must be ascending!",
+ focalLengths[i] < focalLengths[i+1]);
+ }
+ float[] apertures = c.get(CameraCharacteristics.LENS_INFO_AVAILABLE_APERTURES);
+ for (int i = 0; i < apertures.length-1; i++) {
+ mCollector.expectTrue("Camera's available apertures must be ascending!",
+ apertures[i] < apertures[i+1]);
+ }
counter++;
}
}
diff --git a/tests/camera/src/android/hardware/camera2/cts/ImageReaderTest.java b/tests/camera/src/android/hardware/camera2/cts/ImageReaderTest.java
index 6b95f8c..51a1f9b 100644
--- a/tests/camera/src/android/hardware/camera2/cts/ImageReaderTest.java
+++ b/tests/camera/src/android/hardware/camera2/cts/ImageReaderTest.java
@@ -309,6 +309,29 @@
}
/**
+ * Test two image stream (YUV420_888 and JPEG) capture by using ImageReader with the ImageReader
+ * factory method that has usage flag argument.
+ *
+ * <p>Both stream formats are mandatory for Camera2 API</p>
+ */
+ public void testYuvAndJpegWithUsageFlag() throws Exception {
+ for (String id : mCameraIds) {
+ try {
+ Log.v(TAG, "YUV and JPEG testing for camera " + id);
+ if (!mAllStaticInfo.get(id).isColorOutputSupported()) {
+ Log.i(TAG, "Camera " + id +
+ " does not support color outputs, skipping");
+ continue;
+ }
+ openDevice(id);
+ bufferFormatWithYuvTestByCamera(ImageFormat.JPEG, true);
+ } finally {
+ closeDevice(id);
+ }
+ }
+ }
+
+ /**
* Test two image stream (YUV420_888 and RAW_SENSOR) capture by using ImageReader.
*
*/
@@ -330,6 +353,28 @@
}
/**
+ * Test two image stream (YUV420_888 and RAW_SENSOR) capture by using ImageReader with the
+ * ImageReader factory method that has usage flag argument.
+ *
+ */
+ public void testImageReaderYuvAndRawWithUsageFlag() throws Exception {
+ for (String id : mCameraIds) {
+ try {
+ Log.v(TAG, "YUV and RAW testing for camera " + id);
+ if (!mAllStaticInfo.get(id).isColorOutputSupported()) {
+ Log.i(TAG, "Camera " + id +
+ " does not support color outputs, skipping");
+ continue;
+ }
+ openDevice(id);
+ bufferFormatWithYuvTestByCamera(ImageFormat.RAW_SENSOR, true);
+ } finally {
+ closeDevice(id);
+ }
+ }
+ }
+
+ /**
* Check that the center patches for YUV and JPEG outputs for the same frame match for each YUV
* resolution and format supported.
*/
@@ -685,6 +730,20 @@
* @param format The capture format to be tested along with yuv format.
*/
private void bufferFormatWithYuvTestByCamera(int format) throws Exception {
+ bufferFormatWithYuvTestByCamera(format, false);
+ }
+
+ /**
+ * Test capture a given format stream with yuv stream simultaneously.
+ *
+ * <p>Use fixed yuv size, varies targeted format capture size. Single capture is tested.</p>
+ *
+ * @param format The capture format to be tested along with yuv format.
+ * @param setUsageFlag The ImageReader factory method to be used (with or without specifying
+ * usage flag)
+ */
+ private void bufferFormatWithYuvTestByCamera(int format, boolean setUsageFlag)
+ throws Exception {
if (format != ImageFormat.JPEG && format != ImageFormat.RAW_SENSOR
&& format != ImageFormat.YUV_420_888) {
throw new IllegalArgumentException("Unsupported format: " + format);
@@ -706,14 +765,25 @@
try {
// Create YUV image reader
SimpleImageReaderListener yuvListener = new SimpleImageReaderListener();
- yuvReader = createImageReader(maxYuvSz, ImageFormat.YUV_420_888, MAX_NUM_IMAGES,
- yuvListener);
+ if (setUsageFlag) {
+ yuvReader = createImageReader(maxYuvSz, ImageFormat.YUV_420_888, MAX_NUM_IMAGES,
+ HardwareBuffer.USAGE_CPU_READ_OFTEN, yuvListener);
+ } else {
+ yuvReader = createImageReader(maxYuvSz, ImageFormat.YUV_420_888, MAX_NUM_IMAGES,
+ yuvListener);
+ }
+
Surface yuvSurface = yuvReader.getSurface();
// Create capture image reader
SimpleImageReaderListener captureListener = new SimpleImageReaderListener();
- captureReader = createImageReader(captureSz, format, MAX_NUM_IMAGES,
- captureListener);
+ if (setUsageFlag) {
+ captureReader = createImageReader(captureSz, format, MAX_NUM_IMAGES,
+ HardwareBuffer.USAGE_CPU_READ_OFTEN, captureListener);
+ } else {
+ captureReader = createImageReader(captureSz, format, MAX_NUM_IMAGES,
+ captureListener);
+ }
Surface captureSurface = captureReader.getSurface();
// Capture images.
diff --git a/tests/camera/src/android/hardware/camera2/cts/ImageWriterTest.java b/tests/camera/src/android/hardware/camera2/cts/ImageWriterTest.java
index 6216f36..38f8816 100644
--- a/tests/camera/src/android/hardware/camera2/cts/ImageWriterTest.java
+++ b/tests/camera/src/android/hardware/camera2/cts/ImageWriterTest.java
@@ -24,6 +24,7 @@
import android.hardware.camera2.CameraDevice;
import android.hardware.camera2.CaptureRequest;
import android.hardware.camera2.CaptureResult;
+import android.hardware.HardwareBuffer;
import android.media.Image;
import android.media.Image.Plane;
import android.media.ImageReader;
@@ -70,7 +71,6 @@
}
/**
- * `
* <p>
* Basic YUV420_888 format ImageWriter ImageReader test that checks the
* images produced by camera can be passed correctly by ImageWriter.
@@ -97,7 +97,29 @@
continue;
}
openDevice(id);
- readerWriterFormatTestByCamera(ImageFormat.YUV_420_888);
+ readerWriterFormatTestByCamera(ImageFormat.YUV_420_888, false);
+ } finally {
+ closeDevice(id);
+ }
+ }
+ }
+
+ /**
+ * <p>
+ * Similar to testYuvImageWriterReaderOperation, but use the alternative
+ * factory method of ImageReader and ImageWriter.
+ * </p>
+ */
+ public void testYuvImageWriterReaderOperationAlt() throws Exception {
+ for (String id : mCameraIds) {
+ try {
+ Log.i(TAG, "Testing Camera " + id);
+ if (!mAllStaticInfo.get(id).isColorOutputSupported()) {
+ Log.i(TAG, "Camera " + id + " does not support color outputs, skipping");
+ continue;
+ }
+ openDevice(id);
+ readerWriterFormatTestByCamera(ImageFormat.YUV_420_888, true);
} finally {
closeDevice(id);
}
@@ -148,7 +170,8 @@
}
}
- private void readerWriterFormatTestByCamera(int format) throws Exception {
+ private void readerWriterFormatTestByCamera(int format, boolean altFactoryMethod)
+ throws Exception {
List<Size> sizes = getSortedSizesForFormat(mCamera.getId(), mCameraManager, format, null);
Size maxSize = sizes.get(0);
if (VERBOSE) {
@@ -157,14 +180,28 @@
// Create ImageReader for camera output.
SimpleImageReaderListener listenerForCamera = new SimpleImageReaderListener();
- createDefaultImageReader(maxSize, format, MAX_NUM_IMAGES, listenerForCamera);
+ if (altFactoryMethod) {
+ createDefaultImageReader(maxSize, format, MAX_NUM_IMAGES,
+ HardwareBuffer.USAGE_CPU_READ_OFTEN, listenerForCamera);
+ } else {
+ createDefaultImageReader(maxSize, format, MAX_NUM_IMAGES, listenerForCamera);
+ }
+
if (VERBOSE) {
Log.v(TAG, "Created camera output ImageReader");
}
// Create ImageReader for ImageWriter output
SimpleImageReaderListener listenerForWriter = new SimpleImageReaderListener();
- mReaderForWriter = createImageReader(maxSize, format, MAX_NUM_IMAGES, listenerForWriter);
+ if (altFactoryMethod) {
+ mReaderForWriter = createImageReader(
+ maxSize, format, MAX_NUM_IMAGES,
+ HardwareBuffer.USAGE_CPU_READ_OFTEN, listenerForWriter);
+ } else {
+ mReaderForWriter = createImageReader(
+ maxSize, format, MAX_NUM_IMAGES, listenerForWriter);
+ }
+
if (VERBOSE) {
Log.v(TAG, "Created ImageWriter output ImageReader");
}
@@ -172,7 +209,11 @@
// Create ImageWriter
Surface surface = mReaderForWriter.getSurface();
assertNotNull("Surface from ImageReader shouldn't be null", surface);
- mWriter = ImageWriter.newInstance(surface, MAX_NUM_IMAGES);
+ if (altFactoryMethod) {
+ mWriter = ImageWriter.newInstance(surface, MAX_NUM_IMAGES, format);
+ } else {
+ mWriter = ImageWriter.newInstance(surface, MAX_NUM_IMAGES);
+ }
SimpleImageWriterListener writerImageListener = new SimpleImageWriterListener(mWriter);
mWriter.setOnImageReleasedListener(writerImageListener, mHandler);
diff --git a/tests/camera/src/android/hardware/camera2/cts/LogicalCameraDeviceTest.java b/tests/camera/src/android/hardware/camera2/cts/LogicalCameraDeviceTest.java
index b608f93..ecd5798 100644
--- a/tests/camera/src/android/hardware/camera2/cts/LogicalCameraDeviceTest.java
+++ b/tests/camera/src/android/hardware/camera2/cts/LogicalCameraDeviceTest.java
@@ -20,6 +20,8 @@
import android.content.Context;
import android.graphics.ImageFormat;
+import android.graphics.PointF;
+import android.graphics.Rect;
import android.graphics.SurfaceTexture;
import android.hardware.camera2.CameraCaptureSession;
import android.hardware.camera2.CameraCharacteristics;
@@ -66,7 +68,7 @@
* Tests exercising logical camera setup, configuration, and usage.
*/
public final class LogicalCameraDeviceTest extends Camera2SurfaceViewTestCase {
- private static final String TAG = "LogicalCameraTest";
+ private static final String TAG = "LogicalCameraDeviceTest";
private static final boolean VERBOSE = Log.isLoggable(TAG, Log.VERBOSE);
private static final int CONFIGURE_TIMEOUT = 5000; //ms
@@ -508,6 +510,237 @@
}
/**
+ * Test for physical camera switch based on focal length (optical zoom) and crop region
+ * (digital zoom).
+ *
+ * - Focal length and crop region change must be synchronized to not have sudden jump in field
+ * of view.
+ * - Main physical id must be valid.
+ */
+ @Test
+ public void testLogicalCameraZoomSwitch() throws Exception {
+
+ for (String id : mCameraIds) {
+ try {
+ Log.i(TAG, "Testing Camera " + id);
+
+ StaticMetadata staticInfo = mAllStaticInfo.get(id);
+ if (!staticInfo.isColorOutputSupported()) {
+ Log.i(TAG, "Camera " + id + " does not support color outputs, skipping");
+ continue;
+ }
+
+ if (!staticInfo.isLogicalMultiCamera()) {
+ Log.i(TAG, "Camera " + id + " is not a logical multi-camera, skipping");
+ continue;
+ }
+
+ openDevice(id);
+ Size yuvSize = mOrderedPreviewSizes.get(0);
+ // Create a YUV image reader.
+ ImageReader imageReader = CameraTestUtils.makeImageReader(yuvSize,
+ ImageFormat.YUV_420_888, MAX_IMAGE_COUNT,
+ new ImageDropperListener(), mHandler);
+
+ List<OutputConfiguration> outputConfigs = new ArrayList<>();
+ OutputConfiguration config = new OutputConfiguration(imageReader.getSurface());
+ outputConfigs.add(config);
+
+ mSessionListener = new BlockingSessionCallback();
+ mSession = configureCameraSessionWithConfig(mCamera, outputConfigs,
+ mSessionListener, mHandler);
+
+ final float FOV_MARGIN = 0.01f;
+ final float[] focalLengths = staticInfo.getAvailableFocalLengthsChecked();
+ final int zoomSteps = focalLengths.length;
+ final float maxZoom = staticInfo.getAvailableMaxDigitalZoomChecked();
+ final Rect activeArraySize = staticInfo.getActiveArraySizeChecked();
+ final Set<String> physicalIds =
+ staticInfo.getCharacteristics().getPhysicalCameraIds();
+
+ CaptureRequest.Builder requestBuilder =
+ mCamera.createCaptureRequest(CameraDevice.TEMPLATE_PREVIEW);
+ requestBuilder.addTarget(imageReader.getSurface());
+
+ // For each adjacent focal lengths, set different crop region such that the
+ // resulting angle of view is the same. This is to make sure that no sudden FOV
+ // (field of view) jump when switching between different focal lengths.
+ for (int i = 0; i < zoomSteps-1; i++) {
+ // Start with larger focal length + full active array crop region.
+ requestBuilder.set(CaptureRequest.LENS_FOCAL_LENGTH, focalLengths[i+1]);
+ requestBuilder.set(CaptureRequest.SCALER_CROP_REGION, activeArraySize);
+ SimpleCaptureCallback simpleResultListener = new SimpleCaptureCallback();
+ mSession.setRepeatingRequest(requestBuilder.build(), simpleResultListener,
+ mHandler);
+ waitForAeStable(simpleResultListener, NUM_FRAMES_WAITED_FOR_UNKNOWN_LATENCY);
+
+ // This is an approximate, assuming that subject distance >> focal length.
+ float zoomFactor = focalLengths[i+1]/focalLengths[i];
+ PointF zoomCenter = new PointF(0.5f, 0.5f);
+ Rect requestCropRegion = getCropRegionForZoom(zoomFactor,
+ zoomCenter, maxZoom, activeArraySize);
+ if (VERBOSE) {
+ Log.v(TAG, "Switching from crop region " + activeArraySize + ", focal " +
+ "length " + focalLengths[i+1] + " to crop region " + requestCropRegion +
+ ", focal length " + focalLengths[i]);
+ }
+
+ // Create a burst capture to switch between different focal_length/crop_region
+ // combination with same field of view.
+ List<CaptureRequest> requests = new ArrayList<CaptureRequest>();
+ SimpleCaptureCallback listener = new SimpleCaptureCallback();
+
+ requestBuilder.set(CaptureRequest.LENS_FOCAL_LENGTH, focalLengths[i]);
+ requestBuilder.set(CaptureRequest.SCALER_CROP_REGION, requestCropRegion);
+ requests.add(requestBuilder.build());
+ requests.add(requestBuilder.build());
+
+ requestBuilder.set(CaptureRequest.LENS_FOCAL_LENGTH, focalLengths[i+1]);
+ requestBuilder.set(CaptureRequest.SCALER_CROP_REGION, activeArraySize);
+ requests.add(requestBuilder.build());
+ requests.add(requestBuilder.build());
+
+ requestBuilder.set(CaptureRequest.LENS_FOCAL_LENGTH, focalLengths[i]);
+ requestBuilder.set(CaptureRequest.SCALER_CROP_REGION, requestCropRegion);
+ requests.add(requestBuilder.build());
+ requests.add(requestBuilder.build());
+
+ mSession.captureBurst(requests, listener, mHandler);
+ TotalCaptureResult[] results = listener.getTotalCaptureResultsForRequests(
+ requests, WAIT_FOR_RESULT_TIMEOUT_MS);
+
+ // Verify result metadata to produce similar field of view.
+ float fov = activeArraySize.width()/(2*focalLengths[i+1]);
+ for (int j = 0; j < results.length; j++) {
+ TotalCaptureResult result = results[j];
+ Float resultFocalLength = result.get(CaptureResult.LENS_FOCAL_LENGTH);
+ Rect resultCropRegion = result.get(CaptureResult.SCALER_CROP_REGION);
+
+ if (VERBOSE) {
+ Log.v(TAG, "Result crop region " + resultCropRegion + ", focal length "
+ + resultFocalLength + " for result " + j);
+ }
+ float newFov = resultCropRegion.width()/(2*resultFocalLength);
+
+ mCollector.expectTrue("Field of view must be consistent with focal " +
+ "length and crop region change cancelling out each other.",
+ Math.abs(newFov - fov)/fov < FOV_MARGIN);
+
+ if (staticInfo.isActivePhysicalCameraIdSupported()) {
+ String activePhysicalId = result.get(
+ CaptureResult.LOGICAL_MULTI_CAMERA_ACTIVE_PHYSICAL_ID);
+ assertTrue(physicalIds.contains(activePhysicalId));
+
+ StaticMetadata physicalCameraStaticInfo =
+ mAllStaticInfo.get(activePhysicalId);
+ float[] physicalCameraFocalLengths =
+ physicalCameraStaticInfo.getAvailableFocalLengthsChecked();
+ mCollector.expectTrue("Current focal length " + resultFocalLength
+ + " must be supported by active physical camera "
+ + activePhysicalId, Arrays.asList(CameraTestUtils.toObject(
+ physicalCameraFocalLengths)).contains(resultFocalLength));
+ }
+ }
+ }
+
+ if (mSession != null) {
+ mSession.close();
+ }
+
+ } finally {
+ closeDevice();
+ }
+ }
+ }
+
+ /**
+ * Test that for logical multi-camera, the activePhysicalId is valid, and is the same
+ * for all capture templates.
+ */
+ @Test
+ public void testActivePhysicalId() throws Exception {
+ int[] sTemplates = new int[] {
+ CameraDevice.TEMPLATE_PREVIEW,
+ CameraDevice.TEMPLATE_RECORD,
+ CameraDevice.TEMPLATE_STILL_CAPTURE,
+ CameraDevice.TEMPLATE_VIDEO_SNAPSHOT,
+ CameraDevice.TEMPLATE_ZERO_SHUTTER_LAG,
+ CameraDevice.TEMPLATE_MANUAL,
+ };
+
+ for (String id : mCameraIds) {
+ try {
+ Log.i(TAG, "Testing Camera " + id);
+
+ StaticMetadata staticInfo = mAllStaticInfo.get(id);
+ if (!staticInfo.isColorOutputSupported()) {
+ Log.i(TAG, "Camera " + id + " does not support color outputs, skipping");
+ continue;
+ }
+
+ if (!staticInfo.isLogicalMultiCamera()) {
+ Log.i(TAG, "Camera " + id + " is not a logical multi-camera, skipping");
+ continue;
+ }
+
+ if (!staticInfo.isActivePhysicalCameraIdSupported()) {
+ continue;
+ }
+
+ final Set<String> physicalIds =
+ staticInfo.getCharacteristics().getPhysicalCameraIds();
+ openDevice(id);
+ Size previewSz =
+ getMaxPreviewSize(mCamera.getId(), mCameraManager,
+ getPreviewSizeBound(mWindowManager, PREVIEW_SIZE_BOUND));
+
+ String storedActiveId = null;
+ for (int template : sTemplates) {
+ try {
+ CaptureRequest.Builder requestBuilder =
+ mCamera.createCaptureRequest(template);
+ SimpleCaptureCallback listener = new SimpleCaptureCallback();
+ startPreview(requestBuilder, previewSz, listener);
+ waitForSettingsApplied(listener, NUM_FRAMES_WAITED_FOR_UNKNOWN_LATENCY);
+
+ CaptureResult result = listener.getCaptureResult(WAIT_FOR_RESULT_TIMEOUT_MS);
+ String activePhysicalId = result.get(
+ CaptureResult.LOGICAL_MULTI_CAMERA_ACTIVE_PHYSICAL_ID);
+
+ assertNotNull("activePhysicalId must not be null", activePhysicalId);
+ if (storedActiveId == null) {
+ storedActiveId = activePhysicalId;
+ assertTrue(
+ "Camera device reported invalid activePhysicalId: " +
+ activePhysicalId, physicalIds.contains(activePhysicalId));
+ } else {
+ assertTrue(
+ "Camera device reported different activePhysicalId " +
+ activePhysicalId + " vs " + storedActiveId +
+ " for different capture templates",
+ storedActiveId.equals(activePhysicalId));
+ }
+ } catch (IllegalArgumentException e) {
+ if (template == CameraDevice.TEMPLATE_MANUAL &&
+ !staticInfo.isCapabilitySupported(CameraCharacteristics.
+ REQUEST_AVAILABLE_CAPABILITIES_MANUAL_SENSOR)) {
+ // OK
+ } else if (template == CameraDevice.TEMPLATE_ZERO_SHUTTER_LAG &&
+ !staticInfo.isCapabilitySupported(CameraCharacteristics.
+ REQUEST_AVAILABLE_CAPABILITIES_PRIVATE_REPROCESSING)) {
+ // OK.
+ } else {
+ throw e; // rethrow
+ }
+ }
+ }
+ } finally {
+ closeDevice();
+ }
+ }
+ }
+
+ /**
* Find a common preview size that's supported by both the logical camera and
* two of the underlying physical cameras.
*/
diff --git a/tests/camera/src/android/hardware/camera2/cts/RecordingTest.java b/tests/camera/src/android/hardware/camera2/cts/RecordingTest.java
index e98229d..35507e9 100644
--- a/tests/camera/src/android/hardware/camera2/cts/RecordingTest.java
+++ b/tests/camera/src/android/hardware/camera2/cts/RecordingTest.java
@@ -26,6 +26,7 @@
import android.hardware.camera2.params.OutputConfiguration;
import android.hardware.camera2.params.SessionConfiguration;
import android.hardware.camera2.params.StreamConfigurationMap;
+import android.hardware.HardwareBuffer;
import android.util.Size;
import android.hardware.camera2.cts.testcases.Camera2SurfaceViewTestCase;
import android.media.CamcorderProfile;
@@ -35,6 +36,7 @@
import android.media.MediaCodecInfo.CodecProfileLevel;
import android.media.Image;
import android.media.ImageReader;
+import android.media.ImageWriter;
import android.media.MediaCodecList;
import android.media.MediaExtractor;
import android.media.MediaFormat;
@@ -104,6 +106,11 @@
private Size mVideoSize;
private long mRecordingStartTime;
+ private Surface mIntermediateSurface;
+ private ImageReader mIntermediateReader;
+ private ImageWriter mIntermediateWriter;
+ private ImageWriterQueuer mQueuer;
+
@Override
public void setUp() throws Exception {
super.setUp();
@@ -115,6 +122,11 @@
}
private void doBasicRecording(boolean useVideoStab) throws Exception {
+ doBasicRecording(useVideoStab, false);
+ }
+
+ private void doBasicRecording(boolean useVideoStab, boolean useIntermediateSurface)
+ throws Exception {
for (int i = 0; i < mCameraIds.length; i++) {
try {
Log.i(TAG, "Testing basic recording for camera " + mCameraIds[i]);
@@ -144,7 +156,8 @@
openDevice(mCameraIds[i]);
initSupportedVideoSize(mCameraIds[i]);
- basicRecordingTestByCamera(mCamcorderProfileList, useVideoStab);
+ basicRecordingTestByCamera(mCamcorderProfileList, useVideoStab,
+ useIntermediateSurface);
} finally {
closeDevice();
releaseRecorder();
@@ -165,7 +178,7 @@
* recorded video. Preview is set to the video size.
* </p>
*/
- @Test
+ @Test(timeout=60*60*1000) // timeout = 60 mins for long running tests
public void testBasicVideoStabilizationRecording() throws Exception {
doBasicRecording(/*useVideoStab*/true);
}
@@ -189,6 +202,21 @@
/**
* <p>
+ * Test camera recording with intermediate surface.
+ * </p>
+ * <p>
+ * This test is similar to testBasicRecording with a tweak where an intermediate
+ * surface is setup between camera and MediaRecorder, giving application a chance
+ * to decide whether to send a frame to recorder or not.
+ * </p>
+ */
+ @Test(timeout=60*60*1000) // timeout = 60 mins for long running tests
+ public void testIntermediateSurfaceRecording() throws Exception {
+ doBasicRecording(/*useVideoStab*/false, /*useIntermediateSurface*/true);
+ }
+
+ /**
+ * <p>
* Test basic camera recording from a persistent input surface.
* </p>
* <p>
@@ -926,12 +954,17 @@
}
+ private void basicRecordingTestByCamera(int[] camcorderProfileList, boolean useVideoStab)
+ throws Exception {
+ basicRecordingTestByCamera(camcorderProfileList, useVideoStab, false);
+ }
+
/**
* Test camera recording by using each available CamcorderProfile for a
* given camera. preview size is set to the video size.
*/
- private void basicRecordingTestByCamera(int[] camcorderProfileList, boolean useVideoStab)
- throws Exception {
+ private void basicRecordingTestByCamera(int[] camcorderProfileList, boolean useVideoStab,
+ boolean useIntermediateSurface) throws Exception {
Size maxPreviewSize = mOrderedPreviewSizes.get(0);
List<Range<Integer> > fpsRanges = Arrays.asList(
mStaticInfo.getAeAvailableTargetFpsRangesChecked());
@@ -977,20 +1010,21 @@
+ videoSz.toString() + ".mp4";
}
- prepareRecordingWithProfile(profile);
+ prepareRecordingWithProfile(profile, useIntermediateSurface);
// prepare preview surface by using video size.
updatePreviewSurfaceWithVideo(videoSz, profile.videoFrameRate);
// Start recording
SimpleCaptureCallback resultListener = new SimpleCaptureCallback();
- startRecording(/* useMediaRecorder */true, resultListener, useVideoStab);
+ startRecording(/* useMediaRecorder */true, resultListener, useVideoStab,
+ useIntermediateSurface);
// Record certain duration.
SystemClock.sleep(RECORDING_DURATION_MS);
// Stop recording and preview
- stopRecording(/* useMediaRecorder */true);
+ stopRecording(/* useMediaRecorder */true, useIntermediateSurface);
// Convert number of frames camera produced into the duration in unit of ms.
float frameDurationMs = 1000.0f / profile.videoFrameRate;
float durationMs = resultListener.getTotalNumFrames() * frameDurationMs;
@@ -1060,7 +1094,7 @@
SimpleCaptureCallback resultListener = new SimpleCaptureCallback();
startRecording(
/* useMediaRecorder */true, resultListener,
- /*useVideoStab*/false, fpsRange);
+ /*useVideoStab*/false, fpsRange, false);
// Record certain duration.
SystemClock.sleep(RECORDING_DURATION_MS);
@@ -1462,12 +1496,16 @@
updatePreviewSurface(previewSize);
}
+ private void prepareRecordingWithProfile(CamcorderProfile profile) throws Exception {
+ prepareRecordingWithProfile(profile, false);
+ }
+
/**
* Configure MediaRecorder recording session with CamcorderProfile, prepare
* the recording surface.
*/
- private void prepareRecordingWithProfile(CamcorderProfile profile)
- throws Exception {
+ private void prepareRecordingWithProfile(CamcorderProfile profile,
+ boolean useIntermediateSurface) throws Exception {
// Prepare MediaRecorder.
mMediaRecorder.setAudioSource(MediaRecorder.AudioSource.CAMCORDER);
mMediaRecorder.setVideoSource(MediaRecorder.VideoSource.SURFACE);
@@ -1484,6 +1522,19 @@
assertNotNull("Recording surface must be non-null!", mRecordingSurface);
mVideoFrameRate = profile.videoFrameRate;
mVideoSize = new Size(profile.videoFrameWidth, profile.videoFrameHeight);
+
+ if (useIntermediateSurface) {
+ mIntermediateReader = ImageReader.newInstance(
+ profile.videoFrameWidth, profile.videoFrameHeight,
+ ImageFormat.PRIVATE, /*maxImages*/3, HardwareBuffer.USAGE_VIDEO_ENCODE);
+
+ mIntermediateSurface = mIntermediateReader.getSurface();
+ mIntermediateWriter = ImageWriter.newInstance(mRecordingSurface, /*maxImages*/3,
+ ImageFormat.PRIVATE);
+ mQueuer = new ImageWriterQueuer(mIntermediateWriter);
+
+ mIntermediateReader.setOnImageAvailableListener(mQueuer, mHandler);
+ }
}
/**
@@ -1519,12 +1570,20 @@
private void startRecording(boolean useMediaRecorder,
CameraCaptureSession.CaptureCallback listener, boolean useVideoStab) throws Exception {
- startRecording(useMediaRecorder, listener, useVideoStab, /*variableFpsRange*/null);
+ startRecording(useMediaRecorder, listener, useVideoStab, /*variableFpsRange*/null,
+ /*useIntermediateSurface*/false);
}
private void startRecording(boolean useMediaRecorder,
CameraCaptureSession.CaptureCallback listener, boolean useVideoStab,
- Range<Integer> variableFpsRange) throws Exception {
+ boolean useIntermediateSurface) throws Exception {
+ startRecording(useMediaRecorder, listener, useVideoStab, /*variableFpsRange*/null,
+ useIntermediateSurface);
+ }
+
+ private void startRecording(boolean useMediaRecorder,
+ CameraCaptureSession.CaptureCallback listener, boolean useVideoStab,
+ Range<Integer> variableFpsRange, boolean useIntermediateSurface) throws Exception {
if (!mStaticInfo.isVideoStabilizationSupported() && useVideoStab) {
throw new IllegalArgumentException("Video stabilization is not supported");
}
@@ -1533,7 +1592,12 @@
assertTrue("Both preview and recording surfaces should be valid",
mPreviewSurface.isValid() && mRecordingSurface.isValid());
outputSurfaces.add(mPreviewSurface);
- outputSurfaces.add(mRecordingSurface);
+ if (useIntermediateSurface) {
+ outputSurfaces.add(mIntermediateSurface);
+ } else {
+ outputSurfaces.add(mRecordingSurface);
+ }
+
// Video snapshot surface
if (mReaderSurface != null) {
outputSurfaces.add(mReaderSurface);
@@ -1551,7 +1615,11 @@
recordingRequestBuilder.set(CaptureRequest.CONTROL_VIDEO_STABILIZATION_MODE,
CaptureRequest.CONTROL_VIDEO_STABILIZATION_MODE_ON);
}
- recordingRequestBuilder.addTarget(mRecordingSurface);
+ if (useIntermediateSurface) {
+ recordingRequestBuilder.addTarget(mIntermediateSurface);
+ } else {
+ recordingRequestBuilder.addTarget(mRecordingSurface);
+ }
recordingRequestBuilder.addTarget(mPreviewSurface);
CaptureRequest recordingRequest = recordingRequestBuilder.build();
mSession = configureCameraSessionWithParameters(mCamera, outputSurfaces, mSessionListener,
@@ -1631,8 +1699,13 @@
mSessionListener.getStateWaiter().waitForState(SESSION_CLOSED, SESSION_CLOSE_TIMEOUT_MS);
}
- // Stop recording and return the estimated video duration in milliseconds.
private int stopRecording(boolean useMediaRecorder) throws Exception {
+ return stopRecording(useMediaRecorder, false);
+ }
+
+ // Stop recording and return the estimated video duration in milliseconds.
+ private int stopRecording(boolean useMediaRecorder, boolean useIntermediateSurface)
+ throws Exception {
long stopRecordingTime = SystemClock.elapsedRealtime();
if (useMediaRecorder) {
stopCameraStreaming();
@@ -1647,6 +1720,16 @@
mRecordingSurface.release();
mRecordingSurface = null;
}
+ if (useIntermediateSurface) {
+ mIntermediateSurface.release();
+ mIntermediateReader.close();
+ mIntermediateWriter.close();
+ mQueuer.close();
+ mIntermediateSurface = null;
+ mIntermediateReader = null;
+ mIntermediateWriter = null;
+ mQueuer = null;
+ }
return (int) (stopRecordingTime - mRecordingStartTime);
}
@@ -1955,4 +2038,28 @@
MediaCodecList mcl = new MediaCodecList(MediaCodecList.REGULAR_CODECS);
return mcl.findEncoderForFormat(format) != null;
}
+
+ private static class ImageWriterQueuer implements ImageReader.OnImageAvailableListener {
+ public ImageWriterQueuer(ImageWriter writer) {
+ mWriter = writer;
+ }
+
+ @Override
+ public void onImageAvailable(ImageReader reader) {
+ Image image = null;
+ try {
+ image = reader.acquireNextImage();
+ } finally {
+ if (image != null && mWriter != null) {
+ mWriter.queueInputImage(image);
+ }
+ }
+ }
+
+ public void close() {
+ mWriter = null;
+ }
+
+ private ImageWriter mWriter = null;
+ }
}
diff --git a/tests/camera/src/android/hardware/camera2/cts/testcases/Camera2AndroidTestCase.java b/tests/camera/src/android/hardware/camera2/cts/testcases/Camera2AndroidTestCase.java
index 1169e64..7fd1e2b 100644
--- a/tests/camera/src/android/hardware/camera2/cts/testcases/Camera2AndroidTestCase.java
+++ b/tests/camera/src/android/hardware/camera2/cts/testcases/Camera2AndroidTestCase.java
@@ -331,6 +331,31 @@
}
/**
+ * Create an {@link ImageReader} object and get the surface.
+ * <p>
+ * This function creates {@link ImageReader} object and surface, then assign
+ * to the default {@link mReader} and {@link mReaderSurface}. It closes the
+ * current default active {@link ImageReader} if it exists.
+ * </p>
+ *
+ * @param size The size of this ImageReader to be created.
+ * @param format The format of this ImageReader to be created
+ * @param maxNumImages The max number of images that can be acquired
+ * simultaneously.
+ * @param usage The usage flag of the ImageReader
+ * @param listener The listener used by this ImageReader to notify
+ * callbacks.
+ */
+ protected void createDefaultImageReader(Size size, int format, int maxNumImages, long usage,
+ ImageReader.OnImageAvailableListener listener) throws Exception {
+ closeDefaultImageReader();
+
+ mReader = createImageReader(size, format, maxNumImages, usage, listener);
+ mReaderSurface = mReader.getSurface();
+ if (VERBOSE) Log.v(TAG, "Created ImageReader size " + size.toString());
+ }
+
+ /**
* Create an {@link ImageReader} object.
*
* <p>This function creates image reader object for given format, maxImages, and size.</p>
@@ -354,6 +379,29 @@
}
/**
+ * Create an {@link ImageReader} object.
+ *
+ * <p>This function creates image reader object for given format, maxImages, usage and size.</p>
+ *
+ * @param size The size of this ImageReader to be created.
+ * @param format The format of this ImageReader to be created
+ * @param maxNumImages The max number of images that can be acquired simultaneously.
+ * @param usage The usage flag of the ImageReader
+ * @param listener The listener used by this ImageReader to notify callbacks.
+ */
+
+ protected ImageReader createImageReader(Size size, int format, int maxNumImages, long usage,
+ ImageReader.OnImageAvailableListener listener) throws Exception {
+ ImageReader reader = null;
+ reader = ImageReader.newInstance(size.getWidth(), size.getHeight(),
+ format, maxNumImages, usage);
+
+ reader.setOnImageAvailableListener(listener, mHandler);
+ if (VERBOSE) Log.v(TAG, "Created ImageReader size " + size.toString());
+ return reader;
+ }
+
+ /**
* Close the pending images then close current default {@link ImageReader} object.
*/
protected void closeDefaultImageReader() {
diff --git a/tests/camera/utils/src/android/hardware/camera2/cts/CameraTestUtils.java b/tests/camera/utils/src/android/hardware/camera2/cts/CameraTestUtils.java
index 8a9d92f..3dc7c8c 100644
--- a/tests/camera/utils/src/android/hardware/camera2/cts/CameraTestUtils.java
+++ b/tests/camera/utils/src/android/hardware/camera2/cts/CameraTestUtils.java
@@ -1677,9 +1677,9 @@
private static void validateRawPrivateData(byte[] rawData, int width, int height,
long ts, String filePath) {
if (VERBOSE) Log.v(TAG, "Validating private raw data");
- // Expect each RAW pixel should occupy at least one byte and no more than 2.5 bytes
+ // Expect each RAW pixel should occupy at least one byte and no more than 30 bytes
int expectedSizeMin = width * height;
- int expectedSizeMax = width * height * 5 / 2;
+ int expectedSizeMax = width * height * 30;
assertTrue("Opaque RAW size " + rawData.length + "out of normal bound [" +
expectedSizeMin + "," + expectedSizeMax + "]",
diff --git a/tests/camera/utils/src/android/hardware/camera2/cts/helpers/StaticMetadata.java b/tests/camera/utils/src/android/hardware/camera2/cts/helpers/StaticMetadata.java
index 5085bcc..15701f1 100644
--- a/tests/camera/utils/src/android/hardware/camera2/cts/helpers/StaticMetadata.java
+++ b/tests/camera/utils/src/android/hardware/camera2/cts/helpers/StaticMetadata.java
@@ -2427,6 +2427,13 @@
}
/**
+ * Check if active physical camera Id metadata is supported.
+ */
+ public boolean isActivePhysicalCameraIdSupported() {
+ return areKeysAvailable(CaptureResult.LOGICAL_MULTI_CAMERA_ACTIVE_PHYSICAL_ID);
+ }
+
+ /**
* Get the value in index for a fixed-size array from a given key.
*
* <p>If the camera device is incorrectly reporting values, log a warning and return
diff --git a/tests/contentcaptureservice/Android.mk b/tests/contentcaptureservice/Android.mk
index 48254ef..e6f42ac 100644
--- a/tests/contentcaptureservice/Android.mk
+++ b/tests/contentcaptureservice/Android.mk
@@ -26,7 +26,8 @@
androidx.annotation_annotation \
compatibility-device-util \
ctstestrunner \
- truth-prebuilt
+ truth-prebuilt \
+ testng # TODO: remove once Android migrates to JUnit 4.12, which provide assertThrows
LOCAL_SRC_FILES := $(call all-java-files-under, src)
diff --git a/tests/contentcaptureservice/AndroidManifest.xml b/tests/contentcaptureservice/AndroidManifest.xml
index 47c62c4..11dc7ff 100644
--- a/tests/contentcaptureservice/AndroidManifest.xml
+++ b/tests/contentcaptureservice/AndroidManifest.xml
@@ -33,6 +33,16 @@
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
+ <activity android:name=".BlankWithTitleActivity"
+ android:label="Blanka"
+ android:taskAffinity=".BlankWithTitleActivity">
+ <intent-filter>
+ <!-- This intent filter is not really needed by CTS, but it makes easier to launch
+ this app during CTS development... -->
+ <action android:name="android.intent.action.MAIN" />
+ <category android:name="android.intent.category.LAUNCHER" />
+ </intent-filter>
+ </activity>
<activity android:name=".LoginActivity"
android:label="Login"
android:taskAffinity=".LoginActivity"
diff --git a/tests/contentcaptureservice/src/android/contentcaptureservice/cts/AbstractContentCaptureActivity.java b/tests/contentcaptureservice/src/android/contentcaptureservice/cts/AbstractContentCaptureActivity.java
index b9617bb..8e248cc 100644
--- a/tests/contentcaptureservice/src/android/contentcaptureservice/cts/AbstractContentCaptureActivity.java
+++ b/tests/contentcaptureservice/src/android/contentcaptureservice/cts/AbstractContentCaptureActivity.java
@@ -16,6 +16,7 @@
package android.contentcaptureservice.cts;
import android.app.Activity;
+import android.contentcaptureservice.cts.CtsContentCaptureService.Session;
import android.os.Bundle;
import android.util.Log;
import android.view.contentcapture.ContentCaptureManager;
@@ -81,6 +82,12 @@
}
/**
+ * Asserts the events generated when this session was launched and finished,
+ * without any custom / dynamic operations in between.
+ */
+ public abstract void assertDefaultEvents(@NonNull Session session);
+
+ /**
* Gets the real task id associated with the activity, as {@link #getTaskId()} returns
* {@code -1} after it's gone.
*/
diff --git a/tests/contentcaptureservice/src/android/contentcaptureservice/cts/AbstractRootViewActivity.java b/tests/contentcaptureservice/src/android/contentcaptureservice/cts/AbstractRootViewActivity.java
index 9290ffc..f328ca0 100644
--- a/tests/contentcaptureservice/src/android/contentcaptureservice/cts/AbstractRootViewActivity.java
+++ b/tests/contentcaptureservice/src/android/contentcaptureservice/cts/AbstractRootViewActivity.java
@@ -18,6 +18,7 @@
import android.contentcaptureservice.cts.common.DoubleVisitor;
import android.os.Bundle;
import android.util.Log;
+import android.view.ViewGroup;
import android.widget.LinearLayout;
import androidx.annotation.NonNull;
@@ -48,16 +49,50 @@
mRootView = findViewById(R.id.root_view);
+ Log.d(TAG, "Parents for " + getClass() + ": rootView=" + mRootView
+ + "\ngrandParent=" + getGrandParent()
+ + "\ngrandGrandParent=" + getGrandGrandParent()
+ + "\ndecorView=" + getDecorView());
+
if (sRootViewVisitor != null) {
Log.d(TAG, "Applying visitor to " + this + "/" + mRootView);
sRootViewVisitor.visit(this, mRootView);
}
}
+ @Override
+ protected void onResume() {
+ super.onResume();
+
+ Log.d(TAG, "AutofillIds for " + getClass() + ": "
+ + " rootView=" + getRootView().getAutofillId()
+ + ", grandParent=" + getGrandParent().getAutofillId()
+ + ", grandGrandParent=" + getGrandGrandParent().getAutofillId()
+ + ", decorView=" + getDecorView().getAutofillId());
+ }
+
public LinearLayout getRootView() {
return mRootView;
}
+ // TODO(b/122315042): remove this method when not needed anymore
+ @NonNull
+ public ViewGroup getGrandParent() {
+ return (ViewGroup) mRootView.getParent();
+ }
+
+ // TODO(b/122315042): remove this method when not needed anymore
+ @NonNull
+ public ViewGroup getGrandGrandParent() {
+ return (ViewGroup) getGrandParent().getParent();
+ }
+
+ // TODO(b/122315042): remove this method when not needed anymore
+ @NonNull
+ public ViewGroup getDecorView() {
+ return (ViewGroup) getGrandGrandParent().getParent();
+ }
+
/**
* The real "onCreate" method that should be extended by subclasses.
*
diff --git a/tests/contentcaptureservice/src/android/contentcaptureservice/cts/Assertions.java b/tests/contentcaptureservice/src/android/contentcaptureservice/cts/Assertions.java
index 8c77521..f5366f6 100644
--- a/tests/contentcaptureservice/src/android/contentcaptureservice/cts/Assertions.java
+++ b/tests/contentcaptureservice/src/android/contentcaptureservice/cts/Assertions.java
@@ -16,6 +16,7 @@
package android.contentcaptureservice.cts;
import static android.contentcaptureservice.cts.Helper.MY_EPOCH;
+import static android.contentcaptureservice.cts.Helper.TAG;
import static android.view.contentcapture.ContentCaptureEvent.TYPE_VIEW_APPEARED;
import static android.view.contentcapture.ContentCaptureEvent.TYPE_VIEW_DISAPPEARED;
import static android.view.contentcapture.ContentCaptureEvent.TYPE_VIEW_TEXT_CHANGED;
@@ -25,6 +26,7 @@
import android.contentcaptureservice.cts.CtsContentCaptureService.Session;
import android.net.Uri;
+import android.util.Log;
import android.view.View;
import android.view.autofill.AutofillId;
import android.view.contentcapture.ContentCaptureEvent;
@@ -35,7 +37,6 @@
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
-import java.util.ArrayList;
import java.util.List;
/**
@@ -62,7 +63,7 @@
*/
public static void assertMainSessionContext(@NonNull Session session,
@NonNull AbstractContentCaptureActivity activity) {
- assertMainSessionContext(session, activity, /* flags= */ 0);
+ assertMainSessionContext(session, activity, /* expectedFlags= */ 0);
}
/**
@@ -140,11 +141,9 @@
public static ViewNode assertViewWithUnknownParentAppeared(
@NonNull List<ContentCaptureEvent> events, int index, @NonNull View expectedView,
@Nullable String expectedText) {
- final ContentCaptureEvent event = getEvent(events, index);
- assertWithMessage("wrong event type at index %s: %s", index, event).that(event.getType())
- .isEqualTo(TYPE_VIEW_APPEARED);
- final ViewNode node = event.getViewNode();
- assertThat(node).isNotNull();
+ final ViewNode node = assertViewAppeared(events, index);
+ final ContentCaptureEvent event = events.get(index);
+
assertWithMessage("invalid time on %s (%s)", event, index).that(event.getEventTime())
.isAtLeast(MY_EPOCH);
assertWithMessage("wrong class on %s (%s)", event, index).that(node.getClassName())
@@ -161,6 +160,19 @@
}
/**
+ * Asserts the contents of a {@link #TYPE_VIEW_APPEARED} event, without checking for parent id.
+ */
+ public static ViewNode assertViewAppeared(@NonNull List<ContentCaptureEvent> events,
+ int index) {
+ final ContentCaptureEvent event = getEvent(events, index);
+ assertWithMessage("wrong event type at index %s: %s", index, event).that(event.getType())
+ .isEqualTo(TYPE_VIEW_APPEARED);
+ final ViewNode node = event.getViewNode();
+ assertThat(node).isNotNull();
+ return node;
+ }
+
+ /**
* Asserts the contents of a {@link #TYPE_VIEW_APPEARED} event.
*/
public static void assertViewAppeared(@NonNull List<ContentCaptureEvent> events, int index,
@@ -191,6 +203,18 @@
}
/**
+ * Asserts that a session for the given activity has no events.
+ */
+ public static void assertNoEvents(@NonNull Session session,
+ @NonNull AbstractContentCaptureActivity activity) {
+ assertRightActivity(session, session.id, activity);
+
+ final List<ContentCaptureEvent> events = session.getEvents();
+ Log.v(TAG, "events on " + activity + ": " + events);
+ assertThat(events).isEmpty();
+ }
+
+ /**
* Asserts that the events received by the service optionally contains the
* {@code TYPE_VIEW_DISAPPEARED} events, as they might have not been generated if the views
* disappeared after the activity stopped.
@@ -203,25 +227,13 @@
public static void assertViewsOptionallyDisappeared(@NonNull List<ContentCaptureEvent> events,
int minimumSize, @NonNull AutofillId... expectedIds) {
final int actualSize = events.size();
- final int optionalSize = expectedIds.length;
if (actualSize == minimumSize) {
// Activity stopped before TYPE_VIEW_DISAPPEARED were sent.
return;
}
-
- assertThat(events).hasSize(minimumSize + optionalSize);
- final ArrayList<AutofillId> actualIds = new ArrayList<>(optionalSize);
- final StringBuilder errors = new StringBuilder();
- for (int i = 0; i < optionalSize; i++) {
- final int index = minimumSize + i;
- final ContentCaptureEvent event = getEvent(events, index);
- if (event.getType() != TYPE_VIEW_DISAPPEARED) {
- errors.append("Invalid event at index ").append(index).append(": ").append(event)
- .append('\n');
- continue;
- }
- actualIds.add(event.getId());
- }
+ assertThat(events).hasSize(minimumSize + 1);
+ final ContentCaptureEvent batchDisappearEvent = events.get(minimumSize);
+ final List<AutofillId> actualIds = batchDisappearEvent.getIds();
assertThat(actualIds).containsExactly((Object[]) expectedIds);
}
@@ -236,10 +248,34 @@
}
/**
- * Asserts the contents of a {@link #TYPE_VIEW_DISAPPEARED} event.
+ * Asserts the contents of a {@link #TYPE_VIEW_DISAPPEARED} event for a single view.
*/
public static void assertViewDisappeared(@NonNull List<ContentCaptureEvent> events, int index,
@NonNull AutofillId expectedId) {
+ final ContentCaptureEvent event = assertCommonViewDisappearedProperties(events, index);
+ assertWithMessage("wrong autofillId on event %s (index %s)", event, index)
+ .that(event.getId()).isEqualTo(expectedId);
+ assertWithMessage("event %s (index %s) should not have autofillIds", event, index)
+ .that(event.getIds()).isNull();
+ }
+
+ /**
+ * Asserts the contents of a {@link #TYPE_VIEW_DISAPPEARED} event for multiple views.
+ */
+ public static void assertViewsDisappeared(@NonNull List<ContentCaptureEvent> events, int index,
+ @NonNull AutofillId... expectedIds) {
+ final ContentCaptureEvent event = assertCommonViewDisappearedProperties(events, index);
+ final List<AutofillId> ids = event.getIds();
+ assertWithMessage("no autofillIds on event %s (index %s)", event, index).that(ids)
+ .isNotNull();
+ assertWithMessage("wrong autofillId on event %s (index %s)", event, index)
+ .that(ids).containsExactly((Object[]) expectedIds).inOrder();
+ assertWithMessage("event %s (index %s) should not have autofillId", event, index)
+ .that(event.getId()).isNull();
+ }
+
+ private static ContentCaptureEvent assertCommonViewDisappearedProperties(
+ @NonNull List<ContentCaptureEvent> events, int index) {
final ContentCaptureEvent event = getEvent(events, index);
assertWithMessage("wrong event type at index %s: %s", index, event).that(event.getType())
.isEqualTo(TYPE_VIEW_DISAPPEARED);
@@ -249,12 +285,9 @@
.that(event.getViewNode()).isNull();
assertWithMessage("event %s (index %s) should not have text", event, index)
.that(event.getText()).isNull();
- assertWithMessage("event %s (index %s) should not have flags", event, index)
- .that(event.getFlags()).isEqualTo(0);
assertWithMessage("event %s (index %s) should not have a ViewNode", event, index)
.that(event.getViewNode()).isNull();
- assertWithMessage("wrong autofillId on event %s (index %s)", event, index)
- .that(event.getId()).isEqualTo(expectedId);
+ return event;
}
/**
@@ -287,9 +320,22 @@
*/
public static void assertVirtualViewDisappeared(@NonNull List<ContentCaptureEvent> events,
int index, @NonNull AutofillId parentId, @NonNull ContentCaptureSession session,
- int childId) {
- final AutofillId expectedId = session.newAutofillId(parentId, childId);
- assertViewDisappeared(events, index, expectedId);
+ long childId) {
+ assertViewDisappeared(events, index, session.newAutofillId(parentId, childId));
+ }
+
+ /**
+ * Asserts the contents of a {@link #TYPE_VIEW_DISAPPEARED} event for many virtual nodes.
+ */
+ public static void assertVirtualViewsDisappeared(@NonNull List<ContentCaptureEvent> events,
+ int index, @NonNull AutofillId parentId, @NonNull ContentCaptureSession session,
+ long... childrenIds) {
+ final int size = childrenIds.length;
+ final AutofillId[] expectedIds = new AutofillId[size];
+ for (int i = 0; i < childrenIds.length; i++) {
+ expectedIds[i] = session.newAutofillId(parentId, childrenIds[i]);
+ }
+ assertViewsDisappeared(events, index, expectedIds);
}
/**
diff --git a/tests/contentcaptureservice/src/android/contentcaptureservice/cts/BlankActivity.java b/tests/contentcaptureservice/src/android/contentcaptureservice/cts/BlankActivity.java
index 6fd9c2a..6ccbae9 100644
--- a/tests/contentcaptureservice/src/android/contentcaptureservice/cts/BlankActivity.java
+++ b/tests/contentcaptureservice/src/android/contentcaptureservice/cts/BlankActivity.java
@@ -15,6 +15,16 @@
*/
package android.contentcaptureservice.cts;
+import static android.contentcaptureservice.cts.Assertions.assertNoEvents;
+
+import android.contentcaptureservice.cts.CtsContentCaptureService.Session;
+
+import androidx.annotation.NonNull;
+
public class BlankActivity extends AbstractContentCaptureActivity {
+ @Override
+ public void assertDefaultEvents(@NonNull Session session) {
+ assertNoEvents(session, this);
+ }
}
diff --git a/tests/contentcaptureservice/src/android/contentcaptureservice/cts/BlankActivityTest.java b/tests/contentcaptureservice/src/android/contentcaptureservice/cts/BlankActivityTest.java
index ddbd0b7..3597ae6 100644
--- a/tests/contentcaptureservice/src/android/contentcaptureservice/cts/BlankActivityTest.java
+++ b/tests/contentcaptureservice/src/android/contentcaptureservice/cts/BlankActivityTest.java
@@ -15,7 +15,6 @@
*/
package android.contentcaptureservice.cts;
-import static android.contentcaptureservice.cts.Assertions.assertRightActivity;
import static android.contentcaptureservice.cts.CtsContentCaptureService.CONTENT_CAPTURE_SERVICE_COMPONENT_NAME;
import static android.contentcaptureservice.cts.Helper.resetService;
import static android.contentcaptureservice.cts.common.ActivitiesWatcher.ActivityLifecycle.DESTROYED;
@@ -27,12 +26,9 @@
import android.contentcaptureservice.cts.common.ActivitiesWatcher.ActivityWatcher;
import android.support.test.rule.ActivityTestRule;
import android.util.Log;
-import android.view.contentcapture.ContentCaptureEvent;
import org.junit.Test;
-import java.util.List;
-
public class BlankActivityTest extends AbstractContentCaptureIntegrationTest<BlankActivity> {
private static final String TAG = BlankActivityTest.class.getSimpleName();
@@ -63,11 +59,7 @@
final Session session = service.getOnlyFinishedSession();
Log.v(TAG, "session id: " + session.id);
- assertRightActivity(session, session.id, activity);
-
- final List<ContentCaptureEvent> events = session.getEvents();
- Log.v(TAG, "events: " + events);
- assertThat(events).isEmpty();
+ activity.assertDefaultEvents(session);
}
@Test
diff --git a/tests/contentcaptureservice/src/android/contentcaptureservice/cts/BlankWithTitleActivity.java b/tests/contentcaptureservice/src/android/contentcaptureservice/cts/BlankWithTitleActivity.java
new file mode 100644
index 0000000..256b502
--- /dev/null
+++ b/tests/contentcaptureservice/src/android/contentcaptureservice/cts/BlankWithTitleActivity.java
@@ -0,0 +1,50 @@
+/*
+ * Copyright (C) 2019 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.contentcaptureservice.cts;
+
+import static android.contentcaptureservice.cts.Assertions.assertRightActivity;
+import static android.contentcaptureservice.cts.Assertions.assertViewAppeared;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import android.contentcaptureservice.cts.CtsContentCaptureService.Session;
+import android.util.Log;
+import android.view.contentcapture.ContentCaptureEvent;
+import android.view.contentcapture.ContentCaptureSessionId;
+import android.view.contentcapture.ViewNode;
+
+import androidx.annotation.NonNull;
+
+import java.util.List;
+
+public class BlankWithTitleActivity extends AbstractContentCaptureActivity {
+
+ @Override
+ public void assertDefaultEvents(@NonNull Session session) {
+ final ContentCaptureSessionId sessionId = session.id;
+ assertRightActivity(session, sessionId, this);
+
+ final List<ContentCaptureEvent> events = session.getEvents();
+ Log.v(mTag, "events: " + events);
+
+ final int minEvents = 1;
+ // TODO(b/119638528): somehow asset the grandparents...
+ assertThat(events.size()).isAtLeast(minEvents);
+
+ final ViewNode title = assertViewAppeared(events, 0);
+ assertThat(title.getText()).isEqualTo("Blanka");
+ }
+}
diff --git a/tests/contentcaptureservice/src/android/contentcaptureservice/cts/BlankWithTitleActivityTest.java b/tests/contentcaptureservice/src/android/contentcaptureservice/cts/BlankWithTitleActivityTest.java
new file mode 100644
index 0000000..e08371c
--- /dev/null
+++ b/tests/contentcaptureservice/src/android/contentcaptureservice/cts/BlankWithTitleActivityTest.java
@@ -0,0 +1,61 @@
+/*
+ * Copyright (C) 2019 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.contentcaptureservice.cts;
+
+import static android.contentcaptureservice.cts.common.ActivitiesWatcher.ActivityLifecycle.DESTROYED;
+import static android.contentcaptureservice.cts.common.ActivitiesWatcher.ActivityLifecycle.RESUMED;
+
+import android.contentcaptureservice.cts.CtsContentCaptureService.Session;
+import android.contentcaptureservice.cts.common.ActivitiesWatcher.ActivityWatcher;
+import android.support.test.rule.ActivityTestRule;
+import android.util.Log;
+
+import org.junit.Test;
+
+public class BlankWithTitleActivityTest
+ extends AbstractContentCaptureIntegrationTest<BlankWithTitleActivity> {
+
+ private static final String TAG = BlankWithTitleActivityTest.class.getSimpleName();
+
+ private static final ActivityTestRule<BlankWithTitleActivity> sActivityRule =
+ new ActivityTestRule<>(BlankWithTitleActivity.class, false, false);
+
+ public BlankWithTitleActivityTest() {
+ super(BlankWithTitleActivity.class);
+ }
+
+ @Override
+ protected ActivityTestRule<BlankWithTitleActivity> getActivityTestRule() {
+ return sActivityRule;
+ }
+
+ @Test
+ public void testSimpleSessionLifecycle() throws Exception {
+ final CtsContentCaptureService service = enableService();
+ final ActivityWatcher watcher = startWatcher();
+
+ final BlankWithTitleActivity activity = launchActivity();
+ watcher.waitFor(RESUMED);
+
+ activity.finish();
+ watcher.waitFor(DESTROYED);
+
+ final Session session = service.getOnlyFinishedSession();
+ Log.v(TAG, "session id: " + session.id);
+
+ activity.assertDefaultEvents(session);
+ }
+}
diff --git a/tests/contentcaptureservice/src/android/contentcaptureservice/cts/ChildlessActivity.java b/tests/contentcaptureservice/src/android/contentcaptureservice/cts/ChildlessActivity.java
index f13c199..153c4c0 100644
--- a/tests/contentcaptureservice/src/android/contentcaptureservice/cts/ChildlessActivity.java
+++ b/tests/contentcaptureservice/src/android/contentcaptureservice/cts/ChildlessActivity.java
@@ -15,12 +15,24 @@
*/
package android.contentcaptureservice.cts;
+import static android.contentcaptureservice.cts.Assertions.assertNoEvents;
+
+import android.contentcaptureservice.cts.CtsContentCaptureService.Session;
import android.os.Bundle;
+import androidx.annotation.NonNull;
+
public class ChildlessActivity extends AbstractRootViewActivity {
@Override
protected void setContentViewOnCreate(Bundle savedInstanceState) {
setContentView(R.layout.childless_activity);
}
+
+ @Override
+ public void assertDefaultEvents(@NonNull Session session) {
+ // Should be empty because the root view is not important for content capture without a
+ // child that is important.
+ assertNoEvents(session, this);
+ }
}
diff --git a/tests/contentcaptureservice/src/android/contentcaptureservice/cts/ChildlessActivityTest.java b/tests/contentcaptureservice/src/android/contentcaptureservice/cts/ChildlessActivityTest.java
index d429a35..40c1420 100644
--- a/tests/contentcaptureservice/src/android/contentcaptureservice/cts/ChildlessActivityTest.java
+++ b/tests/contentcaptureservice/src/android/contentcaptureservice/cts/ChildlessActivityTest.java
@@ -24,7 +24,9 @@
import static android.contentcaptureservice.cts.Assertions.assertViewAppeared;
import static android.contentcaptureservice.cts.Assertions.assertViewDisappeared;
import static android.contentcaptureservice.cts.Assertions.assertViewWithUnknownParentAppeared;
+import static android.contentcaptureservice.cts.Assertions.assertViewsDisappeared;
import static android.contentcaptureservice.cts.Assertions.assertViewsOptionallyDisappeared;
+import static android.contentcaptureservice.cts.Helper.componentNameFor;
import static android.contentcaptureservice.cts.common.ActivitiesWatcher.ActivityLifecycle.DESTROYED;
import static android.contentcaptureservice.cts.common.ActivitiesWatcher.ActivityLifecycle.RESUMED;
@@ -33,6 +35,7 @@
import android.content.Context;
import android.contentcaptureservice.cts.CtsContentCaptureService.Session;
import android.contentcaptureservice.cts.common.ActivitiesWatcher.ActivityWatcher;
+import android.contentcaptureservice.cts.common.ActivityLauncher;
import android.net.Uri;
import android.os.SystemClock;
import android.support.test.rule.ActivityTestRule;
@@ -49,8 +52,10 @@
import org.junit.After;
import org.junit.Before;
+import org.junit.Ignore;
import org.junit.Test;
+import java.util.Arrays;
import java.util.List;
import java.util.concurrent.atomic.AtomicReference;
@@ -89,19 +94,85 @@
watcher.waitFor(DESTROYED);
final Session session = service.getOnlyFinishedSession();
- final ContentCaptureSessionId sessionId = session.id;
- Log.v(TAG, "session id: " + sessionId);
+ Log.v(TAG, "session id: " + session.id);
- assertRightActivity(session, sessionId, activity);
-
- // Should be empty because the root view is not important for content capture without a
- // child that is important.
- final List<ContentCaptureEvent> events = session.getEvents();
- Log.v(TAG, "events: " + events);
- assertThat(events).isEmpty();
+ activity.assertDefaultEvents(session);
}
@Test
+ public void testLaunchAnotherActivity() throws Exception {
+ final CtsContentCaptureService service = enableService();
+ final ActivityWatcher watcher1 = startWatcher();
+
+ // Launch and finish 1st activity
+ final ChildlessActivity activity1 = launchActivity();
+ watcher1.waitFor(RESUMED);
+ activity1.finish();
+ watcher1.waitFor(DESTROYED);
+
+ // Launch and finish 2nd activity
+ final ActivityLauncher<LoginActivity> anotherActivityLauncher = new ActivityLauncher<>(
+ sContext, mActivitiesWatcher, LoginActivity.class);
+ final ActivityWatcher watcher2 = anotherActivityLauncher.getWatcher();
+ final LoginActivity activity2 = anotherActivityLauncher.launchActivity();
+ watcher2.waitFor(RESUMED);
+ activity2.finish();
+ watcher2.waitFor(DESTROYED);
+
+ // Assert the sessions
+ final List<ContentCaptureSessionId> sessionIds = service.getAllSessionIds();
+ assertThat(sessionIds).hasSize(2);
+ final ContentCaptureSessionId sessionId1 = sessionIds.get(0);
+ Log.v(TAG, "session id1: " + sessionId1);
+ final ContentCaptureSessionId sessionId2 = sessionIds.get(1);
+ Log.v(TAG, "session id2: " + sessionId2);
+
+ final Session session1 = service.getFinishedSession(sessionId1);
+ activity1.assertDefaultEvents(session1);
+
+ final Session session2 = service.getFinishedSession(sessionId2);
+ activity2.assertDefaultEvents(session2);
+ }
+
+ @Ignore("not implemented yet, pending on b/122595322")
+ @Test
+ public void testLaunchAnotherActivity_serviceDisabledActivity() throws Exception {
+ final CtsContentCaptureService service = enableService();
+ final ActivityWatcher watcher1 = startWatcher();
+
+ // Disable activity 2
+ service.setActivityContentCaptureEnabled(componentNameFor(LoginActivity.class), false);
+
+ // Launch and finish 1st activity
+ final ChildlessActivity activity1 = launchActivity();
+ watcher1.waitFor(RESUMED);
+ activity1.finish();
+ watcher1.waitFor(DESTROYED);
+
+ // Launch and finish 2nd activity
+ final ActivityLauncher<LoginActivity> anotherActivityLauncher = new ActivityLauncher<>(
+ sContext, mActivitiesWatcher, LoginActivity.class);
+ final ActivityWatcher watcher2 = anotherActivityLauncher.getWatcher();
+ final LoginActivity activity2 = anotherActivityLauncher.launchActivity();
+ watcher2.waitFor(RESUMED);
+ activity2.finish();
+ watcher2.waitFor(DESTROYED);
+
+ // Assert the sessions
+ final List<ContentCaptureSessionId> sessionIds = service.getAllSessionIds();
+ assertThat(sessionIds).hasSize(1);
+ final ContentCaptureSessionId sessionId1 = sessionIds.get(0);
+ Log.v(TAG, "session id1: " + sessionId1);
+
+ final Session session1 = service.getFinishedSession(sessionId1);
+ activity1.assertDefaultEvents(session1);
+
+ // TODO(b/122595322): should also test events after re-enabling it
+ }
+
+ // TODO(b/122595322): same tests for disabled by package, explicity whitelisted, etc...
+
+ @Test
public void testAddAndRemoveNoImportantChild() throws Exception {
final CtsContentCaptureService service = enableService();
final ActivityWatcher watcher = startWatcher();
@@ -481,7 +552,7 @@
final TextView s3c1 = addChild(activity, childSession3, "s3c1");
final TextView s3c2 = addChild(activity, childSession3, "s3c2");
- waitAndRemoveView(activity, s3c1);
+ waitAndRemoveViews(activity, s3c1);
final TextView s3c3 = addChild(activity, childSession3, "s3c3");
// ...and close it right away
@@ -719,6 +790,84 @@
assertLifecycleOrder(10, mainTestSession, DESTRUCTION);
}
+ /**
+ * Tests scenario where views from different session are removed in sequence - they should not
+ * have been batched.
+ */
+ @Test
+ public void testRemoveChildrenFromDifferentSessions() throws Exception {
+ final CtsContentCaptureService service = enableService();
+ final ActivityWatcher watcher = startWatcher();
+
+ final ChildlessActivity activity = launchActivity();
+ watcher.waitFor(RESUMED);
+ final ContentCaptureSession mainSession = activity.getRootView().getContentCaptureSession();
+ final ContentCaptureSessionId mainSessionId = mainSession.getContentCaptureSessionId();
+ Log.v(TAG, "main session id: " + mainSessionId);
+
+ // Create 1st session
+ final ContentCaptureContext context1 = new ContentCaptureContext.Builder()
+ .setUri(Uri.parse("http://session1")).build();
+ final ContentCaptureSession childSession1 = mainSession
+ .createContentCaptureSession(context1);
+ final ContentCaptureSessionId childSessionId1 = childSession1.getContentCaptureSessionId();
+ Log.v(TAG, "child session id 1: " + childSessionId1);
+
+ // Session 1, child 1
+ final TextView s1c1 = addChild(activity, childSession1, "s1c1");
+ final AutofillId s1c1Id = s1c1.getAutofillId();
+ Log.v(TAG, "childrens from session1: " + s1c1Id);
+
+ // Create 2nd session
+ final ContentCaptureContext context2 = new ContentCaptureContext.Builder()
+ .setUri(Uri.parse("http://session2")).build();
+ final ContentCaptureSession childSession2 = mainSession
+ .createContentCaptureSession(context2);
+ final ContentCaptureSessionId childSessionId2 = childSession2.getContentCaptureSessionId();
+ Log.v(TAG, "child session id 2: " + childSessionId2);
+
+ final TextView s2c1 = addChild(activity, childSession2, "s2c1");
+ final AutofillId s2c1Id = s2c1.getAutofillId();
+ final TextView s2c2 = addChild(activity, childSession2, "s2c2");
+ final AutofillId s2c2Id = s2c2.getAutofillId();
+ Log.v(TAG, "childrens from session2: " + s2c1Id + ", " + s2c2Id);
+
+ // Remove views - should generate one batch event for s2 and one single event for s1
+ waitAndRemoveViews(activity, s2c1, s2c2, s1c1);
+
+ activity.finish();
+ watcher.waitFor(DESTROYED);
+
+ final List<ContentCaptureSessionId> receivedIds = service.getAllSessionIds();
+ assertThat(receivedIds).containsExactly(
+ mainSessionId,
+ childSessionId1,
+ childSessionId2)
+ .inOrder();
+
+ // Assert main sessions info
+ final Session mainTestSession = service.getFinishedSession(mainSessionId);
+ assertMainSessionContext(mainTestSession, activity);
+
+ final Session childTestSession1 = service.getFinishedSession(childSessionId1);
+ assertChildSessionContext(childTestSession1, "http://session1");
+ final List<ContentCaptureEvent> events1 = childTestSession1.getEvents();
+ Log.v(TAG, "events1: " + events1);
+ assertThat(events1.size()).isAtLeast(2);
+ final AutofillId rootId = activity.getRootView().getAutofillId();
+ assertViewAppeared(events1, 0, s1c1, rootId);
+ assertViewDisappeared(events1, 1, s1c1Id);
+
+ final Session childTestSession2 = service.getFinishedSession(childSessionId2);
+ final List<ContentCaptureEvent> events2 = childTestSession2.getEvents();
+ assertChildSessionContext(childTestSession2, "http://session2");
+ Log.v(TAG, "events2: " + events2);
+ assertThat(events2.size()).isAtLeast(3);
+ assertViewAppeared(events2, 0, s2c1, rootId);
+ assertViewAppeared(events2, 1, s2c2, rootId);
+ assertViewsDisappeared(events2, 2, s2c1Id, s2c2Id);
+ }
+
/* TODO(b/119638528): add more scenarios for nested sessions, such as:
* - add views to the children sessions
* - s1 -> s2 -> s3 and main -> s4; close(s1) then generate events on view from s3
@@ -744,8 +893,8 @@
return child;
}
- // TODO(b/119638958): these method are used in cases where we cannot close a session because we
- // would miss intermediate evets, so we need to sleep. This is a hack (it's slow and flaky):
+ // TODO(b/123024698): these method are used in cases where we cannot close a session because we
+ // would miss intermediate events, so we need to sleep. This is a hack (it's slow and flaky):
// ideally we should block and wait until the service receives the event, but right now
// we don't get the service events until after the activity is finished, so we cannot do that...
private void waitAndClose(@NonNull ContentCaptureSession session) {
@@ -753,9 +902,14 @@
SystemClock.sleep(1_000);
session.close();
}
- private void waitAndRemoveView(@NonNull ChildlessActivity activity, @NonNull View view) {
- Log.d(TAG, "sleeping for 1s before removing " + view.getAutofillId());
+
+ private void waitAndRemoveViews(@NonNull ChildlessActivity activity, @NonNull View... views) {
+ Log.d(TAG, "sleeping for 1s before removing " + Arrays.toString(views));
SystemClock.sleep(1_000);
- activity.syncRunOnUiThread(() -> activity.getRootView().removeView(view));
+ activity.syncRunOnUiThread(() -> {
+ for (View view : views) {
+ activity.getRootView().removeView(view);
+ }
+ });
}
}
diff --git a/tests/contentcaptureservice/src/android/contentcaptureservice/cts/ContentCaptureContextTest.java b/tests/contentcaptureservice/src/android/contentcaptureservice/cts/ContentCaptureContextTest.java
new file mode 100644
index 0000000..c19f0f7
--- /dev/null
+++ b/tests/contentcaptureservice/src/android/contentcaptureservice/cts/ContentCaptureContextTest.java
@@ -0,0 +1,170 @@
+/*
+ * Copyright (C) 2019 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.contentcaptureservice.cts;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import static org.testng.Assert.assertThrows;
+
+import android.net.Uri;
+import android.os.Bundle;
+import android.os.Parcel;
+import android.platform.test.annotations.AppModeFull;
+import android.view.contentcapture.ContentCaptureContext;
+import android.view.contentcapture.ContentCaptureContext.Builder;
+
+import androidx.annotation.NonNull;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.JUnit4;
+
+@RunWith(JUnit4.class)
+@AppModeFull // Unit test
+public class ContentCaptureContextTest {
+
+ private static final Uri URI = Uri.parse("file:/dev/null");
+ private static final String ACTION = "Jackson";
+
+ private final ContentCaptureContext.Builder mBuilder = new ContentCaptureContext.Builder();
+
+ private final Bundle mExtras = new Bundle();
+
+ @Before
+ public void setExtras() {
+ mExtras.putString("DUDE", "SWEET");
+ }
+
+ @Test
+ public void testBuilder_invalidUri() {
+ assertThrows(NullPointerException.class, () -> mBuilder.setUri(null));
+ }
+
+ @Test
+ public void testBuilder_invalidAction() {
+ assertThrows(NullPointerException.class, () -> mBuilder.setAction(null));
+ }
+
+ @Test
+ public void testBuilder_invalidExtras() {
+ assertThrows(NullPointerException.class, () -> mBuilder.setExtras(null));
+ }
+
+ @Test
+ public void testAfterBuild_setExtras() {
+ assertThat(mBuilder.setUri(URI).build()).isNotNull();
+ assertThrows(IllegalStateException.class, () -> mBuilder.setExtras(mExtras));
+ }
+
+ @Test
+ public void testAfterBuild_setAction() {
+ assertThat(mBuilder.setUri(URI).build()).isNotNull();
+ assertThrows(IllegalStateException.class, () -> mBuilder.setAction(ACTION));
+ }
+
+ @Test
+ public void testAfterBuild_setUri() {
+ assertThat(mBuilder.setExtras(mExtras).build()).isNotNull();
+ assertThrows(IllegalStateException.class, () -> mBuilder.setUri(URI));
+ }
+
+ @Test
+ public void testAfterBuild_build() {
+ assertThat(mBuilder.setExtras(mExtras).build()).isNotNull();
+ assertThrows(IllegalStateException.class, () -> mBuilder.build());
+ }
+
+ @Test
+ public void testBuild_empty() {
+ assertThrows(IllegalStateException.class, () -> mBuilder.build());
+ }
+
+ @Test
+ public void testSetGetUri() {
+ final Builder builder = mBuilder.setUri(URI);
+ assertThat(builder).isSameAs(mBuilder);
+ final ContentCaptureContext context = builder.build();
+ assertThat(context).isNotNull();
+ assertThat(context.getUri()).isEqualTo(URI);
+ }
+
+ @Test
+ public void testSetGetAction() {
+ final Builder builder = mBuilder.setAction(ACTION);
+ assertThat(builder).isSameAs(mBuilder);
+ final ContentCaptureContext context = builder.build();
+ assertThat(context).isNotNull();
+ assertThat(context.getAction()).isEqualTo(ACTION);
+ }
+
+ @Test
+ public void testGetSetBundle() {
+ final Builder builder = mBuilder.setExtras(mExtras);
+ assertThat(builder).isSameAs(mBuilder);
+ final ContentCaptureContext context = builder.build();
+ assertThat(context).isNotNull();
+ assertExtras(context.getExtras());
+ }
+
+ @Test
+ public void testParcel() {
+ final Builder builder = mBuilder
+ .setUri(URI)
+ .setAction(ACTION)
+ .setExtras(mExtras);
+ assertThat(builder).isSameAs(mBuilder);
+ final ContentCaptureContext context = builder.build();
+ assertEverything(context);
+
+ final ContentCaptureContext clone = cloneThroughParcel(context);
+ assertEverything(clone);
+ }
+
+ private void assertEverything(@NonNull ContentCaptureContext context) {
+ assertThat(context).isNotNull();
+ assertThat(context.getUri()).isEqualTo(URI);
+ assertThat(context.getAction()).isEqualTo(ACTION);
+ assertExtras(context.getExtras());
+ }
+
+ private void assertExtras(@NonNull Bundle bundle) {
+ assertThat(bundle).isNotNull();
+ assertThat(bundle.keySet()).hasSize(1);
+ assertThat(bundle.getString("DUDE")).isEqualTo("SWEET");
+ }
+
+ private ContentCaptureContext cloneThroughParcel(@NonNull ContentCaptureContext context) {
+ final Parcel parcel = Parcel.obtain();
+
+ try {
+ // Write to parcel
+ parcel.setDataPosition(0); // Sanity / paranoid check
+ context.writeToParcel(parcel, 0);
+
+ // Read from parcel
+ parcel.setDataPosition(0);
+ final ContentCaptureContext clone = ContentCaptureContext.CREATOR
+ .createFromParcel(parcel);
+ assertThat(clone).isNotNull();
+ return clone;
+ } finally {
+ parcel.recycle();
+ }
+ }
+
+}
diff --git a/tests/contentcaptureservice/src/android/contentcaptureservice/cts/CtsContentCaptureService.java b/tests/contentcaptureservice/src/android/contentcaptureservice/cts/CtsContentCaptureService.java
index b8b367a..bbbbc0f 100644
--- a/tests/contentcaptureservice/src/android/contentcaptureservice/cts/CtsContentCaptureService.java
+++ b/tests/contentcaptureservice/src/android/contentcaptureservice/cts/CtsContentCaptureService.java
@@ -17,17 +17,18 @@
import static android.contentcaptureservice.cts.Helper.MY_PACKAGE;
import static android.contentcaptureservice.cts.Helper.await;
+import static android.contentcaptureservice.cts.Helper.componentNameFor;
import static com.google.common.truth.Truth.assertWithMessage;
import android.content.ComponentName;
-import android.service.contentcapture.ContentCaptureEventsRequest;
import android.service.contentcapture.ContentCaptureService;
import android.util.ArrayMap;
import android.util.Log;
import android.view.contentcapture.ContentCaptureContext;
import android.view.contentcapture.ContentCaptureEvent;
import android.view.contentcapture.ContentCaptureSessionId;
+import android.view.contentcapture.UserDataRemovalRequest;
import android.view.contentcapture.ViewNode;
import androidx.annotation.NonNull;
@@ -51,7 +52,7 @@
public static final String SERVICE_NAME = MY_PACKAGE + "/."
+ CtsContentCaptureService.class.getSimpleName();
public static final ComponentName CONTENT_CAPTURE_SERVICE_COMPONENT_NAME =
- new ComponentName(MY_PACKAGE, CtsContentCaptureService.class.getName());
+ componentNameFor(CtsContentCaptureService.class);
private static ServiceWatcher sServiceWatcher;
@@ -90,6 +91,11 @@
*/
private int mLifecycleEventsCounter;
+ /**
+ * Used for testing onUserDataRemovalRequest.
+ */
+ private UserDataRemovalRequest mRemovalRequest;
+
@NonNull
public static ServiceWatcher setServiceWatcher() {
if (sServiceWatcher != null) {
@@ -214,26 +220,32 @@
}
@Override
- public void onContentCaptureEventsRequest(ContentCaptureSessionId sessionId,
- ContentCaptureEventsRequest request) {
- final List<ContentCaptureEvent> events = request.getEvents();
- final int size = events.size();
- Log.i(TAG, "onContentCaptureEventsRequest(" + sessionId + "): " + size + " events");
- for (int i = 0; i < size; i++) {
- final ContentCaptureEvent event = events.get(i);
- final StringBuilder msg = new StringBuilder(" ").append(i).append(": ").append(event);
- final ViewNode node = event.getViewNode();
- if (node != null) {
- msg.append(", parent=").append(node.getParentAutofillId());
- }
- Log.v(TAG, msg.toString());
+ public void onContentCaptureEvent(ContentCaptureSessionId sessionId,
+ ContentCaptureEvent event) {
+ Log.i(TAG, "onContentCaptureEvent(" + sessionId + "): " + event);
+ final ViewNode node = event.getViewNode();
+ if (node != null) {
+ Log.v(TAG, "onContentCaptureEvent(): parentId=" + node.getParentAutofillId());
}
safeRun(() -> {
final Session session = getExistingSession(sessionId);
- session.mRequests.add(request);
+ session.mEvents.add(event);
});
}
+ @Override
+ public void onUserDataRemovalRequest(@NonNull UserDataRemovalRequest request) {
+ Log.i(TAG, "onUserDataRemovalRequest(" + request + ")");
+ mRemovalRequest = request;
+ }
+
+ /**
+ * Gets the cached UserDataRemovalRequest for testing.
+ */
+ public UserDataRemovalRequest getRemovalRequest() {
+ return mRemovalRequest;
+ }
+
/**
* Gets the finished session for the given session id.
*
@@ -343,7 +355,7 @@
public final ContentCaptureSessionId id;
public final ContentCaptureContext context;
public final int creationOrder;
- private final List<ContentCaptureEventsRequest> mRequests = new ArrayList<>();
+ private final List<ContentCaptureEvent> mEvents = new ArrayList<>();
public boolean finished;
public int destructionOrder;
@@ -364,16 +376,12 @@
// should track individual requests as well to make sure they're probably batch (it will
// require adding a Settings to tune the buffer parameters.
public List<ContentCaptureEvent> getEvents() {
- final List<ContentCaptureEvent> events = new ArrayList<>();
- for (ContentCaptureEventsRequest request : mRequests) {
- events.addAll(request.getEvents());
- }
- return Collections.unmodifiableList(events);
+ return Collections.unmodifiableList(mEvents);
}
@Override
public String toString() {
- return "[id=" + id + ", context=" + context + ", requests=" + mRequests.size()
+ return "[id=" + id + ", context=" + context + ", events=" + mEvents.size()
+ ", finished=" + finished + "]";
}
}
diff --git a/tests/contentcaptureservice/src/android/contentcaptureservice/cts/CustomViewActivity.java b/tests/contentcaptureservice/src/android/contentcaptureservice/cts/CustomViewActivity.java
index edbd453..5fb5fbf 100644
--- a/tests/contentcaptureservice/src/android/contentcaptureservice/cts/CustomViewActivity.java
+++ b/tests/contentcaptureservice/src/android/contentcaptureservice/cts/CustomViewActivity.java
@@ -15,13 +15,22 @@
*/
package android.contentcaptureservice.cts;
+import static android.contentcaptureservice.cts.Assertions.assertRightActivity;
+import static android.contentcaptureservice.cts.Assertions.assertViewWithUnknownParentAppeared;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import android.contentcaptureservice.cts.CtsContentCaptureService.Session;
import android.contentcaptureservice.cts.common.DoubleVisitor;
import android.os.Bundle;
import android.util.Log;
import android.view.ViewStructure;
+import android.view.contentcapture.ContentCaptureEvent;
import androidx.annotation.NonNull;
+import java.util.List;
+
public class CustomViewActivity extends AbstractContentCaptureActivity {
private static final String TAG = CustomViewActivity.class.getSimpleName();
@@ -50,4 +59,19 @@
(structure) -> sCustomViewDelegate.visit(mCustomView, structure));
}
}
+
+ @Override
+ public void assertDefaultEvents(@NonNull Session session) {
+ assertRightActivity(session, session.id, this);
+
+ final List<ContentCaptureEvent> events = session.getEvents();
+ Log.v(TAG, "events: " + events);
+ // TODO(b/119638528): check right number once we get rid of grandparent
+ assertThat(events.size()).isAtLeast(1);
+
+ // Assert just the relevant events
+ assertViewWithUnknownParentAppeared(events, 0, session.id, mCustomView);
+
+ // TODO(b/122315042): assert views disappeared
+ }
}
diff --git a/tests/contentcaptureservice/src/android/contentcaptureservice/cts/CustomViewActivityTest.java b/tests/contentcaptureservice/src/android/contentcaptureservice/cts/CustomViewActivityTest.java
index 6476faf..c7afd2a 100644
--- a/tests/contentcaptureservice/src/android/contentcaptureservice/cts/CustomViewActivityTest.java
+++ b/tests/contentcaptureservice/src/android/contentcaptureservice/cts/CustomViewActivityTest.java
@@ -19,6 +19,8 @@
import static android.contentcaptureservice.cts.Assertions.assertViewWithUnknownParentAppeared;
import static android.contentcaptureservice.cts.Assertions.assertVirtualViewAppeared;
import static android.contentcaptureservice.cts.Assertions.assertVirtualViewDisappeared;
+import static android.contentcaptureservice.cts.Assertions.assertVirtualViewsDisappeared;
+import static android.contentcaptureservice.cts.Helper.await;
import static android.contentcaptureservice.cts.common.ActivitiesWatcher.ActivityLifecycle.DESTROYED;
import static android.contentcaptureservice.cts.common.ActivitiesWatcher.ActivityLifecycle.RESUMED;
@@ -40,7 +42,9 @@
import org.junit.Test;
+import java.util.Arrays;
import java.util.List;
+import java.util.concurrent.CountDownLatch;
public class CustomViewActivityTest extends
AbstractContentCaptureIntegrationTest<CustomViewActivity> {
@@ -76,17 +80,7 @@
final Session session = service.getOnlyFinishedSession();
Log.v(TAG, "session id: " + session.id);
- assertRightActivity(session, session.id, activity);
-
- final List<ContentCaptureEvent> events = session.getEvents();
- Log.v(TAG, "events: " + events);
- // TODO(b/119638528): check right number once we get rid of grandparent
- assertThat(events.size()).isAtLeast(1);
-
- // Assert just the relevant events
- assertViewWithUnknownParentAppeared(events, 0, session.id, activity.mCustomView);
-
- // TODO(b/122315042): assert views disappeared
+ activity.assertDefaultEvents(session);
}
/**
@@ -153,7 +147,7 @@
final CtsContentCaptureService service = enableService();
final ActivityWatcher watcher = startWatcher();
- setAsyncDelegate((customView, structure) -> {
+ final CountDownLatch asyncLatch = setAsyncDelegate((customView, structure) -> {
Log.d(TAG, "delegate running on " + Thread.currentThread());
final AutofillId customViewId = customView.getAutofillId();
Log.d(TAG, "customViewId: " + customViewId);
@@ -165,14 +159,12 @@
assertThat(session.newAutofillId(customViewId, 1)).isEqualTo(child1Id);
Log.d(TAG, "nofifying child1 appeared: " + child1Id);
session.notifyViewAppeared(child1);
-
final ViewStructure child2 = session.newVirtualViewStructure(customViewId, 2);
child2.setText("child2");
final AutofillId child2Id = child2.getAutofillId();
assertThat(session.newAutofillId(customViewId, 2)).isEqualTo(child2Id);
Log.d(TAG, "nofifying child2 appeared: " + child2Id);
session.notifyViewAppeared(child2);
-
Log.d(TAG, "nofifying child2 disappeared: " + child2Id);
session.notifyViewDisappeared(child2Id);
Log.d(TAG, "nofifying child1 disappeared: " + child1Id);
@@ -181,6 +173,7 @@
final CustomViewActivity activity = launchActivity();
watcher.waitFor(RESUMED);
+ await(asyncLatch, "async onProvide");
activity.finish();
watcher.waitFor(DESTROYED);
@@ -192,8 +185,8 @@
final List<ContentCaptureEvent> events = session.getEvents();
Log.v(TAG, "events: " + events);
- // TODO(b/119638528): check right number once we get rid of grandparent (should be 5)
- assertThat(events.size()).isAtLeast(7);
+ // TODO(b/119638528): check right number once we get rid of grandparent
+ assertThat(events.size()).isAtLeast(6);
// Assert just the relevant events
final AutofillId customViewId = activity.mCustomView.getAutofillId();
@@ -203,8 +196,7 @@
// TODO(b/119638528): next 2 events are the grandparents
assertVirtualViewAppeared(events, 3, mainSession, customViewId, 1, "child1");
assertVirtualViewAppeared(events, 4, mainSession, customViewId, 2, "child2");
- assertVirtualViewDisappeared(events, 5, customViewId, mainSession, 2);
- assertVirtualViewDisappeared(events, 6, customViewId, mainSession, 1);
+ assertVirtualViewsDisappeared(events, 5, customViewId, mainSession, 2, 1);
// TODO(b/122315042): assert views disappeared
}
@@ -217,7 +209,7 @@
final CtsContentCaptureService service = enableService();
final ActivityWatcher watcher = startWatcher();
- setAsyncDelegate((customView, structure) -> {
+ final CountDownLatch asyncLatch = setAsyncDelegate((customView, structure) -> {
Log.d(TAG, "delegate running on " + Thread.currentThread());
final AutofillId customViewId = customView.getAutofillId();
Log.d(TAG, "customViewId: " + customViewId);
@@ -296,7 +288,7 @@
final CustomViewActivity activity = launchActivity();
watcher.waitFor(RESUMED);
-
+ await(asyncLatch, "async onProvide");
activity.finish();
watcher.waitFor(DESTROYED);
@@ -308,7 +300,7 @@
final List<ContentCaptureEvent> events = session.getEvents();
Log.v(TAG, "events: " + events);
// TODO(b/119638528): check right number once we get rid of grandparents
- assertThat(events.size()).isAtLeast(15);
+ assertThat(events.size()).isAtLeast(11);
// Assert just the relevant events
final AutofillId customViewId = activity.mCustomView.getAutofillId();
@@ -323,24 +315,85 @@
assertVirtualViewAppeared(events, 7, mainSession, customViewId, 21, "c2g1");
assertVirtualViewAppeared(events, 8, mainSession, customViewId, 211, "c2g1gg1");
assertVirtualViewAppeared(events, 9, mainSession, customViewId, 3, "c3");
- assertVirtualViewDisappeared(events, 10, customViewId, mainSession, 21);
- assertVirtualViewDisappeared(events, 11, customViewId, mainSession, 2);
- assertVirtualViewDisappeared(events, 12, customViewId, mainSession, 11);
- assertVirtualViewDisappeared(events, 13, customViewId, mainSession, 1);
- assertVirtualViewDisappeared(events, 14, customViewId, mainSession, 12);
+ assertVirtualViewsDisappeared(events, 10, customViewId, mainSession, 21, 2, 11, 1, 12);
- // TODO(b/122315042): assert views disappeared
+ // TODO(b/122315042): assert other views disappeared
}
// TODO(b/119638528): add tests for multiple sessions
+ @Test
+ public void testVirtualView_batchDisappear() throws Exception {
+ final CtsContentCaptureService service = enableService();
+ final ActivityWatcher watcher = startWatcher();
+
+ final CountDownLatch asyncLatch = setAsyncDelegate((customView, structure) -> {
+ Log.d(TAG, "delegate running on " + Thread.currentThread());
+ final AutofillId customViewId = customView.getAutofillId();
+ Log.d(TAG, "customViewId: " + customViewId);
+ final ContentCaptureSession session = customView.getContentCaptureSession();
+
+ final ViewStructure child1 = session.newVirtualViewStructure(customViewId, 1);
+ child1.setText("child1");
+ final AutofillId child1Id = child1.getAutofillId();
+ assertThat(session.newAutofillId(customViewId, 1)).isEqualTo(child1Id);
+ Log.d(TAG, "nofifying child1 appeared: " + child1Id);
+ session.notifyViewAppeared(child1);
+
+ final ViewStructure child2 = session.newVirtualViewStructure(customViewId, 2);
+ child2.setText("child2");
+ final AutofillId child2Id = child2.getAutofillId();
+ assertThat(session.newAutofillId(customViewId, 2)).isEqualTo(child2Id);
+ Log.d(TAG, "nofifying child2 appeared: " + child2Id);
+ session.notifyViewAppeared(child2);
+
+ final long[] childrenIds = {2, 1};
+ Log.d(TAG, "nofifying both children disappeared: " + Arrays.toString(childrenIds));
+ session.notifyViewsDisappeared(customViewId, childrenIds);
+ });
+
+ final CustomViewActivity activity = launchActivity();
+ watcher.waitFor(RESUMED);
+ await(asyncLatch, "async onProvide");
+ activity.finish();
+ watcher.waitFor(DESTROYED);
+
+ final Session session = service.getOnlyFinishedSession();
+ Log.v(TAG, "session id: " + session.id);
+
+ assertRightActivity(session, session.id, activity);
+
+ final List<ContentCaptureEvent> events = session.getEvents();
+ Log.v(TAG, "events: " + events);
+ // TODO(b/119638528): check right number once we get rid of grandparent (should be 5)
+ assertThat(events.size()).isAtLeast(6);
+
+ // Assert just the relevant events
+ final AutofillId customViewId = activity.mCustomView.getAutofillId();
+ final ContentCaptureSession mainSession = activity.mCustomView.getContentCaptureSession();
+
+ assertViewWithUnknownParentAppeared(events, 0, session.id, activity.mCustomView);
+ // TODO(b/119638528): next 2 events are the grandparents
+ assertVirtualViewAppeared(events, 3, mainSession, customViewId, 1, "child1");
+ assertVirtualViewAppeared(events, 4, mainSession, customViewId, 2, "child2");
+ assertVirtualViewsDisappeared(events, 5, customViewId, mainSession, 2, 1);
+
+ // TODO(b/122315042): assert other views disappeared
+ }
+
/**
* Sets a delegate that will generate the events asynchronously,
* after {@code onProvideContentCaptureStructure()} returns.
*/
- private void setAsyncDelegate(@NonNull DoubleVisitor<CustomView, ViewStructure> delegate) {
+ private CountDownLatch setAsyncDelegate(
+ @NonNull DoubleVisitor<CustomView, ViewStructure> delegate) {
+ final CountDownLatch asyncLatch = new CountDownLatch(1);
CustomViewActivity.setCustomViewDelegate(
(customView, structure) -> new Handler(Looper.getMainLooper())
- .post(() -> delegate.visit(customView, structure)));
+ .post(() -> {
+ delegate.visit(customView, structure);
+ asyncLatch.countDown();
+ }));
+ return asyncLatch;
}
}
diff --git a/tests/contentcaptureservice/src/android/contentcaptureservice/cts/Helper.java b/tests/contentcaptureservice/src/android/contentcaptureservice/cts/Helper.java
index 79c6b40..728ee82 100644
--- a/tests/contentcaptureservice/src/android/contentcaptureservice/cts/Helper.java
+++ b/tests/contentcaptureservice/src/android/contentcaptureservice/cts/Helper.java
@@ -17,6 +17,7 @@
import static android.contentcaptureservice.cts.common.ShellHelper.runShellCommand;
+import android.content.ComponentName;
import android.os.SystemClock;
import android.util.Log;
@@ -69,6 +70,13 @@
runShellCommand("cmd content_capture set temporary-service 0");
}
+ /**
+ * Gets the component name for a given class.
+ */
+ public static ComponentName componentNameFor(@NonNull Class<?> clazz) {
+ return new ComponentName(MY_PACKAGE, clazz.getName());
+ }
+
private Helper() {
throw new UnsupportedOperationException("contain static methods only");
}
diff --git a/tests/contentcaptureservice/src/android/contentcaptureservice/cts/LoginActivity.java b/tests/contentcaptureservice/src/android/contentcaptureservice/cts/LoginActivity.java
index 6360651..fc9efbd 100644
--- a/tests/contentcaptureservice/src/android/contentcaptureservice/cts/LoginActivity.java
+++ b/tests/contentcaptureservice/src/android/contentcaptureservice/cts/LoginActivity.java
@@ -15,12 +15,31 @@
*/
package android.contentcaptureservice.cts;
+import static android.contentcaptureservice.cts.Assertions.assertRightActivity;
+import static android.contentcaptureservice.cts.Assertions.assertSessionId;
+import static android.contentcaptureservice.cts.Assertions.assertViewAppeared;
+import static android.contentcaptureservice.cts.Assertions.assertViewsOptionallyDisappeared;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import android.contentcaptureservice.cts.CtsContentCaptureService.Session;
import android.os.Bundle;
+import android.util.Log;
+import android.view.View;
+import android.view.autofill.AutofillId;
+import android.view.contentcapture.ContentCaptureEvent;
+import android.view.contentcapture.ContentCaptureSessionId;
import android.widget.EditText;
import android.widget.TextView;
+import androidx.annotation.NonNull;
+
+import java.util.List;
+
public class LoginActivity extends AbstractRootViewActivity {
+ private static final String TAG = LoginActivity.class.getSimpleName();
+
TextView mUsernameLabel;
EditText mUsername;
TextView mPasswordLabel;
@@ -28,7 +47,6 @@
@Override
protected void setContentViewOnCreate(Bundle savedInstanceState) {
-
setContentView(R.layout.login_activity);
mUsernameLabel = findViewById(R.id.username_label);
@@ -36,4 +54,62 @@
mPasswordLabel = findViewById(R.id.password_label);
mPassword = findViewById(R.id.password);
}
+
+ @Override
+ public void assertDefaultEvents(@NonNull Session session) {
+ final LoginActivity activity = this;
+ final ContentCaptureSessionId sessionId = session.id;
+ assertRightActivity(session, sessionId, activity);
+
+ // Sanity check
+ assertSessionId(sessionId, activity.mUsernameLabel);
+ assertSessionId(sessionId, activity.mUsername);
+ assertSessionId(sessionId, activity.mPassword);
+ assertSessionId(sessionId, activity.mPasswordLabel);
+
+ final List<ContentCaptureEvent> events = session.getEvents();
+ Log.v(mTag, "events: " + events);
+ // TODO(b/119638528): ideally it should be 5 so it reflects just the views defined
+ // in the layout - right now it's generating events for 2 intermediate parents
+ // (android:action_mode_bar_stub and android:content), we should try to create an
+ // activity without them
+
+ final AutofillId rootId = activity.getRootView().getAutofillId();
+
+ final int minEvents = 7;
+ assertThat(events.size()).isAtLeast(minEvents);
+ assertViewAppeared(events, 0, sessionId, activity.mUsernameLabel, rootId);
+ assertViewAppeared(events, 1, sessionId, activity.mUsername, rootId);
+ assertViewAppeared(events, 2, sessionId, activity.mPasswordLabel, rootId);
+ assertViewAppeared(events, 3, sessionId, activity.mPassword, rootId);
+
+ // TODO(b/119638528): get rid of those intermediated parents
+ final View grandpa1 = activity.getGrandParent();
+ final View grandpa2 = activity.getGrandGrandParent();
+ final View decorView = activity.getDecorView();
+
+ assertViewAppeared(events, 4, sessionId, activity.getRootView(),
+ grandpa1.getAutofillId());
+ assertViewAppeared(events, 5, grandpa1, grandpa2.getAutofillId());
+ assertViewAppeared(events, 6, grandpa2, decorView.getAutofillId());
+
+ assertViewsOptionallyDisappeared(events, minEvents,
+ rootId,
+ grandpa1.getAutofillId(), grandpa2.getAutofillId(),
+ // decorView.getAutofillId(), // TODO(b/122315042): figure out why it's not
+ // generated
+ activity.mUsernameLabel.getAutofillId(), activity.mUsername.getAutofillId(),
+ activity.mPasswordLabel.getAutofillId(), activity.mPassword.getAutofillId()
+ );
+ }
+
+ @Override
+ protected void onResume() {
+ super.onResume();
+
+ Log.d(TAG, "AutofillIds: " + "usernameLabel=" + mUsernameLabel.getAutofillId()
+ + ", username=" + mUsername.getAutofillId()
+ + ", passwordLabel=" + mPasswordLabel.getAutofillId()
+ + ", password=" + mPassword.getAutofillId());
+ }
}
diff --git a/tests/contentcaptureservice/src/android/contentcaptureservice/cts/LoginActivityTest.java b/tests/contentcaptureservice/src/android/contentcaptureservice/cts/LoginActivityTest.java
index 00da1c4..379f28f 100644
--- a/tests/contentcaptureservice/src/android/contentcaptureservice/cts/LoginActivityTest.java
+++ b/tests/contentcaptureservice/src/android/contentcaptureservice/cts/LoginActivityTest.java
@@ -23,6 +23,8 @@
import static android.contentcaptureservice.cts.Assertions.assertViewAppeared;
import static android.contentcaptureservice.cts.Assertions.assertViewTextChanged;
import static android.contentcaptureservice.cts.Assertions.assertViewsOptionallyDisappeared;
+import static android.contentcaptureservice.cts.Helper.MY_PACKAGE;
+import static android.contentcaptureservice.cts.Helper.componentNameFor;
import static android.contentcaptureservice.cts.common.ActivitiesWatcher.ActivityLifecycle.DESTROYED;
import static android.contentcaptureservice.cts.common.ActivitiesWatcher.ActivityLifecycle.RESUMED;
@@ -41,13 +43,16 @@
import android.view.contentcapture.ContentCaptureEvent;
import android.view.contentcapture.ContentCaptureSession;
import android.view.contentcapture.ContentCaptureSessionId;
+import android.view.contentcapture.UserDataRemovalRequest;
import org.junit.After;
import org.junit.Before;
+import org.junit.Ignore;
import org.junit.Test;
import java.util.List;
import java.util.concurrent.atomic.AtomicReference;
+import java.util.stream.Collectors;
public class LoginActivityTest extends AbstractContentCaptureIntegrationTest<LoginActivity> {
@@ -83,53 +88,12 @@
watcher.waitFor(DESTROYED);
final Session session = service.getOnlyFinishedSession();
- final ContentCaptureSessionId sessionId = session.id;
- Log.v(TAG, "session id: " + sessionId);
+ Log.v(TAG, "session id: " + session.id);
- assertRightActivity(session, sessionId, activity);
-
- // Sanity check
- assertSessionId(sessionId, activity.mUsernameLabel);
- assertSessionId(sessionId, activity.mUsername);
- assertSessionId(sessionId, activity.mPassword);
- assertSessionId(sessionId, activity.mPasswordLabel);
-
- final List<ContentCaptureEvent> events = session.getEvents();
- Log.v(TAG, "events: " + events);
- // TODO(b/119638528): ideally it should be 5 so it reflects just the views defined
- // in the layout - right now it's generating events for 2 intermediate parents
- // (android:action_mode_bar_stub and android:content), we should try to create an
- // activity without them
-
- final AutofillId rootId = activity.getRootView().getAutofillId();
-
- final int minEvents = 7;
- assertThat(events.size()).isAtLeast(minEvents);
- assertViewAppeared(events, 0, sessionId, activity.mUsernameLabel, rootId);
- assertViewAppeared(events, 1, sessionId, activity.mUsername, rootId);
- assertViewAppeared(events, 2, sessionId, activity.mPasswordLabel, rootId);
- assertViewAppeared(events, 3, sessionId, activity.mPassword, rootId);
-
- // TODO(b/119638528): get rid of those intermediated parents
- final View grandpa1 = (View) activity.getRootView().getParent();
- final View grandpa2 = (View) grandpa1.getParent();
- final View decorView = (View) grandpa2.getParent();
-
- assertViewAppeared(events, 4, sessionId, activity.getRootView(),
- grandpa1.getAutofillId());
- assertViewAppeared(events, 5, grandpa1, grandpa2.getAutofillId());
- assertViewAppeared(events, 6, grandpa2, decorView.getAutofillId());
-
- assertViewsOptionallyDisappeared(events, minEvents,
- rootId,
- grandpa1.getAutofillId(), grandpa2.getAutofillId(),
- // decorView.getAutofillId(), // TODO(b/122315042): figure out why it's not
- // generated
- activity.mUsernameLabel.getAutofillId(), activity.mUsername.getAutofillId(),
- activity.mPasswordLabel.getAutofillId(), activity.mPassword.getAutofillId()
- );
+ activity.assertDefaultEvents(session);
}
+
@Test
public void testSimpleLifecycle_rootViewSession() throws Exception {
final CtsContentCaptureService service = enableService();
@@ -174,13 +138,16 @@
assertSessionId(childSessionId, activity.mPasswordLabel);
// Get the sessions
- final List<ContentCaptureSessionId> allSessionIds = service.getAllSessionIds();
- assertThat(allSessionIds).containsExactly(mainSessionId, childSessionId);
final Session mainSession = service.getFinishedSession(mainSessionId);
final Session childSession = service.getFinishedSession(childSessionId);
+
assertRightActivity(mainSession, mainSessionId, activity);
assertRightRelationship(mainSession, childSession);
+ // Sanity check
+ final List<ContentCaptureSessionId> allSessionIds = service.getAllSessionIds();
+ assertThat(allSessionIds).containsExactly(mainSessionId, childSessionId);
+
/*
* Asserts main session
*/
@@ -197,9 +164,9 @@
// create an activity without them
final int minMainEvents = 2;
assertThat(mainEvents.size()).isAtLeast(minMainEvents);
- final View grandpa1 = (View) activity.getRootView().getParent();
- final View grandpa2 = (View) grandpa1.getParent();
- final View decorView = (View) grandpa2.getParent();
+ final View grandpa1 = activity.getGrandParent();
+ final View grandpa2 = activity.getGrandGrandParent();
+ final View decorView = activity.getDecorView();
assertViewAppeared(mainEvents, 0, grandpa1, grandpa2.getAutofillId());
assertViewAppeared(mainEvents, 1, grandpa2, decorView.getAutofillId());
assertViewsOptionallyDisappeared(mainEvents, minMainEvents,
@@ -238,6 +205,29 @@
);
}
+ @Ignore("not implemented yet, pending on b/122595322")
+ @Test
+ public void testSimpleLifecycle_serviceDisabledActivity() throws Exception {
+ final CtsContentCaptureService service = enableService();
+ final ActivityWatcher watcher = startWatcher();
+
+ // Disable activity
+ service.setActivityContentCaptureEnabled(componentNameFor(LoginActivity.class), false);
+
+ final LoginActivity activity = launchActivity();
+ watcher.waitFor(RESUMED);
+
+ activity.finish();
+ watcher.waitFor(DESTROYED);
+
+ final List<ContentCaptureSessionId> sessionIds = service.getAllSessionIds();
+ assertThat(sessionIds).isEmpty();
+
+ // TODO(b/122595322): should also test events after re-enabling it
+ }
+
+ // TODO(b/122595322): same tests for disabled by package, explicity whitelisted, etc...
+
@Test
public void testTextChanged() throws Exception {
final CtsContentCaptureService service = enableService();
@@ -275,9 +265,9 @@
assertViewAppeared(events, 2, activity.mPasswordLabel, rootId);
assertViewAppeared(events, 3, activity.mPassword, rootId, "");
// TODO(b/119638528): get rid of those intermediated parents
- final View grandpa1 = (View) activity.getRootView().getParent();
- final View grandpa2 = (View) grandpa1.getParent();
- final View decorView = (View) grandpa2.getParent();
+ final View grandpa1 = activity.getGrandParent();
+ final View grandpa2 = activity.getGrandGrandParent();
+ final View decorView = activity.getDecorView();
assertViewAppeared(events, 4, activity.getRootView(), grandpa1.getAutofillId());
assertViewAppeared(events, 5, grandpa1, grandpa2.getAutofillId());
@@ -338,9 +328,9 @@
assertViewAppeared(events, 2, activity.mPasswordLabel, rootId);
assertViewAppeared(events, 3, activity.mPassword, rootId, "");
// TODO(b/119638528): get rid of those intermediated parents
- final View grandpa1 = (View) activity.getRootView().getParent();
- final View grandpa2 = (View) grandpa1.getParent();
- final View decorView = (View) grandpa2.getParent();
+ final View grandpa1 = activity.getGrandParent();
+ final View grandpa2 = activity.getGrandGrandParent();
+ final View decorView = activity.getDecorView();
assertViewAppeared(events, 4, activity.getRootView(), grandpa1.getAutofillId());
assertViewAppeared(events, 5, grandpa1, grandpa2.getAutofillId());
@@ -352,17 +342,15 @@
assertViewsOptionallyDisappeared(events, minEvents,
rootId,
- grandpa1.getAutofillId(), grandpa2.getAutofillId(),
- // decorView.getAutofillId(), // TODO(b/122315042): figure out why it's not
- // generated
+ grandpa1.getAutofillId(),
+ grandpa2.getAutofillId(),
activity.mUsernameLabel.getAutofillId(), activity.mUsername.getAutofillId(),
activity.mPasswordLabel.getAutofillId(), activity.mPassword.getAutofillId()
);
-
}
@Test
- public void testSimpleLifecycle_flagSecure() throws Exception {
+ public void testDisabledByFlagSecure() throws Exception {
final CtsContentCaptureService service = enableService();
final ActivityWatcher watcher = startWatcher();
@@ -376,6 +364,8 @@
watcher.waitFor(DESTROYED);
final Session session = service.getOnlyFinishedSession();
+ assertThat((session.context.getFlags()
+ & ContentCaptureContext.FLAG_DISABLED_BY_FLAG_SECURE) != 0).isTrue();
final ContentCaptureSessionId sessionId = session.id;
Log.v(TAG, "session id: " + sessionId);
@@ -385,6 +375,191 @@
assertThat(events).isEmpty();
}
+ @Test
+ public void testDisabledByApp() throws Exception {
+ final CtsContentCaptureService service = enableService();
+ final ActivityWatcher watcher = startWatcher();
+
+ LoginActivity.onRootView((activity, rootView) -> activity.getContentCaptureManager()
+ .setContentCaptureEnabled(false));
+
+ final LoginActivity activity = launchActivity();
+ watcher.waitFor(RESUMED);
+
+ activity.syncRunOnUiThread(() -> activity.mUsername.setText("D'OH"));
+
+ activity.finish();
+ watcher.waitFor(DESTROYED);
+
+ final Session session = service.getOnlyFinishedSession();
+ assertThat((session.context.getFlags()
+ & ContentCaptureContext.FLAG_DISABLED_BY_APP) != 0).isTrue();
+ final ContentCaptureSessionId sessionId = session.id;
+ Log.v(TAG, "session id: " + sessionId);
+
+ assertRightActivity(session, sessionId, activity);
+
+ final List<ContentCaptureEvent> events = session.getEvents();
+ assertThat(events).isEmpty();
+ }
+
+ @Test
+ public void testDisabledFlagSecureAndByApp() throws Exception {
+ final CtsContentCaptureService service = enableService();
+ final ActivityWatcher watcher = startWatcher();
+
+ LoginActivity.onRootView((activity, rootView) -> {
+ activity.getContentCaptureManager().setContentCaptureEnabled(false);
+ activity.getWindow().addFlags(WindowManager.LayoutParams.FLAG_SECURE);
+ });
+
+ final LoginActivity activity = launchActivity();
+ watcher.waitFor(RESUMED);
+
+ activity.syncRunOnUiThread(() -> activity.mUsername.setText("D'OH"));
+
+ activity.finish();
+ watcher.waitFor(DESTROYED);
+
+ final Session session = service.getOnlyFinishedSession();
+ assertThat((session.context.getFlags()
+ & ContentCaptureContext.FLAG_DISABLED_BY_APP) != 0).isTrue();
+ assertThat((session.context.getFlags()
+ & ContentCaptureContext.FLAG_DISABLED_BY_FLAG_SECURE) != 0).isTrue();
+ final ContentCaptureSessionId sessionId = session.id;
+ Log.v(TAG, "session id: " + sessionId);
+
+ assertRightActivity(session, sessionId, activity);
+
+ final List<ContentCaptureEvent> events = session.getEvents();
+ assertThat(events).isEmpty();
+ }
+
+ @Ignore("not implemented yet, pending on b/122595322")
+ @Test
+ public void testDisabledByFlagSecureAndService() throws Exception {
+ final CtsContentCaptureService service = enableService();
+ final ActivityWatcher watcher = startWatcher();
+
+ LoginActivity.onRootView((activity, rootView) -> activity.getWindow()
+ .addFlags(WindowManager.LayoutParams.FLAG_SECURE));
+
+ // Disable activity
+ service.setActivityContentCaptureEnabled(componentNameFor(LoginActivity.class), false);
+
+ final LoginActivity activity = launchActivity();
+ watcher.waitFor(RESUMED);
+
+ activity.finish();
+ watcher.waitFor(DESTROYED);
+
+ final List<ContentCaptureSessionId> sessionIds = service.getAllSessionIds();
+ assertThat(sessionIds).isEmpty();
+ }
+
+ @Ignore("not implemented yet, pending on b/122595322")
+ @Test
+ public void testDisabledByAppAndAndService() throws Exception {
+ final CtsContentCaptureService service = enableService();
+ final ActivityWatcher watcher = startWatcher();
+
+ LoginActivity.onRootView((activity, rootView) -> activity.getContentCaptureManager()
+ .setContentCaptureEnabled(false));
+
+ // Disable activity
+ service.setActivityContentCaptureEnabled(componentNameFor(LoginActivity.class), false);
+
+ final LoginActivity activity = launchActivity();
+ watcher.waitFor(RESUMED);
+
+ activity.finish();
+ watcher.waitFor(DESTROYED);
+
+ final List<ContentCaptureSessionId> sessionIds = service.getAllSessionIds();
+ }
+
+ @Test
+ public void testUserDataRemovalRequest_forEverything() throws Exception {
+ final CtsContentCaptureService service = enableService();
+ final ActivityWatcher watcher = startWatcher();
+
+ LoginActivity.onRootView((activity, rootView) -> activity.getContentCaptureManager()
+ .removeUserData(new UserDataRemovalRequest.Builder().forEverything()
+ .build()));
+
+ final LoginActivity activity = launchActivity();
+ watcher.waitFor(RESUMED);
+
+ activity.finish();
+ watcher.waitFor(DESTROYED);
+
+ UserDataRemovalRequest request = service.getRemovalRequest();
+ assertThat(request).isNotNull();
+ assertThat(request.isForEverything()).isTrue();
+ assertThat(request.getUriRequests()).isNull();
+ assertThat(request.getPackageName()).isEqualTo(MY_PACKAGE);
+ }
+
+ @Test
+ public void testUserDataRemovalRequest_oneUri() throws Exception {
+ final CtsContentCaptureService service = enableService();
+ final ActivityWatcher watcher = startWatcher();
+
+ Uri uri = Uri.parse("com.example");
+
+ LoginActivity.onRootView((activity, rootView) -> activity.getContentCaptureManager()
+ .removeUserData(new UserDataRemovalRequest.Builder()
+ .addUri(uri, false)
+ .build()));
+
+ final LoginActivity activity = launchActivity();
+ watcher.waitFor(RESUMED);
+
+ activity.finish();
+ watcher.waitFor(DESTROYED);
+
+ UserDataRemovalRequest request = service.getRemovalRequest();
+ assertThat(request).isNotNull();
+ assertThat(request.isForEverything()).isFalse();
+
+ List<UserDataRemovalRequest.UriRequest> requests = request.getUriRequests();
+ assertThat(requests.size()).isEqualTo(1);
+ assertThat(requests.stream().map((r) -> r.getUri()).collect(Collectors.toList()))
+ .containsExactly(uri).inOrder();
+ assertThat(request.getPackageName()).isEqualTo(MY_PACKAGE);
+ }
+
+ @Test
+ public void testUserDataRemovalRequest_manyUris() throws Exception {
+ final CtsContentCaptureService service = enableService();
+ final ActivityWatcher watcher = startWatcher();
+
+ Uri uri = Uri.parse("com.example");
+ Uri uri2 = Uri.parse("com.example2");
+
+ LoginActivity.onRootView((activity, rootView) -> activity.getContentCaptureManager()
+ .removeUserData(new UserDataRemovalRequest.Builder()
+ .addUri(uri, false)
+ .addUri(uri2, false)
+ .build()));
+
+ final LoginActivity activity = launchActivity();
+ watcher.waitFor(RESUMED);
+
+ activity.finish();
+ watcher.waitFor(DESTROYED);
+
+ UserDataRemovalRequest request = service.getRemovalRequest();
+ assertThat(request).isNotNull();
+ assertThat(request.isForEverything()).isFalse();
+
+ List<UserDataRemovalRequest.UriRequest> requests = request.getUriRequests();
+ assertThat(requests.size()).isEqualTo(2);
+ assertThat(requests.stream().map((r) -> r.getUri()).collect(Collectors.toList()))
+ .containsExactly(uri, uri2).inOrder();
+ assertThat(request.getPackageName()).isEqualTo(MY_PACKAGE);
+ }
+
// TODO(b/119638528): add moar test cases for different sessions:
// - session1 on rootView, session2 on children
// - session1 on rootView, session2 on child1, session3 on child2
diff --git a/tests/contentcaptureservice/src/android/contentcaptureservice/cts/common/ActivitiesWatcher.java b/tests/contentcaptureservice/src/android/contentcaptureservice/cts/common/ActivitiesWatcher.java
index 382e925..38a6509 100644
--- a/tests/contentcaptureservice/src/android/contentcaptureservice/cts/common/ActivitiesWatcher.java
+++ b/tests/contentcaptureservice/src/android/contentcaptureservice/cts/common/ActivitiesWatcher.java
@@ -101,6 +101,11 @@
return watch(clazz.getName());
}
+ @Override
+ public String toString() {
+ return "[ActivitiesWatcher: activities=" + mWatchers.keySet() + "]";
+ }
+
/**
* Gets a watcher for the given activity.
*
diff --git a/tests/contentcaptureservice/src/android/contentcaptureservice/cts/common/ActivityLauncher.java b/tests/contentcaptureservice/src/android/contentcaptureservice/cts/common/ActivityLauncher.java
new file mode 100644
index 0000000..d844894
--- /dev/null
+++ b/tests/contentcaptureservice/src/android/contentcaptureservice/cts/common/ActivityLauncher.java
@@ -0,0 +1,51 @@
+/*
+ * Copyright (C) 2019 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.contentcaptureservice.cts.common;
+
+import android.app.Activity;
+import android.content.Context;
+import android.content.Intent;
+import android.contentcaptureservice.cts.common.ActivitiesWatcher.ActivityWatcher;
+import android.support.test.rule.ActivityTestRule;
+
+import androidx.annotation.NonNull;
+
+/**
+ * Helper used to launch an activity and watch for its lifecycle events.
+ */
+public final class ActivityLauncher<A extends Activity> {
+
+ private final ActivityWatcher mWatcher;
+ private final ActivityTestRule<A> mActivityTestRule;
+ private final Intent mLaunchIntent;
+
+ public ActivityLauncher(@NonNull Context context, @NonNull ActivitiesWatcher watcher,
+ @NonNull Class<A> activityClass) {
+ mWatcher = watcher.watch(activityClass);
+ mActivityTestRule = new ActivityTestRule<>(activityClass);
+ mLaunchIntent = new Intent(context, activityClass);
+ }
+
+ @NonNull
+ public ActivityWatcher getWatcher() {
+ return mWatcher;
+ }
+
+ @NonNull
+ public A launchActivity() {
+ return mActivityTestRule.launchActivity(mLaunchIntent);
+ }
+}
diff --git a/tests/framework/base/activitymanager/Android.mk b/tests/framework/base/activitymanager/Android.mk
index 498f0a3..28f6753 100644
--- a/tests/framework/base/activitymanager/Android.mk
+++ b/tests/framework/base/activitymanager/Android.mk
@@ -42,10 +42,13 @@
CtsMockInputMethodLib \
metrics-helper-lib
+LOCAL_ASSET_DIR := $(LOCAL_PATH)/intent_tests
+
LOCAL_CTS_TEST_PACKAGE := android.server
# Tag this module as a cts test artifact
LOCAL_COMPATIBILITY_SUITE := cts vts general-tests
+LOCAL_CERTIFICATE := platform
include $(BUILD_CTS_PACKAGE)
diff --git a/tests/framework/base/activitymanager/AndroidManifest.xml b/tests/framework/base/activitymanager/AndroidManifest.xml
index 8b55608..62cebb6 100644
--- a/tests/framework/base/activitymanager/AndroidManifest.xml
+++ b/tests/framework/base/activitymanager/AndroidManifest.xml
@@ -20,6 +20,9 @@
<uses-permission android:name="android.permission.READ_LOGS" />
<uses-permission android:name="android.permission.REQUEST_DELETE_PACKAGES" />
<uses-permission android:name="android.permission.DISABLE_KEYGUARD" />
+ <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
+ <uses-permission android:name="android.permission.INJECT_EVENTS" />
+ <uses-permission android:name="android.permission.MANAGE_ACTIVITY_STACKS"/>
<application android:label="CtsActivityManagerDeviceTestCases">
<uses-library android:name="android.test.runner" />
@@ -77,6 +80,8 @@
<activity android:name="android.server.am.lifecycle.ActivityLifecycleClientTestBase$SecondActivity"/>
+ <activity android:name="android.server.am.lifecycle.ActivityLifecycleClientTestBase$ThirdActivity"/>
+
<activity
android:name="android.server.am.lifecycle.ActivityLifecycleClientTestBase$TranslucentActivity"
android:theme="@android:style/Theme.Translucent.NoTitleBar" />
@@ -97,12 +102,18 @@
<activity android:name="android.server.am.lifecycle.ActivityLifecycleClientTestBase$ConfigChangeHandlingActivity"
android:configChanges="orientation|screenSize|smallestScreenSize|screenLayout|colorMode|density" />
+ <activity android:name="android.server.am.lifecycle.ActivityLifecycleClientTestBase$PipActivity"
+ android:configChanges="orientation|screenSize|smallestScreenSize|screenLayout"
+ android:supportsPictureInPicture="true"/>
+
<activity android:name="android.server.am.StartActivityTests$TestActivity2" />
<activity android:name="android.server.am.ActivityManagerMultiDisplayTests$ImeTestActivity" />
<activity android:name="android.server.am.ActivityManagerMultiDisplayTests$ImeTestActivity2" />
<activity android:name="android.server.am.ActivityManagerMultiDisplayTests$ImeTestActivityWithBrokenContextWrapper" />
+ <activity android:name="android.server.am.KeyguardLockedTests$ShowWhenLockedImeActivity" />
+
<activity android:name="android.server.am.lifecycle.ActivityStarterTests$StandardActivity"
android:exported="true" />
@@ -128,10 +139,81 @@
android:taskAffinity="nobody.but.LaunchingActivity"
android:exported="true" />
+ <activity android:name="android.server.am.ActivityViewTest$ActivityViewTestActivity"
+ android:exported="true"/>
+
<provider
android:name="android.server.am.TestJournalProvider"
android:authorities="android.server.am.testjournalprovider"
android:exported="true" />
+
+ <!--intent tests-->
+ <activity android:name="android.server.am.intent.Activities$RegularActivity"/>
+ <activity
+ android:name="android.server.am.intent.Activities$SingleTopActivity"
+ android:launchMode="singleTop"/>
+ <activity
+ android:name="android.server.am.intent.Activities$SingleInstanceActivity"
+ android:launchMode="singleInstance"/>
+ <activity
+ android:name="android.server.am.intent.Activities$SingleInstanceActivity2"
+ android:launchMode="singleInstance"
+ android:taskAffinity=".t1"
+ />
+ <activity
+ android:name="android.server.am.intent.Activities$SingleTaskActivity"
+ android:launchMode="singleTask"
+ />
+ <activity
+ android:name="android.server.am.intent.Activities$SingleTaskActivity2"
+ android:launchMode="singleTask"
+ android:taskAffinity=".t1"
+ />
+ <activity
+ android:name="android.server.am.intent.Activities$TaskAffinity1Activity"
+ android:allowTaskReparenting="true"
+ android:launchMode="standard"
+ android:taskAffinity=".t1"/>
+ <activity
+ android:name="android.server.am.intent.Activities$TaskAffinity1Activity2"
+ android:allowTaskReparenting="true"
+ android:launchMode="standard"
+ android:taskAffinity=".t1"/>
+ <activity
+ android:name="android.server.am.intent.Activities$TaskAffinity2Activity"
+ android:allowTaskReparenting="true"
+ android:launchMode="standard"
+ android:taskAffinity=".t2"/>
+ <activity
+ android:name="android.server.am.intent.Activities$TaskAffinity3Activity"
+ android:allowTaskReparenting="true"
+ android:launchMode="standard"
+ android:taskAffinity=".t3"/>
+ <activity
+ android:name="android.server.am.intent.Activities$ClearTaskOnLaunchActivity"
+ android:allowTaskReparenting="true"
+ android:clearTaskOnLaunch="true"
+ android:launchMode="standard"
+ android:taskAffinity=".t2"/>
+ <activity
+ android:name="android.server.am.intent.Activities$DocumentLaunchIntoActivity"
+ android:documentLaunchMode="intoExisting"/>
+ <activity
+ android:name="android.server.am.intent.Activities$DocumentLaunchAlwaysActivity"
+ android:documentLaunchMode="always"/>
+ <activity
+ android:name="android.server.am.intent.Activities$DocumentLaunchNeverActivity"
+ android:documentLaunchMode="never"/>
+ <activity
+ android:name="android.server.am.intent.Activities$NoHistoryActivity"
+ android:noHistory="true"/>
+ <activity
+ android:name="android.server.am.intent.Activities$LauncherActivity"
+ android:documentLaunchMode="always"
+ android:launchMode="singleInstance">
+ </activity>
+
+
</application>
<instrumentation
diff --git a/tests/framework/base/activitymanager/app/AndroidManifest.xml b/tests/framework/base/activitymanager/app/AndroidManifest.xml
index 475f6f8..be557e0 100755
--- a/tests/framework/base/activitymanager/app/AndroidManifest.xml
+++ b/tests/framework/base/activitymanager/app/AndroidManifest.xml
@@ -47,6 +47,10 @@
android:resizeableActivity="true"
android:exported="true"
/>
+ <activity-alias android:name=".AliasTestActivity"
+ android:exported="true"
+ android:targetActivity=".TestActivity"
+ />
<activity android:name=".ResumeWhilePausingActivity"
android:allowEmbedded="true"
android:resumeWhilePausing="true"
@@ -179,10 +183,10 @@
android:resizeableActivity="true"
android:configChanges="orientation|screenSize|smallestScreenSize|screenLayout"
android:exported="true">
- <layout android:defaultWidth="25%"
- android:defaultHeight="35%"
+ <layout android:defaultWidth="50%"
+ android:defaultHeight="70%"
android:gravity="top|right"
- android:minWidth="90dp"
+ android:minWidth="50dp"
android:minHeight="80dp"
/>
</activity>
@@ -190,10 +194,10 @@
android:resizeableActivity="true"
android:configChanges="orientation|screenSize|smallestScreenSize|screenLayout"
android:exported="true">
- <layout android:defaultWidth="25%"
- android:defaultHeight="35%"
+ <layout android:defaultWidth="50%"
+ android:defaultHeight="70%"
android:gravity="bottom|left"
- android:minWidth="90dp"
+ android:minWidth="50dp"
android:minHeight="80dp"
/>
</activity>
@@ -379,6 +383,24 @@
android:showWhenLocked="true"
android:exported="true" />
+ <activity android:name=".InheritShowWhenLockedAddActivity"
+ android:exported="true" />
+
+ <activity android:name=".InheritShowWhenLockedAttrActivity"
+ android:inheritShowWhenLocked="true"
+ android:exported="true" />
+
+ <activity android:name=".InheritShowWhenLockedRemoveActivity"
+ android:inheritShowWhenLocked="true"
+ android:exported="true" />
+
+ <activity android:name=".NoInheritShowWhenLockedAttrActivity"
+ android:exported="true" />
+
+ <activity android:name=".ShowWhenLockedAttrImeActivity"
+ android:showWhenLocked="true"
+ android:exported="true" />
+
<activity android:name=".ToastActivity"
android:exported="true"/>
diff --git a/tests/framework/base/activitymanager/app/src/android/server/am/Components.java b/tests/framework/base/activitymanager/app/src/android/server/am/Components.java
index 05cc88c..e504766 100644
--- a/tests/framework/base/activitymanager/app/src/android/server/am/Components.java
+++ b/tests/framework/base/activitymanager/app/src/android/server/am/Components.java
@@ -84,10 +84,20 @@
component("ResumeWhilePausingActivity");
public static final ComponentName SHOW_WHEN_LOCKED_ACTIVITY =
component("ShowWhenLockedActivity");
+ public static final ComponentName SHOW_WHEN_LOCKED_ATTR_IME_ACTIVITY =
+ component("ShowWhenLockedAttrImeActivity");
public static final ComponentName SHOW_WHEN_LOCKED_ATTR_ACTIVITY =
component("ShowWhenLockedAttrActivity");
public static final ComponentName SHOW_WHEN_LOCKED_ATTR_REMOVE_ATTR_ACTIVITY =
component("ShowWhenLockedAttrRemoveAttrActivity");
+ public static final ComponentName INHERIT_SHOW_WHEN_LOCKED_ADD_ACTIVITY =
+ component("InheritShowWhenLockedAddActivity");
+ public static final ComponentName INHERIT_SHOW_WHEN_LOCKED_ATTR_ACTIVITY =
+ component("InheritShowWhenLockedAttrActivity");
+ public static final ComponentName INHERIT_SHOW_WHEN_LOCKED_REMOVE_ACTIVITY =
+ component("InheritShowWhenLockedRemoveActivity");
+ public static final ComponentName NO_INHERIT_SHOW_WHEN_LOCKED_ATTR_ACTIVITY =
+ component("NoInheritShowWhenLockedAttrActivity");
public static final ComponentName SHOW_WHEN_LOCKED_DIALOG_ACTIVITY =
component("ShowWhenLockedDialogActivity");
public static final ComponentName SHOW_WHEN_LOCKED_TRANSLUCENT_ACTIVITY =
@@ -138,6 +148,7 @@
public static final ComponentName WALLPAPAER_ACTIVITY = component("WallpaperActivity");
public static final ComponentName LAUNCH_TEST_ON_DESTROY_ACTIVITY = component(
"LaunchTestOnDestroyActivity");
+ public static final ComponentName ALIAS_TEST_ACTIVITY = component("AliasTestActivity");
public static final ComponentName ASSISTANT_VOICE_INTERACTION_SERVICE =
component("AssistantVoiceInteractionService");
diff --git a/tests/framework/base/activitymanager/app/src/android/server/am/InheritShowWhenLockedAddActivity.java b/tests/framework/base/activitymanager/app/src/android/server/am/InheritShowWhenLockedAddActivity.java
new file mode 100644
index 0000000..26fdfa0
--- /dev/null
+++ b/tests/framework/base/activitymanager/app/src/android/server/am/InheritShowWhenLockedAddActivity.java
@@ -0,0 +1,29 @@
+/*
+ * Copyright (C) 2019 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.server.am;
+
+import android.Manifest;
+import android.app.Activity;
+import android.os.Bundle;
+
+public class InheritShowWhenLockedAddActivity extends Activity {
+ @Override
+ protected void onCreate(Bundle savedInstance) {
+ super.onCreate(savedInstance);
+ setInheritShowWhenLocked(true);
+ }
+}
diff --git a/tests/framework/base/activitymanager/app/src/android/server/am/InheritShowWhenLockedAttrActivity.java b/tests/framework/base/activitymanager/app/src/android/server/am/InheritShowWhenLockedAttrActivity.java
new file mode 100644
index 0000000..630055c
--- /dev/null
+++ b/tests/framework/base/activitymanager/app/src/android/server/am/InheritShowWhenLockedAttrActivity.java
@@ -0,0 +1,23 @@
+/*
+ * Copyright (C) 2019 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.server.am;
+
+import android.Manifest;
+import android.app.Activity;
+
+public class InheritShowWhenLockedAttrActivity extends Activity {
+}
diff --git a/tests/framework/base/activitymanager/app/src/android/server/am/InheritShowWhenLockedRemoveActivity.java b/tests/framework/base/activitymanager/app/src/android/server/am/InheritShowWhenLockedRemoveActivity.java
new file mode 100644
index 0000000..22e65c3
--- /dev/null
+++ b/tests/framework/base/activitymanager/app/src/android/server/am/InheritShowWhenLockedRemoveActivity.java
@@ -0,0 +1,29 @@
+/*
+ * Copyright (C) 2019 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.server.am;
+
+import android.Manifest;
+import android.app.Activity;
+import android.os.Bundle;
+
+public class InheritShowWhenLockedRemoveActivity extends Activity {
+ @Override
+ protected void onCreate(Bundle savedInstance) {
+ super.onCreate(savedInstance);
+ setInheritShowWhenLocked(false);
+ }
+}
diff --git a/tests/framework/base/activitymanager/app/src/android/server/am/NoInheritShowWhenLockedAttrActivity.java b/tests/framework/base/activitymanager/app/src/android/server/am/NoInheritShowWhenLockedAttrActivity.java
new file mode 100644
index 0000000..eaeed61
--- /dev/null
+++ b/tests/framework/base/activitymanager/app/src/android/server/am/NoInheritShowWhenLockedAttrActivity.java
@@ -0,0 +1,23 @@
+/*
+ * Copyright (C) 2019 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.server.am;
+
+import android.Manifest;
+import android.app.Activity;
+
+public class NoInheritShowWhenLockedAttrActivity extends Activity {
+}
diff --git a/tests/framework/base/activitymanager/app/src/android/server/am/ShowWhenLockedAttrImeActivity.java b/tests/framework/base/activitymanager/app/src/android/server/am/ShowWhenLockedAttrImeActivity.java
new file mode 100644
index 0000000..7bae38b
--- /dev/null
+++ b/tests/framework/base/activitymanager/app/src/android/server/am/ShowWhenLockedAttrImeActivity.java
@@ -0,0 +1,40 @@
+/*
+ * Copyright (C) 2019 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.server.am;
+
+import static android.view.WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_VISIBLE;
+
+import android.os.Bundle;
+import android.widget.EditText;
+import android.widget.LinearLayout;
+
+public class ShowWhenLockedAttrImeActivity extends AbstractLifecycleLogActivity {
+
+ @Override
+ protected void onCreate(Bundle icicle) {
+ super.onCreate(icicle);
+
+ final EditText editText = new EditText(this);
+ final LinearLayout layout = new LinearLayout(this);
+ layout.setOrientation(LinearLayout.VERTICAL);
+ layout.addView(editText);
+ setContentView(layout);
+
+ getWindow().setSoftInputMode(SOFT_INPUT_STATE_ALWAYS_VISIBLE);
+ editText.requestFocus();
+ }
+}
diff --git a/tests/framework/base/activitymanager/intent_tests/clearCases/test-1.json b/tests/framework/base/activitymanager/intent_tests/clearCases/test-1.json
new file mode 100644
index 0000000..a474887
--- /dev/null
+++ b/tests/framework/base/activitymanager/intent_tests/clearCases/test-1.json
@@ -0,0 +1,54 @@
+{
+ "setup": {
+ "initialIntents": [
+ {
+ "flags": "FLAG_ACTIVITY_NEW_TASK",
+ "class": "android.server.am.intent.Activities$RegularActivity",
+ "package": "android.server.cts.am",
+ "startForResult": false
+ }
+ ],
+ "act": [
+ {
+ "flags": "FLAG_ACTIVITY_CLEAR_TOP",
+ "class": "android.server.am.intent.Activities$RegularActivity",
+ "package": "android.server.cts.am",
+ "startForResult": false
+ }
+ ]
+ },
+ "initialState": {
+ "stacks": [
+ {
+ "tasks": [
+ {
+ "activities": [
+ {
+ "name": "android.server.cts.am\/android.server.am.intent.Activities$RegularActivity",
+ "state": "RESUMED"
+ }
+ ]
+ }
+ ],
+ "resumedActivity": "android.server.cts.am\/android.server.am.intent.Activities$RegularActivity"
+ }
+ ]
+ },
+ "endState": {
+ "stacks": [
+ {
+ "tasks": [
+ {
+ "activities": [
+ {
+ "name": "android.server.cts.am\/android.server.am.intent.Activities$RegularActivity",
+ "state": "RESUMED"
+ }
+ ]
+ }
+ ],
+ "resumedActivity": "android.server.cts.am\/android.server.am.intent.Activities$RegularActivity"
+ }
+ ]
+ }
+}
diff --git a/tests/framework/base/activitymanager/intent_tests/clearCases/test-2.json b/tests/framework/base/activitymanager/intent_tests/clearCases/test-2.json
new file mode 100644
index 0000000..26d5a9c
--- /dev/null
+++ b/tests/framework/base/activitymanager/intent_tests/clearCases/test-2.json
@@ -0,0 +1,68 @@
+{
+ "setup": {
+ "initialIntents": [
+ {
+ "flags": "FLAG_ACTIVITY_NEW_TASK",
+ "class": "android.server.am.intent.Activities$RegularActivity",
+ "package": "android.server.cts.am",
+ "startForResult": false
+ },
+ {
+ "flags": "",
+ "class": "android.server.am.intent.Activities$RegularActivity",
+ "package": "android.server.cts.am",
+ "startForResult": false
+ }
+ ],
+ "act": [
+ {
+ "flags": "FLAG_ACTIVITY_CLEAR_TOP",
+ "class": "android.server.am.intent.Activities$RegularActivity",
+ "package": "android.server.cts.am",
+ "startForResult": false
+ }
+ ]
+ },
+ "initialState": {
+ "stacks": [
+ {
+ "tasks": [
+ {
+ "activities": [
+ {
+ "name": "android.server.cts.am\/android.server.am.intent.Activities$RegularActivity",
+ "state": "RESUMED"
+ },
+ {
+ "name": "android.server.cts.am\/android.server.am.intent.Activities$RegularActivity",
+ "state": "STOPPED"
+ }
+ ]
+ }
+ ],
+ "resumedActivity": "android.server.cts.am\/android.server.am.intent.Activities$RegularActivity"
+ }
+ ]
+ },
+ "endState": {
+ "stacks": [
+ {
+ "tasks": [
+ {
+ "activities": [
+ {
+ "name": "android.server.cts.am\/android.server.am.intent.Activities$RegularActivity",
+ "state": "RESUMED"
+ },
+ {
+ "name": "android.server.cts.am\/android.server.am.intent.Activities$RegularActivity",
+ "state": "STOPPED"
+ }
+ ]
+ }
+ ],
+ "resumedActivity": "android.server.cts.am\/android.server.am.intent.Activities$RegularActivity"
+ }
+ ]
+ }
+}
diff --git a/tests/framework/base/activitymanager/intent_tests/clearCases/test-3.json b/tests/framework/base/activitymanager/intent_tests/clearCases/test-3.json
new file mode 100644
index 0000000..8e7fdf1
--- /dev/null
+++ b/tests/framework/base/activitymanager/intent_tests/clearCases/test-3.json
@@ -0,0 +1,64 @@
+{
+ "setup": {
+ "initialIntents": [
+ {
+ "flags": "FLAG_ACTIVITY_NEW_TASK",
+ "class": "android.server.am.intent.Activities$RegularActivity",
+ "package": "android.server.cts.am",
+ "startForResult": false
+ },
+ {
+ "flags": "",
+ "class": "android.server.am.intent.Activities$RegularActivity",
+ "package": "android.server.cts.am",
+ "startForResult": false
+ }
+ ],
+ "act": [
+ {
+ "flags": "FLAG_ACTIVITY_CLEAR_TOP | FLAG_ACTIVITY_NEW_TASK",
+ "class": "android.server.am.intent.Activities$RegularActivity",
+ "package": "android.server.cts.am",
+ "startForResult": false
+ }
+ ]
+ },
+ "initialState": {
+ "stacks": [
+ {
+ "tasks": [
+ {
+ "activities": [
+ {
+ "name": "android.server.cts.am\/android.server.am.intent.Activities$RegularActivity",
+ "state": "RESUMED"
+ },
+ {
+ "name": "android.server.cts.am\/android.server.am.intent.Activities$RegularActivity",
+ "state": "STOPPED"
+ }
+ ]
+ }
+ ],
+ "resumedActivity": "android.server.cts.am\/android.server.am.intent.Activities$RegularActivity"
+ }
+ ]
+ },
+ "endState": {
+ "stacks": [
+ {
+ "tasks": [
+ {
+ "activities": [
+ {
+ "name": "android.server.cts.am\/android.server.am.intent.Activities$RegularActivity",
+ "state": "RESUMED"
+ }
+ ]
+ }
+ ],
+ "resumedActivity": "android.server.cts.am\/android.server.am.intent.Activities$RegularActivity"
+ }
+ ]
+ }
+}
diff --git a/tests/framework/base/activitymanager/intent_tests/clearCases/test-4.json b/tests/framework/base/activitymanager/intent_tests/clearCases/test-4.json
new file mode 100644
index 0000000..96e6d50
--- /dev/null
+++ b/tests/framework/base/activitymanager/intent_tests/clearCases/test-4.json
@@ -0,0 +1,68 @@
+{
+ "setup": {
+ "initialIntents": [
+ {
+ "flags": "FLAG_ACTIVITY_NEW_TASK",
+ "class": "android.server.am.intent.Activities$RegularActivity",
+ "package": "android.server.cts.am",
+ "startForResult": false
+ },
+ {
+ "flags": "",
+ "class": "android.server.am.intent.Activities$RegularActivity",
+ "package": "android.server.cts.am",
+ "startForResult": false
+ }
+ ],
+ "act": [
+ {
+ "flags": "FLAG_ACTIVITY_CLEAR_TOP | FLAG_ACTIVITY_NEW_DOCUMENT",
+ "class": "android.server.am.intent.Activities$RegularActivity",
+ "package": "android.server.cts.am",
+ "startForResult": false
+ }
+ ]
+ },
+ "initialState": {
+ "stacks": [
+ {
+ "tasks": [
+ {
+ "activities": [
+ {
+ "name": "android.server.cts.am\/android.server.am.intent.Activities$RegularActivity",
+ "state": "RESUMED"
+ },
+ {
+ "name": "android.server.cts.am\/android.server.am.intent.Activities$RegularActivity",
+ "state": "STOPPED"
+ }
+ ]
+ }
+ ],
+ "resumedActivity": "android.server.cts.am\/android.server.am.intent.Activities$RegularActivity"
+ }
+ ]
+ },
+ "endState": {
+ "stacks": [
+ {
+ "tasks": [
+ {
+ "activities": [
+ {
+ "name": "android.server.cts.am\/android.server.am.intent.Activities$RegularActivity",
+ "state": "RESUMED"
+ },
+ {
+ "name": "android.server.cts.am\/android.server.am.intent.Activities$RegularActivity",
+ "state": "STOPPED"
+ }
+ ]
+ }
+ ],
+ "resumedActivity": "android.server.cts.am\/android.server.am.intent.Activities$RegularActivity"
+ }
+ ]
+ }
+}
diff --git a/tests/framework/base/activitymanager/intent_tests/clearCases/test-5.json b/tests/framework/base/activitymanager/intent_tests/clearCases/test-5.json
new file mode 100644
index 0000000..185762f
--- /dev/null
+++ b/tests/framework/base/activitymanager/intent_tests/clearCases/test-5.json
@@ -0,0 +1,68 @@
+{
+ "setup": {
+ "initialIntents": [
+ {
+ "flags": "FLAG_ACTIVITY_NEW_TASK",
+ "class": "android.server.am.intent.Activities$RegularActivity",
+ "package": "android.server.cts.am",
+ "startForResult": false
+ },
+ {
+ "flags": "",
+ "class": "android.server.am.intent.Activities$RegularActivity",
+ "package": "android.server.cts.am",
+ "startForResult": false
+ }
+ ],
+ "act": [
+ {
+ "flags": "FLAG_ACTIVITY_CLEAR_TOP | FLAG_ACTIVITY_PREVIOUS_IS_TOP",
+ "class": "android.server.am.intent.Activities$RegularActivity",
+ "package": "android.server.cts.am",
+ "startForResult": false
+ }
+ ]
+ },
+ "initialState": {
+ "stacks": [
+ {
+ "tasks": [
+ {
+ "activities": [
+ {
+ "name": "android.server.cts.am\/android.server.am.intent.Activities$RegularActivity",
+ "state": "RESUMED"
+ },
+ {
+ "name": "android.server.cts.am\/android.server.am.intent.Activities$RegularActivity",
+ "state": "STOPPED"
+ }
+ ]
+ }
+ ],
+ "resumedActivity": "android.server.cts.am\/android.server.am.intent.Activities$RegularActivity"
+ }
+ ]
+ },
+ "endState": {
+ "stacks": [
+ {
+ "tasks": [
+ {
+ "activities": [
+ {
+ "name": "android.server.cts.am\/android.server.am.intent.Activities$RegularActivity",
+ "state": "RESUMED"
+ },
+ {
+ "name": "android.server.cts.am\/android.server.am.intent.Activities$RegularActivity",
+ "state": "STOPPED"
+ }
+ ]
+ }
+ ],
+ "resumedActivity": "android.server.cts.am\/android.server.am.intent.Activities$RegularActivity"
+ }
+ ]
+ }
+}
diff --git a/tests/framework/base/activitymanager/intent_tests/clearCases/test-6.json b/tests/framework/base/activitymanager/intent_tests/clearCases/test-6.json
new file mode 100644
index 0000000..9e70f30
--- /dev/null
+++ b/tests/framework/base/activitymanager/intent_tests/clearCases/test-6.json
@@ -0,0 +1,78 @@
+{
+ "setup": {
+ "initialIntents": [
+ {
+ "flags": "FLAG_ACTIVITY_NEW_TASK",
+ "class": "android.server.am.intent.Activities$RegularActivity",
+ "package": "android.server.cts.am",
+ "startForResult": false
+ },
+ {
+ "flags": "",
+ "class": "android.server.am.intent.Activities$TaskAffinity1Activity",
+ "package": "android.server.cts.am",
+ "startForResult": false
+ },
+ {
+ "flags": "",
+ "class": "android.server.am.intent.Activities$RegularActivity",
+ "package": "android.server.cts.am",
+ "startForResult": false
+ }
+ ],
+ "act": [
+ {
+ "flags": "FLAG_ACTIVITY_CLEAR_TOP",
+ "class": "android.server.am.intent.Activities$TaskAffinity1Activity",
+ "package": "android.server.cts.am",
+ "startForResult": false
+ }
+ ]
+ },
+ "initialState": {
+ "stacks": [
+ {
+ "tasks": [
+ {
+ "activities": [
+ {
+ "name": "android.server.cts.am\/android.server.am.intent.Activities$RegularActivity",
+ "state": "RESUMED"
+ },
+ {
+ "name": "android.server.cts.am\/android.server.am.intent.Activities$TaskAffinity1Activity",
+ "state": "STOPPED"
+ },
+ {
+ "name": "android.server.cts.am\/android.server.am.intent.Activities$RegularActivity",
+ "state": "STOPPED"
+ }
+ ]
+ }
+ ],
+ "resumedActivity": "android.server.cts.am\/android.server.am.intent.Activities$RegularActivity"
+ }
+ ]
+ },
+ "endState": {
+ "stacks": [
+ {
+ "tasks": [
+ {
+ "activities": [
+ {
+ "name": "android.server.cts.am\/android.server.am.intent.Activities$TaskAffinity1Activity",
+ "state": "RESUMED"
+ },
+ {
+ "name": "android.server.cts.am\/android.server.am.intent.Activities$RegularActivity",
+ "state": "STOPPED"
+ }
+ ]
+ }
+ ],
+ "resumedActivity": "android.server.cts.am\/android.server.am.intent.Activities$TaskAffinity1Activity"
+ }
+ ]
+ }
+}
diff --git a/tests/framework/base/activitymanager/intent_tests/forResult/test-1.json b/tests/framework/base/activitymanager/intent_tests/forResult/test-1.json
new file mode 100644
index 0000000..bd1e268
--- /dev/null
+++ b/tests/framework/base/activitymanager/intent_tests/forResult/test-1.json
@@ -0,0 +1,54 @@
+{
+ "setup": {
+ "initialIntents": [
+ {
+ "flags": "FLAG_ACTIVITY_NEW_TASK",
+ "class": "android.server.am.intent.Activities$RegularActivity",
+ "package": "android.server.cts.am",
+ "startForResult": false
+ }
+ ],
+ "act": [
+ {
+ "flags": "FLAG_ACTIVITY_SINGLE_TOP",
+ "class": "android.server.am.intent.Activities$RegularActivity",
+ "package": "android.server.cts.am",
+ "startForResult": false
+ }
+ ]
+ },
+ "initialState": {
+ "stacks": [
+ {
+ "tasks": [
+ {
+ "activities": [
+ {
+ "name": "android.server.cts.am\/android.server.am.intent.Activities$RegularActivity",
+ "state": "RESUMED"
+ }
+ ]
+ }
+ ],
+ "resumedActivity": "android.server.cts.am\/android.server.am.intent.Activities$RegularActivity"
+ }
+ ]
+ },
+ "endState": {
+ "stacks": [
+ {
+ "tasks": [
+ {
+ "activities": [
+ {
+ "name": "android.server.cts.am\/android.server.am.intent.Activities$RegularActivity",
+ "state": "RESUMED"
+ }
+ ]
+ }
+ ],
+ "resumedActivity": "android.server.cts.am\/android.server.am.intent.Activities$RegularActivity"
+ }
+ ]
+ }
+}
diff --git a/tests/framework/base/activitymanager/intent_tests/forResult/test-2.json b/tests/framework/base/activitymanager/intent_tests/forResult/test-2.json
new file mode 100644
index 0000000..eddebc3
--- /dev/null
+++ b/tests/framework/base/activitymanager/intent_tests/forResult/test-2.json
@@ -0,0 +1,58 @@
+{
+ "setup": {
+ "initialIntents": [
+ {
+ "flags": "FLAG_ACTIVITY_NEW_TASK",
+ "class": "android.server.am.intent.Activities$RegularActivity",
+ "package": "android.server.cts.am",
+ "startForResult": false
+ }
+ ],
+ "act": [
+ {
+ "flags": "FLAG_ACTIVITY_SINGLE_TOP",
+ "class": "android.server.am.intent.Activities$RegularActivity",
+ "package": "android.server.cts.am",
+ "startForResult": true
+ }
+ ]
+ },
+ "initialState": {
+ "stacks": [
+ {
+ "tasks": [
+ {
+ "activities": [
+ {
+ "name": "android.server.cts.am\/android.server.am.intent.Activities$RegularActivity",
+ "state": "RESUMED"
+ }
+ ]
+ }
+ ],
+ "resumedActivity": "android.server.cts.am\/android.server.am.intent.Activities$RegularActivity"
+ }
+ ]
+ },
+ "endState": {
+ "stacks": [
+ {
+ "tasks": [
+ {
+ "activities": [
+ {
+ "name": "android.server.cts.am\/android.server.am.intent.Activities$RegularActivity",
+ "state": "RESUMED"
+ },
+ {
+ "name": "android.server.cts.am\/android.server.am.intent.Activities$RegularActivity",
+ "state": "STOPPED"
+ }
+ ]
+ }
+ ],
+ "resumedActivity": "android.server.cts.am\/android.server.am.intent.Activities$RegularActivity"
+ }
+ ]
+ }
+}
diff --git a/tests/framework/base/activitymanager/intent_tests/forResult/test-3.json b/tests/framework/base/activitymanager/intent_tests/forResult/test-3.json
new file mode 100644
index 0000000..7340ace
--- /dev/null
+++ b/tests/framework/base/activitymanager/intent_tests/forResult/test-3.json
@@ -0,0 +1,54 @@
+{
+ "setup": {
+ "initialIntents": [
+ {
+ "flags": "FLAG_ACTIVITY_NEW_TASK",
+ "class": "android.server.am.intent.Activities$SingleTopActivity",
+ "package": "android.server.cts.am",
+ "startForResult": false
+ }
+ ],
+ "act": [
+ {
+ "flags": "",
+ "class": "android.server.am.intent.Activities$SingleTopActivity",
+ "package": "android.server.cts.am",
+ "startForResult": false
+ }
+ ]
+ },
+ "initialState": {
+ "stacks": [
+ {
+ "tasks": [
+ {
+ "activities": [
+ {
+ "name": "android.server.cts.am\/android.server.am.intent.Activities$SingleTopActivity",
+ "state": "RESUMED"
+ }
+ ]
+ }
+ ],
+ "resumedActivity": "android.server.cts.am\/android.server.am.intent.Activities$SingleTopActivity"
+ }
+ ]
+ },
+ "endState": {
+ "stacks": [
+ {
+ "tasks": [
+ {
+ "activities": [
+ {
+ "name": "android.server.cts.am\/android.server.am.intent.Activities$SingleTopActivity",
+ "state": "RESUMED"
+ }
+ ]
+ }
+ ],
+ "resumedActivity": "android.server.cts.am\/android.server.am.intent.Activities$SingleTopActivity"
+ }
+ ]
+ }
+}
diff --git a/tests/framework/base/activitymanager/intent_tests/forResult/test-4.json b/tests/framework/base/activitymanager/intent_tests/forResult/test-4.json
new file mode 100644
index 0000000..feac3aa
--- /dev/null
+++ b/tests/framework/base/activitymanager/intent_tests/forResult/test-4.json
@@ -0,0 +1,58 @@
+{
+ "setup": {
+ "initialIntents": [
+ {
+ "flags": "FLAG_ACTIVITY_NEW_TASK",
+ "class": "android.server.am.intent.Activities$SingleTopActivity",
+ "package": "android.server.cts.am",
+ "startForResult": false
+ }
+ ],
+ "act": [
+ {
+ "flags": "",
+ "class": "android.server.am.intent.Activities$SingleTopActivity",
+ "package": "android.server.cts.am",
+ "startForResult": true
+ }
+ ]
+ },
+ "initialState": {
+ "stacks": [
+ {
+ "tasks": [
+ {
+ "activities": [
+ {
+ "name": "android.server.cts.am\/android.server.am.intent.Activities$SingleTopActivity",
+ "state": "RESUMED"
+ }
+ ]
+ }
+ ],
+ "resumedActivity": "android.server.cts.am\/android.server.am.intent.Activities$SingleTopActivity"
+ }
+ ]
+ },
+ "endState": {
+ "stacks": [
+ {
+ "tasks": [
+ {
+ "activities": [
+ {
+ "name": "android.server.cts.am\/android.server.am.intent.Activities$SingleTopActivity",
+ "state": "RESUMED"
+ },
+ {
+ "name": "android.server.cts.am\/android.server.am.intent.Activities$SingleTopActivity",
+ "state": "STOPPED"
+ }
+ ]
+ }
+ ],
+ "resumedActivity": "android.server.cts.am\/android.server.am.intent.Activities$SingleTopActivity"
+ }
+ ]
+ }
+}
diff --git a/tests/framework/base/activitymanager/intent_tests/forResult/test-5.json b/tests/framework/base/activitymanager/intent_tests/forResult/test-5.json
new file mode 100644
index 0000000..a474887
--- /dev/null
+++ b/tests/framework/base/activitymanager/intent_tests/forResult/test-5.json
@@ -0,0 +1,54 @@
+{
+ "setup": {
+ "initialIntents": [
+ {
+ "flags": "FLAG_ACTIVITY_NEW_TASK",
+ "class": "android.server.am.intent.Activities$RegularActivity",
+ "package": "android.server.cts.am",
+ "startForResult": false
+ }
+ ],
+ "act": [
+ {
+ "flags": "FLAG_ACTIVITY_CLEAR_TOP",
+ "class": "android.server.am.intent.Activities$RegularActivity",
+ "package": "android.server.cts.am",
+ "startForResult": false
+ }
+ ]
+ },
+ "initialState": {
+ "stacks": [
+ {
+ "tasks": [
+ {
+ "activities": [
+ {
+ "name": "android.server.cts.am\/android.server.am.intent.Activities$RegularActivity",
+ "state": "RESUMED"
+ }
+ ]
+ }
+ ],
+ "resumedActivity": "android.server.cts.am\/android.server.am.intent.Activities$RegularActivity"
+ }
+ ]
+ },
+ "endState": {
+ "stacks": [
+ {
+ "tasks": [
+ {
+ "activities": [
+ {
+ "name": "android.server.cts.am\/android.server.am.intent.Activities$RegularActivity",
+ "state": "RESUMED"
+ }
+ ]
+ }
+ ],
+ "resumedActivity": "android.server.cts.am\/android.server.am.intent.Activities$RegularActivity"
+ }
+ ]
+ }
+}
diff --git a/tests/framework/base/activitymanager/intent_tests/forResult/test-6.json b/tests/framework/base/activitymanager/intent_tests/forResult/test-6.json
new file mode 100644
index 0000000..fb393eb
--- /dev/null
+++ b/tests/framework/base/activitymanager/intent_tests/forResult/test-6.json
@@ -0,0 +1,54 @@
+{
+ "setup": {
+ "initialIntents": [
+ {
+ "flags": "FLAG_ACTIVITY_NEW_TASK",
+ "class": "android.server.am.intent.Activities$RegularActivity",
+ "package": "android.server.cts.am",
+ "startForResult": false
+ }
+ ],
+ "act": [
+ {
+ "flags": "FLAG_ACTIVITY_CLEAR_TOP",
+ "class": "android.server.am.intent.Activities$RegularActivity",
+ "package": "android.server.cts.am",
+ "startForResult": true
+ }
+ ]
+ },
+ "initialState": {
+ "stacks": [
+ {
+ "tasks": [
+ {
+ "activities": [
+ {
+ "name": "android.server.cts.am\/android.server.am.intent.Activities$RegularActivity",
+ "state": "RESUMED"
+ }
+ ]
+ }
+ ],
+ "resumedActivity": "android.server.cts.am\/android.server.am.intent.Activities$RegularActivity"
+ }
+ ]
+ },
+ "endState": {
+ "stacks": [
+ {
+ "tasks": [
+ {
+ "activities": [
+ {
+ "name": "android.server.cts.am\/android.server.am.intent.Activities$RegularActivity",
+ "state": "RESUMED"
+ }
+ ]
+ }
+ ],
+ "resumedActivity": "android.server.cts.am\/android.server.am.intent.Activities$RegularActivity"
+ }
+ ]
+ }
+}
diff --git a/tests/framework/base/activitymanager/intent_tests/forResult/test-7.json b/tests/framework/base/activitymanager/intent_tests/forResult/test-7.json
new file mode 100644
index 0000000..20e3d56
--- /dev/null
+++ b/tests/framework/base/activitymanager/intent_tests/forResult/test-7.json
@@ -0,0 +1,66 @@
+{
+ "setup": {
+ "initialIntents": [
+ {
+ "flags": "FLAG_ACTIVITY_NEW_TASK",
+ "class": "android.server.am.intent.Activities$RegularActivity",
+ "package": "android.server.cts.am",
+ "startForResult": false
+ }
+ ],
+ "act": [
+ {
+ "flags": "FLAG_ACTIVITY_NEW_TASK | FLAG_ACTIVITY_MULTIPLE_TASK",
+ "class": "android.server.am.intent.Activities$RegularActivity",
+ "package": "android.server.cts.am",
+ "startForResult": true
+ }
+ ]
+ },
+ "initialState": {
+ "stacks": [
+ {
+ "tasks": [
+ {
+ "activities": [
+ {
+ "name": "android.server.cts.am\/android.server.am.intent.Activities$RegularActivity",
+ "state": "RESUMED"
+ }
+ ]
+ }
+ ],
+ "resumedActivity": "android.server.cts.am\/android.server.am.intent.Activities$RegularActivity"
+ }
+ ]
+ },
+ "endState": {
+ "stacks": [
+ {
+ "tasks": [
+ {
+ "activities": [
+ {
+ "name": "android.server.cts.am\/android.server.am.intent.Activities$RegularActivity",
+ "state": "RESUMED"
+ }
+ ]
+ }
+ ],
+ "resumedActivity": "android.server.cts.am\/android.server.am.intent.Activities$RegularActivity"
+ },
+ {
+ "tasks": [
+ {
+ "activities": [
+ {
+ "name": "android.server.cts.am\/android.server.am.intent.Activities$RegularActivity",
+ "state": "STOPPED"
+ }
+ ]
+ }
+ ]
+ }
+ ]
+ }
+}
diff --git a/tests/framework/base/activitymanager/intent_tests/forResult/test-8.json b/tests/framework/base/activitymanager/intent_tests/forResult/test-8.json
new file mode 100644
index 0000000..dfa0aa7
--- /dev/null
+++ b/tests/framework/base/activitymanager/intent_tests/forResult/test-8.json
@@ -0,0 +1,68 @@
+{
+ "setup": {
+ "initialIntents": [
+ {
+ "flags": "FLAG_ACTIVITY_NEW_TASK",
+ "class": "android.server.am.intent.Activities$RegularActivity",
+ "package": "android.server.cts.am",
+ "startForResult": false
+ },
+ {
+ "flags": "",
+ "class": "android.server.am.intent.Activities$TaskAffinity1Activity",
+ "package": "android.server.cts.am",
+ "startForResult": false
+ }
+ ],
+ "act": [
+ {
+ "flags": "FLAG_ACTIVITY_REORDER_TO_FRONT",
+ "class": "android.server.am.intent.Activities$RegularActivity",
+ "package": "android.server.cts.am",
+ "startForResult": true
+ }
+ ]
+ },
+ "initialState": {
+ "stacks": [
+ {
+ "tasks": [
+ {
+ "activities": [
+ {
+ "name": "android.server.cts.am\/android.server.am.intent.Activities$TaskAffinity1Activity",
+ "state": "RESUMED"
+ },
+ {
+ "name": "android.server.cts.am\/android.server.am.intent.Activities$RegularActivity",
+ "state": "STOPPED"
+ }
+ ]
+ }
+ ],
+ "resumedActivity": "android.server.cts.am\/android.server.am.intent.Activities$TaskAffinity1Activity"
+ }
+ ]
+ },
+ "endState": {
+ "stacks": [
+ {
+ "tasks": [
+ {
+ "activities": [
+ {
+ "name": "android.server.cts.am\/android.server.am.intent.Activities$RegularActivity",
+ "state": "RESUMED"
+ },
+ {
+ "name": "android.server.cts.am\/android.server.am.intent.Activities$TaskAffinity1Activity",
+ "state": "STOPPED"
+ }
+ ]
+ }
+ ],
+ "resumedActivity": "android.server.cts.am\/android.server.am.intent.Activities$RegularActivity"
+ }
+ ]
+ }
+}
diff --git a/tests/framework/base/activitymanager/intent_tests/forResult/test-9.json b/tests/framework/base/activitymanager/intent_tests/forResult/test-9.json
new file mode 100644
index 0000000..c88c21d
--- /dev/null
+++ b/tests/framework/base/activitymanager/intent_tests/forResult/test-9.json
@@ -0,0 +1,68 @@
+{
+ "setup": {
+ "initialIntents": [
+ {
+ "flags": "FLAG_ACTIVITY_NEW_TASK",
+ "class": "android.server.am.intent.Activities$RegularActivity",
+ "package": "android.server.cts.am",
+ "startForResult": false
+ },
+ {
+ "flags": "",
+ "class": "android.server.am.intent.Activities$TaskAffinity1Activity",
+ "package": "android.server.cts.am",
+ "startForResult": true
+ }
+ ],
+ "act": [
+ {
+ "flags": "FLAG_ACTIVITY_REORDER_TO_FRONT",
+ "class": "android.server.am.intent.Activities$RegularActivity",
+ "package": "android.server.cts.am",
+ "startForResult": false
+ }
+ ]
+ },
+ "initialState": {
+ "stacks": [
+ {
+ "tasks": [
+ {
+ "activities": [
+ {
+ "name": "android.server.cts.am\/android.server.am.intent.Activities$TaskAffinity1Activity",
+ "state": "RESUMED"
+ },
+ {
+ "name": "android.server.cts.am\/android.server.am.intent.Activities$RegularActivity",
+ "state": "STOPPED"
+ }
+ ]
+ }
+ ],
+ "resumedActivity": "android.server.cts.am\/android.server.am.intent.Activities$TaskAffinity1Activity"
+ }
+ ]
+ },
+ "endState": {
+ "stacks": [
+ {
+ "tasks": [
+ {
+ "activities": [
+ {
+ "name": "android.server.cts.am\/android.server.am.intent.Activities$RegularActivity",
+ "state": "RESUMED"
+ },
+ {
+ "name": "android.server.cts.am\/android.server.am.intent.Activities$TaskAffinity1Activity",
+ "state": "STOPPED"
+ }
+ ]
+ }
+ ],
+ "resumedActivity": "android.server.cts.am\/android.server.am.intent.Activities$RegularActivity"
+ }
+ ]
+ }
+}
diff --git a/tests/framework/base/activitymanager/intent_tests/newDocumentCases/test-1.json b/tests/framework/base/activitymanager/intent_tests/newDocumentCases/test-1.json
new file mode 100644
index 0000000..330d7f9
--- /dev/null
+++ b/tests/framework/base/activitymanager/intent_tests/newDocumentCases/test-1.json
@@ -0,0 +1,66 @@
+{
+ "setup": {
+ "initialIntents": [
+ {
+ "flags": "FLAG_ACTIVITY_NEW_TASK",
+ "class": "android.server.am.intent.Activities$RegularActivity",
+ "package": "android.server.cts.am",
+ "startForResult": false
+ }
+ ],
+ "act": [
+ {
+ "flags": "",
+ "class": "android.server.am.intent.Activities$SingleInstanceActivity",
+ "package": "android.server.cts.am",
+ "startForResult": false
+ }
+ ]
+ },
+ "initialState": {
+ "stacks": [
+ {
+ "tasks": [
+ {
+ "activities": [
+ {
+ "name": "android.server.cts.am\/android.server.am.intent.Activities$RegularActivity",
+ "state": "RESUMED"
+ }
+ ]
+ }
+ ],
+ "resumedActivity": "android.server.cts.am\/android.server.am.intent.Activities$RegularActivity"
+ }
+ ]
+ },
+ "endState": {
+ "stacks": [
+ {
+ "tasks": [
+ {
+ "activities": [
+ {
+ "name": "android.server.cts.am\/android.server.am.intent.Activities$SingleInstanceActivity",
+ "state": "RESUMED"
+ }
+ ]
+ }
+ ],
+ "resumedActivity": "android.server.cts.am\/android.server.am.intent.Activities$SingleInstanceActivity"
+ },
+ {
+ "tasks": [
+ {
+ "activities": [
+ {
+ "name": "android.server.cts.am\/android.server.am.intent.Activities$RegularActivity",
+ "state": "STOPPED"
+ }
+ ]
+ }
+ ]
+ }
+ ]
+ }
+}
diff --git a/tests/framework/base/activitymanager/intent_tests/newDocumentCases/test-10.json b/tests/framework/base/activitymanager/intent_tests/newDocumentCases/test-10.json
new file mode 100644
index 0000000..cb92240
--- /dev/null
+++ b/tests/framework/base/activitymanager/intent_tests/newDocumentCases/test-10.json
@@ -0,0 +1,66 @@
+{
+ "setup": {
+ "initialIntents": [
+ {
+ "flags": "FLAG_ACTIVITY_NEW_TASK",
+ "class": "android.server.am.intent.Activities$RegularActivity",
+ "package": "android.server.cts.am",
+ "startForResult": false
+ }
+ ],
+ "act": [
+ {
+ "flags": "FLAG_ACTIVITY_NEW_DOCUMENT | FLAG_ACTIVITY_MULTIPLE_TASK",
+ "class": "android.server.am.intent.Activities$RegularActivity",
+ "package": "android.server.cts.am",
+ "startForResult": false
+ }
+ ]
+ },
+ "initialState": {
+ "stacks": [
+ {
+ "tasks": [
+ {
+ "activities": [
+ {
+ "name": "android.server.cts.am\/android.server.am.intent.Activities$RegularActivity",
+ "state": "RESUMED"
+ }
+ ]
+ }
+ ],
+ "resumedActivity": "android.server.cts.am\/android.server.am.intent.Activities$RegularActivity"
+ }
+ ]
+ },
+ "endState": {
+ "stacks": [
+ {
+ "tasks": [
+ {
+ "activities": [
+ {
+ "name": "android.server.cts.am\/android.server.am.intent.Activities$RegularActivity",
+ "state": "RESUMED"
+ }
+ ]
+ }
+ ],
+ "resumedActivity": "android.server.cts.am\/android.server.am.intent.Activities$RegularActivity"
+ },
+ {
+ "tasks": [
+ {
+ "activities": [
+ {
+ "name": "android.server.cts.am\/android.server.am.intent.Activities$RegularActivity",
+ "state": "STOPPED"
+ }
+ ]
+ }
+ ]
+ }
+ ]
+ }
+}
diff --git a/tests/framework/base/activitymanager/intent_tests/newDocumentCases/test-11.json b/tests/framework/base/activitymanager/intent_tests/newDocumentCases/test-11.json
new file mode 100644
index 0000000..fac176d
--- /dev/null
+++ b/tests/framework/base/activitymanager/intent_tests/newDocumentCases/test-11.json
@@ -0,0 +1,54 @@
+{
+ "setup": {
+ "initialIntents": [
+ {
+ "flags": "FLAG_ACTIVITY_NEW_TASK",
+ "class": "android.server.am.intent.Activities$SingleInstanceActivity",
+ "package": "android.server.cts.am",
+ "startForResult": false
+ }
+ ],
+ "act": [
+ {
+ "flags": "FLAG_ACTIVITY_NEW_DOCUMENT | FLAG_ACTIVITY_MULTIPLE_TASK",
+ "class": "android.server.am.intent.Activities$SingleInstanceActivity",
+ "package": "android.server.cts.am",
+ "startForResult": false
+ }
+ ]
+ },
+ "initialState": {
+ "stacks": [
+ {
+ "tasks": [
+ {
+ "activities": [
+ {
+ "name": "android.server.cts.am\/android.server.am.intent.Activities$SingleInstanceActivity",
+ "state": "RESUMED"
+ }
+ ]
+ }
+ ],
+ "resumedActivity": "android.server.cts.am\/android.server.am.intent.Activities$SingleInstanceActivity"
+ }
+ ]
+ },
+ "endState": {
+ "stacks": [
+ {
+ "tasks": [
+ {
+ "activities": [
+ {
+ "name": "android.server.cts.am\/android.server.am.intent.Activities$SingleInstanceActivity",
+ "state": "RESUMED"
+ }
+ ]
+ }
+ ],
+ "resumedActivity": "android.server.cts.am\/android.server.am.intent.Activities$SingleInstanceActivity"
+ }
+ ]
+ }
+}
diff --git a/tests/framework/base/activitymanager/intent_tests/newDocumentCases/test-12.json b/tests/framework/base/activitymanager/intent_tests/newDocumentCases/test-12.json
new file mode 100644
index 0000000..82fe0fd
--- /dev/null
+++ b/tests/framework/base/activitymanager/intent_tests/newDocumentCases/test-12.json
@@ -0,0 +1,54 @@
+{
+ "setup": {
+ "initialIntents": [
+ {
+ "flags": "FLAG_ACTIVITY_NEW_TASK",
+ "class": "android.server.am.intent.Activities$SingleTaskActivity",
+ "package": "android.server.cts.am",
+ "startForResult": false
+ }
+ ],
+ "act": [
+ {
+ "flags": "FLAG_ACTIVITY_NEW_DOCUMENT | FLAG_ACTIVITY_MULTIPLE_TASK",
+ "class": "android.server.am.intent.Activities$SingleTaskActivity",
+ "package": "android.server.cts.am",
+ "startForResult": false
+ }
+ ]
+ },
+ "initialState": {
+ "stacks": [
+ {
+ "tasks": [
+ {
+ "activities": [
+ {
+ "name": "android.server.cts.am\/android.server.am.intent.Activities$SingleTaskActivity",
+ "state": "RESUMED"
+ }
+ ]
+ }
+ ],
+ "resumedActivity": "android.server.cts.am\/android.server.am.intent.Activities$SingleTaskActivity"
+ }
+ ]
+ },
+ "endState": {
+ "stacks": [
+ {
+ "tasks": [
+ {
+ "activities": [
+ {
+ "name": "android.server.cts.am\/android.server.am.intent.Activities$SingleTaskActivity",
+ "state": "RESUMED"
+ }
+ ]
+ }
+ ],
+ "resumedActivity": "android.server.cts.am\/android.server.am.intent.Activities$SingleTaskActivity"
+ }
+ ]
+ }
+}
diff --git a/tests/framework/base/activitymanager/intent_tests/newDocumentCases/test-2.json b/tests/framework/base/activitymanager/intent_tests/newDocumentCases/test-2.json
new file mode 100644
index 0000000..714457e
--- /dev/null
+++ b/tests/framework/base/activitymanager/intent_tests/newDocumentCases/test-2.json
@@ -0,0 +1,66 @@
+{
+ "setup": {
+ "initialIntents": [
+ {
+ "flags": "FLAG_ACTIVITY_NEW_TASK",
+ "class": "android.server.am.intent.Activities$RegularActivity",
+ "package": "android.server.cts.am",
+ "startForResult": false
+ }
+ ],
+ "act": [
+ {
+ "flags": "FLAG_ACTIVITY_NEW_DOCUMENT",
+ "class": "android.server.am.intent.Activities$SingleInstanceActivity",
+ "package": "android.server.cts.am",
+ "startForResult": false
+ }
+ ]
+ },
+ "initialState": {
+ "stacks": [
+ {
+ "tasks": [
+ {
+ "activities": [
+ {
+ "name": "android.server.cts.am\/android.server.am.intent.Activities$RegularActivity",
+ "state": "RESUMED"
+ }
+ ]
+ }
+ ],
+ "resumedActivity": "android.server.cts.am\/android.server.am.intent.Activities$RegularActivity"
+ }
+ ]
+ },
+ "endState": {
+ "stacks": [
+ {
+ "tasks": [
+ {
+ "activities": [
+ {
+ "name": "android.server.cts.am\/android.server.am.intent.Activities$SingleInstanceActivity",
+ "state": "RESUMED"
+ }
+ ]
+ }
+ ],
+ "resumedActivity": "android.server.cts.am\/android.server.am.intent.Activities$SingleInstanceActivity"
+ },
+ {
+ "tasks": [
+ {
+ "activities": [
+ {
+ "name": "android.server.cts.am\/android.server.am.intent.Activities$RegularActivity",
+ "state": "STOPPED"
+ }
+ ]
+ }
+ ]
+ }
+ ]
+ }
+}
diff --git a/tests/framework/base/activitymanager/intent_tests/newDocumentCases/test-3.json b/tests/framework/base/activitymanager/intent_tests/newDocumentCases/test-3.json
new file mode 100644
index 0000000..978f3fe
--- /dev/null
+++ b/tests/framework/base/activitymanager/intent_tests/newDocumentCases/test-3.json
@@ -0,0 +1,58 @@
+{
+ "setup": {
+ "initialIntents": [
+ {
+ "flags": "FLAG_ACTIVITY_NEW_TASK",
+ "class": "android.server.am.intent.Activities$RegularActivity",
+ "package": "android.server.cts.am",
+ "startForResult": false
+ }
+ ],
+ "act": [
+ {
+ "flags": "",
+ "class": "android.server.am.intent.Activities$TaskAffinity1Activity",
+ "package": "android.server.cts.am",
+ "startForResult": false
+ }
+ ]
+ },
+ "initialState": {
+ "stacks": [
+ {
+ "tasks": [
+ {
+ "activities": [
+ {
+ "name": "android.server.cts.am\/android.server.am.intent.Activities$RegularActivity",
+ "state": "RESUMED"
+ }
+ ]
+ }
+ ],
+ "resumedActivity": "android.server.cts.am\/android.server.am.intent.Activities$RegularActivity"
+ }
+ ]
+ },
+ "endState": {
+ "stacks": [
+ {
+ "tasks": [
+ {
+ "activities": [
+ {
+ "name": "android.server.cts.am\/android.server.am.intent.Activities$TaskAffinity1Activity",
+ "state": "RESUMED"
+ },
+ {
+ "name": "android.server.cts.am\/android.server.am.intent.Activities$RegularActivity",
+ "state": "STOPPED"
+ }
+ ]
+ }
+ ],
+ "resumedActivity": "android.server.cts.am\/android.server.am.intent.Activities$TaskAffinity1Activity"
+ }
+ ]
+ }
+}
diff --git a/tests/framework/base/activitymanager/intent_tests/newDocumentCases/test-4.json b/tests/framework/base/activitymanager/intent_tests/newDocumentCases/test-4.json
new file mode 100644
index 0000000..00ca419
--- /dev/null
+++ b/tests/framework/base/activitymanager/intent_tests/newDocumentCases/test-4.json
@@ -0,0 +1,66 @@
+{
+ "setup": {
+ "initialIntents": [
+ {
+ "flags": "FLAG_ACTIVITY_NEW_TASK",
+ "class": "android.server.am.intent.Activities$RegularActivity",
+ "package": "android.server.cts.am",
+ "startForResult": false
+ }
+ ],
+ "act": [
+ {
+ "flags": "FLAG_ACTIVITY_NEW_DOCUMENT",
+ "class": "android.server.am.intent.Activities$TaskAffinity1Activity",
+ "package": "android.server.cts.am",
+ "startForResult": false
+ }
+ ]
+ },
+ "initialState": {
+ "stacks": [
+ {
+ "tasks": [
+ {
+ "activities": [
+ {
+ "name": "android.server.cts.am\/android.server.am.intent.Activities$RegularActivity",
+ "state": "RESUMED"
+ }
+ ]
+ }
+ ],
+ "resumedActivity": "android.server.cts.am\/android.server.am.intent.Activities$RegularActivity"
+ }
+ ]
+ },
+ "endState": {
+ "stacks": [
+ {
+ "tasks": [
+ {
+ "activities": [
+ {
+ "name": "android.server.cts.am\/android.server.am.intent.Activities$TaskAffinity1Activity",
+ "state": "RESUMED"
+ }
+ ]
+ }
+ ],
+ "resumedActivity": "android.server.cts.am\/android.server.am.intent.Activities$TaskAffinity1Activity"
+ },
+ {
+ "tasks": [
+ {
+ "activities": [
+ {
+ "name": "android.server.cts.am\/android.server.am.intent.Activities$RegularActivity",
+ "state": "STOPPED"
+ }
+ ]
+ }
+ ]
+ }
+ ]
+ }
+}
diff --git a/tests/framework/base/activitymanager/intent_tests/newDocumentCases/test-5.json b/tests/framework/base/activitymanager/intent_tests/newDocumentCases/test-5.json
new file mode 100644
index 0000000..1c7b18b
--- /dev/null
+++ b/tests/framework/base/activitymanager/intent_tests/newDocumentCases/test-5.json
@@ -0,0 +1,54 @@
+{
+ "setup": {
+ "initialIntents": [
+ {
+ "flags": "FLAG_ACTIVITY_NEW_TASK",
+ "class": "android.server.am.intent.Activities$RegularActivity",
+ "package": "android.server.cts.am",
+ "startForResult": false
+ }
+ ],
+ "act": [
+ {
+ "flags": "FLAG_ACTIVITY_NEW_DOCUMENT",
+ "class": "android.server.am.intent.Activities$RegularActivity",
+ "package": "android.server.cts.am",
+ "startForResult": false
+ }
+ ]
+ },
+ "initialState": {
+ "stacks": [
+ {
+ "tasks": [
+ {
+ "activities": [
+ {
+ "name": "android.server.cts.am\/android.server.am.intent.Activities$RegularActivity",
+ "state": "RESUMED"
+ }
+ ]
+ }
+ ],
+ "resumedActivity": "android.server.cts.am\/android.server.am.intent.Activities$RegularActivity"
+ }
+ ]
+ },
+ "endState": {
+ "stacks": [
+ {
+ "tasks": [
+ {
+ "activities": [
+ {
+ "name": "android.server.cts.am\/android.server.am.intent.Activities$RegularActivity",
+ "state": "RESUMED"
+ }
+ ]
+ }
+ ],
+ "resumedActivity": "android.server.cts.am\/android.server.am.intent.Activities$RegularActivity"
+ }
+ ]
+ }
+}
diff --git a/tests/framework/base/activitymanager/intent_tests/newDocumentCases/test-6.json b/tests/framework/base/activitymanager/intent_tests/newDocumentCases/test-6.json
new file mode 100644
index 0000000..619d6c2a
--- /dev/null
+++ b/tests/framework/base/activitymanager/intent_tests/newDocumentCases/test-6.json
@@ -0,0 +1,66 @@
+{
+ "setup": {
+ "initialIntents": [
+ {
+ "flags": "FLAG_ACTIVITY_NEW_TASK",
+ "class": "android.server.am.intent.Activities$RegularActivity",
+ "package": "android.server.cts.am",
+ "startForResult": false
+ }
+ ],
+ "act": [
+ {
+ "flags": "FLAG_ACTIVITY_NEW_DOCUMENT",
+ "class": "android.server.am.intent.Activities$SingleTopActivity",
+ "package": "android.server.cts.am",
+ "startForResult": false
+ }
+ ]
+ },
+ "initialState": {
+ "stacks": [
+ {
+ "tasks": [
+ {
+ "activities": [
+ {
+ "name": "android.server.cts.am\/android.server.am.intent.Activities$RegularActivity",
+ "state": "RESUMED"
+ }
+ ]
+ }
+ ],
+ "resumedActivity": "android.server.cts.am\/android.server.am.intent.Activities$RegularActivity"
+ }
+ ]
+ },
+ "endState": {
+ "stacks": [
+ {
+ "tasks": [
+ {
+ "activities": [
+ {
+ "name": "android.server.cts.am\/android.server.am.intent.Activities$SingleTopActivity",
+ "state": "RESUMED"
+ }
+ ]
+ }
+ ],
+ "resumedActivity": "android.server.cts.am\/android.server.am.intent.Activities$SingleTopActivity"
+ },
+ {
+ "tasks": [
+ {
+ "activities": [
+ {
+ "name": "android.server.cts.am\/android.server.am.intent.Activities$RegularActivity",
+ "state": "STOPPED"
+ }
+ ]
+ }
+ ]
+ }
+ ]
+ }
+}
diff --git a/tests/framework/base/activitymanager/intent_tests/newDocumentCases/test-7.json b/tests/framework/base/activitymanager/intent_tests/newDocumentCases/test-7.json
new file mode 100644
index 0000000..268b07a
--- /dev/null
+++ b/tests/framework/base/activitymanager/intent_tests/newDocumentCases/test-7.json
@@ -0,0 +1,98 @@
+{
+ "setup": {
+ "initialIntents": [
+ {
+ "flags": "FLAG_ACTIVITY_NEW_TASK",
+ "class": "android.server.am.intent.Activities$TaskAffinity1Activity",
+ "package": "android.server.cts.am",
+ "startForResult": false
+ },
+ {
+ "flags": "",
+ "class": "android.server.am.intent.Activities$RegularActivity",
+ "package": "android.server.cts.am",
+ "startForResult": false
+ },
+ {
+ "flags": "FLAG_ACTIVITY_NEW_TASK | FLAG_ACTIVITY_MULTIPLE_TASK",
+ "class": "android.server.am.intent.Activities$TaskAffinity1Activity",
+ "package": "android.server.cts.am",
+ "startForResult": false
+ }
+ ],
+ "act": [
+ {
+ "flags": "FLAG_ACTIVITY_NEW_DOCUMENT",
+ "class": "android.server.am.intent.Activities$TaskAffinity1Activity",
+ "package": "android.server.cts.am",
+ "startForResult": false
+ }
+ ]
+ },
+ "initialState": {
+ "stacks": [
+ {
+ "tasks": [
+ {
+ "activities": [
+ {
+ "name": "android.server.cts.am\/android.server.am.intent.Activities$TaskAffinity1Activity",
+ "state": "RESUMED"
+ }
+ ]
+ }
+ ],
+ "resumedActivity": "android.server.cts.am\/android.server.am.intent.Activities$TaskAffinity1Activity"
+ },
+ {
+ "tasks": [
+ {
+ "activities": [
+ {
+ "name": "android.server.cts.am\/android.server.am.intent.Activities$RegularActivity",
+ "state": "STOPPED"
+ },
+ {
+ "name": "android.server.cts.am\/android.server.am.intent.Activities$TaskAffinity1Activity",
+ "state": "STOPPED"
+ }
+ ]
+ }
+ ]
+ }
+ ]
+ },
+ "endState": {
+ "stacks": [
+ {
+ "tasks": [
+ {
+ "activities": [
+ {
+ "name": "android.server.cts.am\/android.server.am.intent.Activities$TaskAffinity1Activity",
+ "state": "RESUMED"
+ }
+ ]
+ }
+ ],
+ "resumedActivity": "android.server.cts.am\/android.server.am.intent.Activities$TaskAffinity1Activity"
+ },
+ {
+ "tasks": [
+ {
+ "activities": [
+ {
+ "name": "android.server.cts.am\/android.server.am.intent.Activities$RegularActivity",
+ "state": "STOPPED"
+ },
+ {
+ "name": "android.server.cts.am\/android.server.am.intent.Activities$TaskAffinity1Activity",
+ "state": "STOPPED"
+ }
+ ]
+ }
+ ]
+ }
+ ]
+ }
+}
diff --git a/tests/framework/base/activitymanager/intent_tests/newDocumentCases/test-8.json b/tests/framework/base/activitymanager/intent_tests/newDocumentCases/test-8.json
new file mode 100644
index 0000000..5b897d5
--- /dev/null
+++ b/tests/framework/base/activitymanager/intent_tests/newDocumentCases/test-8.json
@@ -0,0 +1,104 @@
+{
+ "setup": {
+ "initialIntents": [
+ {
+ "flags": "FLAG_ACTIVITY_NEW_TASK",
+ "class": "android.server.am.intent.Activities$RegularActivity",
+ "package": "android.server.cts.am",
+ "startForResult": false
+ },
+ {
+ "flags": "FLAG_ACTIVITY_NEW_TASK",
+ "class": "android.server.am.intent.Activities$TaskAffinity1Activity",
+ "package": "android.server.cts.am",
+ "startForResult": false
+ },
+ {
+ "flags": "",
+ "class": "android.server.am.intent.Activities$RegularActivity",
+ "package": "android.server.cts.am",
+ "startForResult": false
+ },
+ {
+ "flags": "FLAG_ACTIVITY_REORDER_TO_FRONT",
+ "class": "android.server.am.intent.Activities$TaskAffinity1Activity",
+ "package": "android.server.cts.am",
+ "startForResult": false
+ }
+ ],
+ "act": [
+ {
+ "flags": "FLAG_ACTIVITY_NEW_DOCUMENT",
+ "class": "android.server.am.intent.Activities$TaskAffinity1Activity",
+ "package": "android.server.cts.am",
+ "startForResult": false
+ }
+ ]
+ },
+ "initialState": {
+ "stacks": [
+ {
+ "tasks": [
+ {
+ "activities": [
+ {
+ "name": "android.server.cts.am\/android.server.am.intent.Activities$TaskAffinity1Activity",
+ "state": "RESUMED"
+ },
+ {
+ "name": "android.server.cts.am\/android.server.am.intent.Activities$RegularActivity",
+ "state": "STOPPED"
+ }
+ ]
+ }
+ ],
+ "resumedActivity": "android.server.cts.am\/android.server.am.intent.Activities$TaskAffinity1Activity"
+ },
+ {
+ "tasks": [
+ {
+ "activities": [
+ {
+ "name": "android.server.cts.am\/android.server.am.intent.Activities$RegularActivity",
+ "state": "STOPPED"
+ }
+ ]
+ }
+ ]
+ }
+ ]
+ },
+ "endState": {
+ "stacks": [
+ {
+ "tasks": [
+ {
+ "activities": [
+ {
+ "name": "android.server.cts.am\/android.server.am.intent.Activities$TaskAffinity1Activity",
+ "state": "RESUMED"
+ },
+ {
+ "name": "android.server.cts.am\/android.server.am.intent.Activities$RegularActivity",
+ "state": "STOPPED"
+ }
+ ]
+ }
+ ],
+ "resumedActivity": "android.server.cts.am\/android.server.am.intent.Activities$TaskAffinity1Activity"
+ },
+ {
+ "tasks": [
+ {
+ "activities": [
+ {
+ "name": "android.server.cts.am\/android.server.am.intent.Activities$RegularActivity",
+ "state": "STOPPED"
+ }
+ ]
+ }
+ ]
+ }
+ ]
+ }
+}
diff --git a/tests/framework/base/activitymanager/intent_tests/newDocumentCases/test-9.json b/tests/framework/base/activitymanager/intent_tests/newDocumentCases/test-9.json
new file mode 100644
index 0000000..0d6973e
--- /dev/null
+++ b/tests/framework/base/activitymanager/intent_tests/newDocumentCases/test-9.json
@@ -0,0 +1,116 @@
+{
+ "setup": {
+ "initialIntents": [
+ {
+ "flags": "FLAG_ACTIVITY_NEW_TASK",
+ "class": "android.server.am.intent.Activities$RegularActivity",
+ "package": "android.server.cts.am",
+ "startForResult": false
+ },
+ {
+ "flags": "FLAG_ACTIVITY_NEW_TASK",
+ "class": "android.server.am.intent.Activities$TaskAffinity1Activity",
+ "package": "android.server.cts.am",
+ "startForResult": false
+ },
+ {
+ "flags": "",
+ "class": "android.server.am.intent.Activities$RegularActivity",
+ "package": "android.server.cts.am",
+ "startForResult": false
+ },
+ {
+ "flags": "FLAG_ACTIVITY_REORDER_TO_FRONT",
+ "class": "android.server.am.intent.Activities$TaskAffinity1Activity",
+ "package": "android.server.cts.am",
+ "startForResult": false
+ }
+ ],
+ "act": [
+ {
+ "flags": "FLAG_ACTIVITY_NEW_DOCUMENT",
+ "class": "android.server.am.intent.Activities$TaskAffinity1Activity2",
+ "package": "android.server.cts.am",
+ "startForResult": false
+ }
+ ]
+ },
+ "initialState": {
+ "stacks": [
+ {
+ "tasks": [
+ {
+ "activities": [
+ {
+ "name": "android.server.cts.am\/android.server.am.intent.Activities$TaskAffinity1Activity",
+ "state": "RESUMED"
+ },
+ {
+ "name": "android.server.cts.am\/android.server.am.intent.Activities$RegularActivity",
+ "state": "STOPPED"
+ }
+ ]
+ }
+ ],
+ "resumedActivity": "android.server.cts.am\/android.server.am.intent.Activities$TaskAffinity1Activity"
+ },
+ {
+ "tasks": [
+ {
+ "activities": [
+ {
+ "name": "android.server.cts.am\/android.server.am.intent.Activities$RegularActivity",
+ "state": "STOPPED"
+ }
+ ]
+ }
+ ]
+ }
+ ]
+ },
+ "endState": {
+ "stacks": [
+ {
+ "tasks": [
+ {
+ "activities": [
+ {
+ "name": "android.server.cts.am\/android.server.am.intent.Activities$TaskAffinity1Activity2",
+ "state": "RESUMED"
+ }
+ ]
+ }
+ ],
+ "resumedActivity": "android.server.cts.am\/android.server.am.intent.Activities$TaskAffinity1Activity2"
+ },
+ {
+ "tasks": [
+ {
+ "activities": [
+ {
+ "name": "android.server.cts.am\/android.server.am.intent.Activities$TaskAffinity1Activity",
+ "state": "STOPPED"
+ },
+ {
+ "name": "android.server.cts.am\/android.server.am.intent.Activities$RegularActivity",
+ "state": "STOPPED"
+ }
+ ]
+ }
+ ]
+ },
+ {
+ "tasks": [
+ {
+ "activities": [
+ {
+ "name": "android.server.cts.am\/android.server.am.intent.Activities$RegularActivity",
+ "state": "STOPPED"
+ }
+ ]
+ }
+ ]
+ }
+ ]
+ }
+}
diff --git a/tests/framework/base/activitymanager/intent_tests/newTask/test-1.json b/tests/framework/base/activitymanager/intent_tests/newTask/test-1.json
new file mode 100644
index 0000000..330d7f9
--- /dev/null
+++ b/tests/framework/base/activitymanager/intent_tests/newTask/test-1.json
@@ -0,0 +1,66 @@
+{
+ "setup": {
+ "initialIntents": [
+ {
+ "flags": "FLAG_ACTIVITY_NEW_TASK",
+ "class": "android.server.am.intent.Activities$RegularActivity",
+ "package": "android.server.cts.am",
+ "startForResult": false
+ }
+ ],
+ "act": [
+ {
+ "flags": "",
+ "class": "android.server.am.intent.Activities$SingleInstanceActivity",
+ "package": "android.server.cts.am",
+ "startForResult": false
+ }
+ ]
+ },
+ "initialState": {
+ "stacks": [
+ {
+ "tasks": [
+ {
+ "activities": [
+ {
+ "name": "android.server.cts.am\/android.server.am.intent.Activities$RegularActivity",
+ "state": "RESUMED"
+ }
+ ]
+ }
+ ],
+ "resumedActivity": "android.server.cts.am\/android.server.am.intent.Activities$RegularActivity"
+ }
+ ]
+ },
+ "endState": {
+ "stacks": [
+ {
+ "tasks": [
+ {
+ "activities": [
+ {
+ "name": "android.server.cts.am\/android.server.am.intent.Activities$SingleInstanceActivity",
+ "state": "RESUMED"
+ }
+ ]
+ }
+ ],
+ "resumedActivity": "android.server.cts.am\/android.server.am.intent.Activities$SingleInstanceActivity"
+ },
+ {
+ "tasks": [
+ {
+ "activities": [
+ {
+ "name": "android.server.cts.am\/android.server.am.intent.Activities$RegularActivity",
+ "state": "STOPPED"
+ }
+ ]
+ }
+ ]
+ }
+ ]
+ }
+}
diff --git a/tests/framework/base/activitymanager/intent_tests/newTask/test-10.json b/tests/framework/base/activitymanager/intent_tests/newTask/test-10.json
new file mode 100644
index 0000000..4d7984c
--- /dev/null
+++ b/tests/framework/base/activitymanager/intent_tests/newTask/test-10.json
@@ -0,0 +1,66 @@
+{
+ "setup": {
+ "initialIntents": [
+ {
+ "flags": "FLAG_ACTIVITY_NEW_TASK",
+ "class": "android.server.am.intent.Activities$RegularActivity",
+ "package": "android.server.cts.am",
+ "startForResult": false
+ }
+ ],
+ "act": [
+ {
+ "flags": "FLAG_ACTIVITY_NEW_TASK | FLAG_ACTIVITY_MULTIPLE_TASK",
+ "class": "android.server.am.intent.Activities$RegularActivity",
+ "package": "android.server.cts.am",
+ "startForResult": false
+ }
+ ]
+ },
+ "initialState": {
+ "stacks": [
+ {
+ "tasks": [
+ {
+ "activities": [
+ {
+ "name": "android.server.cts.am\/android.server.am.intent.Activities$RegularActivity",
+ "state": "RESUMED"
+ }
+ ]
+ }
+ ],
+ "resumedActivity": "android.server.cts.am\/android.server.am.intent.Activities$RegularActivity"
+ }
+ ]
+ },
+ "endState": {
+ "stacks": [
+ {
+ "tasks": [
+ {
+ "activities": [
+ {
+ "name": "android.server.cts.am\/android.server.am.intent.Activities$RegularActivity",
+ "state": "RESUMED"
+ }
+ ]
+ }
+ ],
+ "resumedActivity": "android.server.cts.am\/android.server.am.intent.Activities$RegularActivity"
+ },
+ {
+ "tasks": [
+ {
+ "activities": [
+ {
+ "name": "android.server.cts.am\/android.server.am.intent.Activities$RegularActivity",
+ "state": "STOPPED"
+ }
+ ]
+ }
+ ]
+ }
+ ]
+ }
+}
diff --git a/tests/framework/base/activitymanager/intent_tests/newTask/test-11.json b/tests/framework/base/activitymanager/intent_tests/newTask/test-11.json
new file mode 100644
index 0000000..629a371
--- /dev/null
+++ b/tests/framework/base/activitymanager/intent_tests/newTask/test-11.json
@@ -0,0 +1,54 @@
+{
+ "setup": {
+ "initialIntents": [
+ {
+ "flags": "FLAG_ACTIVITY_NEW_TASK",
+ "class": "android.server.am.intent.Activities$SingleInstanceActivity",
+ "package": "android.server.cts.am",
+ "startForResult": false
+ }
+ ],
+ "act": [
+ {
+ "flags": "FLAG_ACTIVITY_NEW_TASK | FLAG_ACTIVITY_MULTIPLE_TASK",
+ "class": "android.server.am.intent.Activities$SingleInstanceActivity",
+ "package": "android.server.cts.am",
+ "startForResult": false
+ }
+ ]
+ },
+ "initialState": {
+ "stacks": [
+ {
+ "tasks": [
+ {
+ "activities": [
+ {
+ "name": "android.server.cts.am\/android.server.am.intent.Activities$SingleInstanceActivity",
+ "state": "RESUMED"
+ }
+ ]
+ }
+ ],
+ "resumedActivity": "android.server.cts.am\/android.server.am.intent.Activities$SingleInstanceActivity"
+ }
+ ]
+ },
+ "endState": {
+ "stacks": [
+ {
+ "tasks": [
+ {
+ "activities": [
+ {
+ "name": "android.server.cts.am\/android.server.am.intent.Activities$SingleInstanceActivity",
+ "state": "RESUMED"
+ }
+ ]
+ }
+ ],
+ "resumedActivity": "android.server.cts.am\/android.server.am.intent.Activities$SingleInstanceActivity"
+ }
+ ]
+ }
+}
diff --git a/tests/framework/base/activitymanager/intent_tests/newTask/test-12.json b/tests/framework/base/activitymanager/intent_tests/newTask/test-12.json
new file mode 100644
index 0000000..5c57171
--- /dev/null
+++ b/tests/framework/base/activitymanager/intent_tests/newTask/test-12.json
@@ -0,0 +1,54 @@
+{
+ "setup": {
+ "initialIntents": [
+ {
+ "flags": "FLAG_ACTIVITY_NEW_TASK",
+ "class": "android.server.am.intent.Activities$SingleTaskActivity",
+ "package": "android.server.cts.am",
+ "startForResult": false
+ }
+ ],
+ "act": [
+ {
+ "flags": "FLAG_ACTIVITY_NEW_TASK | FLAG_ACTIVITY_MULTIPLE_TASK",
+ "class": "android.server.am.intent.Activities$SingleTaskActivity",
+ "package": "android.server.cts.am",
+ "startForResult": false
+ }
+ ]
+ },
+ "initialState": {
+ "stacks": [
+ {
+ "tasks": [
+ {
+ "activities": [
+ {
+ "name": "android.server.cts.am\/android.server.am.intent.Activities$SingleTaskActivity",
+ "state": "RESUMED"
+ }
+ ]
+ }
+ ],
+ "resumedActivity": "android.server.cts.am\/android.server.am.intent.Activities$SingleTaskActivity"
+ }
+ ]
+ },
+ "endState": {
+ "stacks": [
+ {
+ "tasks": [
+ {
+ "activities": [
+ {
+ "name": "android.server.cts.am\/android.server.am.intent.Activities$SingleTaskActivity",
+ "state": "RESUMED"
+ }
+ ]
+ }
+ ],
+ "resumedActivity": "android.server.cts.am\/android.server.am.intent.Activities$SingleTaskActivity"
+ }
+ ]
+ }
+}
diff --git a/tests/framework/base/activitymanager/intent_tests/newTask/test-13.json b/tests/framework/base/activitymanager/intent_tests/newTask/test-13.json
new file mode 100644
index 0000000..4b330fb
--- /dev/null
+++ b/tests/framework/base/activitymanager/intent_tests/newTask/test-13.json
@@ -0,0 +1,66 @@
+{
+ "setup": {
+ "initialIntents": [
+ {
+ "flags": "FLAG_ACTIVITY_NEW_TASK",
+ "class": "android.server.am.intent.Activities$SingleInstanceActivity",
+ "package": "android.server.cts.am",
+ "startForResult": false
+ }
+ ],
+ "act": [
+ {
+ "flags": "",
+ "class": "android.server.am.intent.Activities$RegularActivity",
+ "package": "android.server.cts.am",
+ "startForResult": false
+ }
+ ]
+ },
+ "initialState": {
+ "stacks": [
+ {
+ "tasks": [
+ {
+ "activities": [
+ {
+ "name": "android.server.cts.am\/android.server.am.intent.Activities$SingleInstanceActivity",
+ "state": "RESUMED"
+ }
+ ]
+ }
+ ],
+ "resumedActivity": "android.server.cts.am\/android.server.am.intent.Activities$SingleInstanceActivity"
+ }
+ ]
+ },
+ "endState": {
+ "stacks": [
+ {
+ "tasks": [
+ {
+ "activities": [
+ {
+ "name": "android.server.cts.am\/android.server.am.intent.Activities$RegularActivity",
+ "state": "RESUMED"
+ }
+ ]
+ }
+ ],
+ "resumedActivity": "android.server.cts.am\/android.server.am.intent.Activities$RegularActivity"
+ },
+ {
+ "tasks": [
+ {
+ "activities": [
+ {
+ "name": "android.server.cts.am\/android.server.am.intent.Activities$SingleInstanceActivity",
+ "state": "STOPPED"
+ }
+ ]
+ }
+ ]
+ }
+ ]
+ }
+}
diff --git a/tests/framework/base/activitymanager/intent_tests/newTask/test-14.json b/tests/framework/base/activitymanager/intent_tests/newTask/test-14.json
new file mode 100644
index 0000000..c9441032
--- /dev/null
+++ b/tests/framework/base/activitymanager/intent_tests/newTask/test-14.json
@@ -0,0 +1,58 @@
+{
+ "setup": {
+ "initialIntents": [
+ {
+ "flags": "FLAG_ACTIVITY_NEW_TASK",
+ "class": "android.server.am.intent.Activities$SingleTaskActivity",
+ "package": "android.server.cts.am",
+ "startForResult": false
+ }
+ ],
+ "act": [
+ {
+ "flags": "",
+ "class": "android.server.am.intent.Activities$RegularActivity",
+ "package": "android.server.cts.am",
+ "startForResult": false
+ }
+ ]
+ },
+ "initialState": {
+ "stacks": [
+ {
+ "tasks": [
+ {
+ "activities": [
+ {
+ "name": "android.server.cts.am\/android.server.am.intent.Activities$SingleTaskActivity",
+ "state": "RESUMED"
+ }
+ ]
+ }
+ ],
+ "resumedActivity": "android.server.cts.am\/android.server.am.intent.Activities$SingleTaskActivity"
+ }
+ ]
+ },
+ "endState": {
+ "stacks": [
+ {
+ "tasks": [
+ {
+ "activities": [
+ {
+ "name": "android.server.cts.am\/android.server.am.intent.Activities$RegularActivity",
+ "state": "RESUMED"
+ },
+ {
+ "name": "android.server.cts.am\/android.server.am.intent.Activities$SingleTaskActivity",
+ "state": "STOPPED"
+ }
+ ]
+ }
+ ],
+ "resumedActivity": "android.server.cts.am\/android.server.am.intent.Activities$RegularActivity"
+ }
+ ]
+ }
+}
diff --git a/tests/framework/base/activitymanager/intent_tests/newTask/test-15.json b/tests/framework/base/activitymanager/intent_tests/newTask/test-15.json
new file mode 100644
index 0000000..03140d2
--- /dev/null
+++ b/tests/framework/base/activitymanager/intent_tests/newTask/test-15.json
@@ -0,0 +1,58 @@
+{
+ "setup": {
+ "initialIntents": [
+ {
+ "flags": "FLAG_ACTIVITY_NEW_TASK",
+ "class": "android.server.am.intent.Activities$SingleInstanceActivity",
+ "package": "android.server.cts.am",
+ "startForResult": false
+ }
+ ],
+ "act": [
+ {
+ "flags": "",
+ "class": "android.server.am.intent.Activities$RegularActivity",
+ "package": "android.server.cts.am",
+ "startForResult": true
+ }
+ ]
+ },
+ "initialState": {
+ "stacks": [
+ {
+ "tasks": [
+ {
+ "activities": [
+ {
+ "name": "android.server.cts.am\/android.server.am.intent.Activities$SingleInstanceActivity",
+ "state": "RESUMED"
+ }
+ ]
+ }
+ ],
+ "resumedActivity": "android.server.cts.am\/android.server.am.intent.Activities$SingleInstanceActivity"
+ }
+ ]
+ },
+ "endState": {
+ "stacks": [
+ {
+ "tasks": [
+ {
+ "activities": [
+ {
+ "name": "android.server.cts.am\/android.server.am.intent.Activities$RegularActivity",
+ "state": "RESUMED"
+ },
+ {
+ "name": "android.server.cts.am\/android.server.am.intent.Activities$SingleInstanceActivity",
+ "state": "STOPPED"
+ }
+ ]
+ }
+ ],
+ "resumedActivity": "android.server.cts.am\/android.server.am.intent.Activities$RegularActivity"
+ }
+ ]
+ }
+}
diff --git a/tests/framework/base/activitymanager/intent_tests/newTask/test-16.json b/tests/framework/base/activitymanager/intent_tests/newTask/test-16.json
new file mode 100644
index 0000000..0f4a845
--- /dev/null
+++ b/tests/framework/base/activitymanager/intent_tests/newTask/test-16.json
@@ -0,0 +1,84 @@
+{
+ "setup": {
+ "initialIntents": [
+ {
+ "flags": "FLAG_ACTIVITY_NEW_TASK",
+ "class": "android.server.am.intent.Activities$RegularActivity",
+ "package": "android.server.cts.am",
+ "startForResult": false
+ },
+ {
+ "flags": "",
+ "class": "android.server.am.intent.Activities$SingleInstanceActivity",
+ "package": "android.server.cts.am",
+ "startForResult": false
+ }
+ ],
+ "act": [
+ {
+ "flags": "",
+ "class": "android.server.am.intent.Activities$RegularActivity",
+ "package": "android.server.cts.am",
+ "startForResult": false
+ }
+ ]
+ },
+ "initialState": {
+ "stacks": [
+ {
+ "tasks": [
+ {
+ "activities": [
+ {
+ "name": "android.server.cts.am\/android.server.am.intent.Activities$SingleInstanceActivity",
+ "state": "RESUMED"
+ }
+ ]
+ }
+ ],
+ "resumedActivity": "android.server.cts.am\/android.server.am.intent.Activities$SingleInstanceActivity"
+ },
+ {
+ "tasks": [
+ {
+ "activities": [
+ {
+ "name": "android.server.cts.am\/android.server.am.intent.Activities$RegularActivity",
+ "state": "STOPPED"
+ }
+ ]
+ }
+ ]
+ }
+ ]
+ },
+ "endState": {
+ "stacks": [
+ {
+ "tasks": [
+ {
+ "activities": [
+ {
+ "name": "android.server.cts.am\/android.server.am.intent.Activities$RegularActivity",
+ "state": "RESUMED"
+ }
+ ]
+ }
+ ],
+ "resumedActivity": "android.server.cts.am\/android.server.am.intent.Activities$RegularActivity"
+ },
+ {
+ "tasks": [
+ {
+ "activities": [
+ {
+ "name": "android.server.cts.am\/android.server.am.intent.Activities$SingleInstanceActivity",
+ "state": "STOPPED"
+ }
+ ]
+ }
+ ]
+ }
+ ]
+ }
+}
diff --git a/tests/framework/base/activitymanager/intent_tests/newTask/test-2.json b/tests/framework/base/activitymanager/intent_tests/newTask/test-2.json
new file mode 100644
index 0000000..f83daac
--- /dev/null
+++ b/tests/framework/base/activitymanager/intent_tests/newTask/test-2.json
@@ -0,0 +1,66 @@
+{
+ "setup": {
+ "initialIntents": [
+ {
+ "flags": "FLAG_ACTIVITY_NEW_TASK",
+ "class": "android.server.am.intent.Activities$RegularActivity",
+ "package": "android.server.cts.am",
+ "startForResult": false
+ }
+ ],
+ "act": [
+ {
+ "flags": "FLAG_ACTIVITY_NEW_TASK",
+ "class": "android.server.am.intent.Activities$SingleInstanceActivity",
+ "package": "android.server.cts.am",
+ "startForResult": false
+ }
+ ]
+ },
+ "initialState": {
+ "stacks": [
+ {
+ "tasks": [
+ {
+ "activities": [
+ {
+ "name": "android.server.cts.am\/android.server.am.intent.Activities$RegularActivity",
+ "state": "RESUMED"
+ }
+ ]
+ }
+ ],
+ "resumedActivity": "android.server.cts.am\/android.server.am.intent.Activities$RegularActivity"
+ }
+ ]
+ },
+ "endState": {
+ "stacks": [
+ {
+ "tasks": [
+ {
+ "activities": [
+ {
+ "name": "android.server.cts.am\/android.server.am.intent.Activities$SingleInstanceActivity",
+ "state": "RESUMED"
+ }
+ ]
+ }
+ ],
+ "resumedActivity": "android.server.cts.am\/android.server.am.intent.Activities$SingleInstanceActivity"
+ },
+ {
+ "tasks": [
+ {
+ "activities": [
+ {
+ "name": "android.server.cts.am\/android.server.am.intent.Activities$RegularActivity",
+ "state": "STOPPED"
+ }
+ ]
+ }
+ ]
+ }
+ ]
+ }
+}
diff --git a/tests/framework/base/activitymanager/intent_tests/newTask/test-3.json b/tests/framework/base/activitymanager/intent_tests/newTask/test-3.json
new file mode 100644
index 0000000..978f3fe
--- /dev/null
+++ b/tests/framework/base/activitymanager/intent_tests/newTask/test-3.json
@@ -0,0 +1,58 @@
+{
+ "setup": {
+ "initialIntents": [
+ {
+ "flags": "FLAG_ACTIVITY_NEW_TASK",
+ "class": "android.server.am.intent.Activities$RegularActivity",
+ "package": "android.server.cts.am",
+ "startForResult": false
+ }
+ ],
+ "act": [
+ {
+ "flags": "",
+ "class": "android.server.am.intent.Activities$TaskAffinity1Activity",
+ "package": "android.server.cts.am",
+ "startForResult": false
+ }
+ ]
+ },
+ "initialState": {
+ "stacks": [
+ {
+ "tasks": [
+ {
+ "activities": [
+ {
+ "name": "android.server.cts.am\/android.server.am.intent.Activities$RegularActivity",
+ "state": "RESUMED"
+ }
+ ]
+ }
+ ],
+ "resumedActivity": "android.server.cts.am\/android.server.am.intent.Activities$RegularActivity"
+ }
+ ]
+ },
+ "endState": {
+ "stacks": [
+ {
+ "tasks": [
+ {
+ "activities": [
+ {
+ "name": "android.server.cts.am\/android.server.am.intent.Activities$TaskAffinity1Activity",
+ "state": "RESUMED"
+ },
+ {
+ "name": "android.server.cts.am\/android.server.am.intent.Activities$RegularActivity",
+ "state": "STOPPED"
+ }
+ ]
+ }
+ ],
+ "resumedActivity": "android.server.cts.am\/android.server.am.intent.Activities$TaskAffinity1Activity"
+ }
+ ]
+ }
+}
diff --git a/tests/framework/base/activitymanager/intent_tests/newTask/test-4.json b/tests/framework/base/activitymanager/intent_tests/newTask/test-4.json
new file mode 100644
index 0000000..e5edf6b
--- /dev/null
+++ b/tests/framework/base/activitymanager/intent_tests/newTask/test-4.json
@@ -0,0 +1,66 @@
+{
+ "setup": {
+ "initialIntents": [
+ {
+ "flags": "FLAG_ACTIVITY_NEW_TASK",
+ "class": "android.server.am.intent.Activities$RegularActivity",
+ "package": "android.server.cts.am",
+ "startForResult": false
+ }
+ ],
+ "act": [
+ {
+ "flags": "FLAG_ACTIVITY_NEW_TASK",
+ "class": "android.server.am.intent.Activities$TaskAffinity1Activity",
+ "package": "android.server.cts.am",
+ "startForResult": false
+ }
+ ]
+ },
+ "initialState": {
+ "stacks": [
+ {
+ "tasks": [
+ {
+ "activities": [
+ {
+ "name": "android.server.cts.am\/android.server.am.intent.Activities$RegularActivity",
+ "state": "RESUMED"
+ }
+ ]
+ }
+ ],
+ "resumedActivity": "android.server.cts.am\/android.server.am.intent.Activities$RegularActivity"
+ }
+ ]
+ },
+ "endState": {
+ "stacks": [
+ {
+ "tasks": [
+ {
+ "activities": [
+ {
+ "name": "android.server.cts.am\/android.server.am.intent.Activities$TaskAffinity1Activity",
+ "state": "RESUMED"
+ }
+ ]
+ }
+ ],
+ "resumedActivity": "android.server.cts.am\/android.server.am.intent.Activities$TaskAffinity1Activity"
+ },
+ {
+ "tasks": [
+ {
+ "activities": [
+ {
+ "name": "android.server.cts.am\/android.server.am.intent.Activities$RegularActivity",
+ "state": "STOPPED"
+ }
+ ]
+ }
+ ]
+ }
+ ]
+ }
+}
diff --git a/tests/framework/base/activitymanager/intent_tests/newTask/test-5.json b/tests/framework/base/activitymanager/intent_tests/newTask/test-5.json
new file mode 100644
index 0000000..95a867c
--- /dev/null
+++ b/tests/framework/base/activitymanager/intent_tests/newTask/test-5.json
@@ -0,0 +1,54 @@
+{
+ "setup": {
+ "initialIntents": [
+ {
+ "flags": "FLAG_ACTIVITY_NEW_TASK",
+ "class": "android.server.am.intent.Activities$RegularActivity",
+ "package": "android.server.cts.am",
+ "startForResult": false
+ }
+ ],
+ "act": [
+ {
+ "flags": "FLAG_ACTIVITY_NEW_TASK",
+ "class": "android.server.am.intent.Activities$RegularActivity",
+ "package": "android.server.cts.am",
+ "startForResult": false
+ }
+ ]
+ },
+ "initialState": {
+ "stacks": [
+ {
+ "tasks": [
+ {
+ "activities": [
+ {
+ "name": "android.server.cts.am\/android.server.am.intent.Activities$RegularActivity",
+ "state": "RESUMED"
+ }
+ ]
+ }
+ ],
+ "resumedActivity": "android.server.cts.am\/android.server.am.intent.Activities$RegularActivity"
+ }
+ ]
+ },
+ "endState": {
+ "stacks": [
+ {
+ "tasks": [
+ {
+ "activities": [
+ {
+ "name": "android.server.cts.am\/android.server.am.intent.Activities$RegularActivity",
+ "state": "RESUMED"
+ }
+ ]
+ }
+ ],
+ "resumedActivity": "android.server.cts.am\/android.server.am.intent.Activities$RegularActivity"
+ }
+ ]
+ }
+}
diff --git a/tests/framework/base/activitymanager/intent_tests/newTask/test-6.json b/tests/framework/base/activitymanager/intent_tests/newTask/test-6.json
new file mode 100644
index 0000000..d4052f4
--- /dev/null
+++ b/tests/framework/base/activitymanager/intent_tests/newTask/test-6.json
@@ -0,0 +1,58 @@
+{
+ "setup": {
+ "initialIntents": [
+ {
+ "flags": "FLAG_ACTIVITY_NEW_TASK",
+ "class": "android.server.am.intent.Activities$RegularActivity",
+ "package": "android.server.cts.am",
+ "startForResult": false
+ }
+ ],
+ "act": [
+ {
+ "flags": "FLAG_ACTIVITY_NEW_TASK",
+ "class": "android.server.am.intent.Activities$SingleTopActivity",
+ "package": "android.server.cts.am",
+ "startForResult": false
+ }
+ ]
+ },
+ "initialState": {
+ "stacks": [
+ {
+ "tasks": [
+ {
+ "activities": [
+ {
+ "name": "android.server.cts.am\/android.server.am.intent.Activities$RegularActivity",
+ "state": "RESUMED"
+ }
+ ]
+ }
+ ],
+ "resumedActivity": "android.server.cts.am\/android.server.am.intent.Activities$RegularActivity"
+ }
+ ]
+ },
+ "endState": {
+ "stacks": [
+ {
+ "tasks": [
+ {
+ "activities": [
+ {
+ "name": "android.server.cts.am\/android.server.am.intent.Activities$SingleTopActivity",
+ "state": "RESUMED"
+ },
+ {
+ "name": "android.server.cts.am\/android.server.am.intent.Activities$RegularActivity",
+ "state": "STOPPED"
+ }
+ ]
+ }
+ ],
+ "resumedActivity": "android.server.cts.am\/android.server.am.intent.Activities$SingleTopActivity"
+ }
+ ]
+ }
+}
diff --git a/tests/framework/base/activitymanager/intent_tests/newTask/test-7.json b/tests/framework/base/activitymanager/intent_tests/newTask/test-7.json
new file mode 100644
index 0000000..e3a826f
--- /dev/null
+++ b/tests/framework/base/activitymanager/intent_tests/newTask/test-7.json
@@ -0,0 +1,98 @@
+{
+ "setup": {
+ "initialIntents": [
+ {
+ "flags": "FLAG_ACTIVITY_NEW_TASK",
+ "class": "android.server.am.intent.Activities$TaskAffinity1Activity",
+ "package": "android.server.cts.am",
+ "startForResult": false
+ },
+ {
+ "flags": "",
+ "class": "android.server.am.intent.Activities$RegularActivity",
+ "package": "android.server.cts.am",
+ "startForResult": false
+ },
+ {
+ "flags": "FLAG_ACTIVITY_NEW_TASK | FLAG_ACTIVITY_MULTIPLE_TASK",
+ "class": "android.server.am.intent.Activities$TaskAffinity1Activity",
+ "package": "android.server.cts.am",
+ "startForResult": false
+ }
+ ],
+ "act": [
+ {
+ "flags": "FLAG_ACTIVITY_NEW_TASK",
+ "class": "android.server.am.intent.Activities$TaskAffinity1Activity",
+ "package": "android.server.cts.am",
+ "startForResult": false
+ }
+ ]
+ },
+ "initialState": {
+ "stacks": [
+ {
+ "tasks": [
+ {
+ "activities": [
+ {
+ "name": "android.server.cts.am\/android.server.am.intent.Activities$TaskAffinity1Activity",
+ "state": "RESUMED"
+ }
+ ]
+ }
+ ],
+ "resumedActivity": "android.server.cts.am\/android.server.am.intent.Activities$TaskAffinity1Activity"
+ },
+ {
+ "tasks": [
+ {
+ "activities": [
+ {
+ "name": "android.server.cts.am\/android.server.am.intent.Activities$RegularActivity",
+ "state": "STOPPED"
+ },
+ {
+ "name": "android.server.cts.am\/android.server.am.intent.Activities$TaskAffinity1Activity",
+ "state": "STOPPED"
+ }
+ ]
+ }
+ ]
+ }
+ ]
+ },
+ "endState": {
+ "stacks": [
+ {
+ "tasks": [
+ {
+ "activities": [
+ {
+ "name": "android.server.cts.am\/android.server.am.intent.Activities$TaskAffinity1Activity",
+ "state": "RESUMED"
+ }
+ ]
+ }
+ ],
+ "resumedActivity": "android.server.cts.am\/android.server.am.intent.Activities$TaskAffinity1Activity"
+ },
+ {
+ "tasks": [
+ {
+ "activities": [
+ {
+ "name": "android.server.cts.am\/android.server.am.intent.Activities$RegularActivity",
+ "state": "STOPPED"
+ },
+ {
+ "name": "android.server.cts.am\/android.server.am.intent.Activities$TaskAffinity1Activity",
+ "state": "STOPPED"
+ }
+ ]
+ }
+ ]
+ }
+ ]
+ }
+}
diff --git a/tests/framework/base/activitymanager/intent_tests/newTask/test-8.json b/tests/framework/base/activitymanager/intent_tests/newTask/test-8.json
new file mode 100644
index 0000000..6760b49
--- /dev/null
+++ b/tests/framework/base/activitymanager/intent_tests/newTask/test-8.json
@@ -0,0 +1,104 @@
+{
+ "setup": {
+ "initialIntents": [
+ {
+ "flags": "FLAG_ACTIVITY_NEW_TASK",
+ "class": "android.server.am.intent.Activities$RegularActivity",
+ "package": "android.server.cts.am",
+ "startForResult": false
+ },
+ {
+ "flags": "FLAG_ACTIVITY_NEW_TASK",
+ "class": "android.server.am.intent.Activities$TaskAffinity1Activity",
+ "package": "android.server.cts.am",
+ "startForResult": false
+ },
+ {
+ "flags": "",
+ "class": "android.server.am.intent.Activities$RegularActivity",
+ "package": "android.server.cts.am",
+ "startForResult": false
+ },
+ {
+ "flags": "FLAG_ACTIVITY_REORDER_TO_FRONT",
+ "class": "android.server.am.intent.Activities$TaskAffinity1Activity",
+ "package": "android.server.cts.am",
+ "startForResult": false
+ }
+ ],
+ "act": [
+ {
+ "flags": "FLAG_ACTIVITY_NEW_TASK",
+ "class": "android.server.am.intent.Activities$TaskAffinity1Activity",
+ "package": "android.server.cts.am",
+ "startForResult": false
+ }
+ ]
+ },
+ "initialState": {
+ "stacks": [
+ {
+ "tasks": [
+ {
+ "activities": [
+ {
+ "name": "android.server.cts.am\/android.server.am.intent.Activities$TaskAffinity1Activity",
+ "state": "RESUMED"
+ },
+ {
+ "name": "android.server.cts.am\/android.server.am.intent.Activities$RegularActivity",
+ "state": "STOPPED"
+ }
+ ]
+ }
+ ],
+ "resumedActivity": "android.server.cts.am\/android.server.am.intent.Activities$TaskAffinity1Activity"
+ },
+ {
+ "tasks": [
+ {
+ "activities": [
+ {
+ "name": "android.server.cts.am\/android.server.am.intent.Activities$RegularActivity",
+ "state": "STOPPED"
+ }
+ ]
+ }
+ ]
+ }
+ ]
+ },
+ "endState": {
+ "stacks": [
+ {
+ "tasks": [
+ {
+ "activities": [
+ {
+ "name": "android.server.cts.am\/android.server.am.intent.Activities$TaskAffinity1Activity",
+ "state": "RESUMED"
+ },
+ {
+ "name": "android.server.cts.am\/android.server.am.intent.Activities$RegularActivity",
+ "state": "STOPPED"
+ }
+ ]
+ }
+ ],
+ "resumedActivity": "android.server.cts.am\/android.server.am.intent.Activities$TaskAffinity1Activity"
+ },
+ {
+ "tasks": [
+ {
+ "activities": [
+ {
+ "name": "android.server.cts.am\/android.server.am.intent.Activities$RegularActivity",
+ "state": "STOPPED"
+ }
+ ]
+ }
+ ]
+ }
+ ]
+ }
+}
diff --git a/tests/framework/base/activitymanager/intent_tests/newTask/test-9.json b/tests/framework/base/activitymanager/intent_tests/newTask/test-9.json
new file mode 100644
index 0000000..7f2e4fc
--- /dev/null
+++ b/tests/framework/base/activitymanager/intent_tests/newTask/test-9.json
@@ -0,0 +1,108 @@
+{
+ "setup": {
+ "initialIntents": [
+ {
+ "flags": "FLAG_ACTIVITY_NEW_TASK",
+ "class": "android.server.am.intent.Activities$RegularActivity",
+ "package": "android.server.cts.am",
+ "startForResult": false
+ },
+ {
+ "flags": "FLAG_ACTIVITY_NEW_TASK",
+ "class": "android.server.am.intent.Activities$TaskAffinity1Activity",
+ "package": "android.server.cts.am",
+ "startForResult": false
+ },
+ {
+ "flags": "",
+ "class": "android.server.am.intent.Activities$RegularActivity",
+ "package": "android.server.cts.am",
+ "startForResult": false
+ },
+ {
+ "flags": "FLAG_ACTIVITY_REORDER_TO_FRONT",
+ "class": "android.server.am.intent.Activities$TaskAffinity1Activity",
+ "package": "android.server.cts.am",
+ "startForResult": false
+ }
+ ],
+ "act": [
+ {
+ "flags": "FLAG_ACTIVITY_NEW_TASK",
+ "class": "android.server.am.intent.Activities$TaskAffinity1Activity2",
+ "package": "android.server.cts.am",
+ "startForResult": false
+ }
+ ]
+ },
+ "initialState": {
+ "stacks": [
+ {
+ "tasks": [
+ {
+ "activities": [
+ {
+ "name": "android.server.cts.am\/android.server.am.intent.Activities$TaskAffinity1Activity",
+ "state": "RESUMED"
+ },
+ {
+ "name": "android.server.cts.am\/android.server.am.intent.Activities$RegularActivity",
+ "state": "STOPPED"
+ }
+ ]
+ }
+ ],
+ "resumedActivity": "android.server.cts.am\/android.server.am.intent.Activities$TaskAffinity1Activity"
+ },
+ {
+ "tasks": [
+ {
+ "activities": [
+ {
+ "name": "android.server.cts.am\/android.server.am.intent.Activities$RegularActivity",
+ "state": "STOPPED"
+ }
+ ]
+ }
+ ]
+ }
+ ]
+ },
+ "endState": {
+ "stacks": [
+ {
+ "tasks": [
+ {
+ "activities": [
+ {
+ "name": "android.server.cts.am\/android.server.am.intent.Activities$TaskAffinity1Activity2",
+ "state": "RESUMED"
+ },
+ {
+ "name": "android.server.cts.am\/android.server.am.intent.Activities$TaskAffinity1Activity",
+ "state": "STOPPED"
+ },
+ {
+ "name": "android.server.cts.am\/android.server.am.intent.Activities$RegularActivity",
+ "state": "STOPPED"
+ }
+ ]
+ }
+ ],
+ "resumedActivity": "android.server.cts.am\/android.server.am.intent.Activities$TaskAffinity1Activity2"
+ },
+ {
+ "tasks": [
+ {
+ "activities": [
+ {
+ "name": "android.server.cts.am\/android.server.am.intent.Activities$RegularActivity",
+ "state": "STOPPED"
+ }
+ ]
+ }
+ ]
+ }
+ ]
+ }
+}
diff --git a/tests/framework/base/activitymanager/intent_tests/resetTaskIfNeeded/test-1.json b/tests/framework/base/activitymanager/intent_tests/resetTaskIfNeeded/test-1.json
new file mode 100644
index 0000000..5aff52d
--- /dev/null
+++ b/tests/framework/base/activitymanager/intent_tests/resetTaskIfNeeded/test-1.json
@@ -0,0 +1,72 @@
+{
+ "setup": {
+ "initialIntents": [
+ {
+ "flags": "FLAG_ACTIVITY_NEW_TASK",
+ "class": "android.server.am.intent.Activities$RegularActivity",
+ "package": "android.server.cts.am",
+ "startForResult": false
+ },
+ {
+ "flags": "",
+ "class": "android.server.am.intent.Activities$TaskAffinity1Activity",
+ "package": "android.server.cts.am",
+ "startForResult": false
+ }
+ ],
+ "act": [
+ {
+ "flags": "FLAG_ACTIVITY_NEW_TASK | FLAG_ACTIVITY_RESET_TASK_IF_NEEDED",
+ "class": "android.server.am.intent.Activities$RegularActivity",
+ "package": "android.server.cts.am",
+ "startForResult": false
+ }
+ ]
+ },
+ "initialState": {
+ "stacks": [
+ {
+ "tasks": [
+ {
+ "activities": [
+ {
+ "name": "android.server.cts.am\/android.server.am.intent.Activities$TaskAffinity1Activity",
+ "state": "RESUMED"
+ },
+ {
+ "name": "android.server.cts.am\/android.server.am.intent.Activities$RegularActivity",
+ "state": "STOPPED"
+ }
+ ]
+ }
+ ],
+ "resumedActivity": "android.server.cts.am\/android.server.am.intent.Activities$TaskAffinity1Activity"
+ }
+ ]
+ },
+ "endState": {
+ "stacks": [
+ {
+ "tasks": [
+ {
+ "activities": [
+ {
+ "name": "android.server.cts.am\/android.server.am.intent.Activities$RegularActivity",
+ "state": "RESUMED"
+ }
+ ]
+ },
+ {
+ "activities": [
+ {
+ "name": "android.server.cts.am\/android.server.am.intent.Activities$TaskAffinity1Activity",
+ "state": "STOPPED"
+ }
+ ]
+ }
+ ],
+ "resumedActivity": "android.server.cts.am\/android.server.am.intent.Activities$RegularActivity"
+ }
+ ]
+ }
+}
diff --git a/tests/framework/base/activitymanager/intent_tests/resetTaskIfNeeded/test-2.json b/tests/framework/base/activitymanager/intent_tests/resetTaskIfNeeded/test-2.json
new file mode 100644
index 0000000..7da81f0
--- /dev/null
+++ b/tests/framework/base/activitymanager/intent_tests/resetTaskIfNeeded/test-2.json
@@ -0,0 +1,68 @@
+{
+ "setup": {
+ "initialIntents": [
+ {
+ "flags": "FLAG_ACTIVITY_NEW_TASK",
+ "class": "android.server.am.intent.Activities$RegularActivity",
+ "package": "android.server.cts.am",
+ "startForResult": false
+ },
+ {
+ "flags": "",
+ "class": "android.server.am.intent.Activities$TaskAffinity1Activity",
+ "package": "android.server.cts.am",
+ "startForResult": true
+ }
+ ],
+ "act": [
+ {
+ "flags": "FLAG_ACTIVITY_NEW_TASK | FLAG_ACTIVITY_RESET_TASK_IF_NEEDED",
+ "class": "android.server.am.intent.Activities$RegularActivity",
+ "package": "android.server.cts.am",
+ "startForResult": false
+ }
+ ]
+ },
+ "initialState": {
+ "stacks": [
+ {
+ "tasks": [
+ {
+ "activities": [
+ {
+ "name": "android.server.cts.am\/android.server.am.intent.Activities$TaskAffinity1Activity",
+ "state": "RESUMED"
+ },
+ {
+ "name": "android.server.cts.am\/android.server.am.intent.Activities$RegularActivity",
+ "state": "STOPPED"
+ }
+ ]
+ }
+ ],
+ "resumedActivity": "android.server.cts.am\/android.server.am.intent.Activities$TaskAffinity1Activity"
+ }
+ ]
+ },
+ "endState": {
+ "stacks": [
+ {
+ "tasks": [
+ {
+ "activities": [
+ {
+ "name": "android.server.cts.am\/android.server.am.intent.Activities$TaskAffinity1Activity",
+ "state": "RESUMED"
+ },
+ {
+ "name": "android.server.cts.am\/android.server.am.intent.Activities$RegularActivity",
+ "state": "STOPPED"
+ }
+ ]
+ }
+ ],
+ "resumedActivity": "android.server.cts.am\/android.server.am.intent.Activities$TaskAffinity1Activity"
+ }
+ ]
+ }
+}
diff --git a/tests/framework/base/activitymanager/intent_tests/resetTaskIfNeeded/test-3.json b/tests/framework/base/activitymanager/intent_tests/resetTaskIfNeeded/test-3.json
new file mode 100644
index 0000000..722814f9
--- /dev/null
+++ b/tests/framework/base/activitymanager/intent_tests/resetTaskIfNeeded/test-3.json
@@ -0,0 +1,102 @@
+{
+ "setup": {
+ "initialIntents": [
+ {
+ "flags": "FLAG_ACTIVITY_NEW_TASK",
+ "class": "android.server.am.intent.Activities$RegularActivity",
+ "package": "android.server.cts.am",
+ "startForResult": false
+ },
+ {
+ "flags": "",
+ "class": "android.server.am.intent.Activities$TaskAffinity1Activity",
+ "package": "android.server.cts.am",
+ "startForResult": false
+ },
+ {
+ "flags": "FLAG_ACTIVITY_NEW_TASK",
+ "class": "android.server.am.intent.Activities$TaskAffinity1Activity",
+ "package": "android.server.cts.am",
+ "startForResult": false
+ }
+ ],
+ "act": [
+ {
+ "flags": "FLAG_ACTIVITY_NEW_TASK | FLAG_ACTIVITY_RESET_TASK_IF_NEEDED",
+ "class": "android.server.am.intent.Activities$RegularActivity",
+ "package": "android.server.cts.am",
+ "startForResult": false
+ }
+ ]
+ },
+ "initialState": {
+ "stacks": [
+ {
+ "tasks": [
+ {
+ "activities": [
+ {
+ "name": "android.server.cts.am\/android.server.am.intent.Activities$TaskAffinity1Activity",
+ "state": "RESUMED"
+ }
+ ]
+ }
+ ],
+ "resumedActivity": "android.server.cts.am\/android.server.am.intent.Activities$TaskAffinity1Activity"
+ },
+ {
+ "tasks": [
+ {
+ "activities": [
+ {
+ "name": "android.server.cts.am\/android.server.am.intent.Activities$TaskAffinity1Activity",
+ "state": "STOPPED"
+ },
+ {
+ "name": "android.server.cts.am\/android.server.am.intent.Activities$RegularActivity",
+ "state": "STOPPED"
+ }
+ ]
+ }
+ ]
+ }
+ ]
+ },
+ "endState": {
+ "stacks": [
+ {
+ "tasks": [
+ {
+ "activities": [
+ {
+ "name": "android.server.cts.am\/android.server.am.intent.Activities$RegularActivity",
+ "state": "RESUMED"
+ }
+ ]
+ },
+ {
+ "activities": [
+ {
+ "name": "android.server.cts.am\/android.server.am.intent.Activities$TaskAffinity1Activity",
+ "state": "STOPPED"
+ }
+ ]
+ }
+ ],
+ "resumedActivity": "android.server.cts.am\/android.server.am.intent.Activities$RegularActivity"
+ },
+ {
+ "tasks": [
+ {
+ "activities": [
+ {
+ "name": "android.server.cts.am\/android.server.am.intent.Activities$TaskAffinity1Activity",
+ "state": "STOPPED"
+ }
+ ]
+ }
+ ]
+ }
+ ]
+ }
+}
diff --git a/tests/framework/base/activitymanager/intent_tests/resetTaskIfNeeded/test-4.json b/tests/framework/base/activitymanager/intent_tests/resetTaskIfNeeded/test-4.json
new file mode 100644
index 0000000..126c753
--- /dev/null
+++ b/tests/framework/base/activitymanager/intent_tests/resetTaskIfNeeded/test-4.json
@@ -0,0 +1,86 @@
+{
+ "setup": {
+ "initialIntents": [
+ {
+ "flags": "FLAG_ACTIVITY_NEW_TASK",
+ "class": "android.server.am.intent.Activities$RegularActivity",
+ "package": "android.server.cts.am",
+ "startForResult": false
+ },
+ {
+ "flags": "",
+ "class": "android.server.am.intent.Activities$TaskAffinity1Activity",
+ "package": "android.server.cts.am",
+ "startForResult": false
+ },
+ {
+ "flags": "",
+ "class": "android.server.am.intent.Activities$TaskAffinity1Activity2",
+ "package": "android.server.cts.am",
+ "startForResult": false
+ }
+ ],
+ "act": [
+ {
+ "flags": "FLAG_ACTIVITY_NEW_TASK | FLAG_ACTIVITY_RESET_TASK_IF_NEEDED",
+ "class": "android.server.am.intent.Activities$RegularActivity",
+ "package": "android.server.cts.am",
+ "startForResult": false
+ }
+ ]
+ },
+ "initialState": {
+ "stacks": [
+ {
+ "tasks": [
+ {
+ "activities": [
+ {
+ "name": "android.server.cts.am\/android.server.am.intent.Activities$TaskAffinity1Activity2",
+ "state": "RESUMED"
+ },
+ {
+ "name": "android.server.cts.am\/android.server.am.intent.Activities$TaskAffinity1Activity",
+ "state": "STOPPED"
+ },
+ {
+ "name": "android.server.cts.am\/android.server.am.intent.Activities$RegularActivity",
+ "state": "STOPPED"
+ }
+ ]
+ }
+ ],
+ "resumedActivity": "android.server.cts.am\/android.server.am.intent.Activities$TaskAffinity1Activity2"
+ }
+ ]
+ },
+ "endState": {
+ "stacks": [
+ {
+ "tasks": [
+ {
+ "activities": [
+ {
+ "name": "android.server.cts.am\/android.server.am.intent.Activities$RegularActivity",
+ "state": "RESUMED"
+ }
+ ]
+ },
+ {
+ "activities": [
+ {
+ "name": "android.server.cts.am\/android.server.am.intent.Activities$TaskAffinity1Activity2",
+ "state": "STOPPED"
+ },
+ {
+ "name": "android.server.cts.am\/android.server.am.intent.Activities$TaskAffinity1Activity",
+ "state": "STOPPED"
+ }
+ ]
+ }
+ ],
+ "resumedActivity": "android.server.cts.am\/android.server.am.intent.Activities$RegularActivity"
+ }
+ ]
+ }
+}
diff --git a/tests/framework/base/activitymanager/src/android/server/am/ActivityManagerActivityVisibilityTests.java b/tests/framework/base/activitymanager/src/android/server/am/ActivityManagerActivityVisibilityTests.java
index f1e8616..a696f58 100644
--- a/tests/framework/base/activitymanager/src/android/server/am/ActivityManagerActivityVisibilityTests.java
+++ b/tests/framework/base/activitymanager/src/android/server/am/ActivityManagerActivityVisibilityTests.java
@@ -47,6 +47,7 @@
import static android.server.am.Components.TURN_SCREEN_ON_SINGLE_TASK_ACTIVITY;
import static android.server.am.Components.TURN_SCREEN_ON_WITH_RELAYOUT_ACTIVITY;
import static android.server.am.UiDeviceUtils.pressBackButton;
+import static android.server.am.UiDeviceUtils.pressHomeButton;
import static android.server.am.VirtualDisplayHelper.waitForDefaultDisplayState;
import static android.view.Display.DEFAULT_DISPLAY;
@@ -469,4 +470,58 @@
assertFalse("Display keeps off", isDisplayOn(DEFAULT_DISPLAY));
}
}
+
+ @Test
+ public void testGoingHomeMultipleTimes() throws Exception {
+ for (int i = 0; i < 10; i++) {
+ // Start activity normally
+ launchActivityOnDisplay(TEST_ACTIVITY, DEFAULT_DISPLAY);
+ waitAndAssertTopResumedActivity(TEST_ACTIVITY, DEFAULT_DISPLAY,
+ "Activity launched on default display must be focused");
+
+ // Press home button
+ launchHomeActivity();
+
+ mAmWmState.assertHomeActivityVisible(true);
+ waitAndAssertActivityState(TEST_ACTIVITY, STATE_STOPPED,
+ "Activity should become STOPPED");
+ mAmWmState.assertVisibility(TEST_ACTIVITY, false);
+ }
+ }
+
+ @Test
+ public void testPressingHomeButtonMultipleTimes() throws Exception {
+ for (int i = 0; i < 10; i++) {
+ // Start activity normally
+ launchActivityOnDisplay(TEST_ACTIVITY, DEFAULT_DISPLAY);
+ waitAndAssertTopResumedActivity(TEST_ACTIVITY, DEFAULT_DISPLAY,
+ "Activity launched on default display must be focused");
+
+ // Press home button
+ pressHomeButton();
+
+ // Wait and assert home and activity states
+ mAmWmState.waitForHomeActivityVisible();
+ mAmWmState.assertHomeActivityVisible(true);
+ waitAndAssertActivityState(TEST_ACTIVITY, STATE_STOPPED,
+ "Activity should become STOPPED");
+ mAmWmState.assertVisibility(TEST_ACTIVITY, false);
+ }
+ }
+
+ @Test
+ public void testPressingHomeButtonMultipleTimesQuick() throws Exception {
+ for (int i = 0; i < 10; i++) {
+ // Start activity normally
+ launchActivityOnDisplay(TEST_ACTIVITY, DEFAULT_DISPLAY);
+
+ // Press home button
+ pressHomeButton();
+ mAmWmState.waitForHomeActivityVisible();
+ mAmWmState.assertHomeActivityVisible(true);
+ }
+ waitAndAssertActivityState(TEST_ACTIVITY, STATE_STOPPED,
+ "Activity should become STOPPED");
+ mAmWmState.assertVisibility(TEST_ACTIVITY, false);
+ }
}
diff --git a/tests/framework/base/activitymanager/src/android/server/am/ActivityManagerAppConfigurationTests.java b/tests/framework/base/activitymanager/src/android/server/am/ActivityManagerAppConfigurationTests.java
index 9aae800..396e130 100644
--- a/tests/framework/base/activitymanager/src/android/server/am/ActivityManagerAppConfigurationTests.java
+++ b/tests/framework/base/activitymanager/src/android/server/am/ActivityManagerAppConfigurationTests.java
@@ -51,6 +51,7 @@
import static org.junit.Assert.fail;
import static org.junit.Assume.assumeFalse;
import static org.junit.Assume.assumeTrue;
+import static com.android.compatibility.common.util.PackageUtil.supportsRotation;
import android.content.ComponentName;
import android.content.res.Configuration;
@@ -470,6 +471,10 @@
@Test
public void testNonFullscreenActivityPermitted() throws Exception {
+ if(!supportsRotation()) {
+ //cannot physically rotate the screen on automotive device, skip
+ return;
+ }
try (final RotationSession rotationSession = new RotationSession()) {
rotationSession.set(ROTATION_0);
diff --git a/tests/framework/base/activitymanager/src/android/server/am/ActivityManagerDisplayLockedKeyguardTests.java b/tests/framework/base/activitymanager/src/android/server/am/ActivityManagerDisplayLockedKeyguardTests.java
index 5407f62..bc6171a 100644
--- a/tests/framework/base/activitymanager/src/android/server/am/ActivityManagerDisplayLockedKeyguardTests.java
+++ b/tests/framework/base/activitymanager/src/android/server/am/ActivityManagerDisplayLockedKeyguardTests.java
@@ -18,6 +18,7 @@
import static android.server.am.ActivityManagerState.STATE_RESUMED;
import static android.server.am.ActivityManagerState.STATE_STOPPED;
+import static android.server.am.ActivityManagerTestBase.LockScreenSession.FLAG_REMOVE_ACTIVITIES_ON_CLOSE;
import static android.server.am.Components.DISMISS_KEYGUARD_ACTIVITY;
import static android.server.am.Components.SHOW_WHEN_LOCKED_ACTIVITY;
import static android.server.am.Components.TEST_ACTIVITY;
@@ -52,8 +53,8 @@
*/
@Test
public void testVirtualDisplayHidesContentWhenLocked() throws Exception {
- try (final VirtualDisplaySession virtualDisplaySession = new VirtualDisplaySession();
- final LockScreenSession lockScreenSession = new LockScreenSession()) {
+ try (final LockScreenSession lockScreenSession = new LockScreenSession();
+ final VirtualDisplaySession virtualDisplaySession = new VirtualDisplaySession()) {
lockScreenSession.setLockCredential();
// Create new usual virtual display.
@@ -84,12 +85,34 @@
}
/**
+ * Tests that private display cannot show content while device locked.
+ */
+ @Test
+ public void testPrivateDisplayHideContentWhenLocked() throws Exception {
+ try (final LockScreenSession lockScreenSession = new LockScreenSession();
+ final VirtualDisplaySession virtualDisplaySession = new VirtualDisplaySession()) {
+ lockScreenSession.setLockCredential();
+
+ final ActivityDisplay newDisplay =
+ virtualDisplaySession.setPublicDisplay(false).createDisplay();
+ launchActivityOnDisplay(TEST_ACTIVITY, newDisplay.mId);
+
+ lockScreenSession.gotoKeyguard();
+
+ waitAndAssertActivityState(TEST_ACTIVITY, STATE_STOPPED,
+ "Expected stopped activity on private display");
+ mAmWmState.assertVisibility(TEST_ACTIVITY, false /* visible */);
+ }
+ }
+
+ /**
* Tests whether a FLAG_DISMISS_KEYGUARD activity on a secondary display dismisses the keyguard.
*/
@Test
public void testDismissKeyguard_secondaryDisplay() throws Exception {
- try (final VirtualDisplaySession virtualDisplaySession = new VirtualDisplaySession();
- final LockScreenSession lockScreenSession = new LockScreenSession()) {
+ try (final LockScreenSession lockScreenSession =
+ new LockScreenSession(FLAG_REMOVE_ACTIVITIES_ON_CLOSE);
+ final VirtualDisplaySession virtualDisplaySession = new VirtualDisplaySession()) {
lockScreenSession.setLockCredential();
final ActivityDisplay newDisplay = virtualDisplaySession.setPublicDisplay(true).
createDisplay();
@@ -111,8 +134,9 @@
@Test
public void testDismissKeyguard_whileOccluded_secondaryDisplay() throws Exception {
- try (final VirtualDisplaySession virtualDisplaySession = new VirtualDisplaySession();
- final LockScreenSession lockScreenSession = new LockScreenSession()) {
+ try (final LockScreenSession lockScreenSession =
+ new LockScreenSession(FLAG_REMOVE_ACTIVITIES_ON_CLOSE);
+ final VirtualDisplaySession virtualDisplaySession = new VirtualDisplaySession()) {
lockScreenSession.setLockCredential();
final ActivityDisplay newDisplay = virtualDisplaySession.setPublicDisplay(true).
createDisplay();
diff --git a/tests/framework/base/activitymanager/src/android/server/am/ActivityManagerManifestLayoutTests.java b/tests/framework/base/activitymanager/src/android/server/am/ActivityManagerManifestLayoutTests.java
index fadc8fc..c9044b4 100644
--- a/tests/framework/base/activitymanager/src/android/server/am/ActivityManagerManifestLayoutTests.java
+++ b/tests/framework/base/activitymanager/src/android/server/am/ActivityManagerManifestLayoutTests.java
@@ -50,8 +50,8 @@
// Test parameters
private static final int DEFAULT_WIDTH_DP = 240;
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 float DEFAULT_WIDTH_FRACTION = 0.50f;
+ private static final float DEFAULT_HEIGHT_FRACTION = 0.70f;
private static final int MIN_WIDTH_DP = 100;
private static final int MIN_HEIGHT_DP = 80;
diff --git a/tests/framework/base/activitymanager/src/android/server/am/ActivityManagerMultiDisplayTests.java b/tests/framework/base/activitymanager/src/android/server/am/ActivityManagerMultiDisplayTests.java
index ac73eae..efe401b 100644
--- a/tests/framework/base/activitymanager/src/android/server/am/ActivityManagerMultiDisplayTests.java
+++ b/tests/framework/base/activitymanager/src/android/server/am/ActivityManagerMultiDisplayTests.java
@@ -1493,14 +1493,8 @@
// Destroy the display and check if activities are removed from system.
}
- mAmWmState.waitForWithAmState(
- (state) -> !state.containsActivity(TEST_ACTIVITY)
- && !state.containsActivity(RESIZEABLE_ACTIVITY),
- "Waiting for activity to be removed");
- mAmWmState.waitForWithWmState(
- (state) -> !state.containsWindow(getWindowName(TEST_ACTIVITY))
- && !state.containsWindow(getWindowName(RESIZEABLE_ACTIVITY)),
- "Waiting for activity window to be gone");
+ mAmWmState.waitForActivityRemoved(TEST_ACTIVITY);
+ mAmWmState.waitForActivityRemoved(RESIZEABLE_ACTIVITY);
// Check AM state.
assertFalse("Activity from removed display must be destroyed",
@@ -1546,7 +1540,6 @@
* Test that the update of display metrics updates all its content.
*/
@Test
- @FlakyTest(bugId = 121105810)
public void testDisplayResize() throws Exception {
try (final VirtualDisplaySession virtualDisplaySession = new VirtualDisplaySession()) {
// Create new virtual display.
diff --git a/tests/framework/base/activitymanager/src/android/server/am/ActivityManagerSplitScreenTests.java b/tests/framework/base/activitymanager/src/android/server/am/ActivityManagerSplitScreenTests.java
index c5952b3..bb8c144 100644
--- a/tests/framework/base/activitymanager/src/android/server/am/ActivityManagerSplitScreenTests.java
+++ b/tests/framework/base/activitymanager/src/android/server/am/ActivityManagerSplitScreenTests.java
@@ -508,6 +508,7 @@
mBroadcastActionTrigger.doAction(TEST_ACTIVITY_ACTION_FINISH_SELF);
waitForDockNotMinimized();
+ mAmWmState.waitForActivityRemoved(TEST_ACTIVITY);
mAmWmState.assertNotExist(TEST_ACTIVITY);
assertDockNotMinimized();
}
diff --git a/tests/framework/base/activitymanager/src/android/server/am/ActivityViewTest.java b/tests/framework/base/activitymanager/src/android/server/am/ActivityViewTest.java
new file mode 100644
index 0000000..139c0cd
--- /dev/null
+++ b/tests/framework/base/activitymanager/src/android/server/am/ActivityViewTest.java
@@ -0,0 +1,201 @@
+/*
+ * Copyright (C) 2019 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.server.am;
+
+import static android.server.am.ActivityManagerState.STATE_RESUMED;
+import static android.server.am.ActivityManagerState.STATE_STOPPED;
+import static android.server.am.Components.TEST_ACTIVITY;
+import static android.view.ViewGroup.LayoutParams.MATCH_PARENT;
+
+import static org.junit.Assert.assertTrue;
+
+import android.app.Activity;
+import android.app.ActivityView;
+import android.app.Instrumentation;
+import android.content.ComponentName;
+import android.content.Intent;
+import android.graphics.Rect;
+import android.os.Bundle;
+import android.os.SystemClock;
+import android.platform.test.annotations.Presubmit;
+import android.support.test.InstrumentationRegistry;
+import android.support.test.annotation.UiThreadTest;
+import android.support.test.filters.FlakyTest;
+import android.support.test.rule.ActivityTestRule;
+import android.view.View;
+import android.view.ViewGroup;
+
+import com.android.compatibility.common.util.SystemUtil;
+
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+
+/**
+ * Build/Install/Run:
+ * atest CtsActivityManagerDeviceTestCases:ActivityViewTest
+ */
+@Presubmit
+@FlakyTest
+public class ActivityViewTest extends ActivityManagerTestBase {
+
+ private Instrumentation mInstrumentation;
+ private ActivityView mActivityView;
+
+ @Rule
+ public ActivityTestRule<ActivityViewTestActivity> mActivityRule =
+ new ActivityTestRule<>(ActivityViewTestActivity.class);
+
+ @Before
+ public void setup() {
+ mInstrumentation = InstrumentationRegistry.getInstrumentation();
+ ActivityViewTestActivity activity = mActivityRule.launchActivity(null);
+ mActivityView = activity.getActivityView();
+ separateTestJournal();
+ }
+
+ @Test
+ public void testStartActivity() {
+ launchActivityInActivityView(TEST_ACTIVITY);
+ assertSingleLaunch(TEST_ACTIVITY);
+ }
+
+ @UiThreadTest
+ @Test
+ public void testResizeActivityView() {
+ final int width = 500;
+ final int height = 500;
+
+ launchActivityInActivityView(TEST_ACTIVITY);
+ assertSingleLaunch(TEST_ACTIVITY);
+
+ mActivityView.layout(0, 0, width, height);
+
+ boolean boundsMatched = checkDisplaySize(TEST_ACTIVITY, width, height);
+ assertTrue("displayWidth and displayHeight must equal " + width + "x" + height,
+ boundsMatched);
+ }
+
+ private boolean checkDisplaySize(ComponentName activity, int requestedWidth,
+ int requestedHeight) {
+ final int maxTries = 5;
+ final int retryIntervalMs = 1000;
+
+ boolean boundsMatched = false;
+
+ // Display size for the activity may not get updated right away. Retry in case.
+ for (int i = 0; i < maxTries; i++) {
+ mAmWmState.getWmState().computeState();
+ int displayId = mAmWmState.getAmState().getDisplayByActivity(activity);
+ WindowManagerState.Display display = mAmWmState.getWmState().getDisplay(displayId);
+ int avDisplayWidth = 0;
+ int avDisplayHeight = 0;
+ if (display != null) {
+ Rect bounds = display.mFullConfiguration.windowConfiguration.getAppBounds();
+ if (bounds != null) {
+ avDisplayWidth = bounds.width();
+ avDisplayHeight = bounds.height();
+ }
+ }
+ boundsMatched = avDisplayWidth == requestedWidth && avDisplayHeight == requestedHeight;
+ if (boundsMatched) {
+ return true;
+ }
+
+ // wait and try again
+ SystemClock.sleep(retryIntervalMs);
+ }
+
+ return boundsMatched;
+ }
+
+ @Test
+ public void testAppStoppedWithVisibilityGone() {
+ launchActivityInActivityView(TEST_ACTIVITY);
+ assertSingleLaunch(TEST_ACTIVITY);
+
+ separateTestJournal();
+ mInstrumentation.runOnMainSync(() -> mActivityView.setVisibility(View.GONE));
+ mInstrumentation.waitForIdleSync();
+ mAmWmState.waitForActivityState(TEST_ACTIVITY, STATE_STOPPED);
+
+ assertLifecycleCounts(TEST_ACTIVITY, 0, 0, 0, 1, 1, 0, CountSpec.DONT_CARE);
+ }
+
+ @Test
+ public void testAppStoppedWithVisibilityInvisible() {
+ launchActivityInActivityView(TEST_ACTIVITY);
+ assertSingleLaunch(TEST_ACTIVITY);
+
+ separateTestJournal();
+ mInstrumentation.runOnMainSync(() -> mActivityView.setVisibility(View.INVISIBLE));
+ mInstrumentation.waitForIdleSync();
+ mAmWmState.waitForActivityState(TEST_ACTIVITY, STATE_STOPPED);
+
+ assertLifecycleCounts(TEST_ACTIVITY, 0, 0, 0, 1, 1, 0, CountSpec.DONT_CARE);
+ }
+
+ @Test
+ public void testAppStopAndStartWithVisibilityChange() {
+ launchActivityInActivityView(TEST_ACTIVITY);
+ assertSingleLaunch(TEST_ACTIVITY);
+
+ separateTestJournal();
+ mInstrumentation.runOnMainSync(() -> mActivityView.setVisibility(View.INVISIBLE));
+ mInstrumentation.waitForIdleSync();
+ mAmWmState.waitForActivityState(TEST_ACTIVITY, STATE_STOPPED);
+
+ assertLifecycleCounts(TEST_ACTIVITY, 0, 0, 0, 1, 1, 0, CountSpec.DONT_CARE);
+
+ separateTestJournal();
+ mInstrumentation.runOnMainSync(() -> mActivityView.setVisibility(View.VISIBLE));
+ mInstrumentation.waitForIdleSync();
+ mAmWmState.waitForActivityState(TEST_ACTIVITY, STATE_RESUMED);
+
+ assertLifecycleCounts(TEST_ACTIVITY, 0, 1, 1, 0, 0, 0, CountSpec.DONT_CARE);
+ }
+
+ private void launchActivityInActivityView(ComponentName activity) {
+ Intent intent = new Intent();
+ intent.setComponent(activity);
+ intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_MULTIPLE_TASK);
+ SystemUtil.runWithShellPermissionIdentity(() -> mActivityView.startActivity(intent));
+ mAmWmState.waitForValidState(activity);
+ }
+
+ // Test activity
+ public static class ActivityViewTestActivity extends Activity {
+ private ActivityView mActivityView;
+
+ @Override
+ public void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+
+ mActivityView = new ActivityView(this);
+ setContentView(mActivityView);
+
+ ViewGroup.LayoutParams layoutParams = mActivityView.getLayoutParams();
+ layoutParams.width = MATCH_PARENT;
+ layoutParams.height = MATCH_PARENT;
+ mActivityView.requestLayout();
+ }
+
+ ActivityView getActivityView() {
+ return mActivityView;
+ }
+ }
+}
diff --git a/tests/framework/base/activitymanager/src/android/server/am/KeyguardLockedTests.java b/tests/framework/base/activitymanager/src/android/server/am/KeyguardLockedTests.java
index 7daccc8..28fe737 100644
--- a/tests/framework/base/activitymanager/src/android/server/am/KeyguardLockedTests.java
+++ b/tests/framework/base/activitymanager/src/android/server/am/KeyguardLockedTests.java
@@ -25,20 +25,40 @@
import static android.server.am.Components.PipActivity.EXTRA_ENTER_PIP;
import static android.server.am.Components.PipActivity.EXTRA_SHOW_OVER_KEYGUARD;
import static android.server.am.Components.SHOW_WHEN_LOCKED_ACTIVITY;
+import static android.server.am.Components.SHOW_WHEN_LOCKED_ATTR_IME_ACTIVITY;
import static android.server.am.Components.TURN_SCREEN_ON_ATTR_DISMISS_KEYGUARD_ACTIVITY;
import static android.server.am.UiDeviceUtils.pressBackButton;
import static android.view.Display.DEFAULT_DISPLAY;
+import static android.view.WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_VISIBLE;
+
+import static com.android.cts.mockime.ImeEventStreamTestUtils.expectEvent;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;
import static org.junit.Assume.assumeTrue;
+import android.app.Activity;
import android.app.KeyguardManager;
import android.content.ComponentName;
+import android.os.Bundle;
+import android.os.SystemClock;
+import android.view.inputmethod.EditorInfo;
+import android.view.inputmethod.InputMethodManager;
+import android.widget.EditText;
+import android.widget.LinearLayout;
+
+import android.support.test.InstrumentationRegistry;
+
+import com.android.cts.mockime.ImeEvent;
+import com.android.cts.mockime.ImeEventStream;
+import com.android.cts.mockime.ImeSettings;
+import com.android.cts.mockime.MockImeSession;
import org.junit.Before;
import org.junit.Test;
+import java.util.concurrent.TimeUnit;
+
/**
* Build/Install/Run:
* atest CtsActivityManagerDeviceTestCases:KeyguardLockedTests
@@ -275,6 +295,73 @@
}
}
+ @Test
+ public void testShowWhenLockedAttrImeActivityAndShowSoftInput() throws Exception {
+ try (final LockScreenSession lockScreenSession = new LockScreenSession();
+ // Leverage MockImeSession to ensure at least an IME exists as default.
+ final MockImeSession mockImeSession = MockImeSession.create(mContext,
+ InstrumentationRegistry.getInstrumentation().getUiAutomation(),
+ new ImeSettings.Builder())) {
+ lockScreenSession.setLockCredential().gotoKeyguard();
+ mAmWmState.assertKeyguardShowingAndNotOccluded();
+ launchActivity(SHOW_WHEN_LOCKED_ATTR_IME_ACTIVITY);
+ mAmWmState.computeState(SHOW_WHEN_LOCKED_ATTR_IME_ACTIVITY);
+ mAmWmState.assertVisibility(SHOW_WHEN_LOCKED_ATTR_IME_ACTIVITY, true);
+
+ // Make sure the activity has been called showSoftInput & IME window is visible.
+ final ImeEventStream stream = mockImeSession.openEventStream();
+ expectEvent(stream, event -> "showSoftInput".equals(event.getEventName()),
+ TimeUnit.SECONDS.toMillis(5) /* eventTimeout */);
+ // Assert the IME is shown on the expected display.
+ mAmWmState.waitAndAssertImeWindowShownOnDisplay(DEFAULT_DISPLAY);
+ }
+ }
+
+ @Test
+ public void testShowWhenLockedImeActivityAndShowSoftInput() throws Exception {
+ try (final LockScreenSession lockScreenSession = new LockScreenSession();
+ final TestActivitySession<ShowWhenLockedImeActivity> imeTestActivitySession = new
+ TestActivitySession<>();
+ // Leverage MockImeSession to ensure at least an IME exists as default.
+ final MockImeSession mockImeSession = MockImeSession.create(mContext,
+ InstrumentationRegistry.getInstrumentation().getUiAutomation(),
+ new ImeSettings.Builder())) {
+ lockScreenSession.setLockCredential().gotoKeyguard();
+ mAmWmState.assertKeyguardShowingAndNotOccluded();
+ imeTestActivitySession.launchTestActivityOnDisplaySync(ShowWhenLockedImeActivity.class,
+ DEFAULT_DISPLAY);
+
+ // Make sure the activity has been called showSoftInput & IME window is visible.
+ final ImeEventStream stream = mockImeSession.openEventStream();
+ expectEvent(stream, event -> "showSoftInput".equals(event.getEventName()),
+ TimeUnit.SECONDS.toMillis(5) /* eventTimeout */);
+ // Assert the IME is shown on the expected display.
+ mAmWmState.waitAndAssertImeWindowShownOnDisplay(DEFAULT_DISPLAY);
+ }
+ }
+
+ public static class ShowWhenLockedImeActivity extends Activity {
+
+ @Override
+ protected void onCreate(Bundle icicle) {
+ super.onCreate(icicle);
+ final EditText editText = new EditText(this);
+ // Set private IME option for editorMatcher to identify which TextView received
+ // onStartInput event.
+ editText.setPrivateImeOptions(
+ getClass().getName() + "/" + Long.toString(SystemClock.elapsedRealtimeNanos()));
+ final LinearLayout layout = new LinearLayout(this);
+ layout.setOrientation(LinearLayout.VERTICAL);
+ layout.addView(editText);
+ setContentView(layout);
+
+ // Set showWhenLocked as true & request focus for showing soft input.
+ setShowWhenLocked(true);
+ getWindow().setSoftInputMode(SOFT_INPUT_STATE_ALWAYS_VISIBLE);
+ editText.requestFocus();
+ }
+ }
+
/**
* Waits until the given activity has entered picture-in-picture mode (allowing for the
* subsequent animation to start).
diff --git a/tests/framework/base/activitymanager/src/android/server/am/KeyguardTests.java b/tests/framework/base/activitymanager/src/android/server/am/KeyguardTests.java
index 6ad99cd..f8b4caf 100755
--- a/tests/framework/base/activitymanager/src/android/server/am/KeyguardTests.java
+++ b/tests/framework/base/activitymanager/src/android/server/am/KeyguardTests.java
@@ -23,8 +23,12 @@
import static android.server.am.Components.BROADCAST_RECEIVER_ACTIVITY;
import static android.server.am.Components.DISMISS_KEYGUARD_ACTIVITY;
import static android.server.am.Components.DISMISS_KEYGUARD_METHOD_ACTIVITY;
+import static android.server.am.Components.INHERIT_SHOW_WHEN_LOCKED_ADD_ACTIVITY;
+import static android.server.am.Components.INHERIT_SHOW_WHEN_LOCKED_ATTR_ACTIVITY;
+import static android.server.am.Components.INHERIT_SHOW_WHEN_LOCKED_REMOVE_ACTIVITY;
import static android.server.am.Components.KEYGUARD_LOCK_ACTIVITY;
import static android.server.am.Components.LAUNCHING_ACTIVITY;
+import static android.server.am.Components.NO_INHERIT_SHOW_WHEN_LOCKED_ATTR_ACTIVITY;
import static android.server.am.Components.SHOW_WHEN_LOCKED_ACTIVITY;
import static android.server.am.Components.SHOW_WHEN_LOCKED_ATTR_ACTIVITY;
import static android.server.am.Components.SHOW_WHEN_LOCKED_DIALOG_ACTIVITY;
@@ -211,6 +215,101 @@
}
/**
+ * Tests whether an activity that has called setInheritShowWhenLocked(true) above a
+ * SHOW_WHEN_LOCKED activity is visible if Keyguard is locked.
+ */
+ @Test
+ public void testInheritShowWhenLockedAdd() throws Exception {
+ try (final LockScreenSession lockScreenSession = new LockScreenSession()) {
+ launchActivity(SHOW_WHEN_LOCKED_ATTR_ACTIVITY);
+ mAmWmState.assertVisibility(SHOW_WHEN_LOCKED_ATTR_ACTIVITY, true);
+
+ launchActivity(INHERIT_SHOW_WHEN_LOCKED_ADD_ACTIVITY);
+ mAmWmState.computeState(INHERIT_SHOW_WHEN_LOCKED_ADD_ACTIVITY);
+ mAmWmState.assertVisibility(SHOW_WHEN_LOCKED_ATTR_ACTIVITY, false);
+ mAmWmState.assertVisibility(INHERIT_SHOW_WHEN_LOCKED_ADD_ACTIVITY, true);
+
+ lockScreenSession.gotoKeyguard();
+ mAmWmState.computeState(true);
+ mAmWmState.assertKeyguardShowingAndOccluded();
+ mAmWmState.assertVisibility(SHOW_WHEN_LOCKED_ATTR_ACTIVITY, false);
+ mAmWmState.assertVisibility(INHERIT_SHOW_WHEN_LOCKED_ADD_ACTIVITY, true);
+ }
+ }
+
+ /**
+ * Tests whether an activity that has the manifest attribute inheritShowWhenLocked but then
+ * calls setInheritShowWhenLocked(false) above a SHOW_WHEN_LOCKED activity is invisible if
+ * Keyguard is locked.
+ */
+ @Test
+ public void testInheritShowWhenLockedRemove() throws Exception {
+ try (final LockScreenSession lockScreenSession = new LockScreenSession()) {
+ launchActivity(SHOW_WHEN_LOCKED_ATTR_ACTIVITY);
+ mAmWmState.assertVisibility(SHOW_WHEN_LOCKED_ATTR_ACTIVITY, true);
+
+ launchActivity(INHERIT_SHOW_WHEN_LOCKED_REMOVE_ACTIVITY);
+ mAmWmState.computeState(INHERIT_SHOW_WHEN_LOCKED_REMOVE_ACTIVITY);
+ mAmWmState.assertVisibility(SHOW_WHEN_LOCKED_ATTR_ACTIVITY, false);
+ mAmWmState.assertVisibility(INHERIT_SHOW_WHEN_LOCKED_REMOVE_ACTIVITY, true);
+
+ lockScreenSession.gotoKeyguard();
+ mAmWmState.computeState(true);
+ mAmWmState.assertKeyguardShowingAndNotOccluded();
+ assertTrue(mKeyguardManager.isKeyguardLocked());
+ mAmWmState.assertVisibility(SHOW_WHEN_LOCKED_ATTR_ACTIVITY, false);
+ mAmWmState.assertVisibility(INHERIT_SHOW_WHEN_LOCKED_REMOVE_ACTIVITY, false);
+ }
+ }
+
+ /**
+ * Tests whether an activity that has the manifest attribute inheritShowWhenLocked above a
+ * SHOW_WHEN_LOCKED activity is visible if Keyguard is locked.
+ * */
+ @Test
+ public void testInheritShowWhenLockedAttr() throws Exception {
+ try (final LockScreenSession lockScreenSession = new LockScreenSession()) {
+ launchActivity(SHOW_WHEN_LOCKED_ATTR_ACTIVITY);
+ mAmWmState.assertVisibility(SHOW_WHEN_LOCKED_ATTR_ACTIVITY, true);
+
+ launchActivity(INHERIT_SHOW_WHEN_LOCKED_ATTR_ACTIVITY);
+ mAmWmState.computeState(INHERIT_SHOW_WHEN_LOCKED_ATTR_ACTIVITY);
+ mAmWmState.assertVisibility(SHOW_WHEN_LOCKED_ATTR_ACTIVITY, false);
+ mAmWmState.assertVisibility(INHERIT_SHOW_WHEN_LOCKED_ATTR_ACTIVITY, true);
+
+ lockScreenSession.gotoKeyguard();
+ mAmWmState.computeState(true);
+ mAmWmState.assertKeyguardShowingAndOccluded();
+ mAmWmState.assertVisibility(SHOW_WHEN_LOCKED_ATTR_ACTIVITY, false);
+ mAmWmState.assertVisibility(INHERIT_SHOW_WHEN_LOCKED_ATTR_ACTIVITY, true);
+ }
+ }
+
+ /**
+ * Tests whether an activity that doesn't have the manifest attribute inheritShowWhenLocked
+ * above a SHOW_WHEN_LOCKED activity is invisible if Keyguard is locked.
+ * */
+ @Test
+ public void testNoInheritShowWhenLocked() throws Exception {
+ try (final LockScreenSession lockScreenSession = new LockScreenSession()) {
+ launchActivity(SHOW_WHEN_LOCKED_ATTR_ACTIVITY);
+ mAmWmState.assertVisibility(SHOW_WHEN_LOCKED_ATTR_ACTIVITY, true);
+
+ launchActivity(NO_INHERIT_SHOW_WHEN_LOCKED_ATTR_ACTIVITY);
+ mAmWmState.computeState(NO_INHERIT_SHOW_WHEN_LOCKED_ATTR_ACTIVITY);
+ mAmWmState.assertVisibility(SHOW_WHEN_LOCKED_ATTR_ACTIVITY, false);
+ mAmWmState.assertVisibility(NO_INHERIT_SHOW_WHEN_LOCKED_ATTR_ACTIVITY, true);
+
+ lockScreenSession.gotoKeyguard();
+ mAmWmState.computeState(true);
+ mAmWmState.assertKeyguardShowingAndNotOccluded();
+ assertTrue(mKeyguardManager.isKeyguardLocked());
+ mAmWmState.assertVisibility(SHOW_WHEN_LOCKED_ATTR_ACTIVITY, false);
+ mAmWmState.assertVisibility(NO_INHERIT_SHOW_WHEN_LOCKED_ATTR_ACTIVITY, false);
+ }
+ }
+
+ /**
* Test that when a normal activity finished and an existing FLAG_DISMISS_KEYGUARD activity
* becomes the top activity, it should be resumed.
*/
diff --git a/tests/framework/base/activitymanager/src/android/server/am/intent/Activities.java b/tests/framework/base/activitymanager/src/android/server/am/intent/Activities.java
new file mode 100644
index 0000000..72b5b0e
--- /dev/null
+++ b/tests/framework/base/activitymanager/src/android/server/am/intent/Activities.java
@@ -0,0 +1,80 @@
+/*
+ * Copyright (C) 2019 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.server.am.intent;
+
+import android.app.Activity;
+
+/**
+ * A collection of activities with various launch modes used in the intent tests.
+ * Each activity is named after the LaunchMode it has enabled.
+ *
+ * They reflect the activities present in the IntentPlayground app. The IntentPlayground app
+ * resides in development/samples/IntentPlayground
+ */
+public class Activities {
+
+ public static class TrackerActivity extends Activity {
+ }
+
+ public static class RegularActivity extends Activity {
+ }
+
+ public static class SingleTopActivity extends Activity {
+ }
+
+ public static class SingleInstanceActivity extends Activity {
+ }
+
+ public static class SingleInstanceActivity2 extends Activity {
+ }
+
+ public static class SingleTaskActivity extends Activity {
+ }
+
+ public static class SingleTaskActivity2 extends Activity {
+ }
+
+ public static class TaskAffinity1Activity extends Activity {
+ }
+
+ public static class TaskAffinity1Activity2 extends Activity {
+ }
+
+ public static class TaskAffinity2Activity extends Activity {
+ }
+
+ public static class TaskAffinity3Activity extends Activity {
+ }
+
+ public static class ClearTaskOnLaunchActivity extends Activity {
+ }
+
+ public static class DocumentLaunchIntoActivity extends Activity {
+ }
+
+ public static class DocumentLaunchAlwaysActivity extends Activity {
+ }
+
+ public static class DocumentLaunchNeverActivity extends Activity {
+ }
+
+ public static class NoHistoryActivity extends Activity {
+ }
+
+ public static class LauncherActivity extends Activity {
+ }
+}
diff --git a/tests/framework/base/activitymanager/src/android/server/am/intent/Cases.java b/tests/framework/base/activitymanager/src/android/server/am/intent/Cases.java
new file mode 100644
index 0000000..cd542e3
--- /dev/null
+++ b/tests/framework/base/activitymanager/src/android/server/am/intent/Cases.java
@@ -0,0 +1,314 @@
+/*
+ * Copyright (C) 2019 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.server.am.intent;
+
+import static android.content.Intent.FLAG_ACTIVITY_CLEAR_TASK;
+import static android.content.Intent.FLAG_ACTIVITY_CLEAR_TOP;
+import static android.content.Intent.FLAG_ACTIVITY_MULTIPLE_TASK;
+import static android.content.Intent.FLAG_ACTIVITY_NEW_DOCUMENT;
+import static android.content.Intent.FLAG_ACTIVITY_NEW_TASK;
+import static android.content.Intent.FLAG_ACTIVITY_PREVIOUS_IS_TOP;
+import static android.content.Intent.FLAG_ACTIVITY_REORDER_TO_FRONT;
+import static android.content.Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED;
+import static android.content.Intent.FLAG_ACTIVITY_SINGLE_TOP;
+import static android.server.am.intent.LaunchSequence.intent;
+import static android.server.am.intent.LaunchSequence.intentForResult;
+import static android.server.am.intent.Persistence.flag;
+
+import android.server.am.intent.Activities.RegularActivity;
+import android.server.am.intent.Persistence.IntentFlag;
+import android.server.am.intent.Persistence.LaunchIntent;
+
+import com.google.common.collect.Lists;
+
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * Contains all information to create and reuse intent test launches.
+ * It enumerates all the flags so they can easily be used.
+ *
+ * It also stores commonly used {@link LaunchSequence} objects for reuse.
+ */
+public class Cases {
+
+ public static final IntentFlag CLEAR_TASK = flag(FLAG_ACTIVITY_CLEAR_TASK,
+ "FLAG_ACTIVITY_CLEAR_TASK");
+ public static final IntentFlag CLEAR_TOP = flag(FLAG_ACTIVITY_CLEAR_TOP,
+ "FLAG_ACTIVITY_CLEAR_TOP");
+ private static final IntentFlag SINGLE_TOP = flag(FLAG_ACTIVITY_SINGLE_TOP,
+ "FLAG_ACTIVITY_SINGLE_TOP");
+ public static final IntentFlag NEW_TASK = flag(FLAG_ACTIVITY_NEW_TASK,
+ "FLAG_ACTIVITY_NEW_TASK");
+ public static final IntentFlag NEW_DOCUMENT = flag(FLAG_ACTIVITY_NEW_DOCUMENT,
+ "FLAG_ACTIVITY_NEW_DOCUMENT");
+ private static final IntentFlag MULTIPLE_TASK = flag(FLAG_ACTIVITY_MULTIPLE_TASK,
+ "FLAG_ACTIVITY_MULTIPLE_TASK");
+ public static final IntentFlag RESET_TASK_IF_NEEDED = flag(
+ FLAG_ACTIVITY_RESET_TASK_IF_NEEDED,
+ "FLAG_ACTIVITY_RESET_TASK_IF_NEEDED");
+ public static final IntentFlag PREVIOUS_IS_TOP = flag(FLAG_ACTIVITY_PREVIOUS_IS_TOP,
+ "FLAG_ACTIVITY_PREVIOUS_IS_TOP");
+ public static final IntentFlag REORDER_TO_FRONT = flag(FLAG_ACTIVITY_REORDER_TO_FRONT,
+ "FLAG_ACTIVITY_REORDER_TO_FRONT");
+
+ // Flag only used for parsing intents that contain no flags.
+ private static final IntentFlag NONE = flag(0, "");
+
+ public final List<IntentFlag> flags = Lists.newArrayList(
+ CLEAR_TASK,
+ CLEAR_TOP,
+ SINGLE_TOP,
+ NEW_TASK,
+ NEW_DOCUMENT,
+ MULTIPLE_TASK,
+ RESET_TASK_IF_NEEDED,
+ PREVIOUS_IS_TOP,
+ REORDER_TO_FRONT
+ );
+
+ // Definition of intents used across multiple test cases.
+ private final LaunchIntent mRegularIntent = intent(RegularActivity.class);
+ private final LaunchIntent mSingleTopIntent = intent(Activities.SingleTopActivity.class);
+ private final LaunchIntent mAff1Intent = intent(Activities.TaskAffinity1Activity.class);
+ private final LaunchIntent mSecondAff1Intent = intent(Activities.TaskAffinity1Activity2.class);
+ private final LaunchIntent mSingleInstanceIntent = intent(
+ Activities.SingleInstanceActivity.class);
+ private final LaunchIntent mSingleTaskIntent = intent(Activities.SingleTaskActivity.class);
+ private final LaunchIntent mRegularForResultIntent = intentForResult(RegularActivity.class);
+
+ // LaunchSequences used across multiple test cases.
+ private final LaunchSequence mRegularSequence = LaunchSequence.create(mRegularIntent);
+
+ // To show that the most recent task get's resumed by new task
+ private final LaunchSequence mTwoAffinitiesSequence =
+ LaunchSequence.create(mAff1Intent)
+ .append(mRegularIntent)
+ .append(mAff1Intent.withFlags(NEW_TASK, MULTIPLE_TASK));
+
+ // Used to show that the task affinity is determined by the activity that started it,
+ // Not the affinity of the current root activity.
+ private final LaunchSequence mRearrangedRootSequence = LaunchSequence.create(mRegularIntent)
+ .append(mAff1Intent.withFlags(NEW_TASK))
+ .append(mRegularIntent)
+ .append(mAff1Intent.withFlags(REORDER_TO_FRONT));
+
+
+ private final LaunchSequence mSingleInstanceActivitySequence =
+ LaunchSequence.create(mSingleInstanceIntent);
+
+ private final LaunchSequence mSingleTaskActivitySequence = LaunchSequence.create(
+ mSingleTaskIntent);
+
+ public List<LaunchSequence> newTaskCases() {
+ LaunchIntent aff1NewTask = mAff1Intent.withFlags(NEW_TASK);
+
+ return Lists.newArrayList(
+ // 1. Single instance will start a new task even without new task set
+ mRegularSequence.act(mSingleInstanceIntent),
+ // 2. With new task it will still end up in a new task
+ mRegularSequence.act(mSingleInstanceIntent.withFlags(NEW_TASK)),
+ // 3. Starting an activity with a different affinity without new task will put it in
+ // the existing task
+ mRegularSequence.act(mAff1Intent),
+ // 4. Starting a task with a different affinity and new task will start a new task
+ mRegularSequence.act(aff1NewTask),
+ // 5. Starting the intent with new task will not add a new activity to the task
+ mRegularSequence.act(mRegularIntent.withFlags(NEW_TASK)),
+ // 6. A different activity with the same affinity will start a new activity in
+ // the sam task
+ mRegularSequence.act(mSingleTopIntent.withFlags(NEW_TASK)),
+ // 7. To show that the most recent task get's resumed by new task, this can't
+ // be observed without differences in the same activity / task
+ mTwoAffinitiesSequence.act(aff1NewTask),
+ // 8. To show that new task respects the root as a single even
+ // if it is not at the bottom
+ mRearrangedRootSequence.act(mAff1Intent.withFlags(NEW_TASK)),
+ // 9. To show that new task with non root does start a new activity.
+ mRearrangedRootSequence.act(mSecondAff1Intent.withFlags(NEW_TASK)),
+ // 10. Multiple task will allow starting activities of the same affinity in
+ // different tasks
+ mRegularSequence.act(mRegularIntent.withFlags(NEW_TASK, MULTIPLE_TASK)),
+ // 11. Single instance will not start a new task even with multiple task on
+ mSingleInstanceActivitySequence.act(
+ mSingleInstanceIntent.withFlags(NEW_TASK, MULTIPLE_TASK)),
+ // 12. The same should happen for single task.
+ mSingleTaskActivitySequence.act(
+ mSingleTaskIntent.withFlags(NEW_TASK, MULTIPLE_TASK)),
+ // 13. This starts a regular in a new task
+ mSingleInstanceActivitySequence.act(mRegularIntent),
+ // 14. This adds regular in the same task
+ mSingleTaskActivitySequence.act(mRegularIntent),
+ // 15. Starting the activity for result keeps it in the same task
+ mSingleInstanceActivitySequence.act(mRegularForResultIntent),
+ // 16. Restarts the previous task with regular activity.
+ mRegularSequence.append(mSingleInstanceIntent).act(mRegularIntent)
+ );
+ }
+
+ /**
+ * {@link android.content.Intent#FLAG_ACTIVITY_NEW_DOCUMENT }test cases are the same as
+ * {@link Cases#newTaskCases()}, we should check them for differences.
+ */
+ public List<LaunchSequence> newDocumentCases() {
+ LaunchIntent aff1NewDocument = mAff1Intent.withFlags(NEW_DOCUMENT);
+
+ return Lists.newArrayList(
+ // 1. Single instance will start a new task even without new task set
+ mRegularSequence.act(mSingleInstanceIntent),
+ // 2. With new task it will still end up in a new task
+ mRegularSequence.act(mSingleInstanceIntent.withFlags(NEW_DOCUMENT)),
+ // 3. Starting an activity with a different affinity without new task will put it
+ // in the existing task
+ mRegularSequence.act(mAff1Intent),
+ // 4. With new document it will start it's own task
+ mRegularSequence.act(aff1NewDocument),
+ // 5. Starting the intent with new task will not add a new activity to the task
+ mRegularSequence.act(mRegularIntent.withFlags(NEW_DOCUMENT)),
+ // 6. Unlike the case with NEW_TASK, with new Document
+ mRegularSequence.act(mSingleTopIntent.withFlags(NEW_DOCUMENT)),
+ // 7. To show that the most recent task get's resumed by new task
+ mTwoAffinitiesSequence.act(aff1NewDocument),
+ // 8. To show that new task respects the root as a single
+ mRearrangedRootSequence.act(mAff1Intent.withFlags(NEW_DOCUMENT)),
+ // 9. New document starts a third task here, because there was no task for the
+ // document yet
+ mRearrangedRootSequence.act(mSecondAff1Intent.withFlags(NEW_DOCUMENT)),
+ // 10. Multiple task wil allow starting activities of the same affinity in different
+ // tasks
+ mRegularSequence.act(mRegularIntent.withFlags(NEW_DOCUMENT, MULTIPLE_TASK)),
+ // 11. Single instance will not start a new task even with multiple task on
+ mSingleInstanceActivitySequence
+ .act(mSingleInstanceIntent.withFlags(NEW_DOCUMENT, MULTIPLE_TASK)),
+ // 12. The same should happen for single task.
+ mSingleTaskActivitySequence.act(
+ mSingleTaskIntent.withFlags(NEW_DOCUMENT, MULTIPLE_TASK))
+ );
+ }
+
+ public List<LaunchSequence> clearCases() {
+ LaunchSequence doubleRegularActivity = mRegularSequence.append(mRegularIntent);
+
+ return Lists.newArrayList(
+ // 1. This will clear the bottom and end up with just one activity
+ mRegularSequence.act(mRegularIntent.withFlags(CLEAR_TOP)),
+ // 2. This will result in still two regulars
+ doubleRegularActivity.act(mRegularIntent.withFlags(CLEAR_TOP)),
+ // 3. This will result in a single regular it clears the top regular
+ // activity and then fails to start a new regular activity because it is already
+ // at the root of the task
+ doubleRegularActivity.act(mRegularIntent.withFlags(CLEAR_TOP, NEW_TASK)),
+ // 3. This will also result in two regulars, showing the first difference between
+ // new document and new task.
+ doubleRegularActivity.act(mRegularIntent.withFlags(CLEAR_TOP, NEW_DOCUMENT)),
+ // 4. This is here to show that previous is top has no effect on clear top or single
+ // top
+ doubleRegularActivity.act(mRegularIntent.withFlags(CLEAR_TOP, PREVIOUS_IS_TOP)),
+ // 5. Clear top finds the same activity in the task and clears from there
+ mRegularSequence.append(mAff1Intent).append(mRegularIntent).act(
+ mAff1Intent.withFlags(CLEAR_TOP))
+ );
+ }
+
+ /**
+ * Tests for {@link android.app.Activity#startActivityForResult()}
+ */
+ //TODO: If b/122968776 is fixed these tests need to be updated
+ public List<LaunchSequence> forResultCases() {
+ LaunchIntent singleTopForResult = intentForResult(Activities.SingleTopActivity.class);
+
+ return Lists.newArrayList(
+ // 1. Start just a single regular activity
+ mRegularSequence.act(mRegularIntent.withFlags(SINGLE_TOP)),
+ // 2. For result will start a second activity
+ mRegularSequence.act(mRegularForResultIntent.withFlags(SINGLE_TOP)),
+ // 3. The same but for SINGLE_TOP as a launch mode
+ LaunchSequence.create(mSingleTopIntent).act(mSingleTopIntent),
+ // 4. Launch mode SINGLE_TOP when launched for result also starts a second activity.
+ LaunchSequence.create(mSingleTopIntent).act(singleTopForResult),
+ // 5. CLEAR_TOP results in a single regular activity
+ mRegularSequence.act(mRegularIntent.withFlags(CLEAR_TOP)),
+ // 6. Clear will still kill the for result
+ mRegularSequence.act(mRegularForResultIntent.withFlags(CLEAR_TOP)),
+ // 7. An activity started for result can go to a different task
+ mRegularSequence.act(mRegularForResultIntent.withFlags(NEW_TASK, MULTIPLE_TASK)),
+ // 8. Reorder to front with for result
+ mRegularSequence.append(mAff1Intent).act(
+ mRegularForResultIntent.withFlags(REORDER_TO_FRONT)),
+ // 9. Reorder can move an activity above one that it started for result
+ mRegularSequence.append(intentForResult(Activities.TaskAffinity1Activity.class))
+ .act(mRegularIntent.withFlags(REORDER_TO_FRONT))
+ );
+ }
+
+ /**
+ * Reset task if needed will trigger when it is delivered with new task set
+ * and there are activities in the task that have a different affinity.
+ *
+ * @return the test cases
+ */
+ //TODO: If b/122324373 is fixed these test need to be updated.
+ public List<LaunchSequence> resetTaskIfNeeded() {
+ // If a task with a different affinity like this get's reset
+ // it will create another task in the same stack with the now orphaned activity.
+ LaunchIntent resetRegularTask = mRegularIntent.withFlags(NEW_TASK,
+ RESET_TASK_IF_NEEDED);
+ LaunchSequence resetIfNeeded = mRegularSequence.append(mAff1Intent)
+ .act(resetRegularTask);
+
+ // If you try to reset a task with an activity that was started for result
+ // it will not move task.
+ LaunchSequence resetWontMoveResult = mRegularSequence.append(
+ intentForResult(Activities.TaskAffinity1Activity.class))
+ .act(resetRegularTask);
+
+ // Reset will not move activities with to a task with that affinity,
+ // instead it will always create a new task in that stack.
+ LaunchSequence resetToExistingTask2 = mRegularSequence
+ .append(mAff1Intent)
+ .append(mAff1Intent.withFlags(NEW_TASK))
+ .act(resetRegularTask);
+
+ // If a reset occurs the activities that move retain the same order
+ // in the new task as they had in the old task.
+ LaunchSequence resetOrdering = mRegularSequence
+ .append(mAff1Intent)
+ .append(mSecondAff1Intent)
+ .act(resetRegularTask);
+
+ return Lists.newArrayList(resetIfNeeded, resetWontMoveResult, resetToExistingTask2,
+ resetOrdering);
+ }
+
+ /**
+ * The human readable flags in the JSON files need to be converted back to the corresponding
+ * IntentFlag object when reading the file. This creates a map from the flags to their
+ * corresponding object.
+ *
+ * @return lookup table for the parsing of intent flags in the json files.
+ */
+ public Map<String, IntentFlag> createFlagParsingTable() {
+ HashMap<String, IntentFlag> flags = new HashMap<>();
+ for (IntentFlag flag : this.flags) {
+ flags.put(flag.name, flag);
+ }
+
+ flags.put(NONE.getName(), NONE);
+ return flags;
+ }
+}
diff --git a/tests/framework/base/activitymanager/src/android/server/am/intent/IntentGenerationTests.java b/tests/framework/base/activitymanager/src/android/server/am/intent/IntentGenerationTests.java
new file mode 100644
index 0000000..c5daaaa
--- /dev/null
+++ b/tests/framework/base/activitymanager/src/android/server/am/intent/IntentGenerationTests.java
@@ -0,0 +1,137 @@
+/*
+ * Copyright (C) 2019 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.server.am.intent;
+
+import android.content.ComponentName;
+import android.content.Context;
+import android.os.Environment;
+import android.server.am.intent.Persistence.IntentFlag;
+import android.server.am.intent.Persistence.TestCase;
+import android.support.test.InstrumentationRegistry;
+
+import org.json.JSONException;
+import org.json.JSONObject;
+import org.junit.Ignore;
+import org.junit.Test;
+
+import java.io.File;
+import java.io.IOException;
+import java.nio.charset.StandardCharsets;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.util.Collections;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * The {@link IntentGenerationTests#generate()} method runs a very long generation process that
+ * takes over 10 minutes.
+ *
+ * The generated tests and results observed on a reference device can then be used in CTS for
+ * verification.
+ *
+ * It writes a bunch of files out to the directory obtained from
+ * {@link Environment#getExternalStoragePublicDirectory(String)} which is currently
+ * /storage/emulated/0/Documents/.
+ *
+ * These can then be pulled out via adb and put into the intent_tests asset directory.
+ * These are the tests that are checked by atest CtsActivityManagerDeviceTestCases:IntentTests
+ *
+ * Because this process takes so much time, certain timeouts in the AndroidTest.xml need to be
+ * raised.
+ *
+ * <option name="run-command" value="settings put system screen_off_timeout 1200000000" /> in the
+ * target preparer and <option name="test-timeout" value="3600000" /> in the <test class=></test>
+ *
+ * Since this test only exists to trigger this process using the test infrastructure
+ * it is ignored by default.
+ *
+ * Build/Install/Run:
+ * atest CtsActivityManagerDeviceTestCases:IntentGenerationTests
+ */
+@Ignore
+public class IntentGenerationTests extends IntentTestBase {
+ private static final Cases CASES = new Cases();
+
+ /**
+ * The flag parsing table used to parse the json files.
+ */
+ private static final Map<String, IntentFlag> TABLE = CASES.createFlagParsingTable();
+
+ /**
+ * Runner used to record testCases.
+ */
+ private LaunchRunner mLaunchRunner;
+
+ /**
+ * The target context we can launch the first activity from.
+ */
+ private Context mTargetContext = InstrumentationRegistry.getTargetContext();
+
+ //20 minute timeout.
+ @Test(timeout = 1_200_000)
+ public void generate() throws Exception {
+ mLaunchRunner.runAndWrite(mTargetContext, "forResult", CASES.forResultCases());
+ mLaunchRunner.runAndWrite(mTargetContext, "newTask", CASES.newTaskCases());
+ mLaunchRunner.runAndWrite(mTargetContext, "newDocumentCases", CASES.newDocumentCases());
+ mLaunchRunner.runAndWrite(mTargetContext, "resetTaskIfNeeded", CASES.resetTaskIfNeeded());
+ mLaunchRunner.runAndWrite(mTargetContext, "clearCases", CASES.clearCases());
+ }
+
+ @Override
+ public void setUp() throws Exception {
+ super.setUp();
+ mLaunchRunner = new LaunchRunner(this);
+ }
+
+ /**
+ * Debugging utility to verify a single test in the assets folder.
+ *
+ * @throws IOException if writing to storage fails
+ * @throws JSONException if the file has invalid json in it.
+ */
+ @Test
+ public void verifySingle() throws IOException, JSONException {
+ String test = "forResult/test-1.json";
+ TestCase testCase = readFromStorage(test);
+ mLaunchRunner.verify(mTargetContext, testCase);
+ }
+
+ private TestCase readFromStorage(String fileName) throws IOException, JSONException {
+ File documentsDirectory = Environment.getExternalStoragePublicDirectory(
+ Environment.DIRECTORY_DOCUMENTS);
+ Path testsFilePath = documentsDirectory.toPath().resolve(fileName);
+
+ JSONObject jsonInTestFile = new JSONObject(
+ new String(Files.readAllBytes(testsFilePath), StandardCharsets.UTF_8));
+ return TestCase.fromJson(jsonInTestFile, TABLE, fileName);
+ }
+
+ /**
+ * This class runs multiple {@link TestCase}-s in a single test.
+ * Therefore the list of componentNames that occur in the test is not known here.
+ *
+ * Instead {@link IntentTestBase#cleanUp(List)} is called from {@link
+ * LaunchRunner#runAndWrite(Context, String, List)} instead.
+ *
+ * @return an emptyList
+ */
+ @Override
+ List<ComponentName> activitiesUsedInTest() {
+ return Collections.emptyList();
+ }
+}
diff --git a/tests/framework/base/activitymanager/src/android/server/am/intent/IntentTestBase.java b/tests/framework/base/activitymanager/src/android/server/am/intent/IntentTestBase.java
new file mode 100644
index 0000000..ded10b7
--- /dev/null
+++ b/tests/framework/base/activitymanager/src/android/server/am/intent/IntentTestBase.java
@@ -0,0 +1,57 @@
+/*
+ * Copyright (C) 2019 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.server.am.intent;
+
+import android.content.ComponentName;
+import android.server.am.ActivityManagerTestBase;
+import android.server.am.UiDeviceUtils;
+
+import org.junit.After;
+
+import java.util.List;
+
+public abstract class IntentTestBase extends ActivityManagerTestBase {
+
+ /**
+ * This get's called from {@link IntentGenerationTests} because {@link IntentGenerationTests}
+ * run multiple {@link android.server.am.intent.Persistence.TestCase}-s in a single junit test.
+ *
+ * Normal test classes can just extend this class with manual cleanUp.
+ *
+ * @param activitiesInUsedInTest activities that should be gone after tearDown
+ */
+ public void cleanUp(List<ComponentName> activitiesInUsedInTest) throws Exception {
+ super.tearDown();
+ UiDeviceUtils.pressHomeButton();
+ removeStacksWithActivityTypes(ALL_ACTIVITY_TYPE_BUT_HOME);
+
+ this.getAmWmState().waitForWithAmState(
+ state -> state.containsNoneOf(activitiesInUsedInTest),
+ "Waiting for activity to be removed");
+ }
+
+ @After
+ @Override
+ public void tearDown() throws Exception {
+ cleanUp(activitiesUsedInTest());
+ }
+
+ /**
+ * @return The activities that are launched in this Test.
+ */
+ abstract List<ComponentName> activitiesUsedInTest();
+}
diff --git a/tests/framework/base/activitymanager/src/android/server/am/intent/IntentTests.java b/tests/framework/base/activitymanager/src/android/server/am/intent/IntentTests.java
new file mode 100644
index 0000000..e9ff1cb
--- /dev/null
+++ b/tests/framework/base/activitymanager/src/android/server/am/intent/IntentTests.java
@@ -0,0 +1,160 @@
+/*
+ * Copyright (C) 2019 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.server.am.intent;
+
+import android.content.ComponentName;
+import android.content.Context;
+import android.content.res.AssetManager;
+import android.os.Environment;
+import android.server.am.UiDeviceUtils;
+import android.server.am.intent.Persistence.IntentFlag;
+import android.server.am.intent.Persistence.TestCase;
+import android.support.test.InstrumentationRegistry;
+import android.support.test.filters.LargeTest;
+
+import com.google.common.collect.Lists;
+
+import org.json.JSONException;
+import org.json.JSONObject;
+import org.junit.After;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.Parameterized;
+
+import java.io.BufferedInputStream;
+import java.io.BufferedReader;
+import java.io.File;
+import java.io.IOException;
+import java.io.InputStreamReader;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.util.Collection;
+import java.util.List;
+import java.util.Map;
+import java.util.stream.Collectors;
+
+/**
+ * This test will verify every intent_test json file in a separately run test, through JUnits
+ * Parameterized runner.
+ *
+ * Running a single test using this class is not supported.
+ * For this use case look at {@link IntentGenerationTests#verifySingle()}
+ *
+ * Note: atest CtsActivityManagerDeviceTestCases:IntentTests#verify does not work because the
+ * Parameterized runner won't expose the test that way to atest.
+ *
+ * Build/Install/Run:
+ * atest CtsActivityManagerDeviceTestCases:IntentTests
+ */
+@LargeTest
+@RunWith(Parameterized.class)
+public class IntentTests extends IntentTestBase {
+ private static final Cases CASES = new Cases();
+
+ /**
+ * The flag parsing table used to parse the json files.
+ */
+ private static final Map<String, IntentFlag> TABLE = CASES.createFlagParsingTable();
+ private static Context TARGET_CONTEXT = InstrumentationRegistry.getTargetContext();
+
+ private static final int JSON_INDENTATION_LEVEL = 4;
+
+ /**
+ * The runner used to verify the recorded test cases.
+ */
+ private LaunchRunner mLaunchRunner;
+
+ /**
+ * The Test case we are currently verifying.
+ */
+ private TestCase mTestCase;
+
+ public IntentTests(TestCase testCase, String name) {
+ mTestCase = testCase;
+ }
+
+ /**
+ * Read all the tests in the assets of the application and create a separate test to run for
+ * each of them using the {@link org.junit.runners.Parameterized}
+ */
+ @Parameterized.Parameters(name = "{1}")
+ public static Collection<Object[]> data() throws IOException, JSONException {
+ return readAllFromAssets().stream().map(
+ test -> new Object[]{test, test.getName()}).collect(
+ Collectors.toList());
+ }
+
+ @Test
+ public void verify() {
+ mLaunchRunner.verify(TARGET_CONTEXT, mTestCase);
+ }
+
+
+ @Override
+ public void setUp() throws Exception {
+ super.setUp();
+ mLaunchRunner = new LaunchRunner(this);
+ }
+
+ @Override
+ List<ComponentName> activitiesUsedInTest() {
+ return mTestCase.getSetup().componentsInCase();
+ }
+
+ public static List<TestCase> readAllFromAssets() throws IOException, JSONException {
+ List<TestCase> testCases = Lists.newArrayList();
+ AssetManager assets = TARGET_CONTEXT.getAssets();
+
+ List<String> testFiles = Lists.newArrayList();
+ for (String dir : assets.list("")) {
+ for (String file : assets.list(dir)) {
+ if (file.endsWith(".json")) {
+ testFiles.add(dir + "/" + file);
+ }
+ }
+ }
+
+ for (String testFile : testFiles) {
+ try (BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(
+ new BufferedInputStream(assets.open(testFile))))) {
+ String jsonData = bufferedReader.lines().collect(
+ Collectors.joining("\n"));
+
+ TestCase testCase = TestCase.fromJson(
+ new JSONObject(jsonData), TABLE, testFile);
+
+ testCases.add(testCase);
+ }
+ }
+
+ return testCases;
+ }
+
+ static void writeToDocumentsStorage(TestCase testCase, int number, String dirName)
+ throws JSONException, IOException {
+ File documentsDirectory = Environment.getExternalStoragePublicDirectory(
+ Environment.DIRECTORY_DOCUMENTS);
+ Path testsFilePath = documentsDirectory.toPath().resolve(dirName);
+
+ if (!Files.exists(testsFilePath)) {
+ Files.createDirectories(testsFilePath);
+ }
+ Files.write(testsFilePath.resolve("test-" + number + ".json"),
+ Lists.newArrayList(testCase.toJson().toString(JSON_INDENTATION_LEVEL)));
+ }
+}
+
diff --git a/tests/framework/base/activitymanager/src/android/server/am/intent/LaunchRunner.java b/tests/framework/base/activitymanager/src/android/server/am/intent/LaunchRunner.java
new file mode 100644
index 0000000..5d702db
--- /dev/null
+++ b/tests/framework/base/activitymanager/src/android/server/am/intent/LaunchRunner.java
@@ -0,0 +1,333 @@
+/*
+ * Copyright (C) 2019 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.server.am.intent;
+
+import static android.server.am.intent.Persistence.LaunchFromIntent.prepareSerialisation;
+import static android.server.am.intent.StateComparisonException.assertEndStatesEqual;
+import static android.server.am.intent.StateComparisonException.assertInitialStateEqual;
+
+import static com.google.common.collect.Iterables.getLast;
+
+import static org.junit.Assert.assertNotNull;
+
+import android.app.Activity;
+import android.app.Instrumentation;
+import android.content.ComponentName;
+import android.content.Context;
+import android.content.Intent;
+import android.os.SystemClock;
+import android.server.am.ActivityAndWindowManagersState;
+import android.server.am.ActivityManagerState;
+import android.server.am.intent.LaunchSequence.LaunchSequenceExecutionInfo;
+import android.server.am.intent.Persistence.GenerationIntent;
+import android.server.am.intent.Persistence.LaunchFromIntent;
+import android.server.am.intent.Persistence.StateDump;
+import android.support.test.InstrumentationRegistry;
+import android.view.Display;
+
+import com.google.common.collect.Lists;
+
+import java.util.List;
+
+/**
+ * Launch runner is an interpreter for a {@link LaunchSequence} command object.
+ * It supports three main modes of operation.
+ *
+ * 1. The {@link LaunchRunner#runAndWrite} method to run a launch object and write out the
+ * resulting {@link Persistence.TestCase} to device storage
+ *
+ * 2. The {@link LaunchRunner#verify} method to rerun a previously recorded
+ * {@link Persistence.TestCase} and verify that the recorded states match the states resulting from
+ * the rerun.
+ *
+ * 3. The {@link LaunchRunner#run} method to run a launch object and return an {@link LaunchRecord}
+ * that can be used to do assertions directly in the same test.
+ */
+public class LaunchRunner {
+ private static final int ACTIVITY_LAUNCH_TIMEOUT = 10000;
+ private static final int BEFORE_DUMP_TIMEOUT = 3000;
+
+ /**
+ * Used for the waiting utilities.
+ */
+ private IntentTestBase mTestBase;
+
+ /**
+ * The activities that were already present in the system when the test started.
+ * So they can be removed form the outputs, otherwise our tests would be system dependent.
+ */
+ private List<ActivityManagerState.ActivityStack> mBaseStacks;
+
+ public LaunchRunner(IntentTestBase testBase) {
+ mTestBase = testBase;
+ mBaseStacks = getBaseStacks();
+ }
+
+ /**
+ * Re-run a previously recorded {@link Persistence.TestCase} and verify that the recorded
+ * states match the states resulting from the rerun.
+ *
+ * @param initialContext the context to launch the first Activity from.
+ * @param testCase the {@link Persistence.TestCase} we are verifying.
+ */
+ void verify(Context initialContext, Persistence.TestCase testCase) {
+ List<GenerationIntent> initialState = testCase.getSetup().getInitialIntents();
+ List<GenerationIntent> act = testCase.getSetup().getAct();
+
+ List<Activity> activityLog = Lists.newArrayList();
+
+ // Launch the first activity from the start context
+ GenerationIntent firstIntent = initialState.get(0);
+ activityLog.add(launchFromContext(initialContext, firstIntent.getActualIntent()));
+
+ // launch the rest from the initial intents
+ for (int i = 1; i < initialState.size(); i++) {
+ GenerationIntent generationIntent = initialState.get(i);
+ Activity activityToLaunchFrom = activityLog.get(generationIntent.getLaunchFromIndex(i));
+ Activity result = launch(activityToLaunchFrom, generationIntent.getActualIntent(),
+ generationIntent.startForResult());
+ activityLog.add(result);
+ }
+
+ // assert that the state after setup is the same this time as the recorded state.
+ StateDump setupStateDump = waitDumpAndTrimForVerification(getLast(activityLog),
+ testCase.getEndState());
+ assertInitialStateEqual(testCase.getInitialState(), setupStateDump);
+
+ // apply all the intents in the act stage
+ for (int i = 0; i < act.size(); i++) {
+ GenerationIntent generationIntent = act.get(i);
+ Activity activityToLaunchFrom = activityLog.get(
+ generationIntent.getLaunchFromIndex(initialState.size() + i));
+ Activity result = launch(activityToLaunchFrom, generationIntent.getActualIntent(),
+ generationIntent.startForResult());
+ activityLog.add(result);
+ }
+
+ // assert that the endStates are the same.
+ StateDump endStateDump = waitDumpAndTrimForVerification(getLast(activityLog),
+ testCase.getEndState());
+ assertEndStatesEqual(testCase.getEndState(), endStateDump);
+ }
+
+ /**
+ * Runs a launch object and writes out the resulting {@link Persistence.TestCase} to
+ * device storage
+ *
+ * @param startContext the context to launch the first Activity from.
+ * @param name the name of the directory to store the json files in.
+ * @param launches a list of launches to run and record.
+ */
+ public void runAndWrite(Context startContext, String name, List<LaunchSequence> launches)
+ throws Exception {
+ for (int i = 0; i < launches.size(); i++) {
+ Persistence.TestCase testCase = this.runAndSerialize(launches.get(i), startContext,
+ Integer.toString(i));
+ IntentTests.writeToDocumentsStorage(testCase, i + 1, name);
+ // Cleanup all the activities of this testCase before going to the next
+ // to preserve isolation across test cases.
+ mTestBase.cleanUp(testCase.getSetup().componentsInCase());
+ }
+ }
+
+ private Persistence.TestCase runAndSerialize(LaunchSequence launchSequence,
+ Context startContext, String name) {
+ LaunchRecord launchRecord = run(launchSequence, startContext);
+
+ LaunchSequenceExecutionInfo executionInfo = launchSequence.fold();
+ List<GenerationIntent> setupIntents = prepareSerialisation(executionInfo.setup);
+ List<GenerationIntent> actIntents = prepareSerialisation(executionInfo.acts,
+ setupIntents.size());
+
+ Persistence.Setup setup = new Persistence.Setup(setupIntents, actIntents);
+
+ return new Persistence.TestCase(setup, launchRecord.initialDump, launchRecord.endDump,
+ name);
+ }
+
+ /**
+ * Runs a launch object and returns a {@link LaunchRecord} that can be used to do assertions
+ * directly in the same test.
+ *
+ * @param launch the {@link LaunchSequence}we want to run
+ * @param startContext the {@link android.content.Context} to launch the first Activity from.
+ * @return {@link LaunchRecord} that can be used to do assertions.
+ */
+ LaunchRecord run(LaunchSequence launch, Context startContext) {
+ LaunchSequence.LaunchSequenceExecutionInfo work = launch.fold();
+ List<Activity> activityLog = Lists.newArrayList();
+
+ if (work.setup.isEmpty() || work.acts.isEmpty()) {
+ throw new IllegalArgumentException("no intents to start");
+ }
+
+ // Launch the first activity from the start context.
+ LaunchFromIntent firstIntent = work.setup.get(0);
+ Activity firstActivity = this.launchFromContext(startContext,
+ firstIntent.getActualIntent());
+
+ activityLog.add(firstActivity);
+
+ // launch the rest from the initial intents.
+ for (int i = 1; i < work.setup.size(); i++) {
+ LaunchFromIntent launchFromIntent = work.setup.get(i);
+ Intent actualIntent = launchFromIntent.getActualIntent();
+ Activity activity = launch(activityLog.get(launchFromIntent.getLaunchFrom()),
+ actualIntent, launchFromIntent.startForResult());
+ activityLog.add(activity);
+ }
+
+ // record the state after the initial intents.
+ StateDump initialDump = waitDumpAndTrim(getLast(activityLog));
+
+ // apply all the intents in the act stage
+ for (LaunchFromIntent launchFromIntent : work.acts) {
+ Intent actualIntent = launchFromIntent.getActualIntent();
+ Activity activity = launch(activityLog.get(launchFromIntent.getLaunchFrom()),
+ actualIntent, launchFromIntent.startForResult());
+
+ activityLog.add(activity);
+ }
+
+ //record the end state after all intents are launched.
+ StateDump endDump = waitDumpAndTrim(getLast(activityLog));
+
+ return new LaunchRecord(initialDump, endDump, activityLog);
+ }
+
+ /**
+ * Results from the running of an {@link LaunchSequence} so the user can assert on the results
+ * directly.
+ */
+ class LaunchRecord {
+
+ /**
+ * The end state after the setup intents.
+ */
+ public final StateDump initialDump;
+
+ /**
+ * The end state after the setup and act intents.
+ */
+ public final StateDump endDump;
+
+ /**
+ * The activities that were started by every intent in the {@link LaunchSequence}.
+ */
+ public final List<Activity> mActivitiesLog;
+
+ public LaunchRecord(StateDump initialDump, StateDump endDump,
+ List<Activity> activitiesLog) {
+ this.initialDump = initialDump;
+ this.endDump = endDump;
+ mActivitiesLog = activitiesLog;
+ }
+ }
+
+
+ public Activity launchFromContext(Context context, Intent intent) {
+ Instrumentation.ActivityMonitor monitor = InstrumentationRegistry.getInstrumentation()
+ .addMonitor((String) null, null, false);
+
+ context.startActivity(intent);
+ Activity activity = monitor.waitForActivityWithTimeout(ACTIVITY_LAUNCH_TIMEOUT);
+ waitAndAssertActivityLaunched(activity, intent);
+
+ return activity;
+ }
+
+ public Activity launch(Activity activityContext, Intent intent, boolean startForResult) {
+ Instrumentation.ActivityMonitor monitor = InstrumentationRegistry.getInstrumentation()
+ .addMonitor((String) null, null, false);
+
+ if (startForResult) {
+ activityContext.startActivityForResult(intent, 1);
+ } else {
+ activityContext.startActivity(intent);
+ }
+ Activity activity = monitor.waitForActivityWithTimeout(ACTIVITY_LAUNCH_TIMEOUT);
+
+ if (activity == null) {
+ return activityContext;
+ } else {
+ waitAndAssertActivityLaunched(activity, intent);
+ }
+
+ return activity;
+ }
+
+ private void waitAndAssertActivityLaunched(Activity activity, Intent intent) {
+ assertNotNull("Intent: " + intent.toString(), activity);
+
+ final ComponentName testActivityName = activity.getComponentName();
+ mTestBase.waitAndAssertTopResumedActivity(testActivityName,
+ Display.DEFAULT_DISPLAY, "Activity must be resumed");
+ }
+
+ /**
+ * After the last activity has been launched we wait for a valid state + an extra three seconds
+ * so have a stable state of the system. Also all previously known stacks in
+ * {@link LaunchRunner#mBaseStacks} is excluded from the output.
+ *
+ * @param activity The last activity to be launched before dumping the state.
+ * @return A stable {@link StateDump}, meaning no more {@link android.app.Activity} is in a
+ * life cycle transition.
+ */
+ public StateDump waitDumpAndTrim(Activity activity) {
+ mTestBase.getAmWmState().waitForValidState(activity.getComponentName());
+ // The last activity that was launched before the dump could still be in an intermediate
+ // lifecycle state. wait an extra 3 seconds for it to settle
+ SystemClock.sleep(BEFORE_DUMP_TIMEOUT);
+ mTestBase.getAmWmState().computeState(activity.getComponentName());
+ List<ActivityManagerState.ActivityStack> endStateStacks =
+ mTestBase.getAmWmState().getAmState().getStacks();
+ return StateDump.fromStacks(endStateStacks, mBaseStacks);
+ }
+
+ /**
+ * Like {@link LaunchRunner#waitDumpAndTrim(Activity)} but also waits until the state becomes
+ * equal to the state we expect. It is therefore only used when verifying a recorded testcase.
+ *
+ * If we take a dump of an unstable state we allow it to settle into the expected state.
+ *
+ * @param activity The last activity to be launched before dumping the state.
+ * @param expected The state that was previously recorded for this testCase.
+ * @return A stable {@link StateDump}, meaning no more {@link android.app.Activity} is in a
+ * life cycle transition.
+ */
+ public StateDump waitDumpAndTrimForVerification(Activity activity, StateDump expected) {
+ mTestBase.getAmWmState().waitForValidState(activity.getComponentName());
+ // The last activity that was launched before the dump could still be in an intermediate
+ // lifecycle state. wait an extra 3 seconds for it to settle
+ SystemClock.sleep(BEFORE_DUMP_TIMEOUT);
+ mTestBase.getAmWmState().waitForWithAmState(
+ am -> StateDump.fromStacks(am.getStacks(), mBaseStacks).equals(expected),
+ "Wait until the activity states match up with what we recorded");
+ mTestBase.getAmWmState().computeState(activity.getComponentName());
+
+ List<ActivityManagerState.ActivityStack> endStateStacks =
+ mTestBase.getAmWmState().getAmState().getStacks();
+
+ return StateDump.fromStacks(endStateStacks, mBaseStacks);
+ }
+
+ private List<ActivityManagerState.ActivityStack> getBaseStacks() {
+ ActivityAndWindowManagersState amWmState = mTestBase.getAmWmState();
+ amWmState.computeState(new ComponentName[]{});
+ return amWmState.getAmState().getStacks();
+ }
+}
diff --git a/tests/framework/base/activitymanager/src/android/server/am/intent/LaunchSequence.java b/tests/framework/base/activitymanager/src/android/server/am/intent/LaunchSequence.java
new file mode 100644
index 0000000..8d801e8
--- /dev/null
+++ b/tests/framework/base/activitymanager/src/android/server/am/intent/LaunchSequence.java
@@ -0,0 +1,262 @@
+/*
+ * Copyright (C) 2019 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.server.am.intent;
+
+
+import android.content.ComponentName;
+import android.server.am.intent.Persistence.LaunchFromIntent;
+import android.server.am.intent.Persistence.LaunchIntent;
+import android.support.test.InstrumentationRegistry;
+
+import com.google.common.collect.Lists;
+
+import java.util.List;
+import java.util.Optional;
+
+
+/**
+ * <pre>
+ * The main API entry point for specifying intent tests.
+ * A {@code Launch} object is an immutable command object to specify sequences of intents to
+ * launch.
+ *
+ * They can be run by a {@link LaunchRunner}
+ * Most tests using this api are defined in {@link Cases}.
+ * The two test classes actually using the tests specified there are:
+ *
+ * 1. {@link IntentGenerationTests}, which runs the cases, records the results and writes them
+ * out to device storage
+ * 2. {@link IntentTests}, which reads the recorded test files and verifies them again.
+ *
+ *
+ * Features supported by this API are:
+ * 1. Starting activities normally or for result.
+ * {@code
+ * LaunchSequence.start(intentForResult(RegularActivity.class)) // starting an intent for result.
+ * .append(intent(RegularActivity.class)); // starting an intent normally.
+ * }
+ * 2. Specifying Intent Flags
+ * {@code
+ * LaunchSequence.start(intent(RegularActivity.class).withFlags(Cases.NEW_TASK));
+ * }
+ *
+ * 3. Launching an intent from any point earlier in the launch sequence.
+ * {@code
+ * LaunchIntent multipleTask = intent(RegularActivity.class)
+ * .withFlags(Cases.NEW_TASK,Cases.MULTIPLE_TASK);
+ * LaunchSequence firstTask = LaunchSequence.start(multipleTask);
+ * firstTask.append(multipleTask).append(intent(SingleTopActivity.class), firstTask);
+ * }
+ *
+ * The above will result in: the first task having two activities in it and the second task having
+ * one activity, instead of the normal behaviour adding only one task.
+ *
+ * It is completely immutable and can therefore be reused without hesitation.
+ * Note that making a launch object doesn't start anything yet until it is ran by a
+ * {@link LaunchRunner}
+ * </pre>
+ */
+public interface LaunchSequence {
+ /**
+ * @return the amount of intents that will launch before this {@link LaunchSequence} object.
+ */
+ int depth();
+
+ /**
+ * Extract all the information that has been built up in this {@link LaunchSequence} object, so
+ * that {@link LaunchRunner} can run the described sequence of intents.
+ */
+ LaunchSequenceExecutionInfo fold();
+
+ /**
+ * @return the {@link LaunchIntent} inside of this {@link LaunchSequence}.
+ */
+ LaunchIntent getIntent();
+
+ /**
+ * Create a {@link LaunchSequence} object this always has
+ * {@link android.content.Intent#FLAG_ACTIVITY_NEW_TASK} set because without it we can not
+ * launch from the application context.
+ *
+ * @param intent the first intent to be Launched.
+ * @return an {@link LaunchSequence} object launching just this intent.
+ */
+ static LaunchSequence create(LaunchIntent intent) {
+ return new RootLaunch(intent.withFlags(Cases.NEW_TASK));
+ }
+
+ /**
+ * @param intent the next intent that should be launched
+ * @return a {@link LaunchSequence} that will launch all the intents in this and then
+ * {@code intent}
+ */
+ default LaunchSequence append(LaunchIntent intent) {
+ return new ConsecutiveLaunch(this, intent, false, Optional.empty());
+ }
+
+ /**
+ * @param intent the next intent that should be launched
+ * @param launchFrom a {@link LaunchSequence} to start the intent from, {@code launchFrom}
+ * should be a sub sequence of this.
+ * @return a {@link LaunchSequence} that will launch all the intents in this and then
+ * {@code intent}
+ */
+ default LaunchSequence append(LaunchIntent intent, LaunchSequence launchFrom) {
+ return new ConsecutiveLaunch(this, intent, false, Optional.of(launchFrom));
+ }
+
+ /**
+ * @param intent the intent to Launch
+ * @return a launch with the {@code intent} added to the Act stage.
+ */
+ default LaunchSequence act(LaunchIntent intent) {
+ return new ConsecutiveLaunch(this, intent, true, Optional.empty());
+ }
+
+ /**
+ * @param intent the intent to Launch
+ * @param launchFrom a {@link LaunchSequence} to start the intent from, {@code launchFrom}
+ * should be a sub sequence of this.
+ * @return a launch with the {@code intent} added to the Act stage.
+ */
+ default LaunchSequence act(LaunchIntent intent, LaunchSequence launchFrom) {
+ return new ConsecutiveLaunch(this, intent, true, Optional.of(launchFrom));
+ }
+
+ /**
+ * @param activity the activity to create an intent for.
+ * @return Creates an {@link LaunchIntent} that will target the {@link android.app.activity}
+ * class passed in. see {@link LaunchIntent#withFlags} to add intent flags to the returned
+ * intent.
+ */
+ static LaunchIntent intent(Class<? extends android.app.Activity> activity) {
+ return new LaunchIntent(Lists.newArrayList(), createComponent(activity), false);
+ }
+
+
+ /**
+ * Creates an {@link LaunchIntent} that will be started with {@link
+ * android.app.Activity#startActivityForResult}
+ *
+ * @param activity the activity to create an intent for.
+ */
+ static LaunchIntent intentForResult(Class<? extends android.app.Activity> activity) {
+ return new LaunchIntent(Lists.newArrayList(), createComponent(activity), true);
+ }
+
+ String packageName = InstrumentationRegistry.getTargetContext().getPackageName();
+
+ static ComponentName createComponent(Class<? extends android.app.Activity> activity) {
+ return new ComponentName(packageName, activity.getName());
+ }
+
+ /**
+ * Allows {@link LaunchSequence} objects to form a linkedlist of intents to launch.
+ */
+ class ConsecutiveLaunch implements LaunchSequence {
+ private final LaunchSequence mPrevious;
+ private final LaunchIntent mLaunchIntent;
+ private final boolean mAct;
+
+ public ConsecutiveLaunch(LaunchSequence previous, LaunchIntent launchIntent,
+ boolean act, Optional<LaunchSequence> launchFrom) {
+ mPrevious = previous;
+ mLaunchIntent = launchIntent;
+ mAct = act;
+ mLaunchFrom = launchFrom;
+ }
+
+ /**
+ * This should always be a {@link LaunchSequence} that is in mPrevious.
+ */
+ @SuppressWarnings("OptionalUsedAsFieldOrParameterType")
+ private Optional<LaunchSequence> mLaunchFrom;
+
+ @Override
+ public int depth() {
+ return mPrevious.depth() + 1;
+ }
+
+ @Override
+ public LaunchSequenceExecutionInfo fold() {
+ LaunchSequenceExecutionInfo launchSequenceExecutionInfo = mPrevious.fold();
+ int launchSite = mLaunchFrom.map(LaunchSequence::depth).orElse(this.depth() - 1);
+
+ LaunchFromIntent intent = new LaunchFromIntent(mLaunchIntent, launchSite);
+ if (mAct) {
+ launchSequenceExecutionInfo.acts.add(intent);
+ } else {
+ launchSequenceExecutionInfo.setup.add(intent);
+ }
+ return launchSequenceExecutionInfo;
+ }
+
+ @Override
+ public LaunchIntent getIntent() {
+ return mLaunchIntent;
+ }
+ }
+
+ /**
+ * The first intent to launch in a {@link LaunchSequence} Object.
+ */
+ class RootLaunch implements LaunchSequence {
+ /**
+ * The intent that should be launched.
+ */
+ private final LaunchIntent mLaunchIntent;
+
+ public RootLaunch(LaunchIntent launchIntent) {
+ mLaunchIntent = launchIntent;
+ }
+
+ @Override
+ public int depth() {
+ return 0;
+ }
+
+ @Override
+ public LaunchSequenceExecutionInfo fold() {
+ return new LaunchSequenceExecutionInfo(
+ Lists.newArrayList(new LaunchFromIntent(mLaunchIntent, -1)),
+ Lists.newArrayList());
+ }
+
+ @Override
+ public LaunchIntent getIntent() {
+ return mLaunchIntent;
+ }
+ }
+
+ /**
+ * Information for the {@link LaunchRunner} to run the launch represented by a {@link
+ * LaunchSequence} object. The {@link LaunchSequence} object is "folded" as a list
+ * into the summary of all intents with the corresponding indexes from what context
+ * to launch them.
+ */
+ class LaunchSequenceExecutionInfo {
+ List<LaunchFromIntent> setup;
+ List<LaunchFromIntent> acts;
+
+ public LaunchSequenceExecutionInfo(List<LaunchFromIntent> setup,
+ List<LaunchFromIntent> acts) {
+ this.setup = setup;
+ this.acts = acts;
+ }
+ }
+}
+
diff --git a/tests/framework/base/activitymanager/src/android/server/am/intent/Persistence.java b/tests/framework/base/activitymanager/src/android/server/am/intent/Persistence.java
new file mode 100644
index 0000000..e818631
--- /dev/null
+++ b/tests/framework/base/activitymanager/src/android/server/am/intent/Persistence.java
@@ -0,0 +1,697 @@
+/*
+ * Copyright (C) 2019 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.server.am.intent;
+
+import static java.util.stream.Collectors.toList;
+
+import android.content.ComponentName;
+import android.content.Intent;
+import android.server.am.ActivityManagerState;
+
+import com.google.common.collect.Lists;
+
+import org.json.JSONArray;
+import org.json.JSONException;
+import org.json.JSONObject;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.List;
+import java.util.Map;
+import java.util.Objects;
+import java.util.stream.Collectors;
+import java.util.stream.Stream;
+
+/**
+ * The intent tests are generated by running a series of intents and then recording the end state
+ * of the system. This class contains all the models needed to store the intents that were used to
+ * create the test case and the end states so that they can be asserted on.
+ *
+ * All test cases are serialized to JSON and stored in a single file per testcase.
+ */
+public class Persistence {
+
+ /**
+ * The highest level entity in the JSON file
+ */
+ public static class TestCase {
+ private static final String SETUP_KEY = "setup";
+ private static final String INITIAL_STATE_KEY = "initialState";
+ private static final String END_STATE_KEY = "endState";
+
+ /**
+ * Contains the {@link android.content.Intent}-s that will be launched in this test case.
+ */
+ private final Setup mSetup;
+
+ /**
+ * The state of the system after the {@link Setup#mInitialIntents} have been launched.
+ */
+ private final StateDump mInitialState;
+
+ /**
+ * The state of the system after the {@link Setup#mAct} have been launched
+ */
+ private final StateDump mEndState;
+
+ /**
+ * The name of the testCase, usually the file name it is stored in.
+ * Not actually persisted to json, since it is only used for presentation purposes.
+ */
+ private final String mName;
+
+ public TestCase(Setup setup, StateDump initialState,
+ StateDump endState, String name) {
+ mSetup = setup;
+ mInitialState = initialState;
+ mEndState = endState;
+ mName = name;
+ }
+
+ public JSONObject toJson() throws JSONException {
+ return new JSONObject()
+ .put(SETUP_KEY, mSetup.toJson())
+ .put(INITIAL_STATE_KEY, mInitialState.toJson())
+ .put(END_STATE_KEY, mEndState.toJson());
+ }
+
+ public static TestCase fromJson(JSONObject object,
+ Map<String, IntentFlag> table, String name) throws JSONException {
+ return new TestCase(Setup.fromJson(object.getJSONObject(SETUP_KEY), table),
+ StateDump.fromJson(object.getJSONObject(INITIAL_STATE_KEY)),
+ StateDump.fromJson(object.getJSONObject(END_STATE_KEY)), name);
+ }
+
+ public Setup getSetup() {
+ return mSetup;
+ }
+
+ public StateDump getInitialState() {
+ return mInitialState;
+ }
+
+ public String getName() {
+ return mName;
+ }
+
+ public StateDump getEndState() {
+ return mEndState;
+ }
+ }
+
+ /**
+ * Setup consists of two stages. Firstly a list of intents to bring the system in the state we
+ * want to test something in. Secondly a list of intents to bring the system to the final state.
+ */
+ public static class Setup {
+ private static final String INITIAL_INTENT_KEY = "initialIntents";
+ private static final String ACT_KEY = "act";
+ /**
+ * The intent(s) used to bring the system to the initial state.
+ */
+ private final List<GenerationIntent> mInitialIntents;
+
+ /**
+ * The intent(s) that we actually want to test.
+ */
+ private final List<GenerationIntent> mAct;
+
+ public Setup(List<GenerationIntent> initialIntents, List<GenerationIntent> act) {
+ mInitialIntents = initialIntents;
+ mAct = act;
+ }
+
+ public List<ComponentName> componentsInCase() {
+ return Stream.concat(mInitialIntents.stream(), mAct.stream())
+ .map(GenerationIntent::getActualIntent)
+ .map(Intent::getComponent)
+ .collect(Collectors.toList());
+ }
+
+ public JSONObject toJson() throws JSONException {
+ return new JSONObject()
+ .put(INITIAL_INTENT_KEY, intentsToJson(mInitialIntents))
+ .put(ACT_KEY, intentsToJson(mAct));
+ }
+
+ public static Setup fromJson(JSONObject object,
+ Map<String, IntentFlag> table) throws JSONException {
+ List<GenerationIntent> initialState = intentsFromJson(
+ object.getJSONArray(INITIAL_INTENT_KEY), table);
+ List<GenerationIntent> act = intentsFromJson(object.getJSONArray(ACT_KEY), table);
+
+ return new Setup(initialState, act);
+ }
+
+
+ public static JSONArray intentsToJson(List<GenerationIntent> intents)
+ throws JSONException {
+
+ JSONArray intentArray = new JSONArray();
+ for (GenerationIntent intent : intents) {
+ intentArray.put(intent.toJson());
+ }
+ return intentArray;
+ }
+
+ public static List<GenerationIntent> intentsFromJson(JSONArray intentArray,
+ Map<String, IntentFlag> table) throws JSONException {
+ List<GenerationIntent> intents = new ArrayList<>();
+
+ for (int i = 0; i < intentArray.length(); i++) {
+ JSONObject object = (JSONObject) intentArray.get(i);
+ GenerationIntent intent = GenerationIntent.fromJson(object, table);
+
+ intents.add(intent);
+ }
+
+ return intents;
+ }
+
+ public List<GenerationIntent> getInitialIntents() {
+ return mInitialIntents;
+ }
+
+ public List<GenerationIntent> getAct() {
+ return mAct;
+ }
+ }
+
+ /**
+ * An representation of an {@link android.content.Intent} that can be (de)serialized to / from
+ * JSON. It abstracts whether the context it should be started from is implicitly or explicitly
+ * specified.
+ */
+ interface GenerationIntent {
+ Intent getActualIntent();
+
+ JSONObject toJson() throws JSONException;
+
+ int getLaunchFromIndex(int currentPosition);
+
+ boolean startForResult();
+
+ static GenerationIntent fromJson(JSONObject object, Map<String, IntentFlag> table)
+ throws JSONException {
+ if (object.has(LaunchFromIntent.LAUNCH_FROM_KEY)) {
+ return LaunchFromIntent.fromJson(object, table);
+ } else {
+ return LaunchIntent.fromJson(object, table);
+ }
+ }
+ }
+
+ /**
+ * Representation of {@link android.content.Intent} used by the {@link LaunchSequence} api.
+ * It be can used to normally start activities, to start activities for result and Intent Flags
+ * can be added using {@link LaunchIntent#withFlags(IntentFlag...)}
+ */
+ static class LaunchIntent implements GenerationIntent {
+ private static final String FLAGS_KEY = "flags";
+ private static final String PACKAGE_KEY = "package";
+ private static final String CLASS_KEY = "class";
+ private static final String START_FOR_RESULT_KEY = "startForResult";
+
+ private final List<IntentFlag> mIntentFlags;
+ private final ComponentName mComponentName;
+ private final boolean mStartForResult;
+
+ public LaunchIntent(List<IntentFlag> intentFlags, ComponentName componentName,
+ boolean startForResult) {
+ mIntentFlags = intentFlags;
+ mComponentName = componentName;
+ mStartForResult = startForResult;
+ }
+
+ @Override
+ public Intent getActualIntent() {
+ return new Intent().setComponent(mComponentName).setFlags(buildFlag());
+ }
+
+ @Override
+ public int getLaunchFromIndex(int currentPosition) {
+ return currentPosition - 1;
+ }
+
+ @Override
+ public boolean startForResult() {
+ return mStartForResult;
+ }
+
+ public int buildFlag() {
+ int flag = 0;
+ for (IntentFlag intentFlag : mIntentFlags) {
+ flag |= intentFlag.flag;
+ }
+
+ return flag;
+ }
+
+ public String humanReadableFlags() {
+ return mIntentFlags.stream().map(IntentFlag::toString).collect(
+ Collectors.joining(" | "));
+ }
+
+ public static LaunchIntent fromJson(JSONObject fakeIntent, Map<String, IntentFlag> table)
+ throws JSONException {
+ List<IntentFlag> flags = IntentFlag.parse(table, fakeIntent.getString(FLAGS_KEY));
+
+ boolean startForResult = fakeIntent.optBoolean(START_FOR_RESULT_KEY, false);
+ return new LaunchIntent(flags,
+ new ComponentName(
+ fakeIntent.getString(PACKAGE_KEY),
+ fakeIntent.getString(CLASS_KEY)), startForResult);
+
+ }
+
+ @Override
+ public JSONObject toJson() throws JSONException {
+ return new JSONObject().put(FLAGS_KEY, this.humanReadableFlags())
+ .put(CLASS_KEY, this.mComponentName.getClassName())
+ .put(PACKAGE_KEY, this.mComponentName.getPackageName())
+ .put(START_FOR_RESULT_KEY, mStartForResult);
+ }
+
+ public LaunchIntent withFlags(IntentFlag... flags) {
+ List<IntentFlag> intentFlags = Lists.newArrayList(mIntentFlags);
+ Collections.addAll(intentFlags, flags);
+ return new LaunchIntent(intentFlags, mComponentName, mStartForResult);
+ }
+
+ public List<IntentFlag> getIntentFlags() {
+ return mIntentFlags;
+ }
+
+ public ComponentName getComponentName() {
+ return mComponentName;
+ }
+
+ public boolean isStartForResult() {
+ return mStartForResult;
+ }
+ }
+
+ /**
+ * Representation of {@link android.content.Intent} used by the {@link LaunchSequence} api.
+ * It can used to normally start activities, to start activities for result and Intent Flags
+ * can
+ * be added using {@link LaunchIntent#withFlags(IntentFlag...)} just like {@link LaunchIntent}
+ *
+ * However {@link LaunchFromIntent} also supports launching from a activity earlier in the
+ * launch sequence. This can be done using {@link LaunchSequence#act} and related methods.
+ */
+ static class LaunchFromIntent implements GenerationIntent {
+ static final String LAUNCH_FROM_KEY = "launchFrom";
+
+ /**
+ * The underlying {@link LaunchIntent} that we are wrapping with the launch point behaviour.
+ */
+ private final LaunchIntent mLaunchIntent;
+
+ /**
+ * The index in the activityLog maintained by {@link LaunchRunner}, used to retrieve the
+ * activity from the log to start this {@link LaunchIntent} from.
+ */
+ private final int mLaunchFrom;
+
+ LaunchFromIntent(LaunchIntent fakeIntent, int launchFrom) {
+ mLaunchIntent = fakeIntent;
+ mLaunchFrom = launchFrom;
+ }
+
+
+ @Override
+ public Intent getActualIntent() {
+ return mLaunchIntent.getActualIntent();
+ }
+
+ @Override
+ public int getLaunchFromIndex(int currentPosition) {
+ return mLaunchFrom;
+ }
+
+ @Override
+ public boolean startForResult() {
+ return mLaunchIntent.mStartForResult;
+ }
+
+ @Override
+ public JSONObject toJson() throws JSONException {
+ return mLaunchIntent.toJson()
+ .put(LAUNCH_FROM_KEY, mLaunchFrom);
+ }
+
+ public static LaunchFromIntent fromJson(JSONObject object, Map<String, IntentFlag> table)
+ throws JSONException {
+ LaunchIntent fakeIntent = LaunchIntent.fromJson(object, table);
+ int launchFrom = object.optInt(LAUNCH_FROM_KEY, -1);
+
+ return new LaunchFromIntent(fakeIntent, launchFrom);
+ }
+
+ static List<GenerationIntent> prepareSerialisation(List<LaunchFromIntent> intents) {
+ return prepareSerialisation(intents, 0);
+ }
+
+ // In serialized form we only want to store the launch from index if it deviates from the
+ // default, the default being the previous activity.
+ static List<GenerationIntent> prepareSerialisation(List<LaunchFromIntent> intents,
+ int base) {
+ List<GenerationIntent> serializeIntents = Lists.newArrayList();
+ for (int i = 0; i < intents.size(); i++) {
+ LaunchFromIntent launchFromIntent = intents.get(i);
+ serializeIntents.add(launchFromIntent.forget(base + i));
+ }
+
+ return serializeIntents;
+ }
+
+ public GenerationIntent forget(int currentIndex) {
+ if (mLaunchFrom == currentIndex - 1) {
+ return this.mLaunchIntent;
+ } else {
+ return this;
+ }
+ }
+
+ public int getLaunchFrom() {
+ return mLaunchFrom;
+ }
+ }
+
+ /**
+ * An intent flag that also stores the name of the flag.
+ * It is used to be able to put the flags in human readable form in the JSON file.
+ */
+ static class IntentFlag {
+ /**
+ * The underlying flag, should be a value from Intent.FLAG_ACTIVITY_*.
+ */
+ public final int flag;
+ /**
+ * The name of the flag.
+ */
+ public final String name;
+
+ public IntentFlag(int flag, String name) {
+ this.flag = flag;
+ this.name = name;
+ }
+
+ public int getFlag() {
+ return flag;
+ }
+
+ public String getName() {
+ return name;
+ }
+
+ public int combine(IntentFlag other) {
+ return other.flag | flag;
+ }
+
+ public static List<IntentFlag> parse(Map<String, IntentFlag> names, String flagsToParse) {
+ String[] split = flagsToParse.replaceAll("\\s", "").split("\\|");
+ return Arrays.stream(split).map(names::get).collect(toList());
+ }
+
+ public String toString() {
+ return name;
+ }
+ }
+
+ static IntentFlag flag(int flag, String name) {
+ return new IntentFlag(flag, name);
+ }
+
+ public static class StateDump {
+ final List<StackState> mStacks;
+
+ public static StateDump fromStacks(List<ActivityManagerState.ActivityStack> activityStacks,
+ List<ActivityManagerState.ActivityStack> baseStacks) {
+ List<StackState> stacks = new ArrayList<>();
+ for (ActivityManagerState.ActivityStack stack : trimStacks(activityStacks,
+ baseStacks)) {
+ stacks.add(new StackState(stack));
+ }
+
+ return new StateDump(stacks);
+ }
+
+ public StateDump(List<StackState> stacks) {
+ mStacks = stacks;
+ }
+
+ JSONObject toJson() throws JSONException {
+ JSONArray stacks = new JSONArray();
+ for (StackState stack : mStacks) {
+ stacks.put(stack.toJson());
+ }
+
+ return new JSONObject().put("stacks", stacks);
+ }
+
+ static StateDump fromJson(JSONObject object) throws JSONException {
+ JSONArray jsonTasks = object.getJSONArray("stacks");
+ List<StackState> stacks = new ArrayList<>();
+
+ for (int i = 0; i < jsonTasks.length(); i++) {
+ stacks.add(StackState.fromJson((JSONObject) jsonTasks.get(i)));
+ }
+
+ return new StateDump(stacks);
+ }
+
+ /**
+ * To make the state dump non device specific we remove every stack that was present
+ * in the system before recording, by their ID. For example a stack containing the launcher
+ * activity.
+ */
+ public static List<ActivityManagerState.ActivityStack> trimStacks(
+ List<ActivityManagerState.ActivityStack> toTrim,
+ List<ActivityManagerState.ActivityStack> trimFrom) {
+
+ for (ActivityManagerState.ActivityStack stack : trimFrom) {
+ toTrim.removeIf(t -> t.getStackId() == stack.getStackId());
+ }
+
+ return toTrim;
+ }
+
+ @Override
+ public boolean equals(Object o) {
+ if (this == o) return true;
+ if (o == null || getClass() != o.getClass()) return false;
+ StateDump stateDump = (StateDump) o;
+ return Objects.equals(mStacks, stateDump.mStacks);
+ }
+
+ @Override
+ public int hashCode() {
+ return Objects.hash(mStacks);
+ }
+ }
+
+ /**
+ * A simplified JSON version of the information in {@link ActivityManagerState.ActivityStack}
+ */
+ public static class StackState {
+ private static final String TASKS_KEY = "tasks";
+ private static final String RESUMED_ACTIVITY_KEY = "resumedActivity";
+
+ /**
+ * The component name of the resumedActivity in this Stack, empty string if there is none.
+ */
+ private final String mResumedActivity;
+ /**
+ * The Tasks in this stack ordered from most recent to least recent.
+ */
+ private final List<TaskState> mTasks;
+
+ public StackState(String resumedActivity, List<TaskState> tasks) {
+ mResumedActivity = resumedActivity;
+ mTasks = tasks;
+ }
+
+ public StackState(ActivityManagerState.ActivityStack stack) {
+ this.mResumedActivity = stack.getResumedActivity();
+ mTasks = new ArrayList<>();
+ for (ActivityManagerState.ActivityTask task : stack.getTasks()) {
+ this.mTasks.add(new TaskState(task));
+ }
+ }
+
+ JSONObject toJson() throws JSONException {
+ JSONArray jsonTasks = new JSONArray();
+
+ for (TaskState task : mTasks) {
+ jsonTasks.put(task.toJson());
+ }
+
+ return new JSONObject()
+ .put(TASKS_KEY, jsonTasks)
+ .put(RESUMED_ACTIVITY_KEY, mResumedActivity);
+ }
+
+ static StackState fromJson(JSONObject object) throws JSONException {
+ JSONArray jsonTasks = object.getJSONArray(TASKS_KEY);
+ List<TaskState> tasks = new ArrayList<>();
+
+ for (int i = 0; i < jsonTasks.length(); i++) {
+ tasks.add(TaskState.fromJson((JSONObject) jsonTasks.get(i)));
+ }
+
+ return new StackState(object.optString(RESUMED_ACTIVITY_KEY, ""), tasks);
+ }
+
+ public String getResumedActivity() {
+ return mResumedActivity;
+ }
+
+ public List<TaskState> getTasks() {
+ return mTasks;
+ }
+
+ @Override
+ public boolean equals(Object o) {
+ if (this == o) return true;
+ if (o == null || getClass() != o.getClass()) return false;
+ StackState stack = (StackState) o;
+ return Objects.equals(mTasks, stack.mTasks);
+ }
+
+ @Override
+ public int hashCode() {
+ return Objects.hash(mResumedActivity, mTasks);
+ }
+ }
+
+ public static class TaskState {
+
+ private static final String ACTIVITIES_KEY = "activities";
+
+ /**
+ * The activities in this task ordered from most recent to least recent.
+ */
+ private List<ActivityState> mActivities = new ArrayList<>();
+
+ public TaskState(List<ActivityState> activities) {
+ mActivities = activities;
+ }
+
+ public TaskState(ActivityManagerState.ActivityTask state) {
+ for (ActivityManagerState.Activity activity : state.getActivities()) {
+ this.mActivities.add(new ActivityState(activity));
+ }
+ }
+
+ JSONObject toJson() throws JSONException {
+ JSONArray jsonActivities = new JSONArray();
+
+ for (ActivityState activity : mActivities) {
+ jsonActivities.put(activity.toJson());
+ }
+
+ return new JSONObject()
+ .put(ACTIVITIES_KEY, jsonActivities);
+ }
+
+ static TaskState fromJson(JSONObject object) throws JSONException {
+ JSONArray jsonActivities = object.getJSONArray(ACTIVITIES_KEY);
+ List<ActivityState> activities = new ArrayList<>();
+
+ for (int i = 0; i < jsonActivities.length(); i++) {
+ activities.add(ActivityState.fromJson((JSONObject) jsonActivities.get(i)));
+ }
+
+ return new TaskState(activities);
+ }
+
+ public List<ActivityState> getActivities() {
+ return mActivities;
+ }
+
+ @Override
+ public boolean equals(Object o) {
+ if (this == o) return true;
+ if (o == null || getClass() != o.getClass()) return false;
+ TaskState task = (TaskState) o;
+ return Objects.equals(mActivities, task.mActivities);
+ }
+
+ @Override
+ public int hashCode() {
+ return Objects.hash(mActivities);
+ }
+ }
+
+ public static class ActivityState {
+ private static final String NAME_KEY = "name";
+ private static final String STATE_KEY = "state";
+ /**
+ * The componentName of this activity.
+ */
+ private final String mComponentName;
+
+ /**
+ * The lifecycle state this activity is in.
+ */
+ private final String mLifeCycleState;
+
+ public ActivityState(String name, String state) {
+ mComponentName = name;
+ mLifeCycleState = state;
+ }
+
+ public ActivityState(ActivityManagerState.Activity activity) {
+ mComponentName = activity.getName();
+ mLifeCycleState = activity.getState();
+ }
+
+
+ JSONObject toJson() throws JSONException {
+ return new JSONObject().put(NAME_KEY, mComponentName).put(STATE_KEY, mLifeCycleState);
+ }
+
+ static ActivityState fromJson(JSONObject object) throws JSONException {
+ return new ActivityState(object.getString(NAME_KEY), object.getString(STATE_KEY));
+ }
+
+ @Override
+ public boolean equals(Object o) {
+ if (this == o) return true;
+ if (o == null || getClass() != o.getClass()) return false;
+ ActivityState activity = (ActivityState) o;
+ return Objects.equals(mComponentName, activity.mComponentName) &&
+ Objects.equals(mLifeCycleState, activity.mLifeCycleState);
+ }
+
+ @Override
+ public int hashCode() {
+ return Objects.hash(mComponentName, mLifeCycleState);
+ }
+
+ public String getName() {
+ return mComponentName;
+ }
+
+ public String getState() {
+ return mLifeCycleState;
+ }
+ }
+}
diff --git a/tests/framework/base/activitymanager/src/android/server/am/intent/StateComparisonException.java b/tests/framework/base/activitymanager/src/android/server/am/intent/StateComparisonException.java
new file mode 100644
index 0000000..80a2370
--- /dev/null
+++ b/tests/framework/base/activitymanager/src/android/server/am/intent/StateComparisonException.java
@@ -0,0 +1,80 @@
+/*
+ * Copyright (C) 2019 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.server.am.intent;
+
+import org.json.JSONException;
+
+/**
+ * Exception to report differences in the {@link android.server.am.intent.Persistence.StateDump}
+ * when verifying a {@link android.server.am.intent.Persistence.TestCase} using the
+ * {@linkLaunchRunner#verify} method
+ */
+public class StateComparisonException extends RuntimeException {
+ private Persistence.StateDump mExpected;
+ private Persistence.StateDump mActual;
+ private String stage;
+
+ public StateComparisonException(Persistence.StateDump expected,
+ Persistence.StateDump actual, String stage) {
+ mExpected = expected;
+ mActual = actual;
+ this.stage = stage;
+ }
+
+
+ @Override
+ public String getMessage() {
+ try {
+ String newLine = System.lineSeparator();
+ return new StringBuilder()
+ .append(newLine)
+ .append(stage)
+ .append(newLine)
+ .append("Expected:")
+ .append(newLine)
+ .append(mExpected.toJson().toString(2))
+ .append(newLine)
+ .append(newLine)
+ .append("Actual:")
+ .append(newLine)
+ .append(mActual.toJson().toString(2))
+ .append(newLine)
+ .append(newLine)
+ .toString();
+ } catch (JSONException e) {
+ e.printStackTrace();
+ return "json parse exception during error message creation";
+ }
+ }
+
+ public static void assertEndStatesEqual(Persistence.StateDump expected,
+ Persistence.StateDump actual) {
+ compareAndThrow(expected, actual, "Different endSates");
+ }
+
+ public static void assertInitialStateEqual(Persistence.StateDump expected,
+ Persistence.StateDump actual) {
+ compareAndThrow(expected, actual, "Different initial states");
+ }
+
+ private static void compareAndThrow(Persistence.StateDump expected,
+ Persistence.StateDump actual, String stage) {
+ if (!expected.equals(actual)) {
+ throw new StateComparisonException(expected, actual, stage);
+ }
+ }
+}
diff --git a/tests/framework/base/activitymanager/src/android/server/am/lifecycle/ActivityLifecycleClientTestBase.java b/tests/framework/base/activitymanager/src/android/server/am/lifecycle/ActivityLifecycleClientTestBase.java
index f76979c..c3be401 100644
--- a/tests/framework/base/activitymanager/src/android/server/am/lifecycle/ActivityLifecycleClientTestBase.java
+++ b/tests/framework/base/activitymanager/src/android/server/am/lifecycle/ActivityLifecycleClientTestBase.java
@@ -1,5 +1,22 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License
+ */
+
package android.server.am.lifecycle;
+import static android.server.am.Components.PipActivity.EXTRA_ENTER_PIP;
import static android.server.am.StateLogger.log;
import static android.server.am.lifecycle.LifecycleLog.ActivityCallback.ON_ACTIVITY_RESULT;
import static android.server.am.lifecycle.LifecycleLog.ActivityCallback
@@ -11,6 +28,7 @@
import android.annotation.Nullable;
import android.app.Activity;
+import android.app.PictureInPictureParams;
import android.content.ComponentName;
import android.content.Intent;
import android.content.pm.ActivityInfo;
@@ -49,6 +67,9 @@
final ActivityTestRule mSecondActivityTestRule = new ActivityTestRule(SecondActivity.class,
true /* initialTouchMode */, false /* launchActivity */);
+ final ActivityTestRule mThirdActivityTestRule = new ActivityTestRule(ThirdActivity.class,
+ true /* initialTouchMode */, false /* launchActivity */);
+
final ActivityTestRule mTranslucentActivityTestRule = new ActivityTestRule(
TranslucentActivity.class, true /* initialTouchMode */, false /* launchActivity */);
@@ -70,6 +91,9 @@
ConfigChangeHandlingActivity.class, true /* initialTouchMode */,
false /* launchActivity */);
+ final ActivityTestRule mPipActivityTestRule = new ActivityTestRule(
+ PipActivity.class, true /* initialTouchMode */, false /* launchActivity */);
+
private final ActivityLifecycleMonitor mLifecycleMonitor = ActivityLifecycleMonitorRegistry
.getInstance();
private static LifecycleLog mLifecycleLog;
@@ -166,6 +190,10 @@
public static class SecondActivity extends Activity {
}
+ // Test activity
+ public static class ThirdActivity extends Activity {
+ }
+
// Translucent test activity
public static class TranslucentActivity extends Activity {
}
@@ -251,6 +279,22 @@
public static class ConfigChangeHandlingActivity extends CallbackTrackingActivity {
}
+ // Pip-capable activity
+ // TODO(b/123013403): Disabled onMultiWindowMode changed callbacks to make the tests pass, so
+ // that they can verify other lifecycle transitions. This should be fixed and switched to
+ // extend CallbackTrackingActivity.
+ public static class PipActivity extends Activity {
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+
+ // Enter picture in picture with the given aspect ratio if provided
+ if (getIntent().hasExtra(EXTRA_ENTER_PIP)) {
+ enterPictureInPictureMode(new PictureInPictureParams.Builder().build());
+ }
+ }
+ }
+
static ComponentName getComponentName(Class<? extends Activity> activity) {
return new ComponentName(InstrumentationRegistry.getContext(), activity);
}
diff --git a/tests/framework/base/activitymanager/src/android/server/am/lifecycle/ActivityLifecycleFreeformTests.java b/tests/framework/base/activitymanager/src/android/server/am/lifecycle/ActivityLifecycleFreeformTests.java
new file mode 100644
index 0000000..18b5bfe
--- /dev/null
+++ b/tests/framework/base/activitymanager/src/android/server/am/lifecycle/ActivityLifecycleFreeformTests.java
@@ -0,0 +1,269 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License
+ */
+
+package android.server.am.lifecycle;
+
+import static android.app.WindowConfiguration.WINDOWING_MODE_FREEFORM;
+import static android.content.Intent.FLAG_ACTIVITY_MULTIPLE_TASK;
+import static android.content.Intent.FLAG_ACTIVITY_NEW_TASK;
+import static android.server.am.ActivityManagerState.STATE_PAUSED;
+import static android.server.am.ActivityManagerState.STATE_RESUMED;
+import static android.server.am.ActivityManagerState.STATE_STOPPED;
+import static android.server.am.ComponentNameUtils.getWindowName;
+import static android.server.am.lifecycle.LifecycleLog.ActivityCallback.ON_RESUME;
+
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assume.assumeTrue;
+
+import android.app.Activity;
+import android.app.ActivityOptions;
+import android.content.Intent;
+import android.os.Bundle;
+import android.platform.test.annotations.Presubmit;
+import android.support.test.InstrumentationRegistry;
+import android.support.test.filters.FlakyTest;
+import android.support.test.filters.MediumTest;
+import android.support.test.runner.AndroidJUnit4;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+
+/**
+ * Build/Install/Run:
+ * atest CtsActivityManagerDeviceTestCases:ActivityLifecycleFreeformTests
+ */
+@MediumTest
+@RunWith(AndroidJUnit4.class)
+@Presubmit
+@FlakyTest(bugId = 77652261)
+public class ActivityLifecycleFreeformTests extends ActivityLifecycleClientTestBase {
+
+ @Before
+ public void setUp() throws Exception {
+ super.setUp();
+ assumeTrue(supportsFreeform());
+ }
+
+ @Test
+ public void testLaunchInFreeform() throws Exception {
+ // Launch a fullscreen activity, mainly to prevent setting pending due to task switching.
+ mCallbackTrackingActivityTestRule.launchActivity(new Intent());
+
+ final ActivityOptions launchOptions = ActivityOptions.makeBasic();
+ launchOptions.setLaunchWindowingMode(WINDOWING_MODE_FREEFORM);
+ final Bundle bundle = launchOptions.toBundle();
+
+ // Launch an activity in freeform
+ final Intent firstIntent =
+ new Intent(InstrumentationRegistry.getContext(), FirstActivity.class)
+ .setFlags(FLAG_ACTIVITY_NEW_TASK | FLAG_ACTIVITY_MULTIPLE_TASK);
+ InstrumentationRegistry.getTargetContext().startActivity(firstIntent, bundle);
+
+ // Wait and assert resume
+ waitAndAssertActivityState(getComponentName(FirstActivity.class), STATE_RESUMED,
+ "Activity should be resumed after launch");
+ LifecycleVerifier.assertLaunchSequence(FirstActivity.class, getLifecycleLog(),
+ false /* includeCallbacks */);
+ LifecycleVerifier.assertLaunchSequence(CallbackTrackingActivity.class, getLifecycleLog(),
+ true /* includeCallbacks */);
+ }
+
+ @Test
+ public void testMultiLaunchInFreeform() throws Exception {
+ // Launch a fullscreen activity, mainly to prevent setting pending due to task switching.
+ mCallbackTrackingActivityTestRule.launchActivity(new Intent());
+
+ final ActivityOptions launchOptions = ActivityOptions.makeBasic();
+ launchOptions.setLaunchWindowingMode(WINDOWING_MODE_FREEFORM);
+ final Bundle bundle = launchOptions.toBundle();
+
+ // Launch three activities in freeform
+ final Intent firstIntent =
+ new Intent(InstrumentationRegistry.getContext(), FirstActivity.class)
+ .setFlags(FLAG_ACTIVITY_NEW_TASK | FLAG_ACTIVITY_MULTIPLE_TASK);
+ InstrumentationRegistry.getTargetContext().startActivity(firstIntent, bundle);
+
+ final Intent secondIntent =
+ new Intent(InstrumentationRegistry.getContext(), SecondActivity.class)
+ .setFlags(FLAG_ACTIVITY_NEW_TASK | FLAG_ACTIVITY_MULTIPLE_TASK);
+ InstrumentationRegistry.getTargetContext().startActivity(secondIntent, bundle);
+
+ final Intent thirdIntent =
+ new Intent(InstrumentationRegistry.getContext(), ThirdActivity.class)
+ .setFlags(FLAG_ACTIVITY_NEW_TASK | FLAG_ACTIVITY_MULTIPLE_TASK);
+ InstrumentationRegistry.getTargetContext().startActivity(thirdIntent, bundle);
+
+ // Wait for resume
+ final String message = "Activity should be resumed after launch";
+ waitAndAssertActivityState(getComponentName(FirstActivity.class), STATE_RESUMED, message);
+ waitAndAssertActivityState(getComponentName(SecondActivity.class), STATE_RESUMED, message);
+ waitAndAssertActivityState(getComponentName(ThirdActivity.class), STATE_RESUMED, message);
+
+ // Assert lifecycle
+ LifecycleVerifier.assertLaunchSequence(FirstActivity.class, getLifecycleLog(),
+ false /* includeCallbacks */);
+ LifecycleVerifier.assertLaunchSequence(SecondActivity.class, getLifecycleLog(),
+ false /* includeCallbacks */);
+ LifecycleVerifier.assertLaunchSequence(ThirdActivity.class, getLifecycleLog(),
+ false /* includeCallbacks */);
+ LifecycleVerifier.assertLaunchSequence(CallbackTrackingActivity.class, getLifecycleLog(),
+ true /* includeCallbacks */);
+ }
+
+ @Test
+ public void testLaunchOccludingInFreeform() throws Exception {
+ // Launch a fullscreen activity, mainly to prevent setting pending due to task switching.
+ mCallbackTrackingActivityTestRule.launchActivity(new Intent());
+
+ final ActivityOptions launchOptions = ActivityOptions.makeBasic();
+ launchOptions.setLaunchWindowingMode(WINDOWING_MODE_FREEFORM);
+ final Bundle bundle = launchOptions.toBundle();
+
+ // Launch two activities in freeform in the same task
+ final Intent firstIntent =
+ new Intent(InstrumentationRegistry.getContext(), FirstActivity.class)
+ .setFlags(FLAG_ACTIVITY_NEW_TASK | FLAG_ACTIVITY_MULTIPLE_TASK);
+ InstrumentationRegistry.getTargetContext().startActivity(firstIntent, bundle);
+
+ final Activity secondActivity = mSecondActivityTestRule.launchActivity(new Intent());
+
+ final Intent thirdIntent =
+ new Intent(InstrumentationRegistry.getContext(), ThirdActivity.class)
+ .setFlags(FLAG_ACTIVITY_NEW_TASK | FLAG_ACTIVITY_MULTIPLE_TASK);
+ InstrumentationRegistry.getTargetContext().startActivity(thirdIntent, bundle);
+
+ // Wait for valid states
+ final String stopMessage = "Activity should be stopped after being covered above";
+ waitAndAssertActivityState(getComponentName(FirstActivity.class), STATE_STOPPED,
+ stopMessage);
+ final String message = "Activity should be resumed after launch";
+ waitAndAssertActivityState(getComponentName(SecondActivity.class), STATE_RESUMED, message);
+ waitAndAssertActivityState(getComponentName(ThirdActivity.class), STATE_RESUMED, message);
+
+ // Assert lifecycle
+ LifecycleVerifier.assertLaunchAndStopSequence(FirstActivity.class, getLifecycleLog());
+ LifecycleVerifier.assertLaunchSequence(SecondActivity.class, getLifecycleLog(),
+ false /* includeCallbacks */);
+ LifecycleVerifier.assertLaunchSequence(ThirdActivity.class, getLifecycleLog(),
+ false /* includeCallbacks */);
+ LifecycleVerifier.assertLaunchSequence(CallbackTrackingActivity.class, getLifecycleLog(),
+ true /* includeCallbacks */);
+
+ // Finish the activity that was occluding the first one
+ getLifecycleLog().clear();
+ secondActivity.finish();
+
+ // Wait and assert the lifecycle
+ mAmWmState.waitForWithAmState(
+ (state) -> !state.containsActivity(getComponentName(SecondActivity.class)),
+ "Waiting for activity to be removed");
+ mAmWmState.waitForWithWmState(
+ (state) -> !state.containsWindow(
+ getWindowName(getComponentName(SecondActivity.class))),
+ "Waiting for activity window to be gone");
+ waitAndAssertActivityState(getComponentName(FirstActivity.class), STATE_RESUMED,
+ "Activity must be resumed after occluding finished");
+
+ assertFalse("Activity must be destroyed",
+ mAmWmState.getAmState().containsActivity(getComponentName(SecondActivity.class)));
+ assertFalse("Activity must be destroyed",
+ mAmWmState.getWmState().containsWindow(
+ getWindowName(getComponentName(SecondActivity.class))));
+ LifecycleVerifier.assertRestartAndResumeSequence(FirstActivity.class, getLifecycleLog());
+ LifecycleVerifier.assertResumeToDestroySequence(SecondActivity.class, getLifecycleLog());
+ LifecycleVerifier.assertSequence(ThirdActivity.class, getLifecycleLog(), new ArrayList<>(),
+ "finishInOtherStack");
+ LifecycleVerifier.assertSequence(CallbackTrackingActivity.class, getLifecycleLog(),
+ new ArrayList<>(), "finishInOtherStack");
+ }
+
+ @Test
+ public void testLaunchTranslucentInFreeform() throws Exception {
+ // Launch a fullscreen activity, mainly to prevent setting pending due to task switching.
+ mCallbackTrackingActivityTestRule.launchActivity(new Intent());
+
+ final ActivityOptions launchOptions = ActivityOptions.makeBasic();
+ launchOptions.setLaunchWindowingMode(WINDOWING_MODE_FREEFORM);
+ final Bundle bundle = launchOptions.toBundle();
+
+ // Launch two activities in freeform in the same task
+ final Intent firstIntent =
+ new Intent(InstrumentationRegistry.getContext(), FirstActivity.class)
+ .setFlags(FLAG_ACTIVITY_NEW_TASK | FLAG_ACTIVITY_MULTIPLE_TASK);
+ InstrumentationRegistry.getTargetContext().startActivity(firstIntent, bundle);
+
+ final Activity transparentActivity = mTranslucentActivityTestRule
+ .launchActivity(new Intent());
+
+ final Intent thirdIntent =
+ new Intent(InstrumentationRegistry.getContext(), ThirdActivity.class)
+ .setFlags(FLAG_ACTIVITY_NEW_TASK | FLAG_ACTIVITY_MULTIPLE_TASK);
+ InstrumentationRegistry.getTargetContext().startActivity(thirdIntent, bundle);
+
+ // Wait for valid states
+ final String pauseMessage = "Activity should be stopped after transparent launch above";
+ waitAndAssertActivityState(getComponentName(FirstActivity.class), STATE_PAUSED,
+ pauseMessage);
+ final String message = "Activity should be resumed after launch";
+ waitAndAssertActivityState(getComponentName(TranslucentActivity.class), STATE_RESUMED,
+ message);
+ waitAndAssertActivityState(getComponentName(ThirdActivity.class), STATE_RESUMED, message);
+
+ // Assert lifecycle
+ LifecycleVerifier.assertLaunchAndPauseSequence(FirstActivity.class, getLifecycleLog());
+ LifecycleVerifier.assertLaunchSequence(TranslucentActivity.class, getLifecycleLog(),
+ false /* includeCallbacks */);
+ LifecycleVerifier.assertLaunchSequence(ThirdActivity.class, getLifecycleLog(),
+ false /* includeCallbacks */);
+ LifecycleVerifier.assertLaunchSequence(CallbackTrackingActivity.class, getLifecycleLog(),
+ true /* includeCallbacks */);
+
+ // Finish the activity that was occluding the first one
+ getLifecycleLog().clear();
+ transparentActivity.finish();
+
+ // Wait and assert the lifecycle
+ mAmWmState.waitForWithAmState(
+ (state) -> !state.containsActivity(getComponentName(TranslucentActivity.class)),
+ "Waiting for activity to be removed");
+ mAmWmState.waitForWithWmState(
+ (state) -> !state.containsWindow(
+ getWindowName(getComponentName(TranslucentActivity.class))),
+ "Waiting for activity window to be gone");
+ waitAndAssertActivityState(getComponentName(FirstActivity.class), STATE_RESUMED,
+ "Activity must be resumed after occluding finished");
+
+
+ assertFalse("Activity must be destroyed",
+ mAmWmState.getAmState().containsActivity(
+ getComponentName(TranslucentActivity.class)));
+ assertFalse("Activity must be destroyed",
+ mAmWmState.getWmState().containsWindow(
+ getWindowName(getComponentName(TranslucentActivity.class))));
+ LifecycleVerifier.assertSequence(FirstActivity.class, getLifecycleLog(),
+ Arrays.asList(ON_RESUME), "finishTranslucentOnTop");
+ LifecycleVerifier.assertResumeToDestroySequence(TranslucentActivity.class,
+ getLifecycleLog());
+ LifecycleVerifier.assertSequence(ThirdActivity.class, getLifecycleLog(), new ArrayList<>(),
+ "finishInOtherStack");
+ LifecycleVerifier.assertSequence(CallbackTrackingActivity.class, getLifecycleLog(),
+ new ArrayList<>(), "finishInOtherStack");
+ }
+}
diff --git a/tests/framework/base/activitymanager/src/android/server/am/lifecycle/ActivityLifecycleKeyguardTests.java b/tests/framework/base/activitymanager/src/android/server/am/lifecycle/ActivityLifecycleKeyguardTests.java
index 95fc60e..76c712c 100644
--- a/tests/framework/base/activitymanager/src/android/server/am/lifecycle/ActivityLifecycleKeyguardTests.java
+++ b/tests/framework/base/activitymanager/src/android/server/am/lifecycle/ActivityLifecycleKeyguardTests.java
@@ -1,5 +1,28 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License
+ */
+
package android.server.am.lifecycle;
+import static android.content.Intent.FLAG_ACTIVITY_MULTIPLE_TASK;
+import static android.content.Intent.FLAG_ACTIVITY_NEW_TASK;
+import static android.server.am.Components.PipActivity.EXTRA_ENTER_PIP;
+import static android.server.am.lifecycle.LifecycleLog.ActivityCallback.ON_PAUSE;
+import static android.server.am.lifecycle.LifecycleLog.ActivityCallback.ON_RESTART;
+import static android.server.am.lifecycle.LifecycleLog.ActivityCallback.ON_RESUME;
+import static android.server.am.lifecycle.LifecycleLog.ActivityCallback.ON_START;
import static android.server.am.lifecycle.LifecycleLog.ActivityCallback.ON_STOP;
import android.app.Activity;
@@ -11,6 +34,8 @@
import org.junit.Test;
import org.junit.runner.RunWith;
+import java.util.Arrays;
+
/**
* Build/Install/Run:
* atest CtsActivityManagerDeviceTestCases:ActivityLifecycleKeyguardTests
@@ -34,4 +59,106 @@
LifecycleVerifier.assertLaunchAndStopSequence(FirstActivity.class, getLifecycleLog());
}
}
+
+ @Test
+ public void testKeyguardShowHide() throws Exception {
+ if (!supportsSecureLock()) {
+ return;
+ }
+
+ // Launch first activity and wait for resume
+ final Activity activity = mFirstActivityTestRule.launchActivity(new Intent());
+ waitAndAssertActivityStates(state(activity, ON_RESUME));
+
+ // Show and hide lock screen
+ try (final LockScreenSession lockScreenSession = new LockScreenSession()) {
+ lockScreenSession.setLockCredential().gotoKeyguard();
+ waitAndAssertActivityStates(state(activity, ON_STOP));
+
+ LifecycleVerifier.assertLaunchAndStopSequence(FirstActivity.class, getLifecycleLog());
+ getLifecycleLog().clear();
+ } // keyguard hidden
+
+ // Verify that activity was resumed
+ waitAndAssertActivityStates(state(activity, ON_RESUME));
+ LifecycleVerifier.assertRestartAndResumeSequence(FirstActivity.class, getLifecycleLog());
+ }
+
+ @Test
+ public void testKeyguardShowHideOverSplitScreen() throws Exception {
+ if (!supportsSecureLock() || !supportsSplitScreenMultiWindow()) {
+ return;
+ }
+
+ final Activity firstActivity = mFirstActivityTestRule.launchActivity(new Intent());
+ waitAndAssertActivityStates(state(firstActivity, ON_RESUME));
+
+ // Enter split screen
+ moveTaskToPrimarySplitScreen(firstActivity.getTaskId());
+
+ // Launch second activity to side
+ final Activity secondActivity = mSecondActivityTestRule.launchActivity(
+ new Intent().setFlags(FLAG_ACTIVITY_NEW_TASK | FLAG_ACTIVITY_MULTIPLE_TASK));
+
+ // Wait for second activity to resume.
+ waitAndAssertActivityStates(state(secondActivity, ON_RESUME));
+
+ // Show and hide lock screen
+ getLifecycleLog().clear();
+ try (final LockScreenSession lockScreenSession = new LockScreenSession()) {
+ lockScreenSession.setLockCredential().gotoKeyguard();
+ waitAndAssertActivityStates(state(firstActivity, ON_STOP));
+ waitAndAssertActivityStates(state(secondActivity, ON_STOP));
+
+ LifecycleVerifier.assertResumeToStopSequence(FirstActivity.class, getLifecycleLog());
+ LifecycleVerifier.assertResumeToStopSequence(SecondActivity.class, getLifecycleLog());
+ getLifecycleLog().clear();
+ } // keyguard hidden
+
+ waitAndAssertActivityStates(state(firstActivity, ON_RESUME),
+ state(secondActivity, ON_RESUME));
+ LifecycleVerifier.assertRestartAndResumeSequence(FirstActivity.class, getLifecycleLog());
+ LifecycleVerifier.assertRestartAndResumeSequence(SecondActivity.class, getLifecycleLog());
+ }
+
+ @Test
+ public void testKeyguardShowHideOverPip() throws Exception {
+ if (!supportsPip()) {
+ // Skipping test: no Picture-In-Picture support
+ return;
+ }
+
+ // Launch first activity
+ final Activity firstActivity = mFirstActivityTestRule.launchActivity(new Intent());
+
+ // Clear the log before launching to Pip
+ waitAndAssertActivityStates(state(firstActivity, ON_RESUME));
+ getLifecycleLog().clear();
+
+ // Launch Pip-capable activity and enter Pip immediately
+ final Activity pipActivity = mPipActivityTestRule.launchActivity(
+ new Intent().putExtra(EXTRA_ENTER_PIP, true));
+
+ // Wait and assert lifecycle
+ waitAndAssertActivityStates(state(firstActivity, ON_RESUME), state(pipActivity, ON_PAUSE));
+
+ // Show and hide lock screen
+ getLifecycleLog().clear();
+ try (final LockScreenSession lockScreenSession = new LockScreenSession()) {
+ lockScreenSession.setLockCredential().gotoKeyguard();
+ waitAndAssertActivityStates(state(firstActivity, ON_STOP));
+ waitAndAssertActivityStates(state(pipActivity, ON_STOP));
+
+ LifecycleVerifier.assertResumeToStopSequence(FirstActivity.class, getLifecycleLog());
+ LifecycleVerifier.assertSequence(PipActivity.class, getLifecycleLog(),
+ Arrays.asList(ON_STOP), "keyguardShown");
+ getLifecycleLog().clear();
+ } // keyguard hidden
+
+ // Wait and assert lifecycle
+ waitAndAssertActivityStates(state(firstActivity, ON_RESUME), state(pipActivity, ON_PAUSE));
+ LifecycleVerifier.assertRestartAndResumeSequence(FirstActivity.class, getLifecycleLog());
+ LifecycleVerifier.assertSequence(PipActivity.class, getLifecycleLog(),
+ Arrays.asList(ON_RESTART, ON_START, ON_RESUME, ON_PAUSE), "keyguardGone");
+ }
}
diff --git a/tests/framework/base/activitymanager/src/android/server/am/lifecycle/ActivityLifecyclePipTests.java b/tests/framework/base/activitymanager/src/android/server/am/lifecycle/ActivityLifecyclePipTests.java
new file mode 100644
index 0000000..43cd7d4
--- /dev/null
+++ b/tests/framework/base/activitymanager/src/android/server/am/lifecycle/ActivityLifecyclePipTests.java
@@ -0,0 +1,303 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License
+ */
+
+package android.server.am.lifecycle;
+
+import static android.app.ActivityTaskManager.INVALID_STACK_ID;
+import static android.content.Intent.FLAG_ACTIVITY_MULTIPLE_TASK;
+import static android.content.Intent.FLAG_ACTIVITY_NEW_TASK;
+import static android.server.am.Components.PipActivity.EXTRA_ENTER_PIP;
+import static android.server.am.lifecycle.LifecycleLog.ActivityCallback.ON_CREATE;
+import static android.server.am.lifecycle.LifecycleLog.ActivityCallback.ON_DESTROY;
+import static android.server.am.lifecycle.LifecycleLog.ActivityCallback.ON_PAUSE;
+import static android.server.am.lifecycle.LifecycleLog.ActivityCallback.ON_RESTART;
+import static android.server.am.lifecycle.LifecycleLog.ActivityCallback.ON_RESUME;
+import static android.server.am.lifecycle.LifecycleLog.ActivityCallback.ON_START;
+import static android.server.am.lifecycle.LifecycleLog.ActivityCallback.ON_STOP;
+import static android.server.am.lifecycle.LifecycleLog.ActivityCallback.PRE_ON_CREATE;
+
+import static org.junit.Assert.assertNotEquals;
+import static org.junit.Assume.assumeTrue;
+
+import android.app.Activity;
+import android.content.ComponentName;
+import android.content.Intent;
+import android.platform.test.annotations.Presubmit;
+import android.support.test.InstrumentationRegistry;
+import android.support.test.filters.FlakyTest;
+import android.support.test.filters.MediumTest;
+import android.support.test.runner.AndroidJUnit4;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+
+/**
+ * Build/Install/Run:
+ * atest CtsActivityManagerDeviceTestCases:ActivityLifecyclePipTests
+ */
+@MediumTest
+@RunWith(AndroidJUnit4.class)
+@Presubmit
+@FlakyTest(bugId = 77652261)
+public class ActivityLifecyclePipTests extends ActivityLifecycleClientTestBase {
+
+ @Before
+ public void setUp() throws Exception {
+ super.setUp();
+ assumeTrue(supportsPip());
+ }
+
+ @Test
+ public void testGoToPip() throws Exception {
+ // Launch first activity
+ final Activity firstActivity = mFirstActivityTestRule.launchActivity(new Intent());
+
+ // Launch Pip-capable activity
+ final Activity pipActivity = mPipActivityTestRule.launchActivity(new Intent());
+
+ waitAndAssertActivityStates(state(firstActivity, ON_STOP), state(pipActivity, ON_RESUME));
+
+ // Move activity to Picture-In-Picture
+ getLifecycleLog().clear();
+ final ComponentName pipActivityName = getComponentName(PipActivity.class);
+ mAmWmState.computeState(pipActivityName);
+ final int stackId = mAmWmState.getAmState().getStackIdByActivity(pipActivityName);
+ assertNotEquals(stackId, INVALID_STACK_ID);
+ moveTopActivityToPinnedStack(stackId);
+
+ // Wait and assert lifecycle
+ waitAndAssertActivityStates(state(firstActivity, ON_RESUME), state(pipActivity, ON_PAUSE));
+ LifecycleVerifier.assertRestartAndResumeSequence(FirstActivity.class, getLifecycleLog());
+ LifecycleVerifier.assertSequence(PipActivity.class, getLifecycleLog(),
+ Arrays.asList(ON_PAUSE), "enterPip");
+ }
+
+ @Test
+ public void testPipOnLaunch() throws Exception {
+ // Launch first activity
+ final Activity firstActivity = mFirstActivityTestRule.launchActivity(new Intent());
+
+ // Clear the log before launching to Pip
+ waitAndAssertActivityStates(state(firstActivity, ON_RESUME));
+ getLifecycleLog().clear();
+
+ // Launch Pip-capable activity and enter Pip immediately
+ final Activity pipActivity = mPipActivityTestRule.launchActivity(
+ new Intent().putExtra(EXTRA_ENTER_PIP, true));
+
+ // Wait and assert lifecycle
+ waitAndAssertActivityStates(state(firstActivity, ON_RESUME), state(pipActivity, ON_PAUSE));
+
+ final List<LifecycleLog.ActivityCallback> expectedSequence =
+ Arrays.asList(ON_PAUSE, ON_RESUME);
+ final List<LifecycleLog.ActivityCallback> extraCycleSequence =
+ Arrays.asList(ON_PAUSE, ON_STOP, ON_RESTART, ON_START, ON_RESUME);
+ LifecycleVerifier.assertSequenceMatchesOneOf(FirstActivity.class,
+ getLifecycleLog(), Arrays.asList(expectedSequence, extraCycleSequence),
+ "activityEnteringPipOnTop");
+ LifecycleVerifier.assertSequence(PipActivity.class, getLifecycleLog(),
+ Arrays.asList(PRE_ON_CREATE, ON_CREATE, ON_START, ON_RESUME, ON_PAUSE),
+ "launchAndEnterPip");
+ }
+
+ @Test
+ public void testDestroyPip() throws Exception {
+ // Launch first activity
+ final Activity firstActivity = mFirstActivityTestRule.launchActivity(new Intent());
+
+ // Clear the log before launching to Pip
+ waitAndAssertActivityStates(state(firstActivity, ON_RESUME));
+ getLifecycleLog().clear();
+
+ // Launch Pip-capable activity and enter Pip immediately
+ final Activity pipActivity = mPipActivityTestRule.launchActivity(
+ new Intent().putExtra(EXTRA_ENTER_PIP, true));
+
+ // Wait and assert lifecycle
+ waitAndAssertActivityStates(state(firstActivity, ON_RESUME), state(pipActivity, ON_PAUSE));
+
+ // Exit PiP
+ getLifecycleLog().clear();
+ pipActivity.finish();
+
+ waitAndAssertActivityStates(state(pipActivity, ON_DESTROY));
+ LifecycleVerifier.assertSequence(FirstActivity.class, getLifecycleLog(), new ArrayList<>(),
+ "finishPip");
+ LifecycleVerifier.assertSequence(PipActivity.class, getLifecycleLog(),
+ Arrays.asList(ON_STOP, ON_DESTROY), "finishPip");
+ }
+
+ @Test
+ public void testLaunchBelowPip() throws Exception {
+ // Launch Pip-capable activity and enter Pip immediately
+ final Activity pipActivity = mPipActivityTestRule.launchActivity(
+ new Intent().putExtra(EXTRA_ENTER_PIP, true));
+
+ waitAndAssertActivityStates(state(pipActivity, ON_PAUSE));
+
+ // Launch a regular activity below
+ getLifecycleLog().clear();
+ final Activity firstActivity = mFirstActivityTestRule.launchActivity(new Intent()
+ .setFlags(FLAG_ACTIVITY_NEW_TASK | FLAG_ACTIVITY_MULTIPLE_TASK));
+
+ // Wait and verify the sequence
+ waitAndAssertActivityStates(state(firstActivity, ON_RESUME));
+ LifecycleVerifier.assertLaunchSequence(FirstActivity.class, getLifecycleLog(),
+ false /* includeCallbacks */);
+ LifecycleVerifier.assertSequence(PipActivity.class, getLifecycleLog(),
+ new ArrayList<>(), "launchBelowPip");
+ }
+
+ @Test
+ public void testIntoPipSameTask() throws Exception {
+ // Launch Pip-capable activity and enter Pip immediately
+ final Activity pipActivity = mPipActivityTestRule.launchActivity(
+ new Intent().putExtra(EXTRA_ENTER_PIP, true));
+
+ waitAndAssertActivityStates(state(pipActivity, ON_PAUSE));
+
+ // Launch a regular activity into same task
+ getLifecycleLog().clear();
+ final Activity firstActivity = mFirstActivityTestRule.launchActivity(new Intent());
+
+ // Wait and verify the sequence
+ waitAndAssertActivityStates(state(pipActivity, ON_STOP), state(firstActivity, ON_PAUSE));
+
+ // TODO(b/123013403): sometimes extra one or even more relaunches happen
+ //final List<LifecycleLog.ActivityCallback> extraDestroySequence =
+ // Arrays.asList(PRE_ON_CREATE, ON_CREATE, ON_START, ON_RESUME, ON_PAUSE, ON_STOP,
+ // ON_DESTROY, PRE_ON_CREATE, ON_CREATE, ON_START, ON_RESUME, ON_PAUSE);
+ //waitForActivityTransitions(FirstActivity.class, extraDestroySequence);
+ //final List<LifecycleLog.ActivityCallback> expectedSequence =
+ // Arrays.asList(PRE_ON_CREATE, ON_CREATE, ON_START, ON_RESUME, ON_PAUSE);
+ //LifecycleVerifier.assertSequenceMatchesOneOf(FirstActivity.class, getLifecycleLog(),
+ // Arrays.asList(extraDestroySequence, expectedSequence),
+ // "launchIntoPip");
+
+ LifecycleVerifier.assertSequence(PipActivity.class, getLifecycleLog(),
+ Arrays.asList(ON_STOP), "launchIntoPip");
+ }
+
+ @Test
+ public void testDestroyBelowPip() throws Exception {
+ // Launch a regular activity
+ final Activity firstActivity = mFirstActivityTestRule.launchActivity(new Intent());
+
+ // Launch Pip-capable activity and enter Pip immediately
+ final Activity pipActivity = mPipActivityTestRule.launchActivity(
+ new Intent().putExtra(EXTRA_ENTER_PIP, true));
+
+ waitAndAssertActivityStates(state(pipActivity, ON_PAUSE), state(firstActivity, ON_RESUME));
+
+ // Destroy the activity below
+ getLifecycleLog().clear();
+ firstActivity.finish();
+ waitAndAssertActivityStates(state(firstActivity, ON_DESTROY));
+ LifecycleVerifier.assertResumeToDestroySequence(FirstActivity.class, getLifecycleLog());
+ LifecycleVerifier.assertSequence(PipActivity.class, getLifecycleLog(),
+ new ArrayList<>(), "destroyBelowPip");
+ }
+
+ @Test
+ public void testSplitScreenBelowPip() throws Exception {
+ // Launch Pip-capable activity and enter Pip immediately
+ final Activity pipActivity = mPipActivityTestRule.launchActivity(
+ new Intent().putExtra(EXTRA_ENTER_PIP, true));
+
+ waitAndAssertActivityStates(state(pipActivity, ON_PAUSE));
+
+ // Launch first activity
+ getLifecycleLog().clear();
+ final Activity firstActivity =
+ mFirstActivityTestRule.launchActivity(new Intent()
+ .setFlags(FLAG_ACTIVITY_NEW_TASK | FLAG_ACTIVITY_MULTIPLE_TASK));
+
+ waitAndAssertActivityStates(state(firstActivity, ON_RESUME));
+ LifecycleVerifier.assertLaunchSequence(FirstActivity.class, getLifecycleLog(),
+ false /* includeCallbacks */);
+
+ // Enter split screen
+ getLifecycleLog().clear();
+ moveTaskToPrimarySplitScreen(firstActivity.getTaskId());
+
+ waitAndAssertActivityStates(state(firstActivity, ON_PAUSE));
+ LifecycleVerifier.assertSequence(FirstActivity.class, getLifecycleLog(),
+ Arrays.asList(ON_PAUSE, ON_STOP, ON_DESTROY, PRE_ON_CREATE, ON_CREATE, ON_START,
+ ON_RESUME, ON_PAUSE), "moveToSplitScreen");
+ // TODO(b/123013403): will fail with callback tracking enabled - delivers extra
+ // MULTI_WINDOW_MODE_CHANGED
+ LifecycleVerifier.assertSequence(PipActivity.class, getLifecycleLog(), new ArrayList<>(),
+ "launchBelow");
+
+ // Launch second activity to side
+ getLifecycleLog().clear();
+ final Activity secondActivity = mSecondActivityTestRule.launchActivity(
+ new Intent().setFlags(FLAG_ACTIVITY_NEW_TASK | FLAG_ACTIVITY_MULTIPLE_TASK));
+
+ // Wait for activities to resume and verify lifecycle
+ waitAndAssertActivityStates(state(secondActivity, ON_RESUME));
+ LifecycleVerifier.assertLaunchSequence(SecondActivity.class, getLifecycleLog(),
+ false /* includeCallbacks */);
+ LifecycleVerifier.assertSequence(FirstActivity.class, getLifecycleLog(),
+ Arrays.asList(ON_RESUME), "launchToSide");
+ LifecycleVerifier.assertSequence(PipActivity.class, getLifecycleLog(), new ArrayList<>(),
+ "launchBelow");
+ }
+
+ @Test
+ public void testPipAboveSplitScreen() throws Exception {
+ // Launch first activity
+ final Activity firstActivity =
+ mFirstActivityTestRule.launchActivity(new Intent());
+
+ // Enter split screen
+ moveTaskToPrimarySplitScreen(firstActivity.getTaskId());
+
+ // Launch second activity to side
+ final Activity secondActivity = mSecondActivityTestRule.launchActivity(
+ new Intent().setFlags(FLAG_ACTIVITY_NEW_TASK | FLAG_ACTIVITY_MULTIPLE_TASK));
+
+ // Wait for activities to resume
+ waitAndAssertActivityStates(state(secondActivity, ON_RESUME),
+ state(firstActivity, ON_RESUME));
+
+ // Launch Pip-capable activity and enter Pip immediately
+ getLifecycleLog().clear();
+ final Activity pipActivity = mPipActivityTestRule.launchActivity(
+ new Intent().putExtra(EXTRA_ENTER_PIP, true));
+
+ // Wait for it to launch and pause. Other activities should not be affected.
+ waitAndAssertActivityStates(state(pipActivity, ON_PAUSE), state(secondActivity, ON_RESUME));
+ LifecycleVerifier.assertSequence(PipActivity.class, getLifecycleLog(),
+ Arrays.asList(PRE_ON_CREATE, ON_CREATE, ON_START, ON_RESUME, ON_PAUSE),
+ "launchAndEnterPip");
+ LifecycleVerifier.assertSequence(FirstActivity.class, getLifecycleLog(),
+ new ArrayList<>(), "launchPipOnTop");
+ final List<LifecycleLog.ActivityCallback> expectedSequence =
+ Arrays.asList(ON_PAUSE, ON_RESUME);
+ final List<LifecycleLog.ActivityCallback> extraCycleSequence =
+ Arrays.asList(ON_PAUSE, ON_STOP, ON_RESTART, ON_START, ON_RESUME);
+ // TODO(b/123013403): sometimes extra destroy is observed
+ LifecycleVerifier.assertSequenceMatchesOneOf(SecondActivity.class,
+ getLifecycleLog(), Arrays.asList(expectedSequence, extraCycleSequence),
+ "activityEnteringPipOnTop");
+ }
+}
diff --git a/tests/framework/base/activitymanager/src/android/server/am/lifecycle/ActivityLifecycleSplitScreenTests.java b/tests/framework/base/activitymanager/src/android/server/am/lifecycle/ActivityLifecycleSplitScreenTests.java
new file mode 100644
index 0000000..1214cf0
--- /dev/null
+++ b/tests/framework/base/activitymanager/src/android/server/am/lifecycle/ActivityLifecycleSplitScreenTests.java
@@ -0,0 +1,423 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License
+ */
+
+package android.server.am.lifecycle;
+
+import static android.app.WindowConfiguration.WINDOWING_MODE_FULLSCREEN;
+import static android.app.WindowConfiguration.WINDOWING_MODE_SPLIT_SCREEN_PRIMARY;
+import static android.content.Intent.FLAG_ACTIVITY_MULTIPLE_TASK;
+import static android.content.Intent.FLAG_ACTIVITY_NEW_TASK;
+import static android.server.am.Components.PipActivity.EXTRA_ENTER_PIP;
+import static android.server.am.lifecycle.LifecycleLog.ActivityCallback.ON_ACTIVITY_RESULT;
+import static android.server.am.lifecycle.LifecycleLog.ActivityCallback.ON_CREATE;
+import static android.server.am.lifecycle.LifecycleLog.ActivityCallback.ON_DESTROY;
+import static android.server.am.lifecycle.LifecycleLog.ActivityCallback.ON_MULTI_WINDOW_MODE_CHANGED;
+import static android.server.am.lifecycle.LifecycleLog.ActivityCallback.ON_PAUSE;
+import static android.server.am.lifecycle.LifecycleLog.ActivityCallback.ON_POST_CREATE;
+import static android.server.am.lifecycle.LifecycleLog.ActivityCallback.ON_RESTART;
+import static android.server.am.lifecycle.LifecycleLog.ActivityCallback.ON_RESUME;
+import static android.server.am.lifecycle.LifecycleLog.ActivityCallback.ON_START;
+import static android.server.am.lifecycle.LifecycleLog.ActivityCallback.ON_STOP;
+import static android.server.am.lifecycle.LifecycleLog.ActivityCallback.PRE_ON_CREATE;
+
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assume.assumeTrue;
+
+import android.app.Activity;
+import android.app.Instrumentation;
+import android.content.ComponentName;
+import android.content.Intent;
+import android.platform.test.annotations.Presubmit;
+import android.support.test.InstrumentationRegistry;
+import android.support.test.filters.FlakyTest;
+import android.support.test.filters.MediumTest;
+import android.support.test.runner.AndroidJUnit4;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+
+/**
+ * Build/Install/Run:
+ * atest CtsActivityManagerDeviceTestCases:ActivityLifecycleSplitScreenTests
+ */
+@MediumTest
+@RunWith(AndroidJUnit4.class)
+@Presubmit
+@FlakyTest(bugId = 77652261)
+public class ActivityLifecycleSplitScreenTests extends ActivityLifecycleClientTestBase {
+
+ @Before
+ public void setUp() throws Exception {
+ super.setUp();
+ assumeTrue(supportsSplitScreenMultiWindow());
+ }
+
+ @Test
+ public void testResumedWhenRecreatedFromInNonFocusedStack() throws Exception {
+ // Launch first activity
+ final Activity firstActivity =
+ mFirstActivityTestRule.launchActivity(new Intent());
+
+ // Launch second activity to stop first
+ final Activity secondActivity =
+ mSecondActivityTestRule.launchActivity(new Intent());
+
+ // Wait for second activity to resume. We must also wait for the first activity to stop
+ // so that this event is not included in the logs.
+ waitAndAssertActivityStates(state(secondActivity, ON_RESUME),
+ state(firstActivity, ON_STOP));
+
+ // Enter split screen
+ moveTaskToPrimarySplitScreen(secondActivity.getTaskId());
+
+ // CLear logs so we can capture just the destroy sequence
+ getLifecycleLog().clear();
+
+ // Start an activity in separate task (will be placed in secondary stack)
+ getLaunchActivityBuilder().execute();
+
+ // Finish top activity
+ secondActivity.finish();
+
+ waitAndAssertActivityStates(state(secondActivity, ON_DESTROY));
+ waitAndAssertActivityStates(state(firstActivity, ON_RESUME));
+
+ // Verify that the first activity was recreated to resume as it was created before
+ // windowing mode was switched
+ LifecycleVerifier.assertRecreateAndResumeSequence(FirstActivity.class, getLifecycleLog());
+ }
+
+ @Test
+ public void testOccludingMovedBetweenStacks() throws Exception {
+ // Launch first activity
+ final Activity firstActivity =
+ mFirstActivityTestRule.launchActivity(new Intent());
+ waitAndAssertActivityStates(state(firstActivity, ON_RESUME));
+
+ // Enter split screen
+ moveTaskToPrimarySplitScreen(firstActivity.getTaskId());
+ waitAndAssertActivityStates(state(firstActivity, ON_PAUSE));
+
+ final ComponentName firstActivityName = getComponentName(FirstActivity.class);
+ mAmWmState.computeState(firstActivityName);
+ int primarySplitStack = mAmWmState.getAmState().getStackIdByActivity(firstActivityName);
+
+ // Launch second activity to side
+ getLifecycleLog().clear();
+ final Activity secondActivity = mSecondActivityTestRule.launchActivity(
+ new Intent().setFlags(FLAG_ACTIVITY_NEW_TASK | FLAG_ACTIVITY_MULTIPLE_TASK));
+
+ // Wait for second activity to resume.
+ waitAndAssertActivityStates(state(secondActivity, ON_RESUME),
+ state(firstActivity, ON_RESUME));
+ LifecycleVerifier.assertSequence(FirstActivity.class, getLifecycleLog(),
+ Arrays.asList(ON_RESUME), "launchToSide");
+
+ // Launch third activity on top of second
+ getLifecycleLog().clear();
+ final Activity thirdActivity = mThirdActivityTestRule.launchActivity(
+ new Intent().setFlags(FLAG_ACTIVITY_NEW_TASK | FLAG_ACTIVITY_MULTIPLE_TASK));
+ waitAndAssertActivityStates(state(thirdActivity, ON_RESUME),
+ state(secondActivity, ON_STOP));
+
+ // Move occluding third activity to side, it will occlude first now
+ getLifecycleLog().clear();
+ moveActivityToStack(getComponentName(ThirdActivity.class), primarySplitStack);
+
+ waitAndAssertActivityStates(state(secondActivity, ON_RESUME),
+ state(firstActivity, ON_STOP));
+ LifecycleVerifier.assertSequence(ThirdActivity.class, getLifecycleLog(), new ArrayList<>(),
+ "moveToSide");
+ LifecycleVerifier.assertRestartAndResumeSequence(SecondActivity.class, getLifecycleLog());
+ LifecycleVerifier.assertSequence(FirstActivity.class, getLifecycleLog(),
+ Arrays.asList(ON_PAUSE, ON_STOP), "moveToSide");
+ }
+
+ @Test
+ public void testTranslucentMovedBetweenStacks() throws Exception {
+ // Launch first activity
+ final Activity firstActivity =
+ mFirstActivityTestRule.launchActivity(new Intent());
+ waitAndAssertActivityStates(state(firstActivity, ON_RESUME));
+
+ // Enter split screen
+ moveTaskToPrimarySplitScreen(firstActivity.getTaskId());
+ waitAndAssertActivityStates(state(firstActivity, ON_PAUSE));
+
+ final ComponentName firstActivityName = getComponentName(FirstActivity.class);
+ mAmWmState.computeState(firstActivityName);
+ int primarySplitStack = mAmWmState.getAmState().getStackIdByActivity(firstActivityName);
+
+ // Launch second activity to side
+ getLifecycleLog().clear();
+ final Activity secondActivity = mSecondActivityTestRule.launchActivity(
+ new Intent().setFlags(FLAG_ACTIVITY_NEW_TASK | FLAG_ACTIVITY_MULTIPLE_TASK));
+
+ // Wait for second activity to resume.
+ waitAndAssertActivityStates(state(secondActivity, ON_RESUME),
+ state(firstActivity, ON_RESUME));
+ LifecycleVerifier.assertSequence(FirstActivity.class, getLifecycleLog(),
+ Arrays.asList(ON_RESUME), "launchToSide");
+
+ // Launch translucent activity on top of second
+ getLifecycleLog().clear();
+
+ final Activity translucentActivity = mTranslucentActivityTestRule.launchActivity(
+ new Intent().setFlags(FLAG_ACTIVITY_NEW_TASK | FLAG_ACTIVITY_MULTIPLE_TASK));
+ waitAndAssertActivityStates(state(translucentActivity, ON_RESUME));
+ // Second activity should stay resumed, because it's in a separate stack below the
+ // translucent activity.
+ LifecycleVerifier.assertSequence(SecondActivity.class, getLifecycleLog(),
+ new ArrayList<>(), "moveToSide");
+
+ // Move translucent activity to side, it will be on top of the first now
+ getLifecycleLog().clear();
+ moveActivityToStack(getComponentName(TranslucentActivity.class), primarySplitStack);
+
+ waitAndAssertActivityStates(state(firstActivity, ON_PAUSE));
+ LifecycleVerifier.assertSequence(TranslucentActivity.class, getLifecycleLog(),
+ new ArrayList<>(), "moveToSide");
+ LifecycleVerifier.assertSequence(SecondActivity.class, getLifecycleLog(),
+ new ArrayList<>(), "moveToSide");
+ LifecycleVerifier.assertSequence(FirstActivity.class, getLifecycleLog(),
+ Arrays.asList(ON_PAUSE), "moveToSide");
+ }
+
+ @Test
+ public void testResultInNonFocusedStack() throws Exception {
+ // Launch first activity
+ final Activity callbackTrackingActivity =
+ mCallbackTrackingActivityTestRule.launchActivity(new Intent());
+
+ // Wait for first activity to resume
+ waitAndAssertActivityStates(state(callbackTrackingActivity, ON_RESUME));
+
+ // Enter split screen, the activity will be relaunched.
+ getLifecycleLog().clear();
+ moveTaskToPrimarySplitScreen(callbackTrackingActivity.getTaskId(), true /* showRecents */);
+ // Wait for multi-window mode change that will come after activity relaunch and resume.
+ waitAndAssertActivityStates(state(callbackTrackingActivity, ON_MULTI_WINDOW_MODE_CHANGED));
+ final List<LifecycleLog.ActivityCallback> splitScreenMoveSequence =
+ Arrays.asList(ON_PAUSE, ON_STOP, ON_DESTROY, PRE_ON_CREATE, ON_CREATE, ON_START,
+ ON_POST_CREATE, ON_RESUME, ON_MULTI_WINDOW_MODE_CHANGED);
+ LifecycleVerifier.assertSequence(CallbackTrackingActivity.class, getLifecycleLog(),
+ splitScreenMoveSequence, "moveToPrimarySplitScreen");
+ getLifecycleLog().clear();
+
+ // Launch second activity
+ // Create an ActivityMonitor that catch ChildActivity and return mock ActivityResult:
+ Instrumentation.ActivityMonitor activityMonitor = InstrumentationRegistry
+ .getInstrumentation()
+ .addMonitor(SecondActivity.class.getName(), null /* activityResult */,
+ false /* block */);
+
+ callbackTrackingActivity.startActivityForResult(
+ new Intent(callbackTrackingActivity, SecondActivity.class), 1 /* requestCode */);
+
+ // Wait for the ActivityMonitor to be hit
+ final Activity secondActivity = InstrumentationRegistry.getInstrumentation()
+ .waitForMonitorWithTimeout(activityMonitor, 5 * 1000);
+
+ // Wait for second activity to resume
+ assertNotNull("Second activity should be started", secondActivity);
+ waitAndAssertActivityStates(state(secondActivity, ON_RESUME));
+
+ // Verify if the first activity stopped (since it is not currently visible)
+ waitAndAssertActivityStates(state(callbackTrackingActivity, ON_STOP));
+
+ // Start an activity in separate task (will be placed in secondary stack)
+ final Activity thirdActivity = mThirdActivityTestRule.launchActivity(
+ new Intent().setFlags(FLAG_ACTIVITY_NEW_TASK | FLAG_ACTIVITY_MULTIPLE_TASK));
+
+ // Wait for third activity to resume
+ waitAndAssertActivityStates(state(thirdActivity, ON_RESUME));
+
+ // Finish top activity and verify that activity below became focused.
+ getLifecycleLog().clear();
+ secondActivity.setResult(Activity.RESULT_OK);
+ secondActivity.finish();
+
+ // Check that activity was resumed and result was delivered
+ waitAndAssertActivityStates(state(callbackTrackingActivity, ON_RESUME));
+ LifecycleVerifier.assertSequence(CallbackTrackingActivity.class, getLifecycleLog(),
+ Arrays.asList(ON_RESTART, ON_START, ON_ACTIVITY_RESULT, ON_RESUME), "resume");
+ }
+
+ @Test
+ public void testResumedWhenRestartedFromInNonFocusedStack() throws Exception {
+ // Launch first activity
+ final Activity firstActivity =
+ mFirstActivityTestRule.launchActivity(new Intent());
+
+ // Wait for first activity to resume
+ waitAndAssertActivityStates(state(firstActivity, ON_RESUME));
+
+ // Enter split screen
+ getLifecycleLog().clear();
+ moveTaskToPrimarySplitScreen(firstActivity.getTaskId(), true /* showRecents */);
+ waitAndAssertActivityStates(state(firstActivity, ON_RESUME));
+ LifecycleVerifier.assertRelaunchSequence(FirstActivity.class, getLifecycleLog(), ON_RESUME);
+
+ // Launch second activity, first become stopped
+ final Activity secondActivity =
+ mSecondActivityTestRule.launchActivity(new Intent());
+
+ // Wait for second activity to resume and first to stop
+ waitAndAssertActivityStates(state(secondActivity, ON_RESUME));
+ waitAndAssertActivityStates(state(firstActivity, ON_STOP));
+
+ // Start an activity in separate task (will be placed in secondary stack)
+ final Activity newTaskActivity = mThirdActivityTestRule.launchActivity(
+ new Intent().setFlags(FLAG_ACTIVITY_NEW_TASK | FLAG_ACTIVITY_MULTIPLE_TASK));
+
+ waitAndAssertActivityStates(state(newTaskActivity, ON_RESUME));
+
+ getLifecycleLog().clear();
+
+ // Finish top activity
+ secondActivity.finish();
+
+ waitAndAssertActivityStates(state(firstActivity, ON_RESUME));
+ waitAndAssertActivityStates(state(secondActivity, ON_DESTROY));
+
+ // Verify that the first activity was restarted to resumed state as it was brought back
+ // after windowing mode was switched
+ LifecycleVerifier.assertRestartAndResumeSequence(FirstActivity.class, getLifecycleLog());
+ LifecycleVerifier.assertResumeToDestroySequence(SecondActivity.class, getLifecycleLog());
+ }
+
+ @Test
+ public void testResumedTranslucentWhenRestartedFromInNonFocusedStack() throws Exception {
+ // Launch first activity
+ final Activity firstActivity =
+ mFirstActivityTestRule.launchActivity(new Intent());
+
+ // Wait for first activity to resume
+ waitAndAssertActivityStates(state(firstActivity, ON_RESUME));
+
+ // Enter split screen
+ moveTaskToPrimarySplitScreen(firstActivity.getTaskId(), true /* showRecents */);
+
+ // Launch a translucent activity, first become paused
+ final Activity translucentActivity =
+ mTranslucentActivityTestRule.launchActivity(new Intent());
+
+ // Wait for translucent activity to resume and first to pause
+ waitAndAssertActivityStates(state(translucentActivity, ON_RESUME));
+ waitAndAssertActivityStates(state(firstActivity, ON_PAUSE));
+
+ // Start an activity in separate task (will be placed in secondary stack)
+ final Activity newTaskActivity = mThirdActivityTestRule.launchActivity(
+ new Intent().setFlags(FLAG_ACTIVITY_NEW_TASK | FLAG_ACTIVITY_MULTIPLE_TASK));
+
+ waitAndAssertActivityStates(state(newTaskActivity, ON_RESUME));
+
+ getLifecycleLog().clear();
+
+ // Finish top activity
+ translucentActivity.finish();
+
+ waitAndAssertActivityStates(state(firstActivity, ON_RESUME));
+ waitAndAssertActivityStates(state(translucentActivity, ON_DESTROY));
+
+ // Verify that the first activity was resumed
+ LifecycleVerifier.assertSequence(FirstActivity.class, getLifecycleLog(),
+ Arrays.asList(ON_RESUME), "resume");
+ LifecycleVerifier.assertResumeToDestroySequence(TranslucentActivity.class,
+ getLifecycleLog());
+ }
+
+ @Test
+ public void testLifecycleOnMoveToFromSplitScreenRelaunch() throws Exception {
+ // Launch a singleTop activity
+ final Activity testActivity =
+ mCallbackTrackingActivityTestRule.launchActivity(new Intent());
+
+ // Wait for the activity to resume
+ waitAndAssertActivityStates(state(testActivity, ON_RESUME));
+ LifecycleVerifier.assertLaunchSequence(CallbackTrackingActivity.class, getLifecycleLog(),
+ true /* includeCallbacks */);
+
+ // Enter split screen
+ getLifecycleLog().clear();
+ setActivityTaskWindowingMode(CALLBACK_TRACKING_ACTIVITY,
+ WINDOWING_MODE_SPLIT_SCREEN_PRIMARY);
+
+ // Wait for the activity to relaunch
+ final List<LifecycleLog.ActivityCallback> expectedEnterSequence =
+ Arrays.asList(ON_PAUSE, ON_STOP, ON_DESTROY, PRE_ON_CREATE, ON_CREATE, ON_START,
+ ON_POST_CREATE, ON_RESUME, ON_MULTI_WINDOW_MODE_CHANGED);
+ waitForActivityTransitions(CallbackTrackingActivity.class, expectedEnterSequence);
+
+ // Verify that the activity was relaunched and received multi-window mode change
+ LifecycleVerifier.assertSequence(CallbackTrackingActivity.class, getLifecycleLog(),
+ expectedEnterSequence, "moveToSplitScreen");
+
+ // Exit split-screen
+ getLifecycleLog().clear();
+ setActivityTaskWindowingMode(CALLBACK_TRACKING_ACTIVITY, WINDOWING_MODE_FULLSCREEN);
+
+ // Wait for the activity to resume
+ final List<LifecycleLog.ActivityCallback> expectedExitSequence = expectedEnterSequence;
+ waitForActivityTransitions(CallbackTrackingActivity.class, expectedExitSequence);
+
+ // Verify that the activity was relaunched and received multi-window mode change
+ LifecycleVerifier.assertSequence(CallbackTrackingActivity.class, getLifecycleLog(),
+ expectedExitSequence, "moveFromSplitScreen");
+ }
+
+ @Test
+ public void testLifecycleOnMoveToFromSplitScreenNoRelaunch() throws Exception {
+ // Launch a singleTop activity
+ final Activity testActivity =
+ mConfigChangeHandlingActivityTestRule.launchActivity(new Intent());
+
+ // Wait for the activity to resume
+ waitAndAssertActivityStates(state(testActivity, ON_RESUME));
+ LifecycleVerifier.assertLaunchSequence(ConfigChangeHandlingActivity.class,
+ getLifecycleLog(), true /* includeCallbacks */);
+
+ // Enter split screen
+ getLifecycleLog().clear();
+ setActivityTaskWindowingMode(CONFIG_CHANGE_HANDLING_ACTIVITY,
+ WINDOWING_MODE_SPLIT_SCREEN_PRIMARY);
+
+ // Wait for the activity to receive the change
+ waitForActivityTransitions(ConfigChangeHandlingActivity.class,
+ Arrays.asList(ON_MULTI_WINDOW_MODE_CHANGED));
+
+ // Verify that the activity was relaunched and received multi-window mode change
+ LifecycleVerifier.assertSequence(ConfigChangeHandlingActivity.class, getLifecycleLog(),
+ Arrays.asList(ON_MULTI_WINDOW_MODE_CHANGED), "moveToSplitScreen");
+
+ // Exit split-screen
+ getLifecycleLog().clear();
+ setActivityTaskWindowingMode(CONFIG_CHANGE_HANDLING_ACTIVITY, WINDOWING_MODE_FULLSCREEN);
+
+ // Wait for the activity to receive the change
+ waitForActivityTransitions(ConfigChangeHandlingActivity.class,
+ Arrays.asList(ON_MULTI_WINDOW_MODE_CHANGED));
+
+ // Verify that the activity was relaunched and received multi-window mode change
+ LifecycleVerifier.assertSequence(ConfigChangeHandlingActivity.class, getLifecycleLog(),
+ Arrays.asList(ON_MULTI_WINDOW_MODE_CHANGED), "moveFromSplitScreen");
+ }
+}
diff --git a/tests/framework/base/activitymanager/src/android/server/am/lifecycle/ActivityLifecycleTests.java b/tests/framework/base/activitymanager/src/android/server/am/lifecycle/ActivityLifecycleTests.java
index 4d11d47..7698964 100644
--- a/tests/framework/base/activitymanager/src/android/server/am/lifecycle/ActivityLifecycleTests.java
+++ b/tests/framework/base/activitymanager/src/android/server/am/lifecycle/ActivityLifecycleTests.java
@@ -1,9 +1,27 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License
+ */
+
package android.server.am.lifecycle;
-import static android.app.WindowConfiguration.WINDOWING_MODE_FULLSCREEN;
-import static android.app.WindowConfiguration.WINDOWING_MODE_SPLIT_SCREEN_PRIMARY;
+import static android.app.ActivityTaskManager.INVALID_STACK_ID;
+import static android.content.Intent.FLAG_ACTIVITY_MULTIPLE_TASK;
+import static android.content.Intent.FLAG_ACTIVITY_NEW_TASK;
import static android.server.am.ActivityManagerState.STATE_PAUSED;
import static android.server.am.ActivityManagerState.STATE_STOPPED;
+import static android.server.am.Components.PipActivity.EXTRA_ENTER_PIP;
import static android.server.am.UiDeviceUtils.pressBackButton;
import static android.server.am.lifecycle.LifecycleLog.ActivityCallback.ON_ACTIVITY_RESULT;
import static android.server.am.lifecycle.LifecycleLog.ActivityCallback.ON_CREATE;
@@ -23,11 +41,10 @@
import static android.view.Surface.ROTATION_270;
import static android.view.Surface.ROTATION_90;
-import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertNotEquals;
import static org.junit.Assert.fail;
import android.app.Activity;
-import android.app.Instrumentation.ActivityMonitor;
import android.content.ComponentName;
import android.content.Intent;
import android.content.pm.ActivityInfo;
@@ -42,6 +59,7 @@
import org.junit.Test;
import org.junit.runner.RunWith;
+import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
@@ -79,6 +97,192 @@
}
@Test
+ public void testLaunchTranslucentOnTop() throws Exception {
+ // Launch fullscreen activity
+ final Activity firstActivity = mFirstActivityTestRule.launchActivity(new Intent());
+ waitAndAssertActivityStates(state(firstActivity, ON_RESUME));
+
+ // Launch translucent activity on top
+ getLifecycleLog().clear();
+ final Activity translucentActivity =
+ mTranslucentActivityTestRule.launchActivity(new Intent());
+ waitAndAssertActivityStates(state(firstActivity, ON_PAUSE),
+ state(translucentActivity, ON_RESUME));
+
+ LifecycleVerifier.assertLaunchSequence(TranslucentActivity.class, FirstActivity.class,
+ getLifecycleLog(), true /* launchIsTranslucent */);
+ }
+
+ @Test
+ public void testLaunchDoubleTranslucentOnTop() throws Exception {
+ final Activity firstActivity = mFirstActivityTestRule.launchActivity(new Intent());
+ waitAndAssertActivityStates(state(firstActivity, ON_RESUME));
+
+ // Launch translucent activity on top
+ getLifecycleLog().clear();
+ final Activity translucentActivity =
+ mTranslucentActivityTestRule.launchActivity(new Intent());
+ waitAndAssertActivityStates(state(firstActivity, ON_PAUSE),
+ state(translucentActivity, ON_RESUME));
+
+ LifecycleVerifier.assertLaunchSequence(TranslucentActivity.class, FirstActivity.class,
+ getLifecycleLog(), true /* launchIsTranslucent */);
+
+ // Launch another translucent activity on top
+ getLifecycleLog().clear();
+ final Activity secondTranslucentActivity =
+ mSecondTranslucentActivityTestRule.launchActivity(new Intent());
+ waitAndAssertActivityStates(state(translucentActivity, ON_PAUSE),
+ state(secondTranslucentActivity, ON_RESUME));
+ LifecycleVerifier.assertSequence(TranslucentActivity.class, getLifecycleLog(),
+ Arrays.asList(ON_PAUSE), "launch");
+ LifecycleVerifier.assertSequence(FirstActivity.class, getLifecycleLog(), new ArrayList<>(),
+ "launch");
+
+ // Finish top translucent activity
+ getLifecycleLog().clear();
+ secondTranslucentActivity.finish();
+
+ waitAndAssertActivityStates(state(translucentActivity, ON_RESUME));
+ waitAndAssertActivityStates(state(secondTranslucentActivity, ON_DESTROY));
+ LifecycleVerifier.assertResumeToDestroySequence(SecondTranslucentActivity.class,
+ getLifecycleLog());
+ LifecycleVerifier.assertSequence(TranslucentActivity.class, getLifecycleLog(),
+ Arrays.asList(ON_RESUME), "launch");
+ LifecycleVerifier.assertSequence(FirstActivity.class, getLifecycleLog(), new ArrayList<>(),
+ "launch");
+ }
+
+ @Test
+ public void testTranslucentMovedIntoStack() throws Exception {
+ // Launch a translucent activity and a regular activity in separate stacks
+ final Activity translucentActivity =
+ mTranslucentActivityTestRule.launchActivity(new Intent());
+ final Activity firstActivity = mFirstActivityTestRule.launchActivity(
+ new Intent().setFlags(FLAG_ACTIVITY_NEW_TASK | FLAG_ACTIVITY_MULTIPLE_TASK));
+ waitAndAssertActivityStates(state(firstActivity, ON_RESUME),
+ state(translucentActivity, ON_STOP));
+
+ final ComponentName firstActivityName = getComponentName(FirstActivity.class);
+ mAmWmState.computeState(firstActivityName);
+ int firstActivityStack = mAmWmState.getAmState().getStackIdByActivity(firstActivityName);
+
+ // Move translucent activity into the stack with the first activity
+ getLifecycleLog().clear();
+ moveActivityToStack(getComponentName(TranslucentActivity.class), firstActivityStack);
+
+ // Wait for translucent activity to resume and first activity to pause
+ waitAndAssertActivityStates(state(translucentActivity, ON_RESUME),
+ state(firstActivity, ON_PAUSE));
+ LifecycleVerifier.assertSequence(FirstActivity.class, getLifecycleLog(),
+ Arrays.asList(ON_PAUSE), "launchOnTop");
+ LifecycleVerifier.assertRestartAndResumeSequence(TranslucentActivity.class,
+ getLifecycleLog());
+ }
+
+ @Test
+ public void testDestroyTopTranslucent() throws Exception {
+ // Launch a regular activity and a a translucent activity in the same stack
+ final Activity firstActivity = mFirstActivityTestRule.launchActivity(new Intent());
+ final Activity translucentActivity =
+ mTranslucentActivityTestRule.launchActivity(new Intent());
+ waitAndAssertActivityStates(state(firstActivity, ON_PAUSE),
+ state(translucentActivity, ON_RESUME));
+
+ // Finish translucent activity
+ getLifecycleLog().clear();
+ mTranslucentActivityTestRule.finishActivity();
+
+ waitAndAssertActivityStates(state(firstActivity, ON_RESUME),
+ state(translucentActivity, ON_DESTROY));
+
+ // Verify destruction lifecycle
+ LifecycleVerifier.assertResumeToDestroySequence(TranslucentActivity.class,
+ getLifecycleLog());
+ LifecycleVerifier.assertSequence(FirstActivity.class, getLifecycleLog(),
+ Arrays.asList(ON_RESUME), "resumeAfterTopDestroyed");
+ }
+
+ @Test
+ public void testDestroyOnTopOfTranslucent() throws Exception {
+ // Launch fullscreen activity
+ final Activity firstActivity =
+ mFirstActivityTestRule.launchActivity(new Intent());
+
+ // Launch translucent activity
+ final Activity translucentActivity =
+ mTranslucentActivityTestRule.launchActivity(new Intent());
+
+ // Launch another fullscreen activity
+ final Activity secondActivity =
+ mSecondActivityTestRule.launchActivity(new Intent());
+
+ // Wait for top activity to resume
+ waitAndAssertActivityStates(state(secondActivity, ON_RESUME),
+ occludedActivityState(translucentActivity, secondActivity),
+ occludedActivityState(firstActivity, secondActivity));
+
+ getLifecycleLog().clear();
+
+ final boolean secondActivityIsTranslucent = ActivityInfo.isTranslucentOrFloating(
+ secondActivity.getWindow().getWindowStyle());
+
+ // Finish top activity
+ mSecondActivityTestRule.finishActivity();
+
+ waitAndAssertActivityStates(state(secondActivity, ON_DESTROY));
+ LifecycleVerifier.assertResumeToDestroySequence(SecondActivity.class, getLifecycleLog());
+ if (secondActivityIsTranslucent) {
+ // In this case we don't expect the state of the firstActivity to change since it is
+ // already in the visible paused state. So, we just verify that translucentActivity
+ // transitions to resumed state.
+ waitAndAssertActivityStates(state(translucentActivity, ON_RESUME));
+ } else {
+ // Wait for translucent activity to resume
+ waitAndAssertActivityStates(state(translucentActivity, ON_RESUME),
+ state(firstActivity, ON_START));
+
+ // Verify that the first activity was restarted
+ LifecycleVerifier.assertRestartSequence(FirstActivity.class, getLifecycleLog());
+ }
+ }
+
+ @Test
+ public void testDestroyDoubleTranslucentOnTop() throws Exception {
+ final Activity firstActivity = mFirstActivityTestRule.launchActivity(new Intent());
+ final Activity translucentActivity =
+ mTranslucentActivityTestRule.launchActivity(new Intent());
+ final Activity secondTranslucentActivity =
+ mSecondTranslucentActivityTestRule.launchActivity(new Intent());
+ waitAndAssertActivityStates(state(firstActivity, ON_PAUSE),
+ state(translucentActivity, ON_PAUSE), state(secondTranslucentActivity, ON_RESUME));
+
+ // Finish top translucent activity
+ getLifecycleLog().clear();
+ secondTranslucentActivity.finish();
+
+ waitAndAssertActivityStates(state(translucentActivity, ON_RESUME));
+ waitAndAssertActivityStates(state(secondTranslucentActivity, ON_DESTROY));
+ LifecycleVerifier.assertResumeToDestroySequence(SecondTranslucentActivity.class,
+ getLifecycleLog());
+ LifecycleVerifier.assertSequence(TranslucentActivity.class, getLifecycleLog(),
+ Arrays.asList(ON_RESUME), "destroy");
+ LifecycleVerifier.assertSequence(FirstActivity.class, getLifecycleLog(), new ArrayList<>(),
+ "destroy");
+
+ // Finish first translucent activity
+ getLifecycleLog().clear();
+ translucentActivity.finish();
+
+ waitAndAssertActivityStates(state(firstActivity, ON_RESUME));
+ waitAndAssertActivityStates(state(translucentActivity, ON_DESTROY));
+ LifecycleVerifier.assertResumeToDestroySequence(TranslucentActivity.class,
+ getLifecycleLog());
+ LifecycleVerifier.assertSequence(FirstActivity.class, getLifecycleLog(),
+ Arrays.asList(ON_RESUME), "secondDestroy");
+ }
+
+ @Test
public void testLaunchAndDestroy() throws Exception {
final Activity activity = mFirstActivityTestRule.launchActivity(new Intent());
@@ -205,212 +409,6 @@
}
@Test
- public void testPausedWithTranslucentOnTop() throws Exception {
- // Launch fullscreen activity
- final Activity firstActivity =
- mFirstActivityTestRule.launchActivity(new Intent());
-
- // Launch translucent activity on top
- mTranslucentActivityTestRule.launchActivity(new Intent());
-
- // Launch another translucent activity on top to make sure the fullscreen activity
- // transitions to final state
- final Activity secondTranslucentActivity =
- mSecondTranslucentActivityTestRule.launchActivity(new Intent());
-
- // Wait for the second translucent activity to become resumed.
- waitAndAssertActivityStates(state(secondTranslucentActivity, ON_RESUME),
- state(firstActivity, ON_PAUSE));
-
- // Assert that the fullscreen activity was not stopped and is in the paused state.
- LifecycleVerifier.assertLaunchAndPauseSequence(FirstActivity.class, getLifecycleLog());
- }
-
- @Test
- public void testPausedWhenReturningWithTranslucentOnTop() throws Exception {
- // Launch fullscreen activity
- final Activity firstActivity =
- mFirstActivityTestRule.launchActivity(new Intent());
-
- // Launch translucent activity
- final Activity translucentActivity =
- mTranslucentActivityTestRule.launchActivity(new Intent());
-
- // Launch another fullscreen activity
- final Activity secondActivity =
- mSecondActivityTestRule.launchActivity(new Intent());
-
- // Wait for top activity to resume
- waitAndAssertActivityStates(state(secondActivity, ON_RESUME),
- occludedActivityState(translucentActivity, secondActivity),
- occludedActivityState(firstActivity, secondActivity));
-
- getLifecycleLog().clear();
-
- final boolean secondActivityIsTranslucent = ActivityInfo.isTranslucentOrFloating(
- secondActivity.getWindow().getWindowStyle());
-
- // Finish top activity
- mSecondActivityTestRule.finishActivity();
-
- if (secondActivityIsTranslucent) {
- // In this case we don't expect the state of the firstActivity to change since it is
- // already in the visible paused state. So, we just verify that translucentActivity
- // transitions to resumed state.
- waitAndAssertActivityStates(state(translucentActivity, ON_RESUME));
- } else {
- // Wait for translucent activity to resume
- waitAndAssertActivityStates(state(translucentActivity, ON_RESUME),
- state(firstActivity, ON_START));
-
- // Verify that the first activity was restarted
- LifecycleVerifier.assertRestartSequence(FirstActivity.class, getLifecycleLog());
- }
- }
-
- @Test
- public void testPausedWhenRecreatedFromInNonFocusedStack() throws Exception {
- if (!supportsSplitScreenMultiWindow()) {
- // Skipping test: no split multi-window support
- return;
- }
-
- // Launch first activity
- final Activity firstActivity =
- mFirstActivityTestRule.launchActivity(new Intent());
-
- // Launch second activity to stop first
- final Activity secondActivity =
- mSecondActivityTestRule.launchActivity(new Intent());
-
- // Wait for second activity to resume. We must also wait for the first activity to stop
- // so that this event is not included in the logs.
- waitAndAssertActivityStates(state(secondActivity, ON_RESUME),
- state(firstActivity, ON_STOP));
-
- // Enter split screen
- moveTaskToPrimarySplitScreen(secondActivity.getTaskId());
-
- // CLear logs so we can capture just the destroy sequence
- getLifecycleLog().clear();
-
- // Start an activity in separate task (will be placed in secondary stack)
- getLaunchActivityBuilder().execute();
-
- // Finish top activity
- secondActivity.finish();
-
- waitAndAssertActivityStates(state(firstActivity, ON_PAUSE));
-
- // Verify that the first activity was recreated to pause as it was created before
- // windowing mode was switched
- LifecycleVerifier.assertRecreateAndPauseSequence(FirstActivity.class, getLifecycleLog());
- }
-
- @Test
- public void testResultInNonFocusedStack() throws Exception {
- if (!supportsSplitScreenMultiWindow()) {
- // Skipping test: no split multi-window support
- return;
- }
-
- // Launch first activity
- final Activity callbackTrackingActivity =
- mCallbackTrackingActivityTestRule.launchActivity(new Intent());
-
- // Wait for first activity to resume
- waitAndAssertActivityStates(state(callbackTrackingActivity, ON_RESUME));
-
- // Enter split screen
- moveTaskToPrimarySplitScreen(callbackTrackingActivity.getTaskId(), true /* showRecents */);
-
- // Launch second activity to pause first
- // Create an ActivityMonitor that catch ChildActivity and return mock ActivityResult:
- ActivityMonitor activityMonitor = InstrumentationRegistry.getInstrumentation()
- .addMonitor(SecondActivity.class.getName(), null /* activityResult */,
- false /* block */);
-
- callbackTrackingActivity.startActivityForResult(
- new Intent(callbackTrackingActivity, SecondActivity.class), 1 /* requestCode */);
-
- // Wait for the ActivityMonitor to be hit
- final Activity secondActivity = InstrumentationRegistry.getInstrumentation()
- .waitForMonitorWithTimeout(activityMonitor, 5 * 1000);
-
- // Wait for second activity to resume
- assertNotNull("Second activity should be started", secondActivity);
- waitAndAssertActivityStates(state(secondActivity, ON_RESUME));
-
- // Verify if the first activity stopped (since it is not currently visible)
- waitAndAssertActivityStates(state(callbackTrackingActivity, ON_STOP));
-
- // Start an activity in separate task (will be placed in secondary stack)
- getLaunchActivityBuilder().execute();
-
- waitAndAssertActivityStates(state(secondActivity, ON_PAUSE));
-
- // Finish top activity and verify that activity below became focused.
- getLifecycleLog().clear();
- secondActivity.setResult(Activity.RESULT_OK);
- secondActivity.finish();
-
- waitAndAssertActivityStates(state(callbackTrackingActivity, ON_START));
- LifecycleVerifier.assertRestartSequence(CallbackTrackingActivity.class, getLifecycleLog());
-
- // Bring the first activity to front to verify that it receives the result.
- getLifecycleLog().clear();
- final Intent singleTopIntent = new Intent(InstrumentationRegistry.getTargetContext(),
- CallbackTrackingActivity.class);
- singleTopIntent.setFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP | Intent.FLAG_ACTIVITY_NEW_TASK);
- InstrumentationRegistry.getTargetContext().startActivity(singleTopIntent);
-
- waitAndAssertActivityStates(state(callbackTrackingActivity, ON_RESUME));
- LifecycleVerifier.assertSequence(CallbackTrackingActivity.class, getLifecycleLog(),
- Arrays.asList(ON_ACTIVITY_RESULT, ON_NEW_INTENT, ON_RESUME), "bring to front");
- }
-
- @Test
- public void testPausedWhenRestartedFromInNonFocusedStack() throws Exception {
- if (!supportsSplitScreenMultiWindow()) {
- // Skipping test: no split multi-window support
- return;
- }
-
- // Launch first activity
- final Activity firstActivity =
- mFirstActivityTestRule.launchActivity(new Intent());
-
- // Wait for first activity to resume
- waitAndAssertActivityStates(state(firstActivity, ON_RESUME));
-
- // Enter split screen
- moveTaskToPrimarySplitScreen(firstActivity.getTaskId(), true /* showRecents */);
-
- // Launch second activity to pause first
- final Activity secondActivity =
- mSecondActivityTestRule.launchActivity(new Intent());
-
- // Wait for second activity to resume
- waitAndAssertActivityStates(state(secondActivity, ON_RESUME));
-
- // Start an activity in separate task (will be placed in secondary stack)
- getLaunchActivityBuilder().execute();
-
- waitAndAssertActivityStates(state(secondActivity, ON_PAUSE));
-
- getLifecycleLog().clear();
-
- // Finish top activity
- secondActivity.finish();
-
- waitAndAssertActivityStates(state(firstActivity, ON_PAUSE));
-
- // Verify that the first activity was restarted to pause as it was brought back after
- // windowing mode was switched
- LifecycleVerifier.assertRestartAndPauseSequence(FirstActivity.class, getLifecycleLog());
- }
-
- @Test
public void testOnActivityResult() throws Exception {
final Intent intent = new Intent();
intent.putExtra(EXTRA_FINISH_IN_ON_RESUME, true);
@@ -425,8 +423,15 @@
final List<LifecycleLog.ActivityCallback> sequenceWithStop =
Arrays.asList(PRE_ON_CREATE, ON_CREATE, ON_START, ON_POST_CREATE, ON_RESUME,
ON_PAUSE, ON_STOP, ON_ACTIVITY_RESULT, ON_RESTART, ON_START, ON_RESUME);
+ final List<LifecycleLog.ActivityCallback> thirdSequence =
+ Arrays.asList(PRE_ON_CREATE, ON_CREATE, ON_START, ON_POST_CREATE, ON_RESUME,
+ ON_PAUSE, ON_STOP, ON_ACTIVITY_RESULT, ON_RESTART, ON_START, ON_RESUME);
+ final List<LifecycleLog.ActivityCallback> fourthSequence =
+ Arrays.asList(PRE_ON_CREATE, ON_CREATE, ON_START, ON_POST_CREATE, ON_RESUME,
+ ON_PAUSE, ON_STOP, ON_RESTART, ON_START, ON_ACTIVITY_RESULT, ON_RESUME);
LifecycleVerifier.assertSequenceMatchesOneOf(LaunchForResultActivity.class,
- getLifecycleLog(), Arrays.asList(expectedSequence, sequenceWithStop),
+ getLifecycleLog(),
+ Arrays.asList(expectedSequence, sequenceWithStop, thirdSequence, fourthSequence),
"activityResult");
}
@@ -437,19 +442,24 @@
mLaunchForResultActivityTestRule.launchActivity(intent);
final boolean isTranslucent = isTranslucent(mLaunchForResultActivityTestRule.getActivity());
- final List<LifecycleLog.ActivityCallback> expectedSequence;
+ final List<List<LifecycleLog.ActivityCallback>> expectedSequences;
if (isTranslucent) {
- expectedSequence = Arrays.asList(PRE_ON_CREATE, ON_CREATE, ON_START, ON_POST_CREATE,
- ON_RESUME, ON_PAUSE, ON_ACTIVITY_RESULT, ON_RESUME);
+ expectedSequences = Arrays.asList(
+ Arrays.asList(PRE_ON_CREATE, ON_CREATE, ON_START, ON_POST_CREATE, ON_RESUME,
+ ON_PAUSE, ON_ACTIVITY_RESULT, ON_RESUME)
+ );
} else {
- expectedSequence = Arrays.asList(PRE_ON_CREATE, ON_CREATE, ON_START, ON_POST_CREATE,
- ON_RESUME, ON_PAUSE, ON_STOP, ON_ACTIVITY_RESULT, ON_RESTART, ON_START,
- ON_RESUME);
+ expectedSequences = Arrays.asList(
+ Arrays.asList(PRE_ON_CREATE, ON_CREATE, ON_START, ON_POST_CREATE, ON_RESUME,
+ ON_PAUSE, ON_STOP, ON_RESTART, ON_START, ON_ACTIVITY_RESULT, ON_RESUME),
+ Arrays.asList(PRE_ON_CREATE, ON_CREATE, ON_START, ON_POST_CREATE, ON_RESUME,
+ ON_PAUSE, ON_STOP, ON_ACTIVITY_RESULT, ON_RESTART, ON_START, ON_RESUME)
+ );
}
- waitForActivityTransitions(LaunchForResultActivity.class, expectedSequence);
+ waitForActivityTransitions(LaunchForResultActivity.class, expectedSequences.get(0));
- LifecycleVerifier.assertSequence(LaunchForResultActivity.class,
- getLifecycleLog(), expectedSequence, "activityResult");
+ LifecycleVerifier.assertSequenceMatchesOneOf(LaunchForResultActivity.class,
+ getLifecycleLog(), expectedSequences, "activityResult");
}
@Test
@@ -586,7 +596,7 @@
}
/**
- * The that recreate request from an activity is executed immediately.
+ * Tests that recreate request from an activity is executed immediately.
*/
@Test
public void testLocalRecreate() throws Exception {
@@ -594,36 +604,43 @@
Activity recreatingActivity = mSingleTopActivityTestRule.launchActivity(new Intent());
// Launch second activity to cover and stop first
- final LaunchActivityBuilder launchActivityBuilder = getLaunchActivityBuilder();
- launchActivityBuilder.setNewTask(true).setMultipleTask(true).execute();
+ Activity secondActivity = mSecondActivityTestRule.launchActivity(
+ new Intent().setFlags(FLAG_ACTIVITY_NEW_TASK | FLAG_ACTIVITY_MULTIPLE_TASK));
// Wait for first activity to become stopped
- waitAndAssertActivityStates(occludedActivityState(recreatingActivity,
- launchActivityBuilder.isTargetActivityTranslucent()));
+ final boolean secondActivityIsTranslucent = ActivityInfo.isTranslucentOrFloating(
+ secondActivity.getWindow().getWindowStyle());
+ waitAndAssertActivityStates(
+ occludedActivityState(recreatingActivity, secondActivityIsTranslucent),
+ state(secondActivity, ON_RESUME));
// Launch the activity again to recreate
getLifecycleLog().clear();
final Intent intent = new Intent(InstrumentationRegistry.getContext(),
SingleTopActivity.class);
intent.putExtra(EXTRA_RECREATE, true);
- intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
+ intent.addFlags(FLAG_ACTIVITY_NEW_TASK);
InstrumentationRegistry.getTargetContext().startActivity(intent);
// Wait for activity to relaunch and resume
- final List<LifecycleLog.ActivityCallback> expectedRelaunchSequence;
- if (launchActivityBuilder.isTargetActivityTranslucent()) {
- expectedRelaunchSequence = Arrays.asList(ON_NEW_INTENT, ON_RESUME, ON_PAUSE, ON_STOP,
- ON_DESTROY, PRE_ON_CREATE, ON_CREATE, ON_START, ON_POST_CREATE, ON_RESUME,
- ON_PAUSE, ON_RESUME);
- } else {
- expectedRelaunchSequence = Arrays.asList(ON_NEW_INTENT, ON_RESTART, ON_START, ON_RESUME,
+ final List<List<LifecycleLog.ActivityCallback>> expectedRelaunchSequences;
+ if (secondActivityIsTranslucent) {
+ expectedRelaunchSequences = Arrays.asList(Arrays.asList(ON_NEW_INTENT, ON_RESUME,
ON_PAUSE, ON_STOP, ON_DESTROY, PRE_ON_CREATE, ON_CREATE, ON_START,
- ON_POST_CREATE, ON_RESUME);
+ ON_POST_CREATE, ON_RESUME,ON_PAUSE, ON_RESUME));
+ } else {
+ expectedRelaunchSequences = Arrays.asList(
+ Arrays.asList(ON_RESTART, ON_START, ON_NEW_INTENT, ON_RESUME, ON_PAUSE, ON_STOP,
+ ON_DESTROY, PRE_ON_CREATE, ON_CREATE, ON_START, ON_POST_CREATE,
+ ON_RESUME),
+ Arrays.asList(ON_NEW_INTENT, ON_RESTART, ON_START, ON_RESUME, ON_PAUSE, ON_STOP,
+ ON_DESTROY, PRE_ON_CREATE, ON_CREATE, ON_START, ON_POST_CREATE,
+ ON_RESUME));
}
- waitForActivityTransitions(SingleTopActivity.class, expectedRelaunchSequence);
- LifecycleVerifier.assertSequence(SingleTopActivity.class, getLifecycleLog(),
- expectedRelaunchSequence, "recreate");
+ waitForActivityTransitions(SingleTopActivity.class, expectedRelaunchSequences.get(0));
+ LifecycleVerifier.assertSequenceMatchesOneOf(SingleTopActivity.class, getLifecycleLog(),
+ expectedRelaunchSequences, "recreate");
}
@Test
@@ -641,7 +658,7 @@
getLifecycleLog().clear();
final Intent intent = new Intent(InstrumentationRegistry.getContext(),
SingleTopActivity.class);
- intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
+ intent.addFlags(FLAG_ACTIVITY_NEW_TASK);
InstrumentationRegistry.getTargetContext().startActivity(intent);
// Wait for the activity to resume again
@@ -665,7 +682,7 @@
// Launch something on top
final Intent newTaskIntent = new Intent();
- newTaskIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_MULTIPLE_TASK);
+ newTaskIntent.addFlags(FLAG_ACTIVITY_NEW_TASK | FLAG_ACTIVITY_MULTIPLE_TASK);
final Activity secondActivity = mSecondActivityTestRule.launchActivity(newTaskIntent);
// Wait for the activity to resume
@@ -676,7 +693,7 @@
getLifecycleLog().clear();
final Intent intent = new Intent(InstrumentationRegistry.getContext(),
SingleTopActivity.class);
- intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
+ intent.addFlags(FLAG_ACTIVITY_NEW_TASK);
InstrumentationRegistry.getTargetContext().startActivity(intent);
// Wait for the activity to resume again
@@ -718,7 +735,7 @@
getLifecycleLog().clear();
final Intent intent = new Intent(InstrumentationRegistry.getContext(),
SingleTopActivity.class);
- intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TOP);
+ intent.addFlags(FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TOP);
InstrumentationRegistry.getTargetContext().startActivity(intent);
// Wait for the activity to resume again
@@ -734,91 +751,4 @@
LifecycleVerifier.assertSequenceMatchesOneOf(SingleTopActivity.class, getLifecycleLog(),
Arrays.asList(expectedSequence, extraPauseSequence), "newIntent");
}
-
- @Test
- public void testLifecycleOnMoveToFromSplitScreenRelaunch() throws Exception {
- if (!supportsSplitScreenMultiWindow()) {
- // Skipping test: no split multi-window support
- return;
- }
-
- // Launch a singleTop activity
- final Activity testActivity =
- mCallbackTrackingActivityTestRule.launchActivity(new Intent());
-
- // Wait for the activity to resume
- waitAndAssertActivityStates(state(testActivity, ON_RESUME));
- LifecycleVerifier.assertLaunchSequence(CallbackTrackingActivity.class, getLifecycleLog(),
- true /* includeCallbacks */);
-
- // Enter split screen
- getLifecycleLog().clear();
- setActivityTaskWindowingMode(CALLBACK_TRACKING_ACTIVITY,
- WINDOWING_MODE_SPLIT_SCREEN_PRIMARY);
-
- // Wait for the activity to pause
- final List<LifecycleLog.ActivityCallback> expectedEnterSequence =
- Arrays.asList(ON_PAUSE, ON_STOP, ON_DESTROY, PRE_ON_CREATE, ON_CREATE, ON_START,
- ON_POST_CREATE, ON_RESUME, ON_MULTI_WINDOW_MODE_CHANGED, ON_PAUSE);
- waitForActivityTransitions(CallbackTrackingActivity.class, expectedEnterSequence);
-
- // Verify that the activity was relaunched and received multi-window mode change
- LifecycleVerifier.assertSequence(CallbackTrackingActivity.class, getLifecycleLog(),
- expectedEnterSequence, "moveToSplitScreen");
-
- // Exit split-screen
- getLifecycleLog().clear();
- setActivityTaskWindowingMode(CALLBACK_TRACKING_ACTIVITY, WINDOWING_MODE_FULLSCREEN);
-
- // Wait for the activity to resume
- final List<LifecycleLog.ActivityCallback> expectedExitSequence =
- Arrays.asList(ON_STOP, ON_DESTROY, PRE_ON_CREATE, ON_CREATE, ON_START,
- ON_POST_CREATE, ON_RESUME, ON_PAUSE, ON_MULTI_WINDOW_MODE_CHANGED,
- ON_RESUME);
- waitForActivityTransitions(CallbackTrackingActivity.class, expectedExitSequence);
-
- // Verify that the activity was relaunched and received multi-window mode change
- LifecycleVerifier.assertSequence(CallbackTrackingActivity.class, getLifecycleLog(),
- expectedExitSequence, "moveFromSplitScreen");
- }
-
- @Test
- public void testLifecycleOnMoveToFromSplitScreenNoRelaunch() throws Exception {
- if (!supportsSplitScreenMultiWindow()) {
- // Skipping test: no split multi-window support
- return;
- }
-
- // Launch a singleTop activity
- final Activity testActivity =
- mConfigChangeHandlingActivityTestRule.launchActivity(new Intent());
-
- // Wait for the activity to resume
- waitAndAssertActivityStates(state(testActivity, ON_RESUME));
- LifecycleVerifier.assertLaunchSequence(ConfigChangeHandlingActivity.class,
- getLifecycleLog(), true /* includeCallbacks */);
-
- // Enter split screen
- getLifecycleLog().clear();
- setActivityTaskWindowingMode(CONFIG_CHANGE_HANDLING_ACTIVITY,
- WINDOWING_MODE_SPLIT_SCREEN_PRIMARY);
-
- // Wait for the activity to pause
- waitAndAssertActivityStates(state(testActivity, ON_PAUSE));
-
- // Verify that the activity was relaunched and received multi-window mode change
- LifecycleVerifier.assertSequence(ConfigChangeHandlingActivity.class, getLifecycleLog(),
- Arrays.asList(ON_MULTI_WINDOW_MODE_CHANGED, ON_PAUSE), "moveToSplitScreen");
-
- // Exit split-screen
- getLifecycleLog().clear();
- setActivityTaskWindowingMode(CONFIG_CHANGE_HANDLING_ACTIVITY, WINDOWING_MODE_FULLSCREEN);
-
- // Wait for the activity to resume
- waitAndAssertActivityStates(state(testActivity, ON_RESUME));
-
- // Verify that the activity was relaunched and received multi-window mode change
- LifecycleVerifier.assertSequence(ConfigChangeHandlingActivity.class, getLifecycleLog(),
- Arrays.asList(ON_MULTI_WINDOW_MODE_CHANGED, ON_RESUME), "moveFromSplitScreen");
- }
}
diff --git a/tests/framework/base/activitymanager/src/android/server/am/lifecycle/ActivityStarterTests.java b/tests/framework/base/activitymanager/src/android/server/am/lifecycle/ActivityStarterTests.java
index ef31add..e6aa995 100644
--- a/tests/framework/base/activitymanager/src/android/server/am/lifecycle/ActivityStarterTests.java
+++ b/tests/framework/base/activitymanager/src/android/server/am/lifecycle/ActivityStarterTests.java
@@ -16,14 +16,6 @@
package android.server.am.lifecycle;
-import android.app.Activity;
-import android.content.ComponentName;
-import android.content.Intent;
-import android.os.Bundle;
-import android.server.am.ActivityLauncher;
-import android.support.test.InstrumentationRegistry;
-import org.junit.Test;
-
import static android.content.Intent.FLAG_ACTIVITY_CLEAR_TASK;
import static android.content.Intent.FLAG_ACTIVITY_CLEAR_TOP;
import static android.content.Intent.FLAG_ACTIVITY_MULTIPLE_TASK;
@@ -32,11 +24,22 @@
import static android.server.am.ActivityManagerState.STATE_DESTROYED;
import static android.server.am.ActivityManagerState.STATE_RESUMED;
import static android.server.am.ComponentNameUtils.getActivityName;
+import static android.server.am.Components.ALIAS_TEST_ACTIVITY;
+import static android.server.am.Components.TEST_ACTIVITY;
import static android.server.am.lifecycle.LifecycleLog.ActivityCallback.ON_RESUME;
+import static android.view.Display.DEFAULT_DISPLAY;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotEquals;
+import android.app.Activity;
+import android.content.ComponentName;
+import android.content.Intent;
+import android.os.Bundle;
+import android.server.am.ActivityLauncher;
+
+import org.junit.Test;
+
/**
* Build/Install/Run:
* atest CtsActivityManagerDeviceTestCases:ActivityStarterTests
@@ -234,6 +237,38 @@
}
/**
+ * Tests that the existing task would be brought to top while launching alias activity or
+ * real activity without creating new activity instances, tasks, or stacks.
+ */
+ @Test
+ public void testLaunchAliasActivity() {
+ // Launch alias activity.
+ getLaunchActivityBuilder().setUseInstrumentation().setTargetActivity(ALIAS_TEST_ACTIVITY)
+ .setIntentFlags(FLAG_ACTIVITY_NEW_TASK).execute();
+ final int stacks = mAmWmState.getAmState().getStackCounts();
+ final int taskId =
+ mAmWmState.getAmState().getTaskByActivity(ALIAS_TEST_ACTIVITY).getTaskId();
+
+ // Return to home and launch the alias activity again.
+ launchHomeActivity();
+ getLaunchActivityBuilder().setUseInstrumentation().setTargetActivity(ALIAS_TEST_ACTIVITY)
+ .setIntentFlags(FLAG_ACTIVITY_NEW_TASK).execute();
+ assertEquals("Instance of the activity in its task must be only one", 1,
+ mAmWmState.getAmState().getActivityCountInTask(taskId, ALIAS_TEST_ACTIVITY));
+ assertEquals("Stacks counts should not be increased.", stacks,
+ mAmWmState.getAmState().getStackCounts());
+
+ // Return to home and launch the real activity.
+ launchHomeActivity();
+ getLaunchActivityBuilder().setUseInstrumentation().setTargetActivity(TEST_ACTIVITY)
+ .setIntentFlags(FLAG_ACTIVITY_NEW_TASK).execute();
+ assertEquals("Instance of the activity in its task must be only one", 1,
+ mAmWmState.getAmState().getActivityCountInTask(taskId, ALIAS_TEST_ACTIVITY));
+ assertEquals("Stacks counts should not be increased.", stacks,
+ mAmWmState.getAmState().getStackCounts());
+ }
+
+ /**
* This test case tests behavior of activities launched with FLAG_ACTIVITY_NEW_TASK
* and FLAG_ACTIVITY_CLEAR_TASK.
* A first launched activity is finished, then a second activity is created if the
diff --git a/tests/framework/base/activitymanager/src/android/server/am/lifecycle/LifecycleLog.java b/tests/framework/base/activitymanager/src/android/server/am/lifecycle/LifecycleLog.java
index da8296c..6018f43 100644
--- a/tests/framework/base/activitymanager/src/android/server/am/lifecycle/LifecycleLog.java
+++ b/tests/framework/base/activitymanager/src/android/server/am/lifecycle/LifecycleLog.java
@@ -1,3 +1,19 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License
+ */
+
package android.server.am.lifecycle;
import static android.server.am.StateLogger.log;
diff --git a/tests/framework/base/activitymanager/src/android/server/am/lifecycle/LifecycleTracker.java b/tests/framework/base/activitymanager/src/android/server/am/lifecycle/LifecycleTracker.java
index 24b384b..25374e5 100644
--- a/tests/framework/base/activitymanager/src/android/server/am/lifecycle/LifecycleTracker.java
+++ b/tests/framework/base/activitymanager/src/android/server/am/lifecycle/LifecycleTracker.java
@@ -1,3 +1,19 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License
+ */
+
package android.server.am.lifecycle;
import static org.junit.Assert.fail;
diff --git a/tests/framework/base/activitymanager/src/android/server/am/lifecycle/LifecycleVerifier.java b/tests/framework/base/activitymanager/src/android/server/am/lifecycle/LifecycleVerifier.java
index 8c87439..35cb0bc 100644
--- a/tests/framework/base/activitymanager/src/android/server/am/lifecycle/LifecycleVerifier.java
+++ b/tests/framework/base/activitymanager/src/android/server/am/lifecycle/LifecycleVerifier.java
@@ -1,3 +1,19 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License
+ */
+
package android.server.am.lifecycle;
import static android.server.am.StateLogger.log;
@@ -31,10 +47,14 @@
log("Observed sequence: " + observedTransitions);
final String errorMessage = errorDuringTransition(activityClass, "launch");
- final List<ActivityCallback> expectedTransitions = includeCallbacks
+ final List<ActivityCallback> expectedTransitions = getLaunchSequence(includeCallbacks);
+ assertEquals(errorMessage, expectedTransitions, observedTransitions);
+ }
+
+ static List<ActivityCallback> getLaunchSequence(boolean includeCallbacks) {
+ return includeCallbacks
? Arrays.asList(PRE_ON_CREATE, ON_CREATE, ON_START, ON_POST_CREATE, ON_RESUME)
: Arrays.asList(PRE_ON_CREATE, ON_CREATE, ON_START, ON_RESUME);
- assertEquals(errorMessage, expectedTransitions, observedTransitions);
}
static void assertLaunchSequence(Class<? extends Activity> launchingActivity,
@@ -101,7 +121,7 @@
assertEquals(errorMessage, expectedTransitions, observedTransitions);
}
- static void assertRestartAndPauseSequence(Class<? extends Activity> activityClass,
+ static void assertRestartAndResumeSequence(Class<? extends Activity> activityClass,
LifecycleLog lifecycleLog) {
final List<ActivityCallback> observedTransitions =
lifecycleLog.getActivityLog(activityClass);
@@ -109,11 +129,11 @@
final String errorMessage = errorDuringTransition(activityClass, "restart and pause");
final List<ActivityCallback> expectedTransitions =
- Arrays.asList(ON_RESTART, ON_START, ON_RESUME, ON_PAUSE);
+ Arrays.asList(ON_RESTART, ON_START, ON_RESUME);
assertEquals(errorMessage, expectedTransitions, observedTransitions);
}
- static void assertRecreateAndPauseSequence(Class<? extends Activity> activityClass,
+ static void assertRecreateAndResumeSequence(Class<? extends Activity> activityClass,
LifecycleLog lifecycleLog) {
final List<ActivityCallback> observedTransitions =
lifecycleLog.getActivityLog(activityClass);
@@ -121,7 +141,7 @@
final String errorMessage = errorDuringTransition(activityClass, "recreateA and pause");
final List<ActivityCallback> expectedTransitions =
- Arrays.asList(ON_DESTROY, PRE_ON_CREATE, ON_CREATE, ON_START, ON_RESUME, ON_PAUSE);
+ Arrays.asList(ON_DESTROY, PRE_ON_CREATE, ON_CREATE, ON_START, ON_RESUME);
assertEquals(errorMessage, expectedTransitions, observedTransitions);
}
@@ -137,6 +157,29 @@
assertEquals(errorMessage, expectedTransitions, observedTransitions);
}
+ static void assertResumeToDestroySequence(Class<? extends Activity> activityClass,
+ LifecycleLog lifecycleLog) {
+ final List<ActivityCallback> observedTransitions =
+ lifecycleLog.getActivityLog(activityClass);
+ log("Observed sequence: " + observedTransitions);
+ final String errorMessage = errorDuringTransition(activityClass, "launch and destroy");
+
+ final List<ActivityCallback> expectedTransitions = Arrays.asList(ON_PAUSE, ON_STOP,
+ ON_DESTROY);
+ assertEquals(errorMessage, expectedTransitions, observedTransitions);
+ }
+
+ static void assertResumeToStopSequence(Class<? extends Activity> activityClass,
+ LifecycleLog lifecycleLog) {
+ final List<ActivityCallback> observedTransitions =
+ lifecycleLog.getActivityLog(activityClass);
+ log("Observed sequence: " + observedTransitions);
+ final String errorMessage = errorDuringTransition(activityClass, "launch and destroy");
+
+ final List<ActivityCallback> expectedTransitions = Arrays.asList(ON_PAUSE, ON_STOP);
+ assertEquals(errorMessage, expectedTransitions, observedTransitions);
+ }
+
static void assertRelaunchSequence(Class<? extends Activity> activityClass,
LifecycleLog lifecycleLog, ActivityCallback startState) {
final List<ActivityCallback> expectedTransitions;
diff --git a/tests/framework/base/activitymanager/util/src/android/server/am/ActivityAndWindowManagersState.java b/tests/framework/base/activitymanager/util/src/android/server/am/ActivityAndWindowManagersState.java
index 7671bab..80cf75a 100644
--- a/tests/framework/base/activitymanager/util/src/android/server/am/ActivityAndWindowManagersState.java
+++ b/tests/framework/base/activitymanager/util/src/android/server/am/ActivityAndWindowManagersState.java
@@ -306,6 +306,13 @@
"***Waiting for Activity State: " + activityState);
}
+ public void waitForActivityRemoved(ComponentName activityName) {
+ waitForWithAmState((state) -> !state.containsActivity(activityName),
+ "Waiting for activity to be removed");
+ waitForWithWmState((state) -> !state.containsWindow(getWindowName(activityName)),
+ "Waiting for activity window to be gone");
+ }
+
@Deprecated
void waitForFocusedStack(int stackId) {
waitForWithAmState(state -> state.getFocusedStackId() == stackId,
@@ -343,11 +350,11 @@
assertNotNull(ws);
}
- void waitForWithAmState(Predicate<ActivityManagerState> waitCondition, String message) {
+ public void waitForWithAmState(Predicate<ActivityManagerState> waitCondition, String message) {
waitFor((amState, wmState) -> waitCondition.test(amState), message);
}
- void waitForWithWmState(Predicate<WindowManagerState> waitCondition, String message) {
+ public void waitForWithWmState(Predicate<WindowManagerState> waitCondition, String message) {
waitFor((amState, wmState) -> waitCondition.test(wmState), message);
}
diff --git a/tests/framework/base/activitymanager/util/src/android/server/am/ActivityManagerState.java b/tests/framework/base/activitymanager/util/src/android/server/am/ActivityManagerState.java
index db59381..40ce779a 100644
--- a/tests/framework/base/activitymanager/util/src/android/server/am/ActivityManagerState.java
+++ b/tests/framework/base/activitymanager/util/src/android/server/am/ActivityManagerState.java
@@ -32,7 +32,9 @@
import android.os.ParcelFileDescriptor;
import android.os.SystemClock;
import android.support.test.InstrumentationRegistry;
+
import androidx.annotation.Nullable;
+
import android.util.SparseArray;
import com.android.server.am.nano.ActivityDisplayProto;
@@ -364,7 +366,7 @@
return new ArrayList<>(mDisplays);
}
- List<ActivityStack> getStacks() {
+ public List<ActivityStack> getStacks() {
return new ArrayList<>(mStacks);
}
@@ -376,7 +378,7 @@
return mDisplays.size();
}
- boolean containsActivity(ComponentName activityName) {
+ public boolean containsActivity(ComponentName activityName) {
final String fullName = getActivityName(activityName);
for (ActivityStack stack : mStacks) {
for (ActivityTask task : stack.mTasks) {
@@ -390,6 +392,24 @@
return false;
}
+ public boolean containsNoneOf(Iterable<ComponentName> activityNames) {
+ for (ComponentName activityName : activityNames) {
+ String fullName = getActivityName(activityName);
+
+ for (ActivityStack stack : mStacks) {
+ for (ActivityTask task : stack.mTasks) {
+ for (Activity activity : task.mActivities) {
+ if (activity.name.equals(fullName)) {
+ return false;
+ }
+ }
+ }
+ }
+ }
+
+ return true;
+ }
+
boolean containsActivityInWindowingMode(ComponentName activityName, int windowingMode) {
final String fullName = getActivityName(activityName);
for (ActivityStack stack : mStacks) {
@@ -598,11 +618,15 @@
return 0;
}
+ public int getStackCounts() {
+ return mStacks.size();
+ }
+
boolean pendingActivityContain(ComponentName activityName) {
return mPendingActivities.contains(getActivityName(activityName));
}
- static class ActivityDisplay extends ActivityContainer {
+ public static class ActivityDisplay extends ActivityContainer {
int mId;
ArrayList<ActivityStack> mStacks = new ArrayList<>();
@@ -643,9 +667,13 @@
}
return false;
}
+
+ public ArrayList<ActivityStack> getStacks() {
+ return mStacks;
+ }
}
- static class ActivityStack extends ActivityContainer {
+ public static class ActivityStack extends ActivityContainer {
int mDisplayId;
int mStackId;
@@ -690,7 +718,7 @@
return null;
}
- List<ActivityTask> getTasks() {
+ public List<ActivityTask> getTasks() {
return new ArrayList<>(mTasks);
}
@@ -702,6 +730,14 @@
}
return null;
}
+
+ public int getStackId() {
+ return mStackId;
+ }
+
+ public String getResumedActivity() {
+ return mResumedActivity;
+ }
}
public static class ActivityTask extends ActivityContainer {
@@ -740,6 +776,10 @@
public int getTaskId() {
return mTaskId;
}
+
+ public ArrayList<Activity> getActivities() {
+ return mActivities;
+ }
}
public static class Activity extends ActivityContainer {
@@ -762,6 +802,14 @@
}
translucent = proto.translucent;
}
+
+ public String getName() {
+ return name;
+ }
+
+ public String getState() {
+ return state;
+ }
}
static abstract class ActivityContainer extends WindowManagerState.ConfigurationContainer {
diff --git a/tests/framework/base/activitymanager/util/src/android/server/am/ActivityManagerTestBase.java b/tests/framework/base/activitymanager/util/src/android/server/am/ActivityManagerTestBase.java
index 7303027..a5351b8c 100644
--- a/tests/framework/base/activitymanager/util/src/android/server/am/ActivityManagerTestBase.java
+++ b/tests/framework/base/activitymanager/util/src/android/server/am/ActivityManagerTestBase.java
@@ -85,6 +85,7 @@
import static android.support.test.InstrumentationRegistry.getContext;
import static android.view.Display.DEFAULT_DISPLAY;
import static android.view.Display.INVALID_DISPLAY;
+import static android.view.Surface.ROTATION_0;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
@@ -99,15 +100,19 @@
import android.app.ActivityOptions;
import android.app.ActivityTaskManager;
import android.content.ComponentName;
+import android.content.ContentResolver;
import android.content.Context;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.content.pm.ResolveInfo;
import android.content.res.Resources;
+import android.database.ContentObserver;
import android.graphics.Bitmap;
import android.graphics.Rect;
import android.hardware.display.DisplayManager;
import android.os.Bundle;
+import android.os.Handler;
+import android.os.HandlerThread;
import android.os.SystemClock;
import android.provider.Settings;
import android.server.am.CommandSession.ActivityCallback;
@@ -171,11 +176,13 @@
private static final String SECOND_TEST_PACKAGE = "android.server.am.second";
private static final String THIRD_TEST_PACKAGE = "android.server.am.third";
private static final List<String> TEST_PACKAGES;
+
static {
final List<String> testPackages = new ArrayList<>(3);
testPackages.add(TEST_PACKAGE);
testPackages.add(SECOND_TEST_PACKAGE);
testPackages.add(THIRD_TEST_PACKAGE);
+ testPackages.add("android.server.cts.am");
TEST_PACKAGES = Collections.unmodifiableList(testPackages);
}
@@ -210,7 +217,7 @@
/**
* @return the am command to start the given activity with the following extra key/value pairs.
- * {@param keyValuePairs} must be a list of arguments defining each key/value extra.
+ * {@param keyValuePairs} must be a list of arguments defining each key/value extra.
*/
// TODO: Make this more generic, for instance accepting flags or extras of other types.
protected static String getAmStartCmd(final ComponentName activityName,
@@ -268,6 +275,10 @@
protected ActivityAndWindowManagersState mAmWmState = new ActivityAndWindowManagersState();
+ public ActivityAndWindowManagersState getAmWmState() {
+ return mAmWmState;
+ }
+
protected BroadcastActionTrigger mBroadcastActionTrigger = new BroadcastActionTrigger();
/**
@@ -561,7 +572,7 @@
}
/**
- * Launches {@param activityName} into split-screen primary windowing mode and also makes
+ * Launches {@param activityName} into split-screen primary windowing mode and also makes
* the recents activity visible to the side of it.
* NOTE: Recents view may be combined with home screen on some devices, so using this to wait
* for Recents only makes sense when {@link ActivityManagerState#isHomeRecentsComponent()} is
@@ -595,23 +606,24 @@
/**
* Moves the device into split-screen with the specified task into the primary stack.
- * @param taskId The id of the task to move into the primary stack.
- * @param showRecents Whether to show the recents activity (or a placeholder activity in
- * place of the Recents activity if home is the recents component)
+ * @param taskId The id of the task to move into the primary stack.
+ * @param showSideActivity Whether to show the Recents activity (or a placeholder activity in
+ * place of the Recents activity if home is the recents component)
*/
- public void moveTaskToPrimarySplitScreen(int taskId, boolean showRecents) {
+ public void moveTaskToPrimarySplitScreen(int taskId, boolean showSideActivity) {
+ final boolean isHomeRecentsComponent = mAmWmState.getAmState().isHomeRecentsComponent();
SystemUtil.runWithShellPermissionIdentity(() -> {
mAtm.setTaskWindowingModeSplitScreenPrimary(taskId,
SPLIT_SCREEN_CREATE_MODE_TOP_OR_LEFT, true /* onTop */,
false /* animate */,
- null /* initialBounds */, showRecents);
+ null /* initialBounds */, showSideActivity && !isHomeRecentsComponent);
mAmWmState.waitForRecentsActivityVisible();
- if (mAmWmState.getAmState().isHomeRecentsComponent() && showRecents) {
- // Launch Placeholder Recents
- final Activity recentsActivity = mSideActivityRule.launchActivity(
+ if (isHomeRecentsComponent && showSideActivity) {
+ // Launch Placeholder Side Activity
+ final Activity sideActivity = mSideActivityRule.launchActivity(
new Intent());
- mAmWmState.waitForActivityState(recentsActivity.getComponentName(), STATE_RESUMED);
+ mAmWmState.waitForActivityState(sideActivity.getComponentName(), STATE_RESUMED);
}
});
}
@@ -744,7 +756,7 @@
assertTrue(message, mAmWmState.getAmState().hasActivityState(activityName, state));
}
- protected void waitAndAssertTopResumedActivity(ComponentName activityName, int displayId,
+ public void waitAndAssertTopResumedActivity(ComponentName activityName, int displayId,
String message) {
mAmWmState.waitForValidState(activityName);
mAmWmState.waitForActivityState(activityName, STATE_RESUMED);
@@ -765,7 +777,7 @@
mAmWmState.assertFocusedStack("Top activity's stack must also be on top", frontStackId);
mAmWmState.assertVisibility(activityName, true /* visible */);
}
-
+
// TODO: Switch to using a feature flag, when available.
protected static boolean isUiModeLockedToVrHeadset() {
final String output = runCommandAndPrintOutput("dumpsys uimode");
@@ -921,12 +933,22 @@
private final boolean mIsLockDisabled;
private boolean mLockCredentialSet;
+ private boolean mRemoveActivitiesOnClose;
+
+ public static final int FLAG_REMOVE_ACTIVITIES_ON_CLOSE = 1;
public LockScreenSession() {
+ this(0 /* flags */);
+ }
+
+ public LockScreenSession(int flags) {
mIsLockDisabled = isLockDisabled();
mLockCredentialSet = false;
// Enable lock screen (swipe) by default.
setLockDisabled(false);
+ if ((flags & FLAG_REMOVE_ACTIVITIES_ON_CLOSE) != 0) {
+ mRemoveActivitiesOnClose = true;
+ }
}
public LockScreenSession setLockCredential() {
@@ -997,6 +1019,10 @@
@Override
public void close() {
+ if (mRemoveActivitiesOnClose) {
+ removeStacksWithActivityTypes(ALL_ACTIVITY_TYPE_BUT_HOME);
+ }
+
setLockDisabled(mIsLockDisabled);
if (mLockCredentialSet) {
removeLockCredential();
@@ -1042,6 +1068,10 @@
/** Helper class to save, set & wait, and restore rotation related preferences. */
protected class RotationSession extends SettingsSession<Integer> {
private final SettingsSession<Integer> mUserRotation;
+ private final HandlerThread mThread;
+ private final Handler mRunnableHandler;
+ private final SettingsObserver mRotationObserver;
+ private int mPreviousDegree;
public RotationSession() throws Exception {
// Save accelerometer_rotation preference.
@@ -1050,23 +1080,82 @@
mUserRotation = new SettingsSession<>(
Settings.System.getUriFor(Settings.System.USER_ROTATION),
Settings.System::getInt, Settings.System::putInt);
+
+ mThread = new HandlerThread("Observer_Thread");
+ mThread.start();
+ mRunnableHandler = new Handler(mThread.getLooper());
+ mRotationObserver = new SettingsObserver(mRunnableHandler);
+
+ mPreviousDegree = mUserRotation.get();
// Disable accelerometer_rotation.
super.set(0);
}
@Override
public void set(@NonNull Integer value) throws Exception {
+ // When the rotation is locked and the SystemUI receives the rotation becoming 0deg, it
+ // will call freezeRotation to WMS, which will cause USER_ROTATION be set to zero again.
+ // In order to prevent our test target from being overwritten by SystemUI during
+ // rotation test, wait for the USER_ROTATION changed then continue testing.
+ final boolean waitSystemUI = value == ROTATION_0 && mPreviousDegree != ROTATION_0;
+ if (waitSystemUI) {
+ mRotationObserver.observe();
+ }
mUserRotation.set(value);
+ mPreviousDegree = value;
+
+ if (waitSystemUI) {
+ waitForRotationNotified();
+ }
// Wait for settling rotation.
mAmWmState.waitForRotation(value);
+
+ if (waitSystemUI) {
+ mRotationObserver.stopObserver();
+ }
}
@Override
public void close() throws Exception {
+ mThread.quitSafely();
mUserRotation.close();
// Restore accelerometer_rotation preference.
super.close();
}
+
+ private void waitForRotationNotified() {
+ for (int retry = 1; retry <= 5; retry++) {
+ if (mRotationObserver.notified) {
+ return;
+ }
+ logAlways("waitForRotationNotified retry=" + retry);
+ SystemClock.sleep(500);
+ }
+ logE("waitForRotationNotified skip");
+ }
+
+ private class SettingsObserver extends ContentObserver {
+ boolean notified;
+
+ SettingsObserver(Handler handler) { super(handler); }
+
+ void observe() {
+ notified = false;
+ final ContentResolver resolver = mContext.getContentResolver();
+ resolver.registerContentObserver(Settings.System.getUriFor(
+ Settings.System.USER_ROTATION), false, this);
+ }
+
+ void stopObserver() {
+ final ContentResolver resolver = mContext.getContentResolver();
+ resolver.unregisterContentObserver(this);
+ }
+
+ @Override
+ public void onChange(boolean selfChange) {
+ if (!selfChange) notified = true;
+ }
+ }
}
/**
@@ -1079,10 +1168,10 @@
* rotation, because there is no requirement that an Android device that supports both
* orientations needs to support user rotation mode.
*
- * @param session the rotation session used to set user rotation
+ * @param session the rotation session used to set user rotation
* @param displayId the display ID to check rotation against
* @return {@code true} if test device respects settings of locked user rotation mode;
- * {@code false} if not.
+ * {@code false} if not.
*/
protected boolean supportsLockedUserRotation(RotationSession session, int displayId)
throws Exception {
@@ -1136,6 +1225,7 @@
/**
* Inserts a log separator so we can always find the starting point from where to evaluate
* following logs.
+ *
* @return Unique log separator.
*/
protected LogSeparator separateLogs() {
@@ -1573,11 +1663,13 @@
private enum LauncherType {
INSTRUMENTATION, LAUNCHING_ACTIVITY, BROADCAST_RECEIVER
}
+
private LauncherType mLauncherType = LauncherType.LAUNCHING_ACTIVITY;
public LaunchActivityBuilder(ActivityAndWindowManagersState amWmState) {
mAmWmState = amWmState;
mWaitForLaunched = true;
+ mWithShellPermission = true;
}
public LaunchActivityBuilder setToSide(boolean toSide) {
diff --git a/tests/framework/base/activitymanager/util/src/android/server/am/WindowManagerState.java b/tests/framework/base/activitymanager/util/src/android/server/am/WindowManagerState.java
index 0eceaf4..459dffb 100644
--- a/tests/framework/base/activitymanager/util/src/android/server/am/WindowManagerState.java
+++ b/tests/framework/base/activitymanager/util/src/android/server/am/WindowManagerState.java
@@ -472,7 +472,7 @@
/**
* Check if there exists a window record with matching windowName.
*/
- boolean containsWindow(String windowName) {
+ public boolean containsWindow(String windowName) {
for (WindowState window : mWindowStates) {
if (window.getName().equals(windowName)) {
return true;
diff --git a/tests/framework/base/windowmanager/src/android/server/wm/WindowFocusTests.java b/tests/framework/base/windowmanager/src/android/server/wm/WindowFocusTests.java
index 1c82c6c..fb2f1b6 100644
--- a/tests/framework/base/windowmanager/src/android/server/wm/WindowFocusTests.java
+++ b/tests/framework/base/windowmanager/src/android/server/wm/WindowFocusTests.java
@@ -159,12 +159,12 @@
sendAndAssertTargetConsumedKey(primaryActivity, KEYCODE_1, DEFAULT_DISPLAY);
try (VirtualDisplaySession displaySession = new VirtualDisplaySession()) {
- final Display secondaryDisplay = displaySession.createDisplay(getTargetContext());
- final SecondaryActivity secondaryActivity
- = startActivity(SecondaryActivity.class, secondaryDisplay.getDisplayId());
+ final int secondaryDisplayId =
+ displaySession.createDisplay(getTargetContext()).getDisplayId();
+ final SecondaryActivity secondaryActivity =
+ startActivity(SecondaryActivity.class, secondaryDisplayId);
sendAndAssertTargetConsumedKey(secondaryActivity, KEYCODE_2, INVALID_DISPLAY);
- sendAndAssertTargetConsumedKey(secondaryActivity, KEYCODE_3,
- secondaryDisplay.getDisplayId());
+ sendAndAssertTargetConsumedKey(secondaryActivity, KEYCODE_3, secondaryDisplayId);
final boolean perDisplayFocusEnabled = getTargetContext().getResources().getBoolean(
com.android.internal.R.bool.config_perDisplayFocusEnabled);
@@ -177,7 +177,7 @@
// Press display-unspecified keys and a display-specified key but not release them.
sendKey(ACTION_DOWN, KEYCODE_5, INVALID_DISPLAY);
- sendKey(ACTION_DOWN, KEYCODE_6, secondaryDisplay.getDisplayId());
+ sendKey(ACTION_DOWN, KEYCODE_6, secondaryDisplayId);
sendKey(ACTION_DOWN, KEYCODE_7, INVALID_DISPLAY);
secondaryActivity.assertAndConsumeKeyEvent(ACTION_DOWN, KEYCODE_5, 0 /* flags */);
secondaryActivity.assertAndConsumeKeyEvent(ACTION_DOWN, KEYCODE_6, 0 /* flags */);
@@ -202,6 +202,33 @@
}
/**
+ * Test if a display targeted by a key event can be moved to top in a single-focus system.
+ */
+ @Test
+ public void testMovingDisplayToTopByKeyEvent() throws InterruptedException {
+ if (getTargetContext().getResources().getBoolean(
+ com.android.internal.R.bool.config_perDisplayFocusEnabled)) {
+ return;
+ }
+
+ final PrimaryActivity primaryActivity = startActivity(PrimaryActivity.class,
+ DEFAULT_DISPLAY);
+
+ try (VirtualDisplaySession displaySession = new VirtualDisplaySession()) {
+ final int secondaryDisplayId =
+ displaySession.createDisplay(getTargetContext()).getDisplayId();
+ final SecondaryActivity secondaryActivity =
+ startActivity(SecondaryActivity.class, secondaryDisplayId);
+
+ sendAndAssertTargetConsumedKey(primaryActivity, KEYCODE_0, DEFAULT_DISPLAY);
+ sendAndAssertTargetConsumedKey(primaryActivity, KEYCODE_1, INVALID_DISPLAY);
+
+ sendAndAssertTargetConsumedKey(secondaryActivity, KEYCODE_2, secondaryDisplayId);
+ sendAndAssertTargetConsumedKey(secondaryActivity, KEYCODE_3, INVALID_DISPLAY);
+ }
+ }
+
+ /**
* Test if the client is notified about window-focus lost after the new focused window is drawn.
*/
@Test
@@ -232,9 +259,10 @@
primaryActivity.waitAndAssertPointerCaptureState(true /* hasCapture */);
try (VirtualDisplaySession displaySession = new VirtualDisplaySession()) {
- final Display secondaryDisplay = displaySession.createDisplay(getTargetContext());
- final SecondaryActivity secondaryActivity
- = startActivity(SecondaryActivity.class, secondaryDisplay.getDisplayId());
+ final int secondaryDisplayId =
+ displaySession.createDisplay(getTargetContext()).getDisplayId();
+ final SecondaryActivity secondaryActivity =
+ startActivity(SecondaryActivity.class, secondaryDisplayId);
// Assert primary activity lost pointer capture when it is not top focused.
primaryActivity.waitAndAssertPointerCaptureState(false /* hasCapture */);
@@ -260,9 +288,9 @@
final SecondaryActivity secondaryActivity;
try (VirtualDisplaySession displaySession = new VirtualDisplaySession()) {
- final Display secondaryDisplay = displaySession.createDisplay(getTargetContext());
- secondaryActivity
- = startActivity(SecondaryActivity.class, secondaryDisplay.getDisplayId());
+ final int secondaryDisplayId =
+ displaySession.createDisplay(getTargetContext()).getDisplayId();
+ secondaryActivity = startActivity(SecondaryActivity.class, secondaryDisplayId);
}
// Secondary display disconnected.
diff --git a/tests/libcore/coreplatformapi/Android.mk b/tests/libcore/coreplatformapi/Android.mk
deleted file mode 100644
index 9dd2f17..0000000
--- a/tests/libcore/coreplatformapi/Android.mk
+++ /dev/null
@@ -1,39 +0,0 @@
-# Copyright (C) 2018 The Android Open Source Project
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-
-LOCAL_PATH:= $(call my-dir)
-
-include $(CLEAR_VARS)
-
-LOCAL_PACKAGE_NAME := CtsLibcoreCorePlatformApiTestCases
-LOCAL_PRIVATE_PLATFORM_APIS := true
-
-LOCAL_STATIC_JAVA_LIBRARIES := \
- cts-core-test-runner \
- core-platform-api-test
-
-# 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
-
-# Tag this module as a cts test artifact
-LOCAL_COMPATIBILITY_SUITE := cts vts general-tests
-
-include $(BUILD_CTS_SUPPORT_PACKAGE)
diff --git a/tests/libcore/coreplatformapi/AndroidManifest.xml b/tests/libcore/coreplatformapi/AndroidManifest.xml
deleted file mode 100644
index 6b582a8..0000000
--- a/tests/libcore/coreplatformapi/AndroidManifest.xml
+++ /dev/null
@@ -1,31 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
- * Copyright (C) 2018 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- -->
-
-<manifest xmlns:android="http://schemas.android.com/apk/res/android"
- package="android.libcore.cts.coreplatformapi"
- android:targetSandboxVersion="2">
-
- <application android:usesCleartextTraffic="true">
- <uses-library android:name="android.test.runner" />
- </application>
-
- <instrumentation
- android:name="android.support.test.runner.AndroidJUnitRunner"
- android:label="CTS Libcore core platform API test cases"
- android:targetPackage="android.libcore.cts.coreplatformapi">
- </instrumentation>
-</manifest>
diff --git a/tests/libcore/jsr166/AndroidTest.xml b/tests/libcore/jsr166/AndroidTest.xml
index 9d2cfcf..a05d91a 100644
--- a/tests/libcore/jsr166/AndroidTest.xml
+++ b/tests/libcore/jsr166/AndroidTest.xml
@@ -16,6 +16,8 @@
<configuration description="Config for CTS Libcore JSR166 test cases">
<option name="test-suite-tag" value="cts" />
<option name="config-descriptor:metadata" key="component" value="libcore" />
+ <option name="config-descriptor:metadata" key="parameter" value="multi_abi" />
+ <option name="config-descriptor:metadata" key="parameter" value="not_instant_app" />
<target_preparer class="com.android.tradefed.targetprep.RunCommandTargetPreparer">
<option name="run-command" value="mkdir -p /data/local/tmp/ctslibcore/java.io.tmpdir" />
<option name="run-command" value="mkdir -p /data/local/tmp/ctslibcore/user.home" />
diff --git a/tests/libcore/luni/AndroidTest.xml b/tests/libcore/luni/AndroidTest.xml
index 6de3df5..a069c4f 100644
--- a/tests/libcore/luni/AndroidTest.xml
+++ b/tests/libcore/luni/AndroidTest.xml
@@ -16,6 +16,8 @@
<configuration description="Config for CTS Libcore test cases">
<option name="test-suite-tag" value="cts" />
<option name="config-descriptor:metadata" key="component" value="libcore" />
+ <option name="config-descriptor:metadata" key="parameter" value="multi_abi" />
+ <option name="config-descriptor:metadata" key="parameter" value="not_instant_app" />
<target_preparer class="com.android.tradefed.targetprep.RunCommandTargetPreparer">
<option name="run-command" value="mkdir -p /data/local/tmp/ctslibcore/java.io.tmpdir" />
<option name="run-command" value="mkdir -p /data/local/tmp/ctslibcore/user.home" />
diff --git a/tests/libcore/ojluni/AndroidTest.xml b/tests/libcore/ojluni/AndroidTest.xml
index 589d431..d49736b 100644
--- a/tests/libcore/ojluni/AndroidTest.xml
+++ b/tests/libcore/ojluni/AndroidTest.xml
@@ -16,6 +16,8 @@
<configuration description="Config for CTS Libcore OJ test cases">
<option name="test-suite-tag" value="cts" />
<option name="config-descriptor:metadata" key="component" value="libcore" />
+ <option name="config-descriptor:metadata" key="parameter" value="multi_abi" />
+ <option name="config-descriptor:metadata" key="parameter" value="not_instant_app" />
<target_preparer class="com.android.tradefed.targetprep.RunCommandTargetPreparer">
<option name="run-command" value="mkdir -p /data/local/tmp/ctslibcore/java.io.tmpdir" />
<option name="run-command" value="mkdir -p /data/local/tmp/ctslibcore/user.home" />
diff --git a/tests/libcore/okhttp/AndroidTest.xml b/tests/libcore/okhttp/AndroidTest.xml
index 1865fa5..c6ca3d9 100644
--- a/tests/libcore/okhttp/AndroidTest.xml
+++ b/tests/libcore/okhttp/AndroidTest.xml
@@ -16,6 +16,8 @@
<configuration description="Config for CTS Libcore OkHttp test cases">
<option name="test-suite-tag" value="cts" />
<option name="config-descriptor:metadata" key="component" value="libcore" />
+ <option name="config-descriptor:metadata" key="parameter" value="multi_abi" />
+ <option name="config-descriptor:metadata" key="parameter" value="not_instant_app" />
<target_preparer class="com.android.tradefed.targetprep.RunCommandTargetPreparer">
<option name="run-command" value="mkdir -p /data/local/tmp/ctslibcore/java.io.tmpdir" />
<option name="run-command" value="mkdir -p /data/local/tmp/ctslibcore/user.home" />
diff --git a/tests/libcore/simplemmodule/AndroidManifest.xml b/tests/libcore/simplemmodule/AndroidManifest.xml
deleted file mode 100644
index ed825b3..0000000
--- a/tests/libcore/simplemmodule/AndroidManifest.xml
+++ /dev/null
@@ -1,31 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
- * Copyright (C) 2018 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- -->
-
-<manifest xmlns:android="http://schemas.android.com/apk/res/android"
- package="android.libcore.cts.simplemmodule"
- android:targetSandboxVersion="2">
-
- <application android:usesCleartextTraffic="true">
- <uses-library android:name="android.test.runner" />
- </application>
-
- <instrumentation
- android:name="android.support.test.runner.AndroidJUnitRunner"
- android:label="CTS Libcore simple mmodule test cases"
- android:targetPackage="android.libcore.cts.simplemmodule">
- </instrumentation>
-</manifest>
diff --git a/tests/libcore/simplemmodule/AndroidTest.xml b/tests/libcore/simplemmodule/AndroidTest.xml
deleted file mode 100644
index 5eb0586..0000000
--- a/tests/libcore/simplemmodule/AndroidTest.xml
+++ /dev/null
@@ -1,28 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2018 The Android Open Source Project
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
--->
-<configuration description="Config for CTS Libcore simple mmodule test cases">
- <option name="test-suite-tag" value="cts" />
- <option name="config-descriptor:metadata" key="component" value="libcore" />
- <target_preparer class="com.android.tradefed.targetprep.suite.SuiteApkInstaller">
- <option name="cleanup-apks" value="true" />
- <option name="test-file-name" value="CtsLibcoreSimpleMModuleTestCases.apk" />
- </target_preparer>
- <test class="com.android.tradefed.testtype.AndroidJUnitTest" >
- <option name="package" value="android.libcore.cts.simplemmodule" />
- <option name="runtime-hint" value="1m"/>
- <option name="hidden-api-checks" value="false"/>
- </test>
-</configuration>
diff --git a/tests/libcore/wycheproof-bc/AndroidTest.xml b/tests/libcore/wycheproof-bc/AndroidTest.xml
index badcaec..f137d92 100644
--- a/tests/libcore/wycheproof-bc/AndroidTest.xml
+++ b/tests/libcore/wycheproof-bc/AndroidTest.xml
@@ -16,6 +16,8 @@
<configuration description="Config for CTS Libcore Wycheproof Bouncy Castle test cases">
<option name="test-suite-tag" value="cts" />
<option name="config-descriptor:metadata" key="component" value="libcore" />
+ <option name="config-descriptor:metadata" key="parameter" value="multi_abi" />
+ <option name="config-descriptor:metadata" key="parameter" value="not_instant_app" />
<target_preparer class="com.android.tradefed.targetprep.suite.SuiteApkInstaller">
<option name="cleanup-apks" value="true" />
<!-- this has just the instrumentation which acts as the tests we want to run -->
diff --git a/tests/libcore/wycheproof/AndroidTest.xml b/tests/libcore/wycheproof/AndroidTest.xml
index 0119e6b..4870a52 100644
--- a/tests/libcore/wycheproof/AndroidTest.xml
+++ b/tests/libcore/wycheproof/AndroidTest.xml
@@ -16,6 +16,8 @@
<configuration description="Config for CTS Libcore Wycheproof Conscrypt test cases">
<option name="test-suite-tag" value="cts" />
<option name="config-descriptor:metadata" key="component" value="libcore" />
+ <option name="config-descriptor:metadata" key="parameter" value="multi_abi" />
+ <option name="config-descriptor:metadata" key="parameter" value="not_instant_app" />
<target_preparer class="com.android.tradefed.targetprep.suite.SuiteApkInstaller">
<option name="cleanup-apks" value="true" />
<!-- this has just the instrumentation which acts as the tests we want to run -->
diff --git a/tests/providerui/src/android/providerui/cts/MediaStoreUiTest.java b/tests/providerui/src/android/providerui/cts/MediaStoreUiTest.java
index 959e04d..4dcb1e8 100644
--- a/tests/providerui/src/android/providerui/cts/MediaStoreUiTest.java
+++ b/tests/providerui/src/android/providerui/cts/MediaStoreUiTest.java
@@ -26,6 +26,7 @@
import android.app.Activity;
import android.content.ContentResolver;
+import android.content.ContentUris;
import android.content.Context;
import android.content.Intent;
import android.content.UriPermission;
@@ -326,7 +327,9 @@
}
private void onScanCompleted(Uri uri, CountDownLatch latch) {
- mMediaStoreUri = uri;
+ final String volumeName = MediaStore.getVolumeName(uri);
+ mMediaStoreUri = ContentUris.withAppendedId(MediaStore.Files.getContentUri(volumeName),
+ ContentUris.parseId(uri));
latch.countDown();
}
diff --git a/tests/signature/api-check/Android.mk b/tests/signature/api-check/Android.mk
index 08afe97..bb2c28c 100644
--- a/tests/signature/api-check/Android.mk
+++ b/tests/signature/api-check/Android.mk
@@ -32,6 +32,7 @@
cts-signature-common \
repackaged.android.test.base \
repackaged.android.test.runner \
+ compatibility-device-util
include $(BUILD_STATIC_JAVA_LIBRARY)
diff --git a/tests/signature/api-check/android-test-base-27-api/AndroidManifest.xml b/tests/signature/api-check/android-test-base-27-api/AndroidManifest.xml
index 877e911..7ad6c9e 100644
--- a/tests/signature/api-check/android-test-base-27-api/AndroidManifest.xml
+++ b/tests/signature/api-check/android-test-base-27-api/AndroidManifest.xml
@@ -22,7 +22,7 @@
<uses-sdk android:minSdkVersion="25" android:targetSdkVersion="27"/>
- <application android:debuggable="true"/>
+ <application android:debuggable="true" android:extractNativeLibs="true"/>
<instrumentation android:name="repackaged.android.test.InstrumentationTestRunner"
android:targetPackage="android.signature.cts.api.android_test_base_27"
diff --git a/tests/signature/api-check/android-test-mock-current-api/AndroidManifest.xml b/tests/signature/api-check/android-test-mock-current-api/AndroidManifest.xml
index f0fc8e1..15af902 100644
--- a/tests/signature/api-check/android-test-mock-current-api/AndroidManifest.xml
+++ b/tests/signature/api-check/android-test-mock-current-api/AndroidManifest.xml
@@ -20,7 +20,7 @@
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.READ_PHONE_STATE"/>
- <application android:debuggable="true">
+ <application android:debuggable="true" android:extractNativeLibs="true">
<uses-library android:name="android.test.mock"/>
</application>
diff --git a/tests/signature/api-check/android-test-runner-current-api/AndroidManifest.xml b/tests/signature/api-check/android-test-runner-current-api/AndroidManifest.xml
index f81665e..e055a9f 100644
--- a/tests/signature/api-check/android-test-runner-current-api/AndroidManifest.xml
+++ b/tests/signature/api-check/android-test-runner-current-api/AndroidManifest.xml
@@ -20,7 +20,7 @@
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.READ_PHONE_STATE"/>
- <application android:debuggable="true">
+ <application android:debuggable="true" android:extractNativeLibs="true">
<uses-library android:name="android.test.runner"/>
</application>
diff --git a/tests/signature/api-check/apache-http-legacy-27-api/AndroidManifest.xml b/tests/signature/api-check/apache-http-legacy-27-api/AndroidManifest.xml
index ae69f52..f118565 100644
--- a/tests/signature/api-check/apache-http-legacy-27-api/AndroidManifest.xml
+++ b/tests/signature/api-check/apache-http-legacy-27-api/AndroidManifest.xml
@@ -22,7 +22,7 @@
<uses-sdk android:minSdkVersion="22" android:targetSdkVersion="27"/>
- <application/>
+ <application android:extractNativeLibs="true"/>
<instrumentation android:name="repackaged.android.test.InstrumentationTestRunner"
android:targetPackage="android.signature.cts.api.apache_http_legacy_27"
diff --git a/tests/signature/api-check/apache-http-legacy-current-api/AndroidManifest.xml b/tests/signature/api-check/apache-http-legacy-current-api/AndroidManifest.xml
index f0fb7d8..1497557 100644
--- a/tests/signature/api-check/apache-http-legacy-current-api/AndroidManifest.xml
+++ b/tests/signature/api-check/apache-http-legacy-current-api/AndroidManifest.xml
@@ -20,7 +20,7 @@
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.READ_PHONE_STATE"/>
- <application android:debuggable="true"/>
+ <application android:debuggable="true" android:extractNativeLibs="true"/>
<instrumentation android:name="repackaged.android.test.InstrumentationTestRunner"
android:targetPackage="android.signature.cts.api.apache_http_legacy_current"
diff --git a/tests/signature/api-check/apache-http-legacy-uses-library-api/AndroidManifest.xml b/tests/signature/api-check/apache-http-legacy-uses-library-api/AndroidManifest.xml
index f759c54..7749a8b 100644
--- a/tests/signature/api-check/apache-http-legacy-uses-library-api/AndroidManifest.xml
+++ b/tests/signature/api-check/apache-http-legacy-uses-library-api/AndroidManifest.xml
@@ -20,7 +20,7 @@
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.READ_PHONE_STATE"/>
- <application>
+ <application android:extractNativeLibs="true">
<uses-library android:name="org.apache.http.legacy"/>
</application>
diff --git a/tests/signature/api-check/current-api/AndroidManifest.xml b/tests/signature/api-check/current-api/AndroidManifest.xml
index d6f474b..163d5f2 100644
--- a/tests/signature/api-check/current-api/AndroidManifest.xml
+++ b/tests/signature/api-check/current-api/AndroidManifest.xml
@@ -20,7 +20,7 @@
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.READ_PHONE_STATE"/>
- <application android:debuggable="true"/>
+ <application android:debuggable="true" android:extractNativeLibs="true"/>
<instrumentation android:name="repackaged.android.test.InstrumentationTestRunner"
android:targetPackage="android.signature.cts.api.current"
diff --git a/tests/signature/api-check/hidden-api-blacklist-27-api/AndroidManifest.xml b/tests/signature/api-check/hidden-api-blacklist-27-api/AndroidManifest.xml
index 838112f..eca5c45 100644
--- a/tests/signature/api-check/hidden-api-blacklist-27-api/AndroidManifest.xml
+++ b/tests/signature/api-check/hidden-api-blacklist-27-api/AndroidManifest.xml
@@ -21,7 +21,7 @@
<uses-permission android:name="android.permission.READ_PHONE_STATE"/>
<uses-sdk android:targetSdkVersion="27" />
- <application/>
+ <application android:extractNativeLibs="true"/>
<instrumentation
android:name="repackaged.android.test.InstrumentationTestRunner"
diff --git a/tests/signature/api-check/hidden-api-blacklist-28/AndroidManifest.xml b/tests/signature/api-check/hidden-api-blacklist-28/AndroidManifest.xml
index 51b986e..6325522 100644
--- a/tests/signature/api-check/hidden-api-blacklist-28/AndroidManifest.xml
+++ b/tests/signature/api-check/hidden-api-blacklist-28/AndroidManifest.xml
@@ -21,7 +21,7 @@
<uses-permission android:name="android.permission.READ_PHONE_STATE"/>
<uses-sdk android:targetSdkVersion="28" />
- <application/>
+ <application android:extractNativeLibs="true"/>
<instrumentation
android:name="repackaged.android.test.InstrumentationTestRunner"
diff --git a/tests/signature/api-check/hidden-api-blacklist-current-api/AndroidManifest.xml b/tests/signature/api-check/hidden-api-blacklist-current-api/AndroidManifest.xml
index 12d0393..4d28816 100644
--- a/tests/signature/api-check/hidden-api-blacklist-current-api/AndroidManifest.xml
+++ b/tests/signature/api-check/hidden-api-blacklist-current-api/AndroidManifest.xml
@@ -20,7 +20,7 @@
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.READ_PHONE_STATE"/>
- <application/>
+ <application android:extractNativeLibs="true"/>
<instrumentation
android:name="repackaged.android.test.InstrumentationTestRunner"
diff --git a/tests/signature/api-check/hidden-api-blacklist-debug-class/AndroidManifest.xml b/tests/signature/api-check/hidden-api-blacklist-debug-class/AndroidManifest.xml
index 8586df6..7dd2824 100644
--- a/tests/signature/api-check/hidden-api-blacklist-debug-class/AndroidManifest.xml
+++ b/tests/signature/api-check/hidden-api-blacklist-debug-class/AndroidManifest.xml
@@ -20,7 +20,7 @@
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.READ_PHONE_STATE"/>
- <application/>
+ <application android:extractNativeLibs="true"/>
<instrumentation
android:name="repackaged.android.test.InstrumentationTestRunner"
diff --git a/tests/signature/api-check/hidden-api-killswitch-debug-class/AndroidManifest.xml b/tests/signature/api-check/hidden-api-killswitch-debug-class/AndroidManifest.xml
index 1bd686b..a752b2f 100644
--- a/tests/signature/api-check/hidden-api-killswitch-debug-class/AndroidManifest.xml
+++ b/tests/signature/api-check/hidden-api-killswitch-debug-class/AndroidManifest.xml
@@ -18,7 +18,7 @@
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="android.signature.cts.api.killswitch_debug_class">
- <application android:debuggable="true"/>
+ <application android:debuggable="true" android:extractNativeLibs="true"/>
<instrumentation android:name="repackaged.android.test.InstrumentationTestRunner"
android:targetPackage="android.signature.cts.api.killswitch_debug_class"
diff --git a/tests/signature/api-check/hidden-api-killswitch-whitelist/AndroidManifest.xml b/tests/signature/api-check/hidden-api-killswitch-whitelist/AndroidManifest.xml
index 5b023af..12b35da 100644
--- a/tests/signature/api-check/hidden-api-killswitch-whitelist/AndroidManifest.xml
+++ b/tests/signature/api-check/hidden-api-killswitch-whitelist/AndroidManifest.xml
@@ -18,7 +18,7 @@
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="android.signature.cts.api.killswitch_whitelist">
- <application android:debuggable="true"/>
+ <application android:debuggable="true" android:extractNativeLibs="true"/>
<instrumentation android:name="repackaged.android.test.InstrumentationTestRunner"
android:targetPackage="android.signature.cts.api.killswitch_whitelist"
diff --git a/tests/signature/api-check/hidden-api-killswitch-wildcard/AndroidManifest.xml b/tests/signature/api-check/hidden-api-killswitch-wildcard/AndroidManifest.xml
index 68f3acf..1a73cd0 100644
--- a/tests/signature/api-check/hidden-api-killswitch-wildcard/AndroidManifest.xml
+++ b/tests/signature/api-check/hidden-api-killswitch-wildcard/AndroidManifest.xml
@@ -18,7 +18,7 @@
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="android.signature.cts.api.killswitch_wildcard">
- <application android:debuggable="true"/>
+ <application android:debuggable="true" android:extractNativeLibs="true"/>
<instrumentation android:name="repackaged.android.test.InstrumentationTestRunner"
android:targetPackage="android.signature.cts.api.killswitch_wildcard"
diff --git a/tests/signature/api-check/shared-libs-api/Android.mk b/tests/signature/api-check/shared-libs-api/Android.mk
new file mode 100644
index 0000000..4de233f
--- /dev/null
+++ b/tests/signature/api-check/shared-libs-api/Android.mk
@@ -0,0 +1,47 @@
+# Copyright (C) 2019 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_JAVA_SDK_LIBRARIES := \
+ android.test.base \
+ android.test.mock \
+ android.test.runner \
+ com.android.future.usb.accessory \
+ com.android.location.provider \
+ com.android.mediadrm.signer \
+ com.android.media.remotedisplay \
+ com.android.media.tv.remoteprovider \
+ com.android.nfc_extras \
+ javax.obex \
+ org.apache.http.legacy
+
+$(foreach ver,28,\
+ $(foreach api_level,public system,\
+ $(foreach lib,$(LOCAL_JAVA_SDK_LIBRARIES),\
+ $(eval all_shared_libs_files += $(lib)-$(ver)-$(api_level).api))))
+
+
+LOCAL_PACKAGE_NAME := CtsSharedLibsApiSignatureTestCases
+
+LOCAL_SIGNATURE_API_FILES := \
+ $(all_shared_libs_files)
+
+include $(LOCAL_PATH)/../build_signature_apk.mk
+
+LOCAL_JAVA_SDK_LIBRARIES :=
+all_shared_libs_files :=
+
diff --git a/tests/signature/api-check/shared-libs-api/AndroidManifest.xml b/tests/signature/api-check/shared-libs-api/AndroidManifest.xml
new file mode 100644
index 0000000..c2bc448
--- /dev/null
+++ b/tests/signature/api-check/shared-libs-api/AndroidManifest.xml
@@ -0,0 +1,41 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ * Copyright (C) 2019 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.signature.cts.api.shared_libs">
+ <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
+ <uses-permission android:name="android.permission.READ_PHONE_STATE"/>
+
+ <application android:extractNativeLibs="true">
+ <uses-library android:name="android.test.base" android:required="false"/>
+ <uses-library android:name="android.test.mock" android:required="false"/>
+ <uses-library android:name="android.test.runner" android:required="false"/>
+ <uses-library android:name="com.android.future.usb.accessory" android:required="false"/>
+ <uses-library android:name="com.android.location.provider" android:required="false"/>
+ <uses-library android:name="com.android.mediadrm.signer" android:required="false"/>
+ <uses-library android:name="com.android.media.remotedisplay" android:required="false"/>
+ <uses-library android:name="com.android.media.tv.remoteprovider" android:required="false"/>
+ <uses-library android:name="com.android.nfc_extras" android:required="false"/>
+ <uses-library android:name="javax.obex" android:required="false"/>
+ <uses-library android:name="org.apache.http.legacy" android:required="false"/>
+ </application>
+
+ <instrumentation android:name="repackaged.android.test.InstrumentationTestRunner"
+ android:targetPackage="android.signature.cts.api.shared_libs"
+ android:label="Shared Libraries API Signature Muti Libs Test"/>
+
+</manifest>
diff --git a/tests/signature/api-check/shared-libs-api/AndroidTest.xml b/tests/signature/api-check/shared-libs-api/AndroidTest.xml
new file mode 100644
index 0000000..2e42061
--- /dev/null
+++ b/tests/signature/api-check/shared-libs-api/AndroidTest.xml
@@ -0,0 +1,60 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2019 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 Shared Libraries API Signature test cases">
+ <option name="test-suite-tag" value="cts" />
+ <option name="config-descriptor:metadata" key="component" value="systems" />
+ <target_preparer class="com.android.tradefed.targetprep.RunCommandTargetPreparer">
+ <option name="run-command" value="mkdir -p /data/local/tmp/signature-test" />
+ <option name="teardown-command" value="rm -rf /data/local/tmp/signature-test" />
+ </target_preparer>
+ <target_preparer class="com.android.compatibility.common.tradefed.targetprep.FilePusher">
+ <option name="push" value="android.test.base-28-public.api->/data/local/tmp/signature-test/android.test.base-28-public.api" />
+ <option name="push" value="android.test.mock-28-public.api->/data/local/tmp/signature-test/android.test.mock-28-public.api" />
+ <option name="push" value="android.test.runner-28-public.api->/data/local/tmp/signature-test/android.test.runner-28-public.api" />
+ <option name="push" value="com.android.future.usb.accessory-28-public.api->/data/local/tmp/signature-test/com.android.future.usb.accessory-28-public.api" />
+ <option name="push" value="com.android.location.provider-28-public.api->/data/local/tmp/signature-test/com.android.location.provider-28-public.api" />
+ <option name="push" value="com.android.mediadrm.signer-28-public.api->/data/local/tmp/signature-test/com.android.mediadrm.signer-28-public.api" />
+ <option name="push" value="com.android.media.remotedisplay-28-public.api->/data/local/tmp/signature-test/com.android.media.remotedisplay-28-public.api" />
+ <option name="push" value="com.android.media.tv.remoteprovider-28-public.api->/data/local/tmp/signature-test/com.android.media.tv.remoteprovider-28-public.api" />
+ <option name="push" value="com.android.nfc_extras-28-public.api->/data/local/tmp/signature-test/com.android.nfc_extras-28-public.api" />
+ <option name="push" value="javax.obex-28-public.api->/data/local/tmp/signature-test/javax.obex-28-public.api" />
+ <option name="push" value="org.apache.http.legacy-28-public.api->/data/local/tmp/signature-test/org.apache.http.legacy-28-public.api" />
+ <option name="push" value="android.test.base-28-system.api->/data/local/tmp/signature-test/android.test.base-28-system.api" />
+ <option name="push" value="android.test.mock-28-system.api->/data/local/tmp/signature-test/android.test.mock-28-system.api" />
+ <option name="push" value="android.test.runner-28-system.api->/data/local/tmp/signature-test/android.test.runner-28-system.api" />
+ <option name="push" value="com.android.future.usb.accessory-28-system.api->/data/local/tmp/signature-test/com.android.future.usb.accessory-28-system.api" />
+ <option name="push" value="com.android.location.provider-28-system.api->/data/local/tmp/signature-test/com.android.location.provider-28-system.api" />
+ <option name="push" value="com.android.mediadrm.signer-28-system.api->/data/local/tmp/signature-test/com.android.mediadrm.signer-28-system.api" />
+ <option name="push" value="com.android.media.remotedisplay-28-system.api->/data/local/tmp/signature-test/com.android.media.remotedisplay-28-system.api" />
+ <option name="push" value="com.android.media.tv.remoteprovider-28-system.api->/data/local/tmp/signature-test/com.android.media.tv.remoteprovider-28-system.api" />
+ <option name="push" value="com.android.nfc_extras-28-system.api->/data/local/tmp/signature-test/com.android.nfc_extras-28-system.api" />
+ <option name="push" value="javax.obex-28-system.api->/data/local/tmp/signature-test/javax.obex-28-system.api" />
+ <option name="push" value="org.apache.http.legacy-28-system.api->/data/local/tmp/signature-test/org.apache.http.legacy-28-system.api" />
+ </target_preparer>
+ <target_preparer class="com.android.tradefed.targetprep.suite.SuiteApkInstaller">
+ <option name="cleanup-apks" value="true" />
+ <option name="test-file-name" value="CtsSharedLibsApiSignatureTestCases.apk" />
+ </target_preparer>
+ <test class="com.android.tradefed.testtype.AndroidJUnitTest" >
+ <option name="package" value="android.signature.cts.api.shared_libs" />
+ <option name="runner" value="repackaged.android.test.InstrumentationTestRunner" />
+ <option name="class" value="android.signature.cts.api.SignatureMultiLibsTest" />
+ <option name="instrumentation-arg" key="library-names" value="android.test.base,android.test.mock,android.test.runner,com.android.future.usb.accessory,com.android.location.provider,com.android.mediadrm.signer,com.android.media.remotedisplay,com.android.media.tv.remoteprovider,com.android.nfc_extras,javax.obex,org.apache.http.legacy" />
+ <option name="instrumentation-arg" key="versions" value="28" />
+ <option name="instrumentation-arg" key="api_levels" value="public,system" />
+ <option name="runtime-hint" value="30s" />
+ </test>
+</configuration>
diff --git a/tests/signature/api-check/src/java/android/signature/cts/api/SignatureMultiLibsTest.java b/tests/signature/api-check/src/java/android/signature/cts/api/SignatureMultiLibsTest.java
new file mode 100644
index 0000000..772155a
--- /dev/null
+++ b/tests/signature/api-check/src/java/android/signature/cts/api/SignatureMultiLibsTest.java
@@ -0,0 +1,76 @@
+/*
+ * Copyright (C) 2019 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.signature.cts.api;
+
+import android.os.Bundle;
+import java.io.IOException;
+import java.util.Arrays;
+import java.util.ArrayList;
+import java.util.stream.Stream;
+import static com.android.compatibility.common.util.SystemUtil.runShellCommand;
+
+/**
+ * Performs the signature check via a JUnit test.
+ */
+public class SignatureMultiLibsTest extends SignatureTest {
+
+ private static final String TAG = SignatureMultiLibsTest.class.getSimpleName();
+
+ private String[] libraryNames;
+ private String[] versions;
+ private String[] api_levels;
+
+ @Override
+ protected void initializeFromArgs(Bundle instrumentationArgs) throws Exception {
+ libraryNames = getCommaSeparatedList(instrumentationArgs, "library-names");
+ versions = getCommaSeparatedList(instrumentationArgs, "versions");
+ api_levels = getCommaSeparatedList(instrumentationArgs, "api_levels");
+ super.initializeFromArgs(instrumentationArgs);
+ }
+
+ /**
+ * Tests that the device's API matches the expected set defined in xml.
+ * <p/>
+ * Will check the entire API, and then report the complete list of failures
+ */
+ @Override
+ public void testSignature() {
+ Stream<String> packageListLibraries = getLibraries();
+ ArrayList<String> expected = new ArrayList<>();
+ packageListLibraries.forEach(lib -> {
+ if (Arrays.asList(libraryNames).indexOf(lib) >= 0) {
+ for (String ver : versions) {
+ for (String api_level : api_levels) {
+ expected.add(lib + "-" + ver + "-" + api_level + ".api");
+ }
+ }
+ }
+ });
+ expectedApiFiles = expected.toArray(new String[expected.size()]);
+
+ super.testSignature();
+ }
+
+ private Stream<String> getLibraries() {
+ try {
+ String result = runShellCommand(getInstrumentation(), "cmd package list libraries");
+ return Arrays.stream(result.split("\n")).map(line -> line.split(":")[1]);
+ } catch (IOException e) {
+ throw new RuntimeException(e);
+ }
+ }
+}
diff --git a/tests/signature/api-check/src/java/android/signature/cts/api/SignatureTest.java b/tests/signature/api-check/src/java/android/signature/cts/api/SignatureTest.java
index fadf748..7861df7 100644
--- a/tests/signature/api-check/src/java/android/signature/cts/api/SignatureTest.java
+++ b/tests/signature/api-check/src/java/android/signature/cts/api/SignatureTest.java
@@ -38,8 +38,8 @@
private static final String TAG = SignatureTest.class.getSimpleName();
- private String[] expectedApiFiles;
- private String[] baseApiFiles;
+ protected String[] expectedApiFiles;
+ protected String[] baseApiFiles;
private String[] unexpectedApiFiles;
@Override
diff --git a/tests/signature/api-check/system-annotation/AndroidManifest.xml b/tests/signature/api-check/system-annotation/AndroidManifest.xml
index 74a9b49..fb72cb3 100644
--- a/tests/signature/api-check/system-annotation/AndroidManifest.xml
+++ b/tests/signature/api-check/system-annotation/AndroidManifest.xml
@@ -22,7 +22,7 @@
<uses-sdk android:targetSdkVersion="28" />
- <application android:debuggable="true"/>
+ <application android:debuggable="true" android:extractNativeLibs="true"/>
<instrumentation android:name="repackaged.android.test.InstrumentationTestRunner"
android:targetPackage="android.signature.cts.api.system_annotation"
diff --git a/tests/signature/api-check/system-api/AndroidManifest.xml b/tests/signature/api-check/system-api/AndroidManifest.xml
index 1f7bed8..9df3ddd 100644
--- a/tests/signature/api-check/system-api/AndroidManifest.xml
+++ b/tests/signature/api-check/system-api/AndroidManifest.xml
@@ -20,7 +20,7 @@
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.READ_PHONE_STATE"/>
- <application/>
+ <application android:extractNativeLibs="true"/>
<instrumentation android:name="repackaged.android.test.InstrumentationTestRunner"
android:targetPackage="android.signature.cts.api.system"
diff --git a/tests/signature/api/Android.mk b/tests/signature/api/Android.mk
index 5a95155..2162eec 100644
--- a/tests/signature/api/Android.mk
+++ b/tests/signature/api/Android.mk
@@ -50,6 +50,27 @@
)\
)
+LOCAL_JAVA_SDK_LIBRARIES := \
+ android.test.base \
+ android.test.mock \
+ android.test.runner \
+ com.android.future.usb.accessory \
+ com.android.location.provider \
+ com.android.mediadrm.signer \
+ com.android.media.remotedisplay \
+ com.android.media.tv.remoteprovider \
+ com.android.nfc_extras \
+ javax.obex \
+ org.apache.http.legacy
+
+$(foreach ver,28,\
+ $(foreach api_level,public system,\
+ $(foreach lib,$(LOCAL_JAVA_SDK_LIBRARIES),\
+ $(eval $(call build_xml_api_file,$(lib)-$(ver)-$(api_level).api,prebuilts/sdk/$(ver)/$(api_level)/api/$(lib).txt)))))
+
+LOCAL_JAVA_SDK_LIBRARIES :=
+
+
# current apache-http-legacy minus current api, in text format.
# =============================================================
# Removes any classes from the org.apache.http.legacy API description that are
diff --git a/tests/signature/runSignatureTests.sh b/tests/signature/runSignatureTests.sh
index fead7c7..046300f 100755
--- a/tests/signature/runSignatureTests.sh
+++ b/tests/signature/runSignatureTests.sh
@@ -33,6 +33,8 @@
CtsHiddenApiKillswitchWildcardTestCases
CtsHiddenApiKillswitchWhitelistTestCases
CtsHiddenApiKillswitchDebugClassTestCases
+
+CtsSharedLibsApiSignatureTestCases
"
else
PACKAGES=${1+"$@"}
diff --git a/tests/tests/app.usage/Android.mk b/tests/tests/app.usage/Android.mk
index 9beeeaa..2f1513be 100644
--- a/tests/tests/app.usage/Android.mk
+++ b/tests/tests/app.usage/Android.mk
@@ -41,3 +41,4 @@
LOCAL_COMPATIBILITY_SUITE := cts vts general-tests cts_instant
include $(BUILD_CTS_PACKAGE)
+include $(call all-makefiles-under,$(LOCAL_PATH))
diff --git a/tests/tests/app.usage/AndroidManifest.xml b/tests/tests/app.usage/AndroidManifest.xml
index b8d60bf..3d650fc 100644
--- a/tests/tests/app.usage/AndroidManifest.xml
+++ b/tests/tests/app.usage/AndroidManifest.xml
@@ -50,6 +50,7 @@
<activity android:name=".ActivityTransitionActivity2"
android:taskAffinity="android.app.usage.cts.other_task"/>
<activity android:name=".FragmentTestActivity" />
+ <activity android:name=".TaskRootActivity" />
<service android:name=".TestService" />
</application>
diff --git a/tests/tests/app.usage/AndroidTest.xml b/tests/tests/app.usage/AndroidTest.xml
index 8fba812..f611fbe 100644
--- a/tests/tests/app.usage/AndroidTest.xml
+++ b/tests/tests/app.usage/AndroidTest.xml
@@ -22,6 +22,7 @@
<target_preparer class="com.android.tradefed.targetprep.suite.SuiteApkInstaller">
<option name="cleanup-apks" value="true" />
<option name="test-file-name" value="CtsUsageStatsTestCases.apk" />
+ <option name="test-file-name" value="CtsUsageStatsTestApp1.apk" />
</target_preparer>
<test class="com.android.tradefed.testtype.AndroidJUnitTest" >
<option name="package" value="android.app.usage.cts" />
diff --git a/tests/tests/text/Android.mk b/tests/tests/app.usage/TestApp1/Android.mk
similarity index 76%
rename from tests/tests/text/Android.mk
rename to tests/tests/app.usage/TestApp1/Android.mk
index ffa5f9eb..76d2f47 100644
--- a/tests/tests/text/Android.mk
+++ b/tests/tests/app.usage/TestApp1/Android.mk
@@ -1,4 +1,4 @@
-# Copyright (C) 2008 The Android Open Source Project
+# Copyright (C) 2019 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.
@@ -16,29 +16,28 @@
include $(CLEAR_VARS)
+LOCAL_PACKAGE_NAME := CtsUsageStatsTestApp1
+LOCAL_PRIVATE_PLATFORM_APIS := true
+
# don't include this package in any target
LOCAL_MODULE_TAGS := optional
+
# and when built explicitly put it in the data partition
LOCAL_MODULE_PATH := $(TARGET_OUT_DATA_APPS)
-LOCAL_JAVA_LIBRARIES := android.test.runner.stubs android.test.base.stubs
-
-LOCAL_STATIC_JAVA_LIBRARIES += \
- compatibility-device-util \
- ctsdeviceutillegacy \
- ctstestrunner \
+LOCAL_STATIC_JAVA_LIBRARIES := \
android-support-test \
- mockito-target-minus-junit4 \
+ compatibility-device-util \
+ ctstestrunner \
+ cts-amwm-util \
+ junit \
ub-uiautomator
+LOCAL_JAVA_LIBRARIES := android.test.base.stubs android.test.runner.stubs
+
LOCAL_SRC_FILES := $(call all-java-files-under, src)
-LOCAL_PACKAGE_NAME := CtsTextTestCases
-
# Tag this module as a cts test artifact
LOCAL_COMPATIBILITY_SUITE := cts vts general-tests cts_instant
-# Enforce public / test api only
-LOCAL_SDK_VERSION := test_current
-
include $(BUILD_CTS_PACKAGE)
diff --git a/tests/tests/app.usage/TestApp1/AndroidManifest.xml b/tests/tests/app.usage/TestApp1/AndroidManifest.xml
new file mode 100644
index 0000000..d4306e5
--- /dev/null
+++ b/tests/tests/app.usage/TestApp1/AndroidManifest.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ * Copyright (C) 2019 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.app.usage.cts.test1">
+
+ <application>
+ <activity android:name=".SomeActivity"
+ android:exported="true"
+ />
+ </application>
+</manifest>
diff --git a/tests/tests/app.usage/TestApp1/src/android/app/usage/cts/test1/SomeActivity.java b/tests/tests/app.usage/TestApp1/src/android/app/usage/cts/test1/SomeActivity.java
new file mode 100644
index 0000000..9d2ca8e
--- /dev/null
+++ b/tests/tests/app.usage/TestApp1/src/android/app/usage/cts/test1/SomeActivity.java
@@ -0,0 +1,29 @@
+/**
+ * Copyright (C) 2019 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.usage.cts.test1;
+
+import android.annotation.Nullable;
+import android.app.Activity;
+import android.os.Bundle;
+import android.view.WindowManager;
+
+public final class SomeActivity extends Activity {
+ @Override
+ protected void onCreate(@Nullable Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
+ }
+}
diff --git a/tests/tests/app.usage/src/android/app/usage/cts/TaskRootActivity.java b/tests/tests/app.usage/src/android/app/usage/cts/TaskRootActivity.java
new file mode 100644
index 0000000..e0f7fc6
--- /dev/null
+++ b/tests/tests/app.usage/src/android/app/usage/cts/TaskRootActivity.java
@@ -0,0 +1,50 @@
+/**
+ * Copyright (C) 2019 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.usage.cts;
+
+import android.annotation.Nullable;
+import android.app.Activity;
+import android.content.Context;
+import android.content.Intent;
+import android.os.Bundle;
+import android.support.test.InstrumentationRegistry;
+import android.support.test.uiautomator.By;
+import android.support.test.uiautomator.UiDevice;
+import android.support.test.uiautomator.Until;
+import android.view.WindowManager;
+
+public class TaskRootActivity extends Activity {
+ public static final String TEST_APP_PKG = "android.app.usage.cts.test1";
+ public static final String TEST_APP_CLASS = "android.app.usage.cts.test1.SomeActivity";
+ private static final long TIMEOUT = 5000;
+ private UiDevice mUiDevice;
+
+ @Override
+ protected void onCreate(@Nullable Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ mUiDevice = UiDevice.getInstance(InstrumentationRegistry.getInstrumentation());
+ getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
+ }
+
+ @Override
+ protected void onResume() {
+ super.onResume();
+ Intent intent = new Intent();
+ intent.setClassName(TEST_APP_PKG, TEST_APP_CLASS);
+ startActivity(intent);
+ mUiDevice.wait(Until.hasObject(By.clazz(TEST_APP_PKG, TEST_APP_CLASS)), TIMEOUT);
+ }
+}
diff --git a/tests/tests/app.usage/src/android/app/usage/cts/UsageStatsTest.java b/tests/tests/app.usage/src/android/app/usage/cts/UsageStatsTest.java
index 44dfc5a..99fbff7 100644
--- a/tests/tests/app.usage/src/android/app/usage/cts/UsageStatsTest.java
+++ b/tests/tests/app.usage/src/android/app/usage/cts/UsageStatsTest.java
@@ -54,11 +54,13 @@
import com.android.compatibility.common.util.AppStandbyUtils;
+import org.junit.After;
import org.junit.Before;
import org.junit.Ignore;
import org.junit.Test;
import org.junit.runner.RunWith;
+import java.io.IOException;
import java.text.MessageFormat;
import java.util.ArrayList;
import java.util.Arrays;
@@ -88,6 +90,15 @@
private static final String APPOPS_SET_SHELL_COMMAND = "appops set {0} " +
AppOpsManager.OPSTR_GET_USAGE_STATS + " {1}";
+ private static final String USAGE_SOURCE_GET_SHELL_COMMAND = "settings get global " +
+ Settings.Global.APP_TIME_LIMIT_USAGE_SOURCE;
+
+ private static final String USAGE_SOURCE_SET_SHELL_COMMAND = "settings put global " +
+ Settings.Global.APP_TIME_LIMIT_USAGE_SOURCE + " {0}";
+
+ private static final String USAGE_SOURCE_DELETE_SHELL_COMMAND = "settings delete global " +
+ Settings.Global.APP_TIME_LIMIT_USAGE_SOURCE;
+
private static final long TIMEOUT = TimeUnit.SECONDS.toMillis(5);
private static final long MINUTE = TimeUnit.MINUTES.toMillis(1);
private static final long DAY = TimeUnit.DAYS.toMillis(1);
@@ -101,6 +112,7 @@
private UiDevice mUiDevice;
private UsageStatsManager mUsageStatsManager;
private String mTargetPackage;
+ private String mCachedUsageSourceSetting;
@Before
public void setUp() throws Exception {
@@ -110,6 +122,16 @@
mTargetPackage = InstrumentationRegistry.getContext().getPackageName();
assumeTrue("App Standby not enabled on device", AppStandbyUtils.isAppStandbyEnabled());
setAppOpsMode("allow");
+ mCachedUsageSourceSetting = getUsageSourceSetting();
+ }
+
+
+ @After
+ public void cleanUp() throws Exception {
+ if (!mCachedUsageSourceSetting.equals(getUsageSourceSetting())) {
+ setUsageSourceSetting(mCachedUsageSourceSetting);
+ mUsageStatsManager.forceUsageSourceSettingRead();
+ }
}
private static void assertLessThan(long left, long right) {
@@ -126,6 +148,22 @@
mUiDevice.executeShellCommand(command);
}
+
+ private String getUsageSourceSetting() throws Exception {
+ return mUiDevice.executeShellCommand(USAGE_SOURCE_GET_SHELL_COMMAND);
+ }
+
+ private void setUsageSourceSetting(String usageSource) throws Exception {
+ if (usageSource.equals("null")) {
+ mUiDevice.executeShellCommand(USAGE_SOURCE_DELETE_SHELL_COMMAND);
+ } else {
+ final String command = MessageFormat.format(USAGE_SOURCE_SET_SHELL_COMMAND,
+ usageSource);
+ mUiDevice.executeShellCommand(command);
+ }
+ mUsageStatsManager.forceUsageSourceSettingRead();
+ }
+
private void launchSubActivity(Class<? extends Activity> clazz) {
final Context context = InstrumentationRegistry.getInstrumentation().getContext();
final Intent intent = new Intent(Intent.ACTION_MAIN);
@@ -869,20 +907,57 @@
}
@Test
- public void testObserveUsagePermission() {
+ public void testObserveUsagePermissionForRegisterObserver() {
+ final int observerId = 0;
+ final String[] packages = new String[] {"com.android.settings"};
+
try {
- mUsageStatsManager.registerAppUsageObserver(0, new String[] {"com.android.settings"},
+ mUsageStatsManager.registerAppUsageObserver(observerId, packages,
1, java.util.concurrent.TimeUnit.HOURS, null);
- fail("Should throw SecurityException");
+ fail("Expected SecurityException for an app not holding OBSERVE_APP_USAGE permission.");
} catch (SecurityException e) {
// Exception expected
}
try {
- mUsageStatsManager.registerUsageSessionObserver(0, new String[]{"com.android.settings"},
+ mUsageStatsManager.registerUsageSessionObserver(observerId, packages,
1, java.util.concurrent.TimeUnit.HOURS, 10,
java.util.concurrent.TimeUnit.SECONDS, null, null);
- fail("Should throw SecurityException");
+ fail("Expected SecurityException for an app not holding OBSERVE_APP_USAGE permission.");
+ } catch (SecurityException e) {
+ // Exception expected
+ }
+
+ try {
+ mUsageStatsManager.registerAppUsageLimitObserver(observerId, packages,
+ 1, java.util.concurrent.TimeUnit.HOURS, null);
+ fail("Expected SecurityException for an app not holding OBSERVE_APP_USAGE permission.");
+ } catch (SecurityException e) {
+ // Exception expected
+ }
+ }
+
+ @Test
+ public void testObserveUsagePermissionForUnregisterObserver() {
+ final int observerId = 0;
+
+ try {
+ mUsageStatsManager.unregisterAppUsageObserver(observerId);
+ fail("Expected SecurityException for an app not holding OBSERVE_APP_USAGE permission.");
+ } catch (SecurityException e) {
+ // Exception expected
+ }
+
+ try {
+ mUsageStatsManager.unregisterUsageSessionObserver(observerId);
+ fail("Expected SecurityException for an app not holding OBSERVE_APP_USAGE permission.");
+ } catch (SecurityException e) {
+ // Exception expected
+ }
+
+ try {
+ mUsageStatsManager.unregisterAppUsageLimitObserver(observerId);
+ fail("Expected SecurityException for an app not holding OBSERVE_APP_USAGE permission.");
} catch (SecurityException e) {
// Exception expected
}
@@ -927,6 +1002,68 @@
assertLessThan(startIdx, stopIdx);
}
+ @AppModeFull // No usage events access in instant apps
+ @Test
+ public void testTaskRootEventField() throws Exception {
+ final KeyguardManager kmgr = InstrumentationRegistry.getInstrumentation()
+ .getContext().getSystemService(KeyguardManager.class);
+ mUiDevice.wakeUp();
+ // Also want to start out with the keyguard dismissed.
+ if (kmgr.isKeyguardLocked()) {
+ final long startTime = getEvents(KEYGUARD_EVENTS, 0, null) + 1;
+ mUiDevice.executeShellCommand("wm dismiss-keyguard");
+ ArrayList<Event> events = waitForEventCount(KEYGUARD_EVENTS, startTime, 1);
+ assertEquals(Event.KEYGUARD_HIDDEN, events.get(0).getEventType());
+ SystemClock.sleep(500);
+ }
+
+ final long startTime = System.currentTimeMillis();
+ launchSubActivity(TaskRootActivity.class);
+ final long endTime = System.currentTimeMillis();
+ UsageEvents events = mUsageStatsManager.queryEvents(startTime, endTime);
+
+ while (events.hasNextEvent()) {
+ UsageEvents.Event event = new UsageEvents.Event();
+ assertTrue(events.getNextEvent(event));
+ if (TaskRootActivity.TEST_APP_PKG.equals(event.getPackageName())
+ && TaskRootActivity.TEST_APP_CLASS.equals(event.getClassName())) {
+ assertEquals(mTargetPackage, event.getTaskRootPackageName());
+ assertEquals(TaskRootActivity.class.getCanonicalName(),
+ event.getTaskRootClassName());
+ return;
+ }
+ }
+ fail("Did not find nested activity name in usage events");
+ }
+
+ @Test
+ public void testUsageSourceAttribution() throws Exception {
+ final KeyguardManager kmgr = InstrumentationRegistry.getInstrumentation()
+ .getContext().getSystemService(KeyguardManager.class);
+ mUiDevice.wakeUp();
+ // Also want to start out with the keyguard dismissed.
+ if (kmgr.isKeyguardLocked()) {
+ final long startTime = getEvents(KEYGUARD_EVENTS, 0, null) + 1;
+ mUiDevice.executeShellCommand("wm dismiss-keyguard");
+ ArrayList<Event> events = waitForEventCount(KEYGUARD_EVENTS, startTime, 1);
+ assertEquals(Event.KEYGUARD_HIDDEN, events.get(0).getEventType());
+ SystemClock.sleep(500);
+ }
+
+ setUsageSourceSetting(Integer.toString(mUsageStatsManager.USAGE_SOURCE_CURRENT_ACTIVITY));
+ launchSubActivity(TaskRootActivity.class);
+ // Usage should be attributed to the test app package
+ assertAppOrTokenUsed(TaskRootActivity.TEST_APP_PKG, true);
+
+ mUiDevice.pressHome();
+
+ setUsageSourceSetting(Integer.toString(
+ mUsageStatsManager.USAGE_SOURCE_TASK_ROOT_ACTIVITY));
+ launchSubActivity(TaskRootActivity.class);
+ // Usage should be attributed to this package
+ assertAppOrTokenUsed(mTargetPackage, true);
+ }
+
private void pressWakeUp() {
mUiDevice.pressKeyCode(KeyEvent.KEYCODE_WAKEUP);
}
@@ -934,4 +1071,30 @@
private void pressSleep() {
mUiDevice.pressKeyCode(KeyEvent.KEYCODE_SLEEP);
}
+
+ /**
+ * Assert on an app or token's usage state.
+ * @param entity name of the app or token
+ * @param expected expected usage state, true for in use, false for not in use
+ */
+ private void assertAppOrTokenUsed(String entity, boolean expected) throws IOException {
+ final String activeUsages =
+ mUiDevice.executeShellCommand("dumpsys usagestats apptimelimit actives");
+ final String[] actives = activeUsages.split("\n");
+ boolean found = false;
+
+ for (String active : actives) {
+ if (active.equals(entity)) {
+ found = true;
+ break;
+ }
+ }
+ if (expected) {
+ assertTrue(entity + " not found in list of active activities and tokens\n"
+ + activeUsages, found);
+ } else {
+ assertFalse(entity + " found in list of active activities and tokens\n"
+ + activeUsages, found);
+ }
+ }
}
diff --git a/tests/tests/appop/src/android/app/appops/cts/HistoricalAppopsTest.kt b/tests/tests/appop/src/android/app/appops/cts/HistoricalAppopsTest.kt
index 9ab06d5..1a749b0 100644
--- a/tests/tests/appop/src/android/app/appops/cts/HistoricalAppopsTest.kt
+++ b/tests/tests/appop/src/android/app/appops/cts/HistoricalAppopsTest.kt
@@ -224,7 +224,7 @@
if (d > 0) {
val previousIntervalDuration = computeIntervalDurationMillis(d - 1)
val currentIntervalDuration = computeIntervalDurationMillis(d)
- val sleepDurationMillis = (previousIntervalDuration / 2
+ val sleepDurationMillis = (previousIntervalDuration
+ currentIntervalDuration / 2)
SystemClock.sleep(sleepDurationMillis)
}
@@ -318,7 +318,8 @@
try {
lock.lock()
appOpsManager.getHistoricalOps(uid, packageName, opNames,
- beginTimeMillis, endTimeMillis, null, { ops ->
+ beginTimeMillis, endTimeMillis, getContext().getMainExecutor(),
+ Consumer { ops ->
array[0] = ops
try {
lock.lock()
diff --git a/tests/tests/assist/common/src/android/assist/common/Utils.java b/tests/tests/assist/common/src/android/assist/common/Utils.java
index a41b507..937d8ce 100755
--- a/tests/tests/assist/common/src/android/assist/common/Utils.java
+++ b/tests/tests/assist/common/src/android/assist/common/Utils.java
@@ -16,8 +16,11 @@
package android.assist.common;
import android.content.ComponentName;
+import android.content.Intent;
import android.os.Bundle;
import android.os.LocaleList;
+import android.os.Process;
+import android.util.Log;
import org.json.JSONObject;
@@ -25,6 +28,7 @@
import java.util.Locale;
public class Utils {
+ private static final String TAG = Utils.class.getSimpleName();
public static final String TESTCASE_TYPE = "testcase_type";
public static final String TESTINFO = "testinfo";
public static final String ACTION_PREFIX = "android.intent.action.";
@@ -116,6 +120,8 @@
private static Bundle EXTRA_ASSIST_BUNDLE;
private static String STRUCTURED_JSON;
+ private static String MY_UID_EXTRA = "my_uid";
+
public static final String getStructuredJSON() throws Exception {
if (STRUCTURED_JSON == null) {
STRUCTURED_JSON = new JSONObject()
@@ -139,15 +145,24 @@
public static final Bundle getExtraAssistBundle() {
if (EXTRA_ASSIST_BUNDLE == null) {
EXTRA_ASSIST_BUNDLE = new Bundle();
- addExtraAssistDataToBundle(EXTRA_ASSIST_BUNDLE);
+ addExtraAssistDataToBundle(EXTRA_ASSIST_BUNDLE, /* addMyUid= */ false);
}
return EXTRA_ASSIST_BUNDLE;
}
public static void addExtraAssistDataToBundle(Bundle data) {
+ addExtraAssistDataToBundle(data, /* addMyUid= */ true);
+
+ }
+
+ private static void addExtraAssistDataToBundle(Bundle data, boolean addMyUid) {
data.putString("hello", "there");
data.putBoolean("isthis_true_or_false", true);
data.putInt("number", 123);
+ if (addMyUid) {
+ Log.i(TAG, "adding " + MY_UID_EXTRA + "=" + Process.myUid());
+ data.putInt(MY_UID_EXTRA, Process.myUid());
+ }
}
/** The shim activity that starts the service associated with each test. */
@@ -248,4 +263,8 @@
testinfo.getStringArrayList(testinfo.getString(Utils.TESTCASE_TYPE))
.add(TEST_ERROR + " " + msg);
}
+
+ public static int getExpectedUid(Bundle extras) {
+ return extras.getInt(MY_UID_EXTRA);
+ }
}
diff --git a/tests/tests/assist/src/android/assist/cts/ExtraAssistDataTest.java b/tests/tests/assist/src/android/assist/cts/ExtraAssistDataTest.java
index 1154179..5717fcc 100644
--- a/tests/tests/assist/src/android/assist/cts/ExtraAssistDataTest.java
+++ b/tests/tests/assist/src/android/assist/cts/ExtraAssistDataTest.java
@@ -21,6 +21,7 @@
import android.content.Intent;
import android.content.IntentFilter;
import android.os.Bundle;
+import android.os.Process;
import android.util.Log;
import java.util.concurrent.CountDownLatch;
@@ -80,10 +81,9 @@
Log.i(TAG, "assist bundle is: " + Utils.toBundleString(mAssistBundle));
- // tests that the assist content's structured data is the expected
+ // first tests that the assist content's structured data is the expected
assertEquals("AssistContent structured data did not match data in onProvideAssistContent",
Utils.getStructuredJSON(), mAssistContent.getStructuredData());
- // tests the assist data. EXTRA_ASSIST_CONTEXT is what's expected.
Bundle extraExpectedBundle = Utils.getExtraAssistBundle();
Bundle extraAssistBundle = mAssistBundle.getBundle(Intent.EXTRA_ASSIST_CONTEXT);
for (String key : extraExpectedBundle.keySet()) {
@@ -92,6 +92,12 @@
assertEquals("Extra assist context bundle values do not match for key: " + key,
extraExpectedBundle.get(key), extraAssistBundle.get(key));
}
+
+ // then test the EXTRA_ASSIST_UID
+ int expectedUid = Utils.getExpectedUid(extraAssistBundle);
+ int actualUid = mAssistBundle.getInt(Intent.EXTRA_ASSIST_UID);
+ assertEquals("Wrong value for EXTRA_ASSIST_UID", expectedUid, actualUid);
+
}
private void waitForOnResume() throws Exception {
diff --git a/tests/tests/assist/testapp/src/android/assist/testapp/ExtraAssistDataActivity.java b/tests/tests/assist/testapp/src/android/assist/testapp/ExtraAssistDataActivity.java
index 0cb8801..4b4c909 100644
--- a/tests/tests/assist/testapp/src/android/assist/testapp/ExtraAssistDataActivity.java
+++ b/tests/tests/assist/testapp/src/android/assist/testapp/ExtraAssistDataActivity.java
@@ -29,10 +29,6 @@
*/
public class ExtraAssistDataActivity extends Activity {
private static final String TAG = "ExtraAssistDataActivity";
- @Override
- public void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- }
@Override
public void onProvideAssistData(Bundle data) {
diff --git a/tests/tests/binder_ndk/libbinder_ndk_test/test_native_aidl_client.cpp b/tests/tests/binder_ndk/libbinder_ndk_test/test_native_aidl_client.cpp
index 5a24284..9a4e3dd 100644
--- a/tests/tests/binder_ndk/libbinder_ndk_test/test_native_aidl_client.cpp
+++ b/tests/tests/binder_ndk/libbinder_ndk_test/test_native_aidl_client.cpp
@@ -35,6 +35,15 @@
using ::ndk::SharedRefBase;
using ::ndk::SpAIBinder;
+// AIDL tests which are independent of the service
+class NdkBinderTest_AidlLocal : public NdkBinderTest {};
+
+TEST_F(NdkBinderTest_AidlLocal, FromBinder) {
+ std::shared_ptr<MyTest> test = SharedRefBase::make<MyTest>();
+ SpAIBinder binder = test->asBinder();
+ EXPECT_EQ(test, ITest::fromBinder(binder));
+}
+
struct Params {
std::shared_ptr<ITest> iface;
bool shouldBeRemote;
@@ -45,6 +54,8 @@
#define iface GetParam().iface
#define shouldBeRemote GetParam().shouldBeRemote
+// AIDL tests which run on each type of service (local C++, local Java, remote C++, remote Java,
+// etc..)
class NdkBinderTest_Aidl : public NdkBinderTest,
public ::testing::WithParamInterface<Params> {};
@@ -553,6 +564,9 @@
std::shared_ptr<ITest> getLocalService() {
// BpTest -> AIBinder -> test
+ //
+ // Warning: for testing purposes only. This parcels things within the same process for testing
+ // purposes. In normal usage, this should just return SharedRefBase::make<MyTest> directly.
std::shared_ptr<MyTest> test = SharedRefBase::make<MyTest>();
return BpTest::associate(test->asBinder());
}
diff --git a/tests/tests/bionic/Android.build.copy.libs.mk b/tests/tests/bionic/Android.build.copy.libs.mk
index a1bd707..f346b8a 100644
--- a/tests/tests/bionic/Android.build.copy.libs.mk
+++ b/tests/tests/bionic/Android.build.copy.libs.mk
@@ -16,6 +16,7 @@
dt_runpath_b_c_x/libtest_dt_runpath_b.so \
dt_runpath_b_c_x/libtest_dt_runpath_c.so \
dt_runpath_b_c_x/libtest_dt_runpath_x.so \
+ elftls_dlopen_ie_error_helper/elftls_dlopen_ie_error_helper \
exec_linker_helper/exec_linker_helper \
exec_linker_helper_lib.so \
inaccessible_libs/libtestshared.so \
@@ -74,6 +75,9 @@
libtest_dlsym_from_this_grandchild.so \
libtest_dlsym_weak_func.so \
libtest_dt_runpath_d.so \
+ libtest_elftls_shared_var.so \
+ libtest_elftls_shared_var_ie.so \
+ libtest_elftls_tprel.so \
libtest_empty.so \
libtest_indirect_thread_local_dtor.so \
libtest_init_fini_order_child.so \
diff --git a/tests/tests/bionic/Android.mk b/tests/tests/bionic/Android.mk
index 301a384..ec21b5c 100644
--- a/tests/tests/bionic/Android.mk
+++ b/tests/tests/bionic/Android.mk
@@ -17,15 +17,18 @@
libdl_preempt_test_1 \
libdl_preempt_test_2 \
libdl_test_df_1_global \
+ libtest_elftls_shared_var \
+ libtest_elftls_tprel \
LOCAL_WHOLE_STATIC_LIBRARIES += \
libBionicTests \
libBionicLoaderTests \
+ libBionicElfTlsLoaderTests \
libBionicCtsGtestMain \
LOCAL_STATIC_LIBRARIES += \
libbase \
- libpagemap \
+ libmeminfo \
libziparchive \
libtinyxml2 \
liblog \
diff --git a/tests/tests/bionic/AndroidTest.xml b/tests/tests/bionic/AndroidTest.xml
index f6d2b09..af3c65b 100644
--- a/tests/tests/bionic/AndroidTest.xml
+++ b/tests/tests/bionic/AndroidTest.xml
@@ -16,6 +16,7 @@
<configuration description="Config for CTS Bionic test cases">
<option name="test-suite-tag" value="cts" />
<option name="config-descriptor:metadata" key="component" value="bionic" />
+ <option name="config-descriptor:metadata" key="parameter" value="not_instant_app" />
<target_preparer class="com.android.compatibility.common.tradefed.targetprep.FilePusher">
<option name="cleanup" value="true" />
<option name="push" value="CtsBionicTestCases->/data/local/tmp/CtsBionicTestCases" />
diff --git a/tests/tests/bluetooth/AndroidManifest.xml b/tests/tests/bluetooth/AndroidManifest.xml
index 4eb9cd9..0cf4065 100644
--- a/tests/tests/bluetooth/AndroidManifest.xml
+++ b/tests/tests/bluetooth/AndroidManifest.xml
@@ -20,6 +20,7 @@
<uses-permission android:name="android.permission.BLUETOOTH" />
<uses-permission android:name="android.permission.BLUETOOTH_ADMIN" />
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
+ <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="android.permission.DISABLE_KEYGUARD" />
<uses-permission android:name="android.permission.WRITE_SECURE_SETTINGS" />
diff --git a/tests/tests/bluetooth/src/android/bluetooth/cts/BluetoothLeScanTest.java b/tests/tests/bluetooth/src/android/bluetooth/cts/BluetoothLeScanTest.java
index cb59a0a3..905c821 100644
--- a/tests/tests/bluetooth/src/android/bluetooth/cts/BluetoothLeScanTest.java
+++ b/tests/tests/bluetooth/src/android/bluetooth/cts/BluetoothLeScanTest.java
@@ -91,7 +91,7 @@
TestUtils.enableLocation(getContext());
}
InstrumentationRegistry.getInstrumentation().getUiAutomation().grantRuntimePermission(
- "android.bluetooth.cts", android.Manifest.permission.ACCESS_COARSE_LOCATION);
+ "android.bluetooth.cts", android.Manifest.permission.ACCESS_FINE_LOCATION);
}
@Override
diff --git a/tests/tests/bluetooth/src/android/bluetooth/cts/HearingAidProfileTest.java b/tests/tests/bluetooth/src/android/bluetooth/cts/HearingAidProfileTest.java
new file mode 100644
index 0000000..7336f3b
--- /dev/null
+++ b/tests/tests/bluetooth/src/android/bluetooth/cts/HearingAidProfileTest.java
@@ -0,0 +1,289 @@
+/*
+ * Copyright (C) 2019 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.bluetooth.cts;
+
+import android.bluetooth.BluetoothAdapter;
+import android.bluetooth.BluetoothDevice;
+import android.bluetooth.BluetoothHearingAid;
+import android.bluetooth.BluetoothManager;
+import android.bluetooth.BluetoothProfile;
+import android.content.BroadcastReceiver;
+import android.content.Context;
+import android.content.Intent;
+import android.content.IntentFilter;
+import android.content.pm.PackageManager;
+import android.test.AndroidTestCase;
+import android.test.suitebuilder.annotation.MediumTest;
+import android.util.Log;
+
+import java.io.IOException;
+import java.util.List;
+import java.util.ArrayList;
+import java.util.Arrays;
+
+/**
+ * Unit test cases for {@link BluetoothHearingAid}.
+ * <p>
+ * To run the test, use adb shell am instrument -e class 'android.bluetooth.HearingAidProfileTest'
+ * -w 'com.android.bluetooth.tests/android.bluetooth.BluetoothTestRunner'
+ */
+public class HearingAidProfileTest extends AndroidTestCase {
+ private static final String TAG = "HearingAidProfileTest";
+
+ private static final int WAIT_FOR_INTENT_TIMEOUT_MS = 10000; // ms to wait for intent callback
+ private static final int PROXY_CONNECTION_TIMEOUT_MS = 500; // ms timeout for Proxy Connect
+ private static final int ADAPTER_ENABLE_TIMEOUT_MS = 5000;
+
+ private boolean mIsHearingAidSupported;
+ private boolean mIsProfileReady;
+ private boolean mIsBleSupported;
+ private BluetoothHearingAid mService;
+ private BluetoothAdapter mBluetoothAdapter;
+ private BroadcastReceiver mIntentReceiver;
+
+ private static List<Integer> mValidConnectionStates = new ArrayList<Integer>(
+ Arrays.asList(BluetoothProfile.STATE_CONNECTING, BluetoothProfile.STATE_CONNECTED,
+ BluetoothProfile.STATE_DISCONNECTED, BluetoothProfile.STATE_DISCONNECTING));
+
+ private List<BluetoothDevice> mIntentCallbackDeviceList;
+
+ public void setUp() throws Exception {
+ if (!isBleSupported()) return;
+ mIsBleSupported = true;
+
+ BluetoothManager manager = (BluetoothManager) mContext.getSystemService(
+ Context.BLUETOOTH_SERVICE);
+ mBluetoothAdapter = manager.getAdapter();
+ if (!mBluetoothAdapter.isEnabled()) {
+ mBluetoothAdapter.enable();
+ sleep(ADAPTER_ENABLE_TIMEOUT_MS);
+ assertTrue(mBluetoothAdapter.isEnabled());
+ }
+
+ mIsProfileReady = false;
+ mService = null;
+ mIsHearingAidSupported = mBluetoothAdapter.getProfileProxy(getContext(),
+ new HearingAidsServiceListener(),
+ BluetoothProfile.HEARING_AID);
+ if (!mIsHearingAidSupported) return;
+
+ // Give the Service Proxy enough time to Connect
+ sleep(PROXY_CONNECTION_TIMEOUT_MS);
+ }
+
+ @Override
+ public void tearDown() {
+ if (!mIsBleSupported) return;
+
+ mBluetoothAdapter.disable();
+ sleep(ADAPTER_ENABLE_TIMEOUT_MS);
+ }
+
+ /**
+ * Basic test case to make sure that Hearing Aid Profile Proxy can connect.
+ */
+ @MediumTest
+ public void test_getProxyServiceConnect() {
+ if (!(mIsBleSupported && mIsHearingAidSupported)) return;
+
+ assertTrue(mIsProfileReady);
+ assertNotNull(mService);
+ }
+
+ /**
+ * Basic test case to make sure that a fictional device is disconnected.
+ */
+ @MediumTest
+ public void test_getConnectionState() {
+ if (!(mIsBleSupported && mIsHearingAidSupported && mIsProfileReady &&
+ (mService != null))) {
+ return;
+ }
+
+ // Create a dummy device
+ BluetoothDevice device = mBluetoothAdapter.getRemoteDevice("00:11:22:AA:BB:CC");
+ assertNotNull(device);
+
+ int connectionState = mService.getConnectionState(device);
+ // Dummy device should be disconnected
+ assertEquals(connectionState, BluetoothProfile.STATE_DISCONNECTED);
+ }
+
+ /**
+ * Basic test case to get the list of connected Hearing Aid devices.
+ */
+ @MediumTest
+ public void test_getConnectedDevices() {
+ if (!(mIsBleSupported && mIsHearingAidSupported && mIsProfileReady &&
+ (mService != null))) {
+ return;
+ }
+
+ List<BluetoothDevice> deviceList;
+
+ deviceList = mService.getConnectedDevices();
+ Log.d(TAG, "getConnectedDevices(): size=" + deviceList.size());
+ for (BluetoothDevice device : deviceList) {
+ int connectionState = mService.getConnectionState(device);
+ checkValidConnectionState(connectionState);
+ }
+ }
+
+ /**
+ * Basic test case to get the list of matching Hearing Aid devices for each of the 4 connection
+ * states.
+ */
+ @MediumTest
+ public void test_getDevicesMatchingConnectionStates() {
+ if (!(mIsBleSupported && mIsHearingAidSupported && mIsProfileReady &&
+ (mService != null))) {
+ return;
+ }
+
+ for (int connectionState : mValidConnectionStates) {
+ List<BluetoothDevice> deviceList;
+
+ deviceList = mService.getDevicesMatchingConnectionStates(new int[]{connectionState});
+ assertNotNull(deviceList);
+ Log.d(TAG, "getDevicesMatchingConnectionStates(" + connectionState + "): size="
+ + deviceList.size());
+ checkDeviceListAndStates(deviceList, connectionState);
+ }
+ }
+
+ /**
+ * Test case to make sure that if the connection changed intent is called, the parameters and
+ * device are correct.
+ */
+ @MediumTest
+ public void test_getConnectionStateChangedIntent() {
+ if (!(mIsBleSupported && mIsHearingAidSupported && mIsProfileReady &&
+ (mService != null))) {
+ return;
+ }
+
+ // Find out how many Hearing Aid bonded devices
+ List<BluetoothDevice> bondedDeviceList = new ArrayList();
+ int numDevices = 0;
+ for (int connectionState : mValidConnectionStates) {
+ List<BluetoothDevice> deviceList;
+
+ deviceList = mService.getDevicesMatchingConnectionStates(new int[]{connectionState});
+ bondedDeviceList.addAll(deviceList);
+ numDevices += deviceList.size();
+ }
+
+ if (numDevices <= 0) return;
+ Log.d(TAG, "Number Hearing Aids devices bonded=" + numDevices);
+
+ mIntentCallbackDeviceList = new ArrayList();
+
+ // Set up the Connection State Changed receiver
+ IntentFilter filter = new IntentFilter();
+ filter.addAction(BluetoothHearingAid.ACTION_CONNECTION_STATE_CHANGED);
+ mIntentReceiver = new HearingAidIntentReceiver();
+ mContext.registerReceiver(mIntentReceiver, filter);
+
+ Log.d(TAG, "test_getConnectionStateChangedIntent: disable adapter and wait");
+ mBluetoothAdapter.disable();
+ sleep(ADAPTER_ENABLE_TIMEOUT_MS);
+
+ Log.d(TAG, "test_getConnectionStateChangedIntent: re-enable adapter and wait");
+ mBluetoothAdapter.enable();
+
+ int sanityCount = WAIT_FOR_INTENT_TIMEOUT_MS;
+ while ((numDevices != mIntentCallbackDeviceList.size()) && (sanityCount > 0)) {
+ final int SLEEP_QUANTUM_MS = 100;
+ sleep(SLEEP_QUANTUM_MS);
+ sanityCount -= SLEEP_QUANTUM_MS;
+ }
+
+ // Tear down
+ mContext.unregisterReceiver(mIntentReceiver);
+
+ Log.d(TAG, "test_getConnectionStateChangedIntent: number of bonded device="
+ + numDevices + ", mIntentCallbackDeviceList.size()="
+ + mIntentCallbackDeviceList.size());
+ for (BluetoothDevice device : mIntentCallbackDeviceList) {
+ assertTrue(bondedDeviceList.contains(device));
+ }
+ }
+
+ private final class HearingAidsServiceListener
+ implements BluetoothProfile.ServiceListener {
+
+ public void onServiceConnected(int profile, BluetoothProfile proxy) {
+ mService = (BluetoothHearingAid) proxy;
+
+ mIsProfileReady = true;
+ }
+
+ public void onServiceDisconnected(int profile) {
+ mIsProfileReady = false;
+ }
+ }
+
+ private class HearingAidIntentReceiver extends BroadcastReceiver {
+ @Override
+ public void onReceive(Context context, Intent intent) {
+ if (BluetoothHearingAid.ACTION_CONNECTION_STATE_CHANGED.equals(intent.getAction())) {
+ int state = intent.getIntExtra(BluetoothProfile.EXTRA_STATE, -1);
+ int previousState = intent.getIntExtra(BluetoothProfile.EXTRA_PREVIOUS_STATE, -1);
+ BluetoothDevice device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
+
+ Log.d(TAG,"HearingAidIntentReceiver.onReceive: device=" + device
+ + ", state=" + state + ", previousState=" + previousState);
+
+ checkValidConnectionState(state);
+ checkValidConnectionState(previousState);
+
+ mIntentCallbackDeviceList.add(device);
+ }
+ }
+ }
+
+ private void checkDeviceListAndStates(List<BluetoothDevice> deviceList, int connectionState) {
+ Log.d(TAG, "checkDeviceListAndStates(): size=" + deviceList.size()
+ + ", connectionState=" + connectionState);
+ for (BluetoothDevice device : deviceList) {
+ int deviceConnectionState = mService.getConnectionState(device);
+ assertEquals("Mismatched connection state for " + device,
+ connectionState, deviceConnectionState);
+ }
+ }
+
+ private void checkValidConnectionState(int connectionState) {
+ assertTrue(mValidConnectionStates.contains(connectionState));
+ }
+
+ // Returns whether offloaded scan batching is supported.
+ private boolean isBleBatchScanSupported() {
+ return mBluetoothAdapter.isOffloadedScanBatchingSupported();
+ }
+
+ // Check if Bluetooth LE feature is supported on DUT.
+ private boolean isBleSupported() {
+ return getContext().getPackageManager()
+ .hasSystemFeature(PackageManager.FEATURE_BLUETOOTH_LE);
+ }
+
+ private static void sleep(long t) {
+ try {
+ Thread.sleep(t);
+ } catch (InterruptedException e) {}
+ }
+}
diff --git a/tests/tests/bluetooth/src/android/bluetooth/cts/ScanFilterTest.java b/tests/tests/bluetooth/src/android/bluetooth/cts/ScanFilterTest.java
index 1d78ebb..df1bb16 100644
--- a/tests/tests/bluetooth/src/android/bluetooth/cts/ScanFilterTest.java
+++ b/tests/tests/bluetooth/src/android/bluetooth/cts/ScanFilterTest.java
@@ -52,6 +52,7 @@
0x02, 0x0A, (byte) 0xec, // tx power level
0x05, 0x16, 0x0b, 0x11, 0x50, 0x64, // service data
0x05, (byte) 0xff, (byte) 0xe0, 0x00, 0x02, 0x15, // manufacturer specific data
+ 0x05, 0x14, 0x0c, 0x11, 0x0a, 0x11, // 16 bit service solicitation uuids
0x03, 0x50, 0x01, 0x02, // an unknown data type won't cause trouble
};
@@ -118,6 +119,28 @@
}
@SmallTest
+ public void testsetServiceSolicitationUuidFilter() {
+ if (mFilterBuilder == null) return;
+
+ ScanFilter filter = mFilterBuilder.setServiceSolicitationUuid(
+ ParcelUuid.fromString(UUID1)).build();
+ assertEquals(UUID1, filter.getServiceSolicitationUuid().toString());
+ assertTrue("uuid filter fails", filter.matches(mScanResult));
+
+ filter = mFilterBuilder.setServiceSolicitationUuid(
+ ParcelUuid.fromString(UUID2)).build();
+ assertEquals(UUID2, filter.getServiceSolicitationUuid().toString());
+ assertFalse("uuid filter fails", filter.matches(mScanResult));
+
+ ParcelUuid mask = ParcelUuid.fromString("FFFFFFF0-FFFF-FFFF-FFFF-FFFFFFFFFFFF");
+ filter = mFilterBuilder
+ .setServiceSolicitationUuid(ParcelUuid.fromString(UUID3), mask)
+ .build();
+ assertEquals(mask.toString(), filter.getServiceSolicitationUuidMask().toString());
+ assertTrue("uuid filter fails", filter.matches(mScanResult));
+ }
+
+ @SmallTest
public void testsetServiceDataFilter() {
if (mFilterBuilder == null) return;
diff --git a/tests/tests/bluetooth/src/android/bluetooth/cts/ScanRecordTest.java b/tests/tests/bluetooth/src/android/bluetooth/cts/ScanRecordTest.java
index 30ad06f..0afd1ec 100644
--- a/tests/tests/bluetooth/src/android/bluetooth/cts/ScanRecordTest.java
+++ b/tests/tests/bluetooth/src/android/bluetooth/cts/ScanRecordTest.java
@@ -38,14 +38,23 @@
0x02, 0x0A, (byte) 0xec, // tx power level
0x05, 0x16, 0x0b, 0x11, 0x50, 0x64, // service data
0x05, (byte) 0xff, (byte) 0xe0, 0x00, 0x02, 0x15, // manufacturer specific data
+ 0x05, 0x14, 0x0c, 0x11, 0x0d, 0x11, // 16 bit service solicitation uuids
0x03, 0x50, 0x01, 0x02, // an unknown data type won't cause trouble
};
ScanRecord data = TestUtils.parseScanRecord(scanRecord);
assertEquals(0x1a, data.getAdvertiseFlags());
ParcelUuid uuid1 = ParcelUuid.fromString("0000110A-0000-1000-8000-00805F9B34FB");
ParcelUuid uuid2 = ParcelUuid.fromString("0000110B-0000-1000-8000-00805F9B34FB");
+ ParcelUuid uuid3 = ParcelUuid.fromString("0000110C-0000-1000-8000-00805F9B34FB");
+ ParcelUuid uuid4 = ParcelUuid.fromString("0000110D-0000-1000-8000-00805F9B34FB");
assertTrue(data.getServiceUuids().contains(uuid1));
assertTrue(data.getServiceUuids().contains(uuid2));
+ assertFalse(data.getServiceUuids().contains(uuid3));
+ assertFalse(data.getServiceUuids().contains(uuid4));
+ assertFalse(data.getServiceSolicitationUuids().contains(uuid1));
+ assertFalse(data.getServiceSolicitationUuids().contains(uuid2));
+ assertTrue(data.getServiceSolicitationUuids().contains(uuid3));
+ assertTrue(data.getServiceSolicitationUuids().contains(uuid4));
assertEquals("Ped", data.getDeviceName());
assertEquals(-20, data.getTxPowerLevel());
diff --git a/tests/tests/car/AndroidManifest.xml b/tests/tests/car/AndroidManifest.xml
index 41e8c71..fe1b64f 100644
--- a/tests/tests/car/AndroidManifest.xml
+++ b/tests/tests/car/AndroidManifest.xml
@@ -23,6 +23,12 @@
<uses-permission android:name="android.car.permission.CAR_SPEED" />
<application>
<uses-library android:name="android.test.runner" />
+ <activity android:name=".drivingstate.DistractionOptimizedActivity">
+ <meta-data android:name="distractionOptimized" android:value="true"/>
+ </activity>
+ <activity android:name=".drivingstate.NonDistractionOptimizedActivity">
+ <meta-data android:name="distractionOptimized" android:value="false"/>
+ </activity>
</application>
<instrumentation android:name="android.support.test.runner.AndroidJUnitRunner"
diff --git a/tests/tests/car/src/android/car/cts/CarPackageManagerTest.java b/tests/tests/car/src/android/car/cts/CarPackageManagerTest.java
index 3f3c9a9..ec79572 100644
--- a/tests/tests/car/src/android/car/cts/CarPackageManagerTest.java
+++ b/tests/tests/car/src/android/car/cts/CarPackageManagerTest.java
@@ -82,50 +82,19 @@
} catch (IllegalArgumentException expected) {
// Expected.
}
- }
-
- @Test
- public void testSystemActivitiesAllowed() throws CarNotConnectedException {
- Context context = InstrumentationRegistry.getInstrumentation().getTargetContext();
- List<PackageInfo> packages = context.getPackageManager().getInstalledPackages(
- PackageManager.GET_ACTIVITIES | PackageManager.GET_META_DATA);
-
- for (PackageInfo info : packages) {
- if (info.applicationInfo == null) {
- continue;
- }
- if ((info.applicationInfo.flags & ApplicationInfo.FLAG_SYSTEM) != 0 ||
- ((info.applicationInfo.flags & ApplicationInfo.FLAG_UPDATED_SYSTEM_APP) != 0)) {
-
- Bundle metaData = info.applicationInfo.metaData;
- if (metaData == null || metaData.getInt(METADATA_ATTRIBUTE, 0) == 0) {
- continue; // No car metadata, ignoring this app.
- }
-
- if (info.activities != null && info.activities.length > 0) {
- String activity = info.activities[0].name;
- String packageName = info.packageName;
- assertTrue("Failed for package: " + packageName + ", activity: " + activity,
- mCarPm.isActivityDistractionOptimized(packageName, activity));
- }
- }
- }
}
@Test
- @Ignore // Enable when b/120125891 is fixed
- public void testServiceDistractionOptimized() throws Exception {
- assertFalse(mCarPm.isServiceDistractionOptimized("com.basic.package", ""));
- assertTrue(mCarPm.isServiceDistractionOptimized("com.android.car.settings", "Any"));
- assertTrue(mCarPm.isServiceDistractionOptimized("com.android.car.settings", ""));
- assertTrue(mCarPm.isServiceDistractionOptimized("com.android.car.settings", null));
-
- try {
- mCarPm.isServiceDistractionOptimized(null, "Any");
- fail();
- } catch (IllegalArgumentException expected) {
- // Expected.
- }
+ public void testDistractionOptimizedActivityIsAllowed() throws CarNotConnectedException {
+ // This test relies on test activity in installed apk, and AndroidManifest declaration.
+ assertTrue(mCarPm.isActivityDistractionOptimized("android.car.cts",
+ "android.car.cts.drivingstate.DistractionOptimizedActivity"));
}
+ @Test
+ public void testNonDistractionOptimizedActivityNotAllowed() throws CarNotConnectedException {
+ // This test relies on test activity in installed apk, and AndroidManifest declaration.
+ assertFalse(mCarPm.isActivityDistractionOptimized("android.car.cts",
+ "android.car.cts.drivingstate.NonDistractionOptimizedActivity"));
+ }
}
diff --git a/tests/tests/car/src/android/car/cts/drivingstate/DistractionOptimizedActivity.java b/tests/tests/car/src/android/car/cts/drivingstate/DistractionOptimizedActivity.java
new file mode 100644
index 0000000..00440b6
--- /dev/null
+++ b/tests/tests/car/src/android/car/cts/drivingstate/DistractionOptimizedActivity.java
@@ -0,0 +1,6 @@
+package android.car.cts.drivingstate;
+
+import android.app.Activity;
+
+public class DistractionOptimizedActivity extends Activity {
+}
\ No newline at end of file
diff --git a/tests/tests/car/src/android/car/cts/drivingstate/NonDistractionOptimizedActivity.java b/tests/tests/car/src/android/car/cts/drivingstate/NonDistractionOptimizedActivity.java
new file mode 100644
index 0000000..0c75a3a
--- /dev/null
+++ b/tests/tests/car/src/android/car/cts/drivingstate/NonDistractionOptimizedActivity.java
@@ -0,0 +1,6 @@
+package android.car.cts.drivingstate;
+
+import android.app.Activity;
+
+public class NonDistractionOptimizedActivity extends Activity {
+}
diff --git a/tests/tests/content/jni/NativeCursorWindow.c b/tests/tests/content/jni/NativeCursorWindow.c
index a2fb92a..95342e6 100644
--- a/tests/tests/content/jni/NativeCursorWindow.c
+++ b/tests/tests/content/jni/NativeCursorWindow.c
@@ -69,7 +69,7 @@
JNIEXPORT jint JNICALL
Java_android_content_cts_CursorWindowContentProvider_makeNativeCursorWindowFd(JNIEnv *env, jclass clazz,
jint offset, jint size, jboolean isBlob) {
- int fd = open("/dev/ashmem", O_RDWR);
+ int fd = open("/dev/ashmem", O_RDWR | O_CLOEXEC);
ioctl(fd, ASHMEM_SET_NAME, "Fake CursorWindow");
ioctl(fd, ASHMEM_SET_SIZE, 1024);
diff --git a/tests/tests/content/res/values/styles.xml b/tests/tests/content/res/values/styles.xml
index 91191cf..7da5c5e 100644
--- a/tests/tests/content/res/values/styles.xml
+++ b/tests/tests/content/res/values/styles.xml
@@ -39,6 +39,21 @@
<item name="typeUndefined">@null</item>
</style>
+ <style name="StyleA" parent="StyleB">
+ <item name="type1">true</item>
+ </style>
+ <style name="StyleB" parent="StyleC">
+ <item name="type1">false</item>
+ <item name="type2">false</item>
+ <item name="type4">@color/testcolor1</item>
+ </style>
+
+ <style name="StyleC">
+ <item name="type1">false</item>
+ <item name="type2">true</item>
+ <item name="type3">#ff0000ff</item>
+ </style>
+
<style name="TextViewWithoutColorAndAppearance">
<item name="android:textSize">18sp</item>
</style>
diff --git a/tests/tests/content/src/android/content/om/cts/OverlayInfoTest.java b/tests/tests/content/src/android/content/om/cts/OverlayInfoTest.java
new file mode 100644
index 0000000..a8919b9
--- /dev/null
+++ b/tests/tests/content/src/android/content/om/cts/OverlayInfoTest.java
@@ -0,0 +1,99 @@
+/*
+ * Copyright (C) 2019 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.content.om.cts;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.fail;
+import static android.content.om.OverlayInfo.CREATOR;
+
+import org.junit.Assert;
+import org.junit.runner.RunWith;
+import org.junit.Test;
+
+import android.content.om.OverlayInfo;
+import android.content.om.OverlayManager;
+import android.os.Parcel;
+import android.os.RemoteException;
+import android.support.test.runner.AndroidJUnit4;
+
+
+/**
+ * Verifies the member variables inside {@link OverlayInfo}
+ */
+@RunWith(AndroidJUnit4.class)
+public class OverlayInfoTest {
+
+ private static final String PKG_NAME = "source package name";
+ private static final String TARGET_PKG_NAME = "target package name";
+ private static final String CATEGORY = "sample category";
+ private static final String BASE_CODE_PATH = "base code path";
+
+ @Test
+ public void testEnsureValidState() {
+ OverlayInfo info = new OverlayInfo(PKG_NAME, TARGET_PKG_NAME, CATEGORY, BASE_CODE_PATH,
+ 0, 0, 0, true);
+ assertNotNull(info);
+ }
+
+ @Test
+ public void testEnsureValidState_fail() {
+ try {
+ OverlayInfo info = new OverlayInfo(null, TARGET_PKG_NAME, CATEGORY, BASE_CODE_PATH,
+ 0, 0, 0, true);
+ fail("Should throw exception.");
+ } catch (IllegalArgumentException e) {
+ // no op, working as intended.
+ }
+
+ try {
+ OverlayInfo info = new OverlayInfo(PKG_NAME, null, CATEGORY, BASE_CODE_PATH,
+ 0, 0, 0, true);
+ fail("Should throw exception.");
+ } catch (IllegalArgumentException e) {
+ // no op, working as intended.
+ }
+
+ try {
+ OverlayInfo info = new OverlayInfo(PKG_NAME, TARGET_PKG_NAME, CATEGORY, null,
+ 0, 0, 0, true);
+ fail("Should throw exception.");
+ } catch (IllegalArgumentException e) {
+ // no op, working as intended.
+ }
+ }
+
+ @Test
+ public void testWriteToParcel() {
+ OverlayInfo info = new OverlayInfo(PKG_NAME, TARGET_PKG_NAME, CATEGORY, BASE_CODE_PATH,
+ 0, 0, 0, true);
+ Parcel p = Parcel.obtain();
+ info.writeToParcel(p, 0);
+ p.setDataPosition(0);
+ OverlayInfo copyInfo = CREATOR.createFromParcel(p);
+ p.recycle();
+
+ assertEquals(info.packageName, copyInfo.packageName);
+ assertEquals(info.targetPackageName, copyInfo.targetPackageName);
+ assertEquals(info.category, copyInfo.category);
+ assertEquals(info.baseCodePath, copyInfo.baseCodePath);
+ assertEquals(info.state, copyInfo.state);
+ assertEquals(info.userId, copyInfo.userId);
+ assertEquals(info.priority, copyInfo.priority);
+ assertEquals(info.isStatic, copyInfo.isStatic);
+ }
+}
\ No newline at end of file
diff --git a/tests/tests/content/src/android/content/om/cts/OverlayManagerTest.java b/tests/tests/content/src/android/content/om/cts/OverlayManagerTest.java
new file mode 100644
index 0000000..bda44a2
--- /dev/null
+++ b/tests/tests/content/src/android/content/om/cts/OverlayManagerTest.java
@@ -0,0 +1,73 @@
+/*
+ * Copyright (C) 2019 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.content.om.cts;
+
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+import static org.mockito.Mockito.times;
+
+import android.content.Context;
+import android.content.om.IOverlayManager;
+import android.content.om.OverlayManager;
+import android.content.om.OverlayInfo;
+import android.os.RemoteException;
+import android.support.test.runner.AndroidJUnit4;
+import android.support.test.InstrumentationRegistry;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+
+/**
+ * This only tests the client API implementation of the OverlayManager
+ * and not the service implementation.
+ */
+@RunWith(AndroidJUnit4.class)
+public class OverlayManagerTest {
+
+ private OverlayManager mManager;
+ @Mock
+ private IOverlayManager mMockService;
+
+ @Before
+ public void setUp() throws Exception {
+ MockitoAnnotations.initMocks(this);
+ Context context = InstrumentationRegistry.getInstrumentation().getContext();
+ mManager = new OverlayManager(context, mMockService);
+ }
+
+ @Test
+ public void testSetEnabledExclusiveInCategory() throws Exception {
+ String packageName = "overlay source package name";
+ int userId = 10;
+ verify(mMockService, times(0)).setEnabledExclusiveInCategory(packageName, userId);
+ mManager.setEnabledExclusiveInCategory(packageName, userId);
+ verify(mMockService, times(1)).setEnabledExclusiveInCategory(packageName, userId);
+ }
+
+ @Test
+ public void testGetOverlayInfosForTarget() throws Exception {
+ String targetPackageName = "overlay target package name";
+ int userId = 10;
+ verify(mMockService, times(0)).getOverlayInfosForTarget(targetPackageName, userId);
+ mManager.getOverlayInfosForTarget(targetPackageName, userId);
+ verify(mMockService, times(1)).getOverlayInfosForTarget(targetPackageName, userId);
+ }
+}
\ No newline at end of file
diff --git a/tests/tests/content/src/android/content/pm/cts/ApplicationInfoTest.java b/tests/tests/content/src/android/content/pm/cts/ApplicationInfoTest.java
index a21039e..29c533c 100644
--- a/tests/tests/content/src/android/content/pm/cts/ApplicationInfoTest.java
+++ b/tests/tests/content/src/android/content/pm/cts/ApplicationInfoTest.java
@@ -36,6 +36,8 @@
import android.content.pm.ApplicationInfo;
import android.content.pm.PackageManager.NameNotFoundException;
import android.os.Parcel;
+import android.os.Process;
+import android.os.UserHandle;
import android.support.test.InstrumentationRegistry;
import android.support.test.runner.AndroidJUnit4;
import android.util.StringBuilderPrinter;
@@ -153,14 +155,14 @@
// The application "com.android.cts.stub" does not have any attributes set
mApplicationInfo = getContext().getPackageManager().getApplicationInfo(
SYNC_ACCOUNT_ACCESS_STUB_PACKAGE_NAME, 0);
+ int currentUserId = Process.myUserHandle().getIdentifier();
assertNull(mApplicationInfo.className);
assertNull(mApplicationInfo.permission);
assertEquals(SYNC_ACCOUNT_ACCESS_STUB_PACKAGE_NAME, mApplicationInfo.packageName);
assertEquals(SYNC_ACCOUNT_ACCESS_STUB_PACKAGE_NAME, mApplicationInfo.processName);
assertEquals(SYNC_ACCOUNT_ACCESS_STUB_PACKAGE_NAME, mApplicationInfo.taskAffinity);
- assertTrue(FIRST_APPLICATION_UID <= mApplicationInfo.uid
- && LAST_APPLICATION_UID >= mApplicationInfo.uid);
+ assertTrue(UserHandle.isApp(mApplicationInfo.uid));
assertEquals(0, mApplicationInfo.theme);
assertEquals(0, mApplicationInfo.requiresSmallestWidthDp);
assertEquals(0, mApplicationInfo.compatibleWidthLimitDp);
@@ -169,11 +171,11 @@
assertEquals(mApplicationInfo.sourceDir, mApplicationInfo.publicSourceDir);
assertNull(mApplicationInfo.splitSourceDirs);
assertArrayEquals(mApplicationInfo.splitSourceDirs, mApplicationInfo.splitPublicSourceDirs);
- assertEquals("/data/user/0/" + SYNC_ACCOUNT_ACCESS_STUB_PACKAGE_NAME,
+ assertEquals("/data/user/" + currentUserId + "/" + SYNC_ACCOUNT_ACCESS_STUB_PACKAGE_NAME,
mApplicationInfo.dataDir);
- assertEquals("/data/user_de/0/" + SYNC_ACCOUNT_ACCESS_STUB_PACKAGE_NAME,
+ assertEquals("/data/user_de/" + currentUserId + "/" + SYNC_ACCOUNT_ACCESS_STUB_PACKAGE_NAME,
mApplicationInfo.deviceProtectedDataDir);
- assertEquals("/data/user/0/" + SYNC_ACCOUNT_ACCESS_STUB_PACKAGE_NAME,
+ assertEquals("/data/user/" + currentUserId + "/" + SYNC_ACCOUNT_ACCESS_STUB_PACKAGE_NAME,
mApplicationInfo.credentialProtectedDataDir);
assertNull(mApplicationInfo.sharedLibraryFiles);
assertTrue(mApplicationInfo.enabled);
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 03788b5..a68445f 100644
--- a/tests/tests/content/src/android/content/res/cts/ResourcesTest.java
+++ b/tests/tests/content/src/android/content/res/cts/ResourcesTest.java
@@ -70,6 +70,10 @@
mResources = getContext().getResources();
}
+ public void testIdNull() {
+ assertEquals(0, Resources.ID_NULL);
+ }
+
public void testResources() {
final AssetManager am = new AssetManager();
final Configuration cfg = new Configuration();
diff --git a/tests/tests/content/src/android/content/res/cts/TypedArrayTest.java b/tests/tests/content/src/android/content/res/cts/TypedArrayTest.java
index f27f06c..38a6a5b 100644
--- a/tests/tests/content/src/android/content/res/cts/TypedArrayTest.java
+++ b/tests/tests/content/src/android/content/res/cts/TypedArrayTest.java
@@ -18,8 +18,6 @@
import static com.google.common.truth.Truth.assertThat;
-import org.xmlpull.v1.XmlPullParserException;
-
import android.content.cts.R;
import android.content.cts.util.XmlUtils;
import android.content.pm.ActivityInfo;
@@ -32,6 +30,8 @@
import android.util.TypedValue;
import android.view.ContextThemeWrapper;
+import org.xmlpull.v1.XmlPullParserException;
+
import java.io.IOException;
public class TypedArrayTest extends AndroidTestCase {
@@ -72,6 +72,19 @@
mTypedArray.recycle();
}
+ public void testSourceStyleResourceId() {
+ final TypedArray t = getContext().getTheme().obtainStyledAttributes(
+ R.style.StyleA, R.styleable.style1);
+
+ assertEquals(R.style.StyleA, t.getSourceStyleResourceId(R.styleable.style1_type1, 0));
+ assertEquals(R.style.StyleB, t.getSourceStyleResourceId(R.styleable.style1_type2, 0));
+ assertEquals(R.style.StyleC, t.getSourceStyleResourceId(R.styleable.style1_type3, 0));
+ assertEquals(R.style.StyleB, t.getSourceStyleResourceId(R.styleable.style1_type4, 0));
+ assertEquals(0, t.getSourceStyleResourceId(R.styleable.style1_type5, 0));
+
+ t.recycle();
+ }
+
public void testGetType() {
final TypedArray t = getContext().getTheme().obtainStyledAttributes(
R.style.Whatever, R.styleable.style1);
diff --git a/tests/tests/database/AndroidTest.xml b/tests/tests/database/AndroidTest.xml
index 1a53a10..9c53d2d 100644
--- a/tests/tests/database/AndroidTest.xml
+++ b/tests/tests/database/AndroidTest.xml
@@ -20,6 +20,7 @@
<target_preparer class="com.android.tradefed.targetprep.suite.SuiteApkInstaller">
<option name="cleanup-apks" value="true" />
<option name="test-file-name" value="CtsDatabaseTestCases.apk" />
+ <option name="test-file-name" value="CtsProviderApp.apk" />
</target_preparer>
<test class="com.android.tradefed.testtype.AndroidJUnitTest" >
<option name="package" value="android.database.cts" />
diff --git a/tests/tests/database/apps/Android.bp b/tests/tests/database/apps/Android.bp
new file mode 100644
index 0000000..9953fc1
--- /dev/null
+++ b/tests/tests/database/apps/Android.bp
@@ -0,0 +1,28 @@
+// Copyright (C) 2019 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.
+
+android_test {
+ name: "CtsProviderApp",
+ sdk_version: "test_current",
+
+ srcs: [
+ "src/**/*.java"
+ ],
+
+ test_suites: [
+ "cts",
+ "vts",
+ "general-tests",
+ ]
+}
\ No newline at end of file
diff --git a/tests/tests/database/apps/AndroidManifest.xml b/tests/tests/database/apps/AndroidManifest.xml
new file mode 100644
index 0000000..a199a8f
--- /dev/null
+++ b/tests/tests/database/apps/AndroidManifest.xml
@@ -0,0 +1,27 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ * Copyright (C) 2019 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.cts.providerapp">
+
+ <application>
+ <provider android:name=".DummyProvider"
+ android:authorities="com.android.cts.providerapp"
+ android:exported="true">
+ </provider>
+ </application>
+</manifest>
\ No newline at end of file
diff --git a/tests/tests/database/apps/src/com/android/cts/providerapp/DummyProvider.java b/tests/tests/database/apps/src/com/android/cts/providerapp/DummyProvider.java
new file mode 100644
index 0000000..8c06f05
--- /dev/null
+++ b/tests/tests/database/apps/src/com/android/cts/providerapp/DummyProvider.java
@@ -0,0 +1,105 @@
+/*
+ * Copyright (C) 2019 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.providerapp;
+
+import android.content.ContentProvider;
+import android.content.ContentValues;
+import android.database.Cursor;
+import android.database.MatrixCursor;
+import android.net.Uri;
+import android.os.Bundle;
+import android.provider.BaseColumns;
+import android.util.Log;
+
+import java.util.Arrays;
+
+public class DummyProvider extends ContentProvider {
+ private static final String TAG = DummyProvider.class.getName();
+
+ private static final String AUTHORITY = "com.android.cts.providerapp";
+ private static final Uri CONTENT_URI = Uri.parse("content://" + AUTHORITY);
+
+ private static final Uri TEST_URI1 = Uri.withAppendedPath(CONTENT_URI, "test1");
+ private static final Uri TEST_URI2 = Uri.withAppendedPath(CONTENT_URI, "test2");
+
+ private static final String CALL_NOTIFY = "notify";
+
+ @Override
+ public boolean onCreate() {
+ Log.d(TAG, "onCreate");
+ return true;
+ }
+
+ @Override
+ public Cursor query(Uri uri, String[] projection, String selection,
+ String[] selectionArgs, String sortOrder) {
+ Log.d(TAG, "query uri: " + uri);
+ if (!CONTENT_URI.equals(uri)) {
+ throw new UnsupportedOperationException();
+ }
+
+ final MatrixCursor cursor = new MatrixCursor(new String[] {
+ BaseColumns._ID, BaseColumns._COUNT
+ }, 2);
+ cursor.addRow(new Integer[] {100, 2});
+ cursor.addRow(new Integer[] {101, 3});
+ cursor.setNotificationUris(getContext().getContentResolver(),
+ Arrays.asList(TEST_URI1, TEST_URI2));
+ return cursor;
+ }
+
+ @Override
+ public Bundle call(String method, String arg, Bundle extras) {
+ Log.d(TAG, "call method: " + method + ", arg: " + arg);
+ if (!CALL_NOTIFY.equals(method)) {
+ throw new UnsupportedOperationException();
+ }
+
+ switch (arg) {
+ case "1":
+ getContext().getContentResolver().notifyChange(TEST_URI1, null);
+ break;
+ case "2":
+ getContext().getContentResolver().notifyChange(TEST_URI2, null);
+ break;
+ default:
+ throw new UnsupportedOperationException();
+ }
+ return null;
+ }
+
+ @Override
+ public Uri insert(Uri uri, ContentValues values) {
+ return null;
+ }
+
+ @Override
+ public int update(Uri uri, ContentValues values, String selection,
+ String[] selectionArgs) {
+ return 0;
+ }
+
+ @Override
+ public int delete(Uri uri, String selection, String[] selectionArgs) {
+ return 0;
+ }
+
+ @Override
+ public String getType(Uri uri) {
+ return null;
+ }
+}
\ No newline at end of file
diff --git a/tests/tests/database/src/android/database/cts/AbstractCursorTest.java b/tests/tests/database/src/android/database/cts/AbstractCursorTest.java
index ba2f1fd..9a4ba50 100644
--- a/tests/tests/database/src/android/database/cts/AbstractCursorTest.java
+++ b/tests/tests/database/src/android/database/cts/AbstractCursorTest.java
@@ -20,6 +20,7 @@
import android.database.AbstractCursor;
import android.database.CharArrayBuffer;
import android.database.ContentObserver;
+import android.database.Cursor;
import android.database.CursorIndexOutOfBoundsException;
import android.database.CursorWindow;
import android.database.DataSetObserver;
@@ -29,9 +30,15 @@
import android.provider.Settings;
import android.test.InstrumentationTestCase;
+import org.junit.Assert;
+
import java.io.File;
+import java.util.Arrays;
import java.util.ArrayList;
+import java.util.List;
import java.util.Random;
+import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.TimeUnit;
/**
* Test {@link AbstractCursor}.
@@ -52,6 +59,9 @@
private SQLiteDatabase mDatabase;
private File mDatabaseFile;
private AbstractCursor mDatabaseCursor;
+ private Context mContext;
+
+ private static final long ON_CHANGE_TIMEOUT_MS = 5000;
@Override
protected void setUp() throws Exception {
@@ -60,6 +70,7 @@
setupDatabase();
ArrayList<ArrayList> list = createTestList(ROW_MAX, COLUMN_NAMES.length);
mTestAbstractCursor = new TestAbstractCursor(COLUMN_NAMES, list);
+ mContext = getInstrumentation().getContext();
}
@Override
@@ -139,6 +150,47 @@
testUri);
}
+ public void testSetNotificationUris_selfNotify() throws Exception {
+ final Uri testUri1 = Settings.System.getUriFor(Settings.System.TIME_12_24);
+ final Uri testUri2 = Settings.Global.getUriFor(
+ Settings.Global.DEVELOPMENT_SETTINGS_ENABLED);
+ mDatabaseCursor.setNotificationUris(mContext.getContentResolver(),
+ Arrays.asList(testUri1, testUri2));
+ final MockContentObserver observer = new MockContentObserver();
+ mDatabaseCursor.registerContentObserver(observer);
+
+ mContext.getContentResolver().notifyChange(testUri1, null);
+ observer.waitForOnChange(ON_CHANGE_TIMEOUT_MS);
+ observer.resetOnChangeWatch();
+ mContext.getContentResolver().notifyChange(testUri2, null);
+ observer.waitForOnChange(ON_CHANGE_TIMEOUT_MS);
+ }
+
+ public void testSetNotificationsUris() throws Exception {
+ final Uri queryUri = Uri.parse("content://com.android.cts.providerapp");
+ try (Cursor cursor = mContext.getContentResolver().query(queryUri, null, null, null)) {
+ final MockContentObserver observer = new MockContentObserver();
+ cursor.registerContentObserver(observer);
+
+ mContext.getContentResolver().call(queryUri, "notify", "1", null);
+ observer.waitForOnChange(ON_CHANGE_TIMEOUT_MS);
+ observer.resetOnChangeWatch();
+ mContext.getContentResolver().call(queryUri, "notify", "2", null);
+ observer.waitForOnChange(ON_CHANGE_TIMEOUT_MS);
+ }
+ }
+
+ public void testGetNotificationUris() throws Exception {
+ final Uri[] notificationUris = new Uri[] {
+ Settings.Global.getUriFor(Settings.Global.MODE_RINGER),
+ Settings.Global.getUriFor(Settings.Global.BOOT_COUNT)
+ };
+ mDatabaseCursor.setNotificationUris(mContext.getContentResolver(),
+ Arrays.asList(notificationUris));
+ final List<Uri> actualNotificationUris = mDatabaseCursor.getNotificationUris();
+ Assert.assertArrayEquals(notificationUris, actualNotificationUris.toArray(new Uri[0]));
+ }
+
public void testRespond() {
Bundle b = new Bundle();
Bundle bundle = mDatabaseCursor.respond(b);
@@ -159,14 +211,8 @@
public void testOnChange() throws InterruptedException {
MockContentObserver mock = new MockContentObserver();
mTestAbstractCursor.registerContentObserver(mock);
- assertFalse(mock.hadCalledOnChange());
mTestAbstractCursor.onChange(true);
- synchronized(mLockObj) {
- if ( !mock.hadCalledOnChange() ) {
- mLockObj.wait(5000);
- }
- }
- assertTrue(mock.hadCalledOnChange());
+ mock.waitForOnChange(ON_CHANGE_TIMEOUT_MS);
}
public void testOnMove() {
@@ -588,19 +634,18 @@
}
private class MockContentObserver extends ContentObserver {
- public boolean mHadCalledOnChange;
+ private CountDownLatch mCountDownLatch;
public MockContentObserver() {
super(null);
+
+ mCountDownLatch = new CountDownLatch(1);
}
@Override
public void onChange(boolean selfChange) {
super.onChange(selfChange);
- mHadCalledOnChange = true;
- synchronized(mLockObj) {
- mLockObj.notify();
- }
+ mCountDownLatch.countDown();
}
@Override
@@ -608,8 +653,14 @@
return true;
}
- public boolean hadCalledOnChange() {
- return mHadCalledOnChange;
+ public void resetOnChangeWatch() {
+ mCountDownLatch = new CountDownLatch(1);
+ }
+
+ public void waitForOnChange(long timeoutMs) throws InterruptedException {
+ if (!mCountDownLatch.await(timeoutMs, TimeUnit.MILLISECONDS)) {
+ fail("Timed out waiting for onChange() to get called");
+ }
}
}
diff --git a/tests/tests/display/src/android/display/cts/BrightnessTest.java b/tests/tests/display/src/android/display/cts/BrightnessTest.java
index 6b01df2..a4e3aa3 100644
--- a/tests/tests/display/src/android/display/cts/BrightnessTest.java
+++ b/tests/tests/display/src/android/display/cts/BrightnessTest.java
@@ -19,16 +19,19 @@
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;
import android.Manifest;
import android.app.UiAutomation;
import android.content.Context;
+import android.content.pm.ApplicationInfo;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
import android.hardware.display.BrightnessChangeEvent;
import android.hardware.display.BrightnessConfiguration;
+import android.hardware.display.BrightnessCorrection;
import android.hardware.display.DisplayManager;
import android.os.ParcelFileDescriptor;
import android.os.PowerManager;
@@ -210,10 +213,20 @@
BrightnessConfiguration config =
new BrightnessConfiguration.Builder(
new float[]{0.0f, 1000.0f},new float[]{20.0f, 500.0f})
+ .addCorrectionByCategory(ApplicationInfo.CATEGORY_IMAGE,
+ BrightnessCorrection.createScaleAndTranslateLog(0.80f, 0.2f))
+ .addCorrectionByPackageName("some.package.name",
+ BrightnessCorrection.createScaleAndTranslateLog(0.70f, 0.1f))
.setDescription("some test").build();
mDisplayManager.setBrightnessConfiguration(config);
BrightnessConfiguration returnedConfig = mDisplayManager.getBrightnessConfiguration();
assertEquals(config, returnedConfig);
+ assertEquals(config.getCorrectionByCategory(ApplicationInfo.CATEGORY_IMAGE),
+ BrightnessCorrection.createScaleAndTranslateLog(0.80f, 0.2f));
+ assertEquals(config.getCorrectionByPackageName("some.package.name"),
+ BrightnessCorrection.createScaleAndTranslateLog(0.70f, 0.1f));
+ assertNull(config.getCorrectionByCategory(ApplicationInfo.CATEGORY_GAME));
+ assertNull(config.getCorrectionByPackageName("someother.package.name"));
// After clearing the curve we should get back the default curve.
mDisplayManager.setBrightnessConfiguration(null);
diff --git a/tests/tests/display/src/android/display/cts/DisplayTest.java b/tests/tests/display/src/android/display/cts/DisplayTest.java
index cb8e7cd..8283d61 100644
--- a/tests/tests/display/src/android/display/cts/DisplayTest.java
+++ b/tests/tests/display/src/android/display/cts/DisplayTest.java
@@ -26,6 +26,7 @@
import android.content.Intent;
import android.content.res.Configuration;
import android.graphics.Color;
+import android.graphics.ColorSpace;
import android.graphics.PixelFormat;
import android.graphics.Point;
import android.hardware.display.DisplayManager;
@@ -192,7 +193,7 @@
HdrCapabilities cap = display.getHdrCapabilities();
int[] hdrTypes = cap.getSupportedHdrTypes();
for (int type : hdrTypes) {
- assertTrue(type >= 1 && type <= 3);
+ assertTrue(type >= 1 && type <= 4);
}
assertFalse(cap.getDesiredMaxLuminance() < -1.0f);
assertFalse(cap.getDesiredMinLuminance() < -1.0f);
@@ -372,6 +373,22 @@
}
/**
+ * Verify that getColorSpace method returns the expected color space of the display.
+ */
+ @Test
+ public void testGetPreferredWideGamutColorSpace() {
+ final Display defaultDisplay = mWindowManager.getDefaultDisplay();
+ final ColorSpace colorSpace = defaultDisplay.getPreferredWideGamutColorSpace();
+
+ if (defaultDisplay.isWideColorGamut()) {
+ assertFalse(colorSpace.isSrgb());
+ assertTrue(colorSpace.isWideGamut());
+ } else {
+ assertNull(colorSpace);
+ }
+ }
+
+ /**
* Used to force mode changes on a display.
* <p>
* Note that due to limitations of the Presentation class, the modes must have the same size
diff --git a/tests/tests/dynamic_linker/Android.mk b/tests/tests/dynamic_linker/Android.mk
index ef122ca..be1e782 100644
--- a/tests/tests/dynamic_linker/Android.mk
+++ b/tests/tests/dynamic_linker/Android.mk
@@ -43,6 +43,19 @@
LOCAL_SRC_FILES := $(call all-java-files-under, .)
LOCAL_MULTILIB := both
LOCAL_JNI_SHARED_LIBRARIES := libdynamiclinker_native_lib_a libdynamiclinker_native_lib_b
+LOCAL_MANIFEST_FILE := AndroidManifest_27.xml
+LOCAL_PACKAGE_NAME := CtsDynamicLinkerTestCases27
+LOCAL_SDK_VERSION := current
+LOCAL_COMPATIBILITY_SUITE := cts vts
+include $(BUILD_CTS_PACKAGE)
+
+include $(CLEAR_VARS)
+LOCAL_MODULE_TAGS := optional
+LOCAL_MODULE_PATH := $(TARGET_OUT_DATA_APPS)
+LOCAL_STATIC_JAVA_LIBRARIES := ctstestrunner
+LOCAL_SRC_FILES := $(call all-java-files-under, .)
+LOCAL_MULTILIB := both
+LOCAL_JNI_SHARED_LIBRARIES := libdynamiclinker_native_lib_a libdynamiclinker_native_lib_b
LOCAL_MANIFEST_FILE := AndroidManifest.xml
LOCAL_PACKAGE_NAME := CtsDynamicLinkerTestCases
LOCAL_SDK_VERSION := current
diff --git a/tests/tests/dynamic_linker/AndroidManifest.xml b/tests/tests/dynamic_linker/AndroidManifest.xml
index db8099e..7a9166d 100644
--- a/tests/tests/dynamic_linker/AndroidManifest.xml
+++ b/tests/tests/dynamic_linker/AndroidManifest.xml
@@ -17,7 +17,7 @@
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.android.dynamiclinker">
- <application android:extractNativeLibs="false">
+ <application>
<uses-library android:name="android.test.runner" />
</application>
<instrumentation
diff --git a/tests/tests/dynamic_linker/AndroidManifest_27.xml b/tests/tests/dynamic_linker/AndroidManifest_27.xml
new file mode 100644
index 0000000..eae214a
--- /dev/null
+++ b/tests/tests/dynamic_linker/AndroidManifest_27.xml
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2019 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.dynamiclinker27">
+ <!-- Before 27, extractNativeLibs is default to true. -->
+ <uses-sdk android:minSdkVersion="27" android:targetSdkVersion="27" />
+
+ <application android:extractNativeLibs="false">
+ <uses-library android:name="android.test.runner" />
+ </application>
+ <instrumentation
+ android:targetPackage="com.android.dynamiclinker27"
+ android:name="android.support.test.runner.AndroidJUnitRunner" />
+</manifest>
diff --git a/tests/tests/dynamic_linker/AndroidTest.xml b/tests/tests/dynamic_linker/AndroidTest.xml
index 483ae03..a043e15 100644
--- a/tests/tests/dynamic_linker/AndroidTest.xml
+++ b/tests/tests/dynamic_linker/AndroidTest.xml
@@ -18,9 +18,13 @@
<option name="config-descriptor:metadata" key="component" value="bionic" />
<target_preparer class="com.android.tradefed.targetprep.suite.SuiteApkInstaller">
<option name="cleanup-apks" value="true" />
+ <option name="test-file-name" value="CtsDynamicLinkerTestCases27.apk" />
<option name="test-file-name" value="CtsDynamicLinkerTestCases.apk" />
</target_preparer>
<test class="com.android.tradefed.testtype.AndroidJUnitTest" >
+ <option name="package" value="com.android.dynamiclinker27" />
+ </test>
+ <test class="com.android.tradefed.testtype.AndroidJUnitTest" >
<option name="package" value="com.android.dynamiclinker" />
</test>
</configuration>
diff --git a/tests/tests/dynamic_linker/com/android/dynamiclinker/DynamicLinkerTest.java b/tests/tests/dynamic_linker/com/android/dynamiclinker/DynamicLinkerTest.java
index f0d7c4b..a23bc50 100644
--- a/tests/tests/dynamic_linker/com/android/dynamiclinker/DynamicLinkerTest.java
+++ b/tests/tests/dynamic_linker/com/android/dynamiclinker/DynamicLinkerTest.java
@@ -19,6 +19,8 @@
import junit.framework.TestCase;
import android.support.test.InstrumentationRegistry;
+import java.io.File;
+
public class DynamicLinkerTest extends TestCase {
private native int functionA();
@@ -47,4 +49,9 @@
assertEquals(1, functionB());
}
+ public void testNativeLibraryNotExtracted() {
+ File dir = new File(InstrumentationRegistry.getContext().getApplicationInfo().nativeLibraryDir);
+ assertTrue(dir.isDirectory());
+ assertEquals(0, dir.list().length);
+ }
}
diff --git a/tests/tests/graphics/src/android/graphics/cts/BitmapColorSpaceTest.java b/tests/tests/graphics/src/android/graphics/cts/BitmapColorSpaceTest.java
index c24086a..f5f1560 100644
--- a/tests/tests/graphics/src/android/graphics/cts/BitmapColorSpaceTest.java
+++ b/tests/tests/graphics/src/android/graphics/cts/BitmapColorSpaceTest.java
@@ -85,13 +85,13 @@
b = Bitmap.createBitmap(32, 32, Bitmap.Config.RGBA_F16, true, sRGB);
cs = b.getColorSpace();
assertNotNull(cs);
- assertSame(ColorSpace.get(ColorSpace.Named.LINEAR_EXTENDED_SRGB), cs);
+ assertSame(ColorSpace.get(ColorSpace.Named.EXTENDED_SRGB), cs);
b = Bitmap.createBitmap(32, 32, Bitmap.Config.RGBA_F16, true,
ColorSpace.get(ColorSpace.Named.ADOBE_RGB));
cs = b.getColorSpace();
assertNotNull(cs);
- assertSame(ColorSpace.get(ColorSpace.Named.LINEAR_EXTENDED_SRGB), cs);
+ assertSame(ColorSpace.get(ColorSpace.Named.EXTENDED_SRGB), cs);
b = Bitmap.createBitmap(32, 32, Bitmap.Config.RGB_565, true, sRGB);
cs = b.getColorSpace();
diff --git a/tests/tests/graphics/src/android/graphics/cts/BitmapTest.java b/tests/tests/graphics/src/android/graphics/cts/BitmapTest.java
index 69bb828..f43df11 100644
--- a/tests/tests/graphics/src/android/graphics/cts/BitmapTest.java
+++ b/tests/tests/graphics/src/android/graphics/cts/BitmapTest.java
@@ -580,6 +580,13 @@
mBitmap.eraseColor(0);
}
+ @Test(expected = IllegalStateException.class)
+ public void testEraseColorLongOnRecycled() {
+ mBitmap.recycle();
+
+ mBitmap.eraseColor(Color.pack(0));
+ }
+
@Test(expected=IllegalStateException.class)
public void testEraseColorOnImmutable() {
mBitmap = BitmapFactory.decodeResource(mRes, R.drawable.start, mOptions);
@@ -588,6 +595,14 @@
mBitmap.eraseColor(0);
}
+ @Test(expected = IllegalStateException.class)
+ public void testEraseColorLongOnImmutable() {
+ mBitmap = BitmapFactory.decodeResource(mRes, R.drawable.start, mOptions);
+
+ //abnormal case: bitmap is immutable
+ mBitmap.eraseColor(Color.pack(0));
+ }
+
@Test
public void testEraseColor() {
// normal case
@@ -597,6 +612,109 @@
assertEquals(0xffff0000, mBitmap.getPixel(50, 50));
}
+ private static class ARGB {
+ public float alpha;
+ public float red;
+ public float green;
+ public float blue;
+ ARGB(float alpha, float red, float green, float blue) {
+ this.alpha = alpha;
+ this.red = red;
+ this.green = green;
+ this.blue = blue;
+ }
+ };
+
+ @Test
+ public void testEraseColorLong() {
+ // normal case
+ for (Config config : new Config[]{Config.ARGB_8888, Config.RGB_565, Config.RGBA_F16}) {
+ mBitmap = Bitmap.createBitmap(100, 100, config);
+ // pack SRGB colors into ColorLongs.
+ for (int color : new int[]{ Color.RED, Color.BLUE, Color.GREEN, Color.BLACK,
+ Color.WHITE, Color.TRANSPARENT }) {
+ if (config.equals(Config.RGB_565) && Float.compare(Color.alpha(color), 1.0f) != 0) {
+ // 565 doesn't support alpha.
+ continue;
+ }
+ mBitmap.eraseColor(Color.pack(color));
+ // The Bitmap is either SRGB or SRGBLinear (F16). getPixel(), which retrieves the
+ // color in SRGB, should match exactly.
+ ColorUtils.verifyColor("Config " + config + " mismatch at 10, 10 ",
+ color, mBitmap.getPixel(10, 10), 0);
+ ColorUtils.verifyColor("Config " + config + " mismatch at 50, 50 ",
+ color, mBitmap.getPixel(50, 50), 0);
+ }
+
+ // Use arbitrary colors in various ColorSpaces. getPixel() should approximately match
+ // the SRGB version of the color.
+ for (ARGB color : new ARGB[]{ new ARGB(1.0f, .5f, .5f, .5f),
+ new ARGB(1.0f, .3f, .6f, .9f),
+ new ARGB(0.5f, .2f, .8f, .7f) }) {
+ if (config.equals(Config.RGB_565) && Float.compare(color.alpha, 1.0f) != 0) {
+ continue;
+ }
+ int srgbColor = Color.argb(color.alpha, color.red, color.green, color.blue);
+ for (ColorSpace.Named e : ColorSpace.Named.values()) {
+ ColorSpace cs = ColorSpace.get(e);
+ if (cs.getModel() != ColorSpace.Model.RGB) {
+ continue;
+ }
+ if (((ColorSpace.Rgb) cs).getTransferParameters() == null) {
+ continue;
+ }
+ long longColor = Color.convert(srgbColor, cs);
+ mBitmap.eraseColor(longColor);
+ // These tolerances were chosen by trial and error. It is expected that
+ // some conversions do not round-trip perfectly.
+ int tolerance = 1;
+ if (config.equals(Config.RGB_565)) {
+ tolerance = 4;
+ } else if (cs.equals(ColorSpace.get(ColorSpace.Named.SMPTE_C))) {
+ tolerance = 3;
+ }
+
+ ColorUtils.verifyColor("Config " + config + ", ColorSpace " + cs
+ + ", mismatch at 10, 10 ", srgbColor, mBitmap.getPixel(10, 10),
+ tolerance);
+ ColorUtils.verifyColor("Config " + config + ", ColorSpace " + cs
+ + ", mismatch at 50, 50 ", srgbColor, mBitmap.getPixel(50, 50),
+ tolerance);
+ }
+ }
+ }
+ }
+
+ @Test
+ public void testEraseColorOnP3() {
+ // Use a ColorLong with a different ColorSpace than the Bitmap. getPixel() should
+ // approximately match the SRGB version of the color.
+ mBitmap = Bitmap.createBitmap(100, 100, Config.ARGB_8888, true,
+ ColorSpace.get(ColorSpace.Named.DISPLAY_P3));
+ int srgbColor = Color.argb(.5f, .3f, .6f, .7f);
+ long acesColor = Color.convert(srgbColor, ColorSpace.get(ColorSpace.Named.ACES));
+ mBitmap.eraseColor(acesColor);
+ ColorUtils.verifyColor("Mismatch at 15, 15", srgbColor, mBitmap.getPixel(15, 15), 1);
+ }
+
+ @Test(expected = IllegalArgumentException.class)
+ public void testEraseColorXYZ() {
+ mBitmap = Bitmap.createBitmap(100, 100, Config.ARGB_8888);
+ mBitmap.eraseColor(Color.convert(Color.BLUE, ColorSpace.get(ColorSpace.Named.CIE_XYZ)));
+ }
+
+ @Test(expected = IllegalArgumentException.class)
+ public void testEraseColorLAB() {
+ mBitmap = Bitmap.createBitmap(100, 100, Config.ARGB_8888);
+ mBitmap.eraseColor(Color.convert(Color.BLUE, ColorSpace.get(ColorSpace.Named.CIE_LAB)));
+ }
+
+ @Test(expected = IllegalArgumentException.class)
+ public void testEraseColorUnknown() {
+ mBitmap = Bitmap.createBitmap(100, 100, Config.ARGB_8888);
+ mBitmap.eraseColor(-1L);
+ }
+
@Test(expected=IllegalStateException.class)
public void testExtractAlphaFromRecycled() {
mBitmap.recycle();
@@ -1495,6 +1613,12 @@
}
@Test(expected = IllegalStateException.class)
+ public void testHardwareEraseColorLong() {
+ Bitmap bitmap = BitmapFactory.decodeResource(mRes, R.drawable.robot, HARDWARE_OPTIONS);
+ bitmap.eraseColor(Color.pack(0));
+ }
+
+ @Test(expected = IllegalStateException.class)
public void testHardwareCopyPixelsToBuffer() {
Bitmap bitmap = BitmapFactory.decodeResource(mRes, R.drawable.start, HARDWARE_OPTIONS);
ByteBuffer byteBuf = ByteBuffer.allocate(bitmap.getRowBytes() * bitmap.getHeight());
diff --git a/tests/tests/graphics/src/android/graphics/cts/ColorSpaceTest.java b/tests/tests/graphics/src/android/graphics/cts/ColorSpaceTest.java
index 01ba9e5..ad72765b 100644
--- a/tests/tests/graphics/src/android/graphics/cts/ColorSpaceTest.java
+++ b/tests/tests/graphics/src/android/graphics/cts/ColorSpaceTest.java
@@ -22,8 +22,6 @@
import static org.junit.Assert.assertSame;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;
-import org.junit.Rule;
-import org.junit.rules.ExpectedException;
import android.graphics.ColorSpace;
import android.support.test.filters.SmallTest;
@@ -71,9 +69,6 @@
private static final DoubleUnaryOperator sIdentity = DoubleUnaryOperator.identity();
- @Rule
- public ExpectedException mExpectedException = ExpectedException.none();
-
@Test
public void testNamedColorSpaces() {
for (ColorSpace.Named named : ColorSpace.Named.values()) {
@@ -318,17 +313,19 @@
@Test
public void testIsSRGB() {
- assertTrue(ColorSpace.get(ColorSpace.Named.SRGB).isSrgb());
- assertFalse(ColorSpace.get(ColorSpace.Named.LINEAR_SRGB).isSrgb());
- assertFalse(ColorSpace.get(ColorSpace.Named.EXTENDED_SRGB).isSrgb());
- assertFalse(ColorSpace.get(ColorSpace.Named.LINEAR_EXTENDED_SRGB).isSrgb());
- assertFalse(ColorSpace.get(ColorSpace.Named.DISPLAY_P3).isSrgb());
- assertFalse(ColorSpace.get(ColorSpace.Named.CIE_LAB).isSrgb());
- assertFalse(ColorSpace.get(ColorSpace.Named.CIE_XYZ).isSrgb());
+ for (ColorSpace.Named e : ColorSpace.Named.values()) {
+ ColorSpace colorSpace = ColorSpace.get(e);
+ if (e == ColorSpace.Named.SRGB) {
+ assertTrue(colorSpace.isSrgb());
+ } else {
+ assertFalse("Incorrectly treating " + colorSpace + " as SRGB!",
+ colorSpace.isSrgb());
+ }
+ }
- ColorSpace.Rgb cs = new ColorSpace.Rgb("My sRGB", SRGB_TO_XYZ,
+ ColorSpace.Rgb cs = new ColorSpace.Rgb("Almost sRGB", SRGB_TO_XYZ,
x -> Math.pow(x, 1.0f / 2.2f), x -> Math.pow(x, 2.2f));
- assertTrue(cs.isSrgb());
+ assertFalse(cs.isSrgb());
}
@Test
@@ -615,31 +612,6 @@
}
@Test
- public void testSinglePointAdaptation() {
- float[] illumD65xyY = Arrays.copyOf(ColorSpace.ILLUMINANT_D65,
- ColorSpace.ILLUMINANT_D65.length);
- float[] illumD50xyY = Arrays.copyOf(ColorSpace.ILLUMINANT_D50,
- ColorSpace.ILLUMINANT_D50.length);
-
- final float[] catXyz = ColorSpace.chromaticAdaptation(ColorSpace.Adaptation.BRADFORD,
- illumD65xyY, illumD50xyY);
-
- // Ensure the original arguments were not modified
- assertArrayEquals(illumD65xyY, ColorSpace.ILLUMINANT_D65, 0);
- assertArrayEquals(illumD50xyY, ColorSpace.ILLUMINANT_D50, 0);
-
- // Verify results. This reference data has been cross-checked with
- // http://www.brucelindbloom.com/index.html?Eqn_ChromAdapt.html
- final float[] illumD65ToIllumD50Xyz = {
- 1.0478525f, 0.0295722f, -0.0092367f,
- 0.0229074f, 0.9904668f, 0.0150463f,
- -0.0501464f, -0.0170567f, 0.7520621f
- };
-
- assertArrayEquals(catXyz, illumD65ToIllumD50Xyz, 1e-7f);
- }
-
- @Test
public void testImplicitSRGBConnector() {
ColorSpace.Connector connector1 = ColorSpace.connect(
ColorSpace.get(ColorSpace.Named.DCI_P3));
@@ -813,19 +785,6 @@
1 / 1.055, 0.055 / 1.055, 1 / 12.92, 0.04045, 2.4)));
}
- @Test
- public void testCctToIlluminantdXyz() {
- assertArrayEquals(ColorSpace.cctToIlluminantdXyz(5000),
- xyYToXyz(ColorSpace.ILLUMINANT_D50), 0.01f);
- assertArrayEquals(ColorSpace.cctToIlluminantdXyz(7500),
- xyYToXyz(ColorSpace.ILLUMINANT_D75), 0.01f);
- }
-
- @Test
- public void testCctToIlluminantdXyzErrors() {
- mExpectedException.expect(IllegalArgumentException.class);
- ColorSpace.cctToIlluminantdXyz(0);
- }
@SuppressWarnings("SameParameterValue")
private static void assertArrayNotEquals(float[] a, float[] b, float eps) {
@@ -843,12 +802,4 @@
}
}
}
-
- /**
- * Convenience function copied from android.graphics.ColorSpace
- */
- private static float[] xyYToXyz(float[] xyY) {
- return new float[] { xyY[0] / xyY[1], 1.0f, (1 - xyY[0] - xyY[1]) / xyY[1] };
- }
-
}
diff --git a/tests/tests/graphics/src/android/graphics/cts/Color_ColorLongTest.java b/tests/tests/graphics/src/android/graphics/cts/Color_ColorLongTest.java
index adb7c1b..a2c0cd6 100644
--- a/tests/tests/graphics/src/android/graphics/cts/Color_ColorLongTest.java
+++ b/tests/tests/graphics/src/android/graphics/cts/Color_ColorLongTest.java
@@ -366,6 +366,14 @@
}
@Test
+ public void testConvertToBT709() {
+ int sRgb = Color.argb(1.0f, 0.5f, 0.5f, 0.5f);
+ long bt709 = Color.convert(sRgb, ColorSpace.get(Named.BT709));
+
+ assertEquals(ColorSpace.get(Named.BT709), Color.colorSpace(bt709));
+ }
+
+ @Test
public void testConvertColorInt() {
long color = convert(0xffff8000, ColorSpace.get(Named.ADOBE_RGB));
diff --git a/tests/tests/graphics/src/android/graphics/cts/ImageDecoderTest.java b/tests/tests/graphics/src/android/graphics/cts/ImageDecoderTest.java
index 0cbf5d4..786f933 100644
--- a/tests/tests/graphics/src/android/graphics/cts/ImageDecoderTest.java
+++ b/tests/tests/graphics/src/android/graphics/cts/ImageDecoderTest.java
@@ -1693,13 +1693,16 @@
for (int resId : new int[] { R.drawable.png_test, R.raw.f16 }) {
Bitmap normal = null;
try {
- normal = ImageDecoder.decodeBitmap(f.apply(resId));
+ normal = ImageDecoder.decodeBitmap(f.apply(resId), ((decoder, info, source) -> {
+ decoder.setAllocator(ImageDecoder.ALLOCATOR_SOFTWARE);
+ }));
} catch (IOException e) {
fail("Failed with exception " + e);
}
assertNotNull(normal);
int normalByteCount = normal.getAllocationByteCount();
- for (int allocator : ALLOCATORS) {
+ int[] allocators = { ImageDecoder.ALLOCATOR_HARDWARE, ImageDecoder.ALLOCATOR_DEFAULT };
+ for (int allocator : allocators) {
l.allocator = allocator;
Bitmap test = null;
try {
@@ -1710,33 +1713,13 @@
assertNotNull(test);
int byteCount = test.getAllocationByteCount();
- if (allocator == ImageDecoder.ALLOCATOR_HARDWARE
- || allocator == ImageDecoder.ALLOCATOR_DEFAULT) {
- if (resId == R.drawable.png_test) {
- // We do not support 565 in HARDWARE, so no RAM savings
- // are possible.
- assertEquals(normalByteCount, byteCount);
- } else { // R.raw.f16
- // This image defaults to F16. MEMORY_POLICY_LOW_RAM
- // forces "test" to decode to 8888. But if the device
- // does not support F16 in HARDWARE, "normal" is also
- // 8888. Its Config is HARDWARE either way, but we can
- // detect its underlying pixel format by checking the
- // ColorSpace, which is always LINEAR_EXTENDED_SRGB for
- // F16.
- if (normal.getColorSpace().equals(
- ColorSpace.get(ColorSpace.Named.LINEAR_EXTENDED_SRGB))) {
- // F16. "test" should be smaller.
- assertTrue(byteCount < normalByteCount);
- } else {
- // 8888. No RAM savings possible.
- assertEquals(normalByteCount, byteCount);
- }
- }
- } else {
- // Not decoding to HARDWARE, but |normal| was. As such this should always
- // succeed in being smaller, as software will decode to 565 in this case.
- // This will always be less than whatever HARDWARE supports.
+ if (resId == R.drawable.png_test) {
+ // We do not support 565 in HARDWARE, so no RAM savings
+ // are possible.
+ assertEquals(normalByteCount, byteCount);
+ } else { // R.raw.f16
+ // This image defaults to F16. MEMORY_POLICY_LOW_RAM
+ // forces "test" to decode to 8888.
assertTrue(byteCount < normalByteCount);
}
}
@@ -2109,7 +2092,7 @@
ImageDecoder.Source src = ImageDecoder.createSource(assets, record.name);
for (ColorSpace cs : new ColorSpace[] {
sSRGB,
- ColorSpace.get(ColorSpace.Named.LINEAR_EXTENDED_SRGB),
+ ColorSpace.get(ColorSpace.Named.LINEAR_SRGB),
ColorSpace.get(ColorSpace.Named.DISPLAY_P3),
ColorSpace.get(ColorSpace.Named.ADOBE_RGB),
ColorSpace.get(ColorSpace.Named.BT709),
@@ -2120,9 +2103,9 @@
ColorSpace.get(ColorSpace.Named.PRO_PHOTO_RGB),
ColorSpace.get(ColorSpace.Named.ACES),
ColorSpace.get(ColorSpace.Named.ACESCG),
- // FIXME: This returns LINEAR_EXTENDED_SRGB.
+ // FIXME: This returns LINEAR_SRGB.
// See b/117601185 and b/77276533
- //ColorSpace.get(ColorSpace.Named.LINEAR_SRGB),
+ //ColorSpace.get(ColorSpace.Named.LINEAR_EXTENDED_SRGB),
}) {
try {
Bitmap bm = ImageDecoder.decodeBitmap(src, (decoder, info, s) -> {
diff --git a/tests/tests/graphics/src/android/graphics/cts/PaintTest.java b/tests/tests/graphics/src/android/graphics/cts/PaintTest.java
index 9d7d510..0d5b5dd 100644
--- a/tests/tests/graphics/src/android/graphics/cts/PaintTest.java
+++ b/tests/tests/graphics/src/android/graphics/cts/PaintTest.java
@@ -31,7 +31,9 @@
import android.graphics.Bitmap;
import android.graphics.BitmapShader;
import android.graphics.BlendMode;
+import android.graphics.Color;
import android.graphics.ColorFilter;
+import android.graphics.ColorSpace;
import android.graphics.MaskFilter;
import android.graphics.Matrix;
import android.graphics.Paint;
@@ -55,11 +57,15 @@
import android.text.SpannedString;
import com.android.compatibility.common.util.CddTest;
+import com.android.compatibility.common.util.ColorUtils;
import org.junit.Test;
import org.junit.runner.RunWith;
import java.util.Locale;
+import java.util.function.BiConsumer;
+import java.util.function.Function;
+import java.util.function.Supplier;
@SmallTest
@RunWith(AndroidJUnit4.class)
@@ -83,6 +89,42 @@
}
@Test
+ public void testDefaultColor() {
+ Supplier<Paint> set = () -> {
+ Paint result = new Paint();
+ result.setColor(Color.BLUE);
+ assertEquals(Color.BLUE, result.getColor());
+ result.setShadowLayer(10.0f, 1.0f, 1.0f, Color.RED);
+ assertEquals(Color.RED, result.getShadowLayerColor());
+
+ Paint def = new Paint();
+ result.set(def);
+ return result;
+ };
+ Supplier<Paint> reset = () -> {
+ Paint result = new Paint();
+ result.setColor(Color.GREEN);
+ assertEquals(Color.GREEN, result.getColor());
+ result.setShadowLayer(10.0f, 1.0f, 1.0f, Color.WHITE);
+ assertEquals(Color.WHITE, result.getShadowLayerColor());
+
+ result.reset();
+ return result;
+ };
+ for (Paint p : new Paint[]{ new Paint(),
+ new Paint(1),
+ new Paint(new Paint()),
+ set.get(),
+ reset.get()}) {
+ assertEquals(Color.BLACK, p.getColor());
+ assertEquals(Color.TRANSPARENT, p.getShadowLayerColor());
+
+ assertEquals(Color.BLACK, Color.toArgb(p.getColorLong()));
+ assertEquals(Color.TRANSPARENT, Color.toArgb(p.getShadowLayerColorLong()));
+ }
+ }
+
+ @Test
public void testBreakText() {
String text = "HIJKLMN";
char[] textChars = text.toCharArray();
@@ -731,6 +773,46 @@
}
@Test
+ public void testSetAlpha() {
+ for (ColorSpace.Named e : new ColorSpace.Named[] {
+ ColorSpace.Named.SRGB,
+ ColorSpace.Named.LINEAR_EXTENDED_SRGB,
+ ColorSpace.Named.DISPLAY_P3}) {
+ ColorSpace cs = ColorSpace.get(e);
+
+ // Arbitrary colors
+ final float red = .2f;
+ final float green = .7f;
+ final float blue = .9f;
+ final long desiredColor = Color.pack(red, green, blue, 1.0f, cs);
+
+ Paint p = new Paint();
+ p.setColor(desiredColor);
+ final long origColor = p.getColorLong();
+ assertEquals(desiredColor, origColor);
+
+ final float origRed = Color.red(origColor);
+ final float origGreen = Color.green(origColor);
+ final float origBlue = Color.blue(origColor);
+
+ // There is a slight difference in the packed color.
+ assertEquals(red, Color.red(origColor), 0.002f);
+ assertEquals(green, Color.green(origColor), 0.002f);
+ assertEquals(blue, Color.blue(origColor), 0.002f);
+
+ for (int alpha = 0; alpha <= 255; ++alpha) {
+ p.setAlpha(alpha);
+ assertEquals(alpha, p.getAlpha());
+
+ final long color = p.getColorLong();
+ assertEquals(origRed, Color.red(color), 0.0f);
+ assertEquals(origGreen, Color.green(color), 0.0f);
+ assertEquals(origBlue, Color.blue(color), 0.0f);
+ }
+ }
+ }
+
+ @Test
public void testSetFilterBitmap() {
Paint p = new Paint();
@@ -2066,4 +2148,99 @@
default: throw new IllegalArgumentException("Unknown PorterDuffmode: " + mode);
}
}
+
+ private void testColorLongs(String methodName, BiConsumer<Paint, Long> setColor,
+ Function<Paint, Integer> getColor,
+ Function<Paint, Long> getColorLong) {
+ // Pack SRGB colors into ColorLongs
+ for (int color : new int[]{ Color.RED, Color.BLUE, Color.GREEN, Color.BLACK,
+ Color.WHITE, Color.TRANSPARENT }) {
+ final Paint p = new Paint();
+ final long longColor = Color.pack(color);
+ setColor.accept(p, longColor);
+
+ assertEquals(color, getColor.apply(p).intValue());
+ assertEquals(longColor, getColorLong.apply(p).longValue());
+ }
+
+ // Arbitrary colors in various ColorSpaces
+ for (int srgbColor : new int[]{ Color.argb(1.0f, .5f, .5f, .5f),
+ Color.argb(1.0f, .3f, .6f, .9f),
+ Color.argb(0.5f, .2f, .8f, .7f) }) {
+ for (ColorSpace.Named e : ColorSpace.Named.values()) {
+ ColorSpace cs = ColorSpace.get(e);
+ if (cs.getModel() != ColorSpace.Model.RGB) {
+ continue;
+ }
+ if (((ColorSpace.Rgb) cs).getTransferParameters() == null) {
+ continue;
+ }
+
+ final long longColor = Color.convert(srgbColor, cs);
+ Paint p = new Paint();
+ setColor.accept(p, longColor);
+ assertEquals(longColor, getColorLong.apply(p).longValue());
+
+ // These tolerances were chosen by trial and error. It is expected that
+ // some conversions do not round-trip perfectly.
+ int tolerance = 0;
+ if (cs.equals(ColorSpace.get(ColorSpace.Named.SMPTE_C))) {
+ tolerance = 2;
+ }
+ int color = getColor.apply(p);
+ ColorUtils.verifyColor("Paint#" + methodName + " mismatch for " + cs, srgbColor,
+ color, tolerance);
+ }
+ }
+ }
+
+ @Test
+ public void testSetColorLong() {
+ testColorLongs("setColor", (p, c) -> p.setColor(c), (p) -> p.getColor(),
+ (p) -> p.getColorLong());
+ }
+
+ @Test(expected = IllegalArgumentException.class)
+ public void testSetColorXYZ() {
+ Paint p = new Paint();
+ p.setColor(Color.convert(Color.BLUE, ColorSpace.get(ColorSpace.Named.CIE_XYZ)));
+ }
+
+ @Test(expected = IllegalArgumentException.class)
+ public void testSetColorLAB() {
+ Paint p = new Paint();
+ p.setColor(Color.convert(Color.BLUE, ColorSpace.get(ColorSpace.Named.CIE_LAB)));
+ }
+
+ @Test(expected = IllegalArgumentException.class)
+ public void testSetColorUnknown() {
+ Paint p = new Paint();
+ p.setColor(-1L);
+ }
+
+ @Test
+ public void testSetShadowLayerLong() {
+ testColorLongs("setShadowLayer", (p, c) -> p.setShadowLayer(10.0f, 1.0f, 1.0f, c),
+ (p) -> p.getShadowLayerColor(), (p) -> p.getShadowLayerColorLong());
+ }
+
+ @Test(expected = IllegalArgumentException.class)
+ public void testSetShadowLayerXYZ() {
+ Paint p = new Paint();
+ p.setShadowLayer(10.0f, 1.0f, 1.0f,
+ Color.convert(Color.BLUE, ColorSpace.get(ColorSpace.Named.CIE_XYZ)));
+ }
+
+ @Test(expected = IllegalArgumentException.class)
+ public void testSetShadowLayerLAB() {
+ Paint p = new Paint();
+ p.setShadowLayer(10.0f, 1.0f, 1.0f,
+ Color.convert(Color.BLUE, ColorSpace.get(ColorSpace.Named.CIE_LAB)));
+ }
+
+ @Test(expected = IllegalArgumentException.class)
+ public void testSetShadowLayerUnknown() {
+ Paint p = new Paint();
+ p.setShadowLayer(10.0f, 1.0f, 1.0f, -1L);
+ }
}
diff --git a/tests/tests/graphics/src/android/graphics/text/cts/MeasuredTextTest.java b/tests/tests/graphics/src/android/graphics/text/cts/MeasuredTextTest.java
index 6c4b312..8478834 100644
--- a/tests/tests/graphics/src/android/graphics/text/cts/MeasuredTextTest.java
+++ b/tests/tests/graphics/src/android/graphics/text/cts/MeasuredTextTest.java
@@ -17,10 +17,14 @@
package android.graphics.text.cts;
import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertTrue;
import android.content.Context;
import android.content.res.AssetManager;
+import android.graphics.Bitmap;
+import android.graphics.Canvas;
import android.graphics.Paint;
import android.graphics.Rect;
import android.graphics.Typeface;
@@ -28,6 +32,9 @@
import android.support.test.InstrumentationRegistry;
import android.support.test.filters.SmallTest;
import android.support.test.runner.AndroidJUnit4;
+import android.text.PrecomputedText;
+import android.text.SpannableStringBuilder;
+import android.text.TextPaint;
import org.junit.BeforeClass;
import org.junit.Test;
@@ -309,4 +316,109 @@
new MeasuredText.Builder(text.toCharArray())
.appendReplacementRun(sPaint, text.length() - 1, 1.0f).build();
}
+
+ public Bitmap makeBitmapFromSsb(String text, TextPaint paint, boolean isRtl) {
+ // drawTetRun is not aware of multiple style text.
+ final SpannableStringBuilder ssb = new SpannableStringBuilder(text);
+ final Bitmap ssbBitmap = Bitmap.createBitmap(640, 480, Bitmap.Config.ARGB_8888);
+ final Canvas ssbCanvas = new Canvas(ssbBitmap);
+ ssbCanvas.save();
+ ssbCanvas.translate(0, 0);
+ ssbCanvas.drawTextRun(ssb, 0, ssb.length(), 0, ssb.length(),
+ 0.0f /* x */, 240.0f /* y */, isRtl, paint);
+ ssbCanvas.restore();
+ return ssbBitmap;
+ }
+
+ public Bitmap makeBitmapFromMtWithSamePaint(String text, TextPaint paint, boolean isRtl) {
+ // MeasuredText uses measured result if the given paint is equal to the applied one.
+ final MeasuredText mt = new MeasuredText.Builder(text.toCharArray())
+ .appendStyleRun(paint, text.length(), isRtl)
+ .build();
+ final Bitmap mtBitmap = Bitmap.createBitmap(640, 480, Bitmap.Config.ARGB_8888);
+ final Canvas mtCanvas = new Canvas(mtBitmap);
+ mtCanvas.save();
+ mtCanvas.translate(0, 0);
+ mtCanvas.drawTextRun(mt, 0, text.length(), 0, text.length(),
+ 0.0f /* x */, 240.0f /* y */, isRtl, paint);
+ mtCanvas.restore();
+ return mtBitmap;
+ }
+
+ public Bitmap makeBitmapFromMtWithDifferentPaint(String text, TextPaint paint, boolean isRtl) {
+ // If different paint is provided when drawing, MeasuredText discards the measured result
+ // and recompute immediately. Thus the final output must be the same with given one.
+ final MeasuredText mt2 = new MeasuredText.Builder(text.toCharArray())
+ .appendStyleRun(new Paint(), text.length(), isRtl)
+ .build();
+ final Bitmap mt2Bitmap = Bitmap.createBitmap(640, 480, Bitmap.Config.ARGB_8888);
+ final Canvas mt2Canvas = new Canvas(mt2Bitmap);
+ mt2Canvas.save();
+ mt2Canvas.translate(0, 0);
+ mt2Canvas.drawTextRun(mt2, 0, text.length(), 0, text.length(),
+ 0.0f /* x */, 240.0f /* y */, isRtl, paint);
+ mt2Canvas.restore();
+ return mt2Bitmap;
+ }
+
+ public Bitmap makeBitmapFromPct(String text, TextPaint paint, boolean isRtl) {
+ final PrecomputedText pct = PrecomputedText.create(
+ text, new PrecomputedText.Params.Builder(paint).build());
+ final Bitmap pctBitmap = Bitmap.createBitmap(640, 480, Bitmap.Config.ARGB_8888);
+ final Canvas pctCanvas = new Canvas(pctBitmap);
+ pctCanvas.save();
+ pctCanvas.translate(0, 0);
+ pctCanvas.drawTextRun(pct, 0, text.length(), 0, text.length(),
+ 0.0f /* x */, 240.0f /* y */, isRtl, paint);
+ pctCanvas.restore();
+ return pctBitmap;
+ }
+
+ @Test
+ public void testCanvasDrawTextRun_sameOutputTestForLatinText() {
+ final TextPaint paint = new TextPaint();
+ paint.setTextSize(30.0f);
+
+ final String text = "Hello, World";
+
+ final Bitmap blankBitmap = Bitmap.createBitmap(640, 480, Bitmap.Config.ARGB_8888);
+ final Bitmap ssbBitmap = makeBitmapFromSsb(text, paint, false);
+ assertFalse(blankBitmap.sameAs(ssbBitmap));
+
+ assertTrue(ssbBitmap.sameAs(makeBitmapFromMtWithSamePaint(text, paint, false)));
+ assertTrue(ssbBitmap.sameAs(makeBitmapFromMtWithDifferentPaint(text, paint, false)));
+ assertTrue(ssbBitmap.sameAs(makeBitmapFromPct(text, paint, false)));
+ }
+
+ @Test
+ public void testCanvasDrawTextRun_sameOutputTestForCJKText() {
+ final TextPaint paint = new TextPaint();
+ paint.setTextSize(30.0f);
+
+ final String text = "\u3042\u3044\u3046\u3048\u304A";
+
+ final Bitmap blankBitmap = Bitmap.createBitmap(640, 480, Bitmap.Config.ARGB_8888);
+ final Bitmap ssbBitmap = makeBitmapFromSsb(text, paint, false);
+ assertFalse(blankBitmap.sameAs(ssbBitmap));
+
+ assertTrue(ssbBitmap.sameAs(makeBitmapFromMtWithSamePaint(text, paint, false)));
+ assertTrue(ssbBitmap.sameAs(makeBitmapFromMtWithDifferentPaint(text, paint, false)));
+ assertTrue(ssbBitmap.sameAs(makeBitmapFromPct(text, paint, false)));
+ }
+
+ @Test
+ public void testCanvasDrawTextRun_sameOutputTestForRTLText() {
+ final TextPaint paint = new TextPaint();
+ paint.setTextSize(30.0f);
+
+ final String text = "\u05D0\u05D1\u05D2\u05D3\u05D4";
+
+ final Bitmap blankBitmap = Bitmap.createBitmap(640, 480, Bitmap.Config.ARGB_8888);
+ final Bitmap ssbBitmap = makeBitmapFromSsb(text, paint, true);
+ assertFalse(blankBitmap.sameAs(ssbBitmap));
+
+ assertTrue(ssbBitmap.sameAs(makeBitmapFromMtWithSamePaint(text, paint, true)));
+ assertTrue(ssbBitmap.sameAs(makeBitmapFromMtWithDifferentPaint(text, paint, true)));
+ assertTrue(ssbBitmap.sameAs(makeBitmapFromPct(text, paint, true)));
+ }
}
diff --git a/tests/tests/hardware/src/android/hardware/biometrics/cts/BiometricManagerTest.java b/tests/tests/hardware/src/android/hardware/biometrics/cts/BiometricManagerTest.java
index 6d85626..44f9b20 100644
--- a/tests/tests/hardware/src/android/hardware/biometrics/cts/BiometricManagerTest.java
+++ b/tests/tests/hardware/src/android/hardware/biometrics/cts/BiometricManagerTest.java
@@ -49,7 +49,7 @@
} else {
// No biometrics are enrolled. CTSVerifier should test the other error cases.
assertTrue(mBiometricManager.canAuthenticate()
- == BiometricManager.BIOMETRIC_ERROR_NO_BIOMETRICS);
+ == BiometricManager.BIOMETRIC_ERROR_NONE_ENROLLED);
}
}
}
diff --git a/tests/tests/jni/AndroidManifest.xml b/tests/tests/jni/AndroidManifest.xml
index 2724573..18ef4c6 100644
--- a/tests/tests/jni/AndroidManifest.xml
+++ b/tests/tests/jni/AndroidManifest.xml
@@ -18,7 +18,7 @@
package="android.jni.cts">
<uses-permission android:name="android.permission.DISABLE_KEYGUARD" />
- <application>
+ <application android:extractNativeLibs="true">
<uses-library android:name="android.test.runner" />
</application>
diff --git a/tests/tests/jvmti/attaching/src/android.jvmti.attaching.cts/AttachingTest.java b/tests/tests/jvmti/attaching/src/android.jvmti.attaching.cts/AttachingTest.java
index 994681f..5874d29 100644
--- a/tests/tests/jvmti/attaching/src/android.jvmti.attaching.cts/AttachingTest.java
+++ b/tests/tests/jvmti/attaching/src/android.jvmti.attaching.cts/AttachingTest.java
@@ -33,6 +33,7 @@
import java.io.File;
import java.io.FileInputStream;
+import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
@@ -43,6 +44,7 @@
import java.util.HashSet;
import java.util.List;
import java.util.Set;
+import java.util.zip.ZipFile;
@RunWith(Parameterized.class)
@FixMethodOrder(MethodSorters.NAME_ASCENDING)
@@ -134,13 +136,29 @@
return params;
}
+ private static InputStream getAgentInputStream(ClassLoader cl, String lib) throws Exception {
+ String clfile = ((BaseDexClassLoader) cl).findLibrary(lib);
+ try {
+ return new FileInputStream(clfile);
+ } catch (FileNotFoundException e) {
+ if (clfile.contains(".apk!/")) {
+ // Looks like it might be a zipaligned library. Get it from the apk directly.
+ // Skip the !/
+ String libPath = clfile.substring(clfile.lastIndexOf('!') + 2);
+ String apkPath = clfile.substring(0, clfile.lastIndexOf('!'));
+ ZipFile zip = new ZipFile(apkPath);
+ return zip.getInputStream(zip.getEntry(libPath));
+ } else {
+ throw e;
+ }
+ }
+ }
private static File copyAgentToFile(String lib) throws Exception {
ClassLoader cl = AttachingTest.class.getClassLoader();
assertTrue(cl instanceof BaseDexClassLoader);
File copiedAgent = File.createTempFile("agent", ".so");
- try (InputStream is = new FileInputStream(
- ((BaseDexClassLoader) cl).findLibrary(lib))) {
+ try (InputStream is = getAgentInputStream(cl, lib)) {
try (OutputStream os = new FileOutputStream(copiedAgent)) {
byte[] buffer = new byte[64 * 1024];
diff --git a/tests/tests/keystore/src/android/keystore/cts/KeyGeneratorTest.java b/tests/tests/keystore/src/android/keystore/cts/KeyGeneratorTest.java
index 9a83b95..b777a7a 100644
--- a/tests/tests/keystore/src/android/keystore/cts/KeyGeneratorTest.java
+++ b/tests/tests/keystore/src/android/keystore/cts/KeyGeneratorTest.java
@@ -297,6 +297,9 @@
// TODO: This test will fail until b/117509689 is resolved.
public void testDESKeySupportedSizes() throws Exception {
+ if (!TestUtils.supports3DES()) {
+ return;
+ }
KeyGenerator keyGenerator = getKeyGenerator("DESede");
KeyGenParameterSpec.Builder goodSpec = getWorkingSpec();
CountingSecureRandom rng = new CountingSecureRandom();
diff --git a/tests/tests/keystore/src/android/keystore/cts/KeyPairGeneratorTest.java b/tests/tests/keystore/src/android/keystore/cts/KeyPairGeneratorTest.java
index b4b17f1..31b644a 100644
--- a/tests/tests/keystore/src/android/keystore/cts/KeyPairGeneratorTest.java
+++ b/tests/tests/keystore/src/android/keystore/cts/KeyPairGeneratorTest.java
@@ -1114,7 +1114,7 @@
generator.initialize(new KeyGenParameterSpec.Builder(
TEST_ALIAS_1,
KeyProperties.PURPOSE_SIGN | KeyProperties.PURPOSE_VERIFY)
- .setDigests(KeyProperties.DIGEST_NONE, KeyProperties.DIGEST_SHA384)
+ .setDigests(KeyProperties.DIGEST_NONE, KeyProperties.DIGEST_SHA256)
.setIsStrongBoxBacked(useStrongbox)
.build());
KeyPair keyPair = generator.generateKeyPair();
diff --git a/tests/tests/libcoreapievolution/AndroidTest.xml b/tests/tests/libcoreapievolution/AndroidTest.xml
index f777701..0dd61fa 100644
--- a/tests/tests/libcoreapievolution/AndroidTest.xml
+++ b/tests/tests/libcoreapievolution/AndroidTest.xml
@@ -16,6 +16,8 @@
<configuration description="Config for CTS Legacy Libcore test cases">
<option name="test-suite-tag" value="cts" />
<option name="config-descriptor:metadata" key="component" value="libcore" />
+ <option name="config-descriptor:metadata" key="parameter" value="multi_abi" />
+ <option name="config-descriptor:metadata" key="parameter" value="not_instant_app" />
<target_preparer class="com.android.tradefed.targetprep.suite.SuiteApkInstaller">
<option name="cleanup-apks" value="true" />
<option name="test-file-name" value="CtsLibcoreApiEvolutionTestCases.apk" />
diff --git a/tests/tests/libcoreapievolution/src/android/apievolution/cts/ApiEvolutionTest.java b/tests/tests/libcoreapievolution/src/android/apievolution/cts/ApiEvolutionTest.java
index a7ba9ad..8fea09b 100644
--- a/tests/tests/libcoreapievolution/src/android/apievolution/cts/ApiEvolutionTest.java
+++ b/tests/tests/libcoreapievolution/src/android/apievolution/cts/ApiEvolutionTest.java
@@ -23,8 +23,17 @@
import java.lang.annotation.RetentionPolicy;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
+import java.nio.Buffer;
+import java.nio.ByteBuffer;
+import java.nio.CharBuffer;
+import java.nio.DoubleBuffer;
+import java.nio.FloatBuffer;
+import java.nio.IntBuffer;
+import java.nio.LongBuffer;
+import java.nio.ShortBuffer;
import java.text.ParseException;
import java.util.Arrays;
+import java.util.List;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
@@ -40,27 +49,84 @@
public class ApiEvolutionTest {
/**
- * Tests for synthetic methods generated by
- * {@link dalvik.annotation.codegen.CovariantReturnType}.
+ * Tests for the presence of a synthetic overload for a subclass method override
+ * that has a more specific (sub-) return type, but doesn't carry any annotation.
*/
@Test
- public void testCovariantReturnTypeMethods() throws Exception {
- // Example of the "normal" way round for synthetic methods generated by the toolchain when
- // a subclass has a more specific return type.
+ public void testCovariantReturnTypeMethods_specializingSubclass() throws Exception {
// Exceptions are not required to be identical in this case because the synthetic method
// mirrors the superclass version.
assertSyntheticMethodOverloadExists(
Sub.class, "myMethod", new Class[] { Integer.class },
String.class, Object.class,
false /* requireIdenticalExceptions */);
+ }
- // Cases of synthetic platform methods that have been introduced by the platform build tools
- // in response to the presence of a @CovarientReturnType annotation.
- // More should be added for every use of the annotation.
+ /**
+ * Tests for the presence of a synthetic overload for {@link ConcurrentHashMap#keySet}
+ * that must be introduced by the platform build tools in response to the presence of a
+ * {@link dalvik.annotation.codegen.CovariantReturnType} annotation. http://b/28099367
+ */
+ @Test
+ public void testCovariantReturnTypeMethods_annotation_concurrentHashMap() throws Exception {
assertSyntheticMethodOverloadExists(ConcurrentHashMap.class, "keySet", null, Set.class,
ConcurrentHashMap.KeySetView.class, true);
}
+ @Test public void testCovariantReturnTypeMethods_annotation_byteBuffer() throws Exception {
+ assertSyntheticBufferMethodOverloadsExists(ByteBuffer.class);
+ }
+
+ @Test public void testCovariantReturnTypeMethods_annotation_charBuffer() throws Exception {
+ assertSyntheticBufferMethodOverloadsExists(CharBuffer.class);
+ }
+
+ @Test public void testCovariantReturnTypeMethods_annotation_doubleBuffer() throws Exception {
+ assertSyntheticBufferMethodOverloadsExists(DoubleBuffer.class);
+ }
+
+ @Test public void testCovariantReturnTypeMethods_annotation_floatBuffer() throws Exception {
+ assertSyntheticBufferMethodOverloadsExists(FloatBuffer.class);
+ }
+
+ @Test public void testCovariantReturnTypeMethods_annotation_intBuffer() throws Exception {
+ assertSyntheticBufferMethodOverloadsExists(IntBuffer.class);
+ }
+
+ @Test public void testCovariantReturnTypeMethods_annotation_longBuffer() throws Exception {
+ assertSyntheticBufferMethodOverloadsExists(LongBuffer.class);
+ }
+
+ @Test public void testCovariantReturnTypeMethods_annotation_shortBuffer() throws Exception {
+ assertSyntheticBufferMethodOverloadsExists(ShortBuffer.class);
+ }
+
+ /**
+ * Asserts the presence of synthetic methods overloads for methods that return {@code this} on
+ * {@link Buffer} subclasses, and which are annotated with {@code @CovariantReturnType}.
+ * In OpenJDK 9 the return types were changed from {@link Buffer} to be the subclass's type
+ * instead. http://b/71597787
+ */
+ private static void assertSyntheticBufferMethodOverloadsExists(Class<? extends Buffer> c)
+ throws Exception {
+ assertSyntheticBufferMethodOverloadExists(c, "position", new Class[] { Integer.TYPE });
+ assertSyntheticBufferMethodOverloadExists(c, "limit", new Class[] { Integer.TYPE });
+ assertSyntheticBufferMethodOverloadExists(c, "mark", null);
+ assertSyntheticBufferMethodOverloadExists(c, "reset", null);
+ assertSyntheticBufferMethodOverloadExists(c, "clear", null);
+ assertSyntheticBufferMethodOverloadExists(c, "flip", null);
+ assertSyntheticBufferMethodOverloadExists(c, "rewind", null);
+ }
+
+ private static void assertSyntheticBufferMethodOverloadExists(
+ Class<? extends Buffer> bufferClass, String methodName, Class[] parameterTypes)
+ throws Exception {
+ assertSyntheticMethodOverloadExists(bufferClass, methodName, parameterTypes,
+ Buffer.class /* originalReturnType */,
+ bufferClass /* syntheticReturnType */,
+ true /* requireIdenticalExceptions */);
+ }
+
private static void assertSyntheticMethodOverloadExists(
Class<?> clazz, String methodName, Class[] parameterTypes,
Class<?> originalReturnType, Class<?> syntheticReturnType,
diff --git a/tests/tests/libcorefileio/AndroidTest.xml b/tests/tests/libcorefileio/AndroidTest.xml
index 074a833..65926f8 100644
--- a/tests/tests/libcorefileio/AndroidTest.xml
+++ b/tests/tests/libcorefileio/AndroidTest.xml
@@ -16,6 +16,8 @@
<configuration description="Config for CTS Legacy Libcore test cases">
<option name="test-suite-tag" value="cts" />
<option name="config-descriptor:metadata" key="component" value="libcore" />
+ <option name="config-descriptor:metadata" key="parameter" value="multi_abi" />
+ <option name="config-descriptor:metadata" key="parameter" value="not_instant_app" />
<target_preparer class="com.android.tradefed.targetprep.suite.SuiteApkInstaller">
<option name="cleanup-apks" value="true" />
<option name="test-file-name" value="CtsLibcoreFileIOTestCases.apk" />
diff --git a/tests/tests/libcorelegacy22/AndroidTest.xml b/tests/tests/libcorelegacy22/AndroidTest.xml
index d5409d7..d1706d9 100644
--- a/tests/tests/libcorelegacy22/AndroidTest.xml
+++ b/tests/tests/libcorelegacy22/AndroidTest.xml
@@ -16,6 +16,8 @@
<configuration description="Config for CTS Legacy Libcore test cases">
<option name="test-suite-tag" value="cts" />
<option name="config-descriptor:metadata" key="component" value="libcore" />
+ <option name="config-descriptor:metadata" key="parameter" value="multi_abi" />
+ <option name="config-descriptor:metadata" key="parameter" value="not_instant_app" />
<target_preparer class="com.android.tradefed.targetprep.suite.SuiteApkInstaller">
<option name="cleanup-apks" value="true" />
<option name="test-file-name" value="CtsLibcoreLegacy22TestCases.apk" />
diff --git a/tests/tests/location/src/android/location/cts/LocationManagerTest.java b/tests/tests/location/src/android/location/cts/LocationManagerTest.java
index daa8d33..5d17e80 100644
--- a/tests/tests/location/src/android/location/cts/LocationManagerTest.java
+++ b/tests/tests/location/src/android/location/cts/LocationManagerTest.java
@@ -255,64 +255,6 @@
}
/**
- * Tests that location mode is consistent with which providers are enabled. Sadly we can only
- * passively test whatever mode happens to be selected--actually changing the mode would require
- * the test to be system-signed, and CTS tests aren't. Also mode changes that enable NLP require
- * user consent. Thus we will have a manual CTS verifier test that is similar to this test but
- * tests every location mode. This test is just a "backup" for that since verifier tests are
- * less reliable.
- */
- public void testModeAndProviderApisConsistent() {
- ContentResolver cr = mContext.getContentResolver();
-
- // Find out what the settings say about which providers are enabled
- int mode = Settings.Secure.getInt(
- cr, Settings.Secure.LOCATION_MODE, Settings.Secure.LOCATION_MODE_OFF);
- boolean gps = Settings.Secure.isLocationProviderEnabled(cr, LocationManager.GPS_PROVIDER);
- boolean nlp = Settings.Secure.isLocationProviderEnabled(
- cr, LocationManager.NETWORK_PROVIDER);
-
- // Find out location manager's opinion on the matter, making sure we dont' get spurious
- // results from test versions of the two providers.
- forceRemoveTestProvider(LocationManager.GPS_PROVIDER);
- forceRemoveTestProvider(LocationManager.NETWORK_PROVIDER);
- boolean lmGps = mManager.isProviderEnabled(LocationManager.GPS_PROVIDER);
- boolean lmNlp = mManager.isProviderEnabled(LocationManager.NETWORK_PROVIDER);
-
- // Location Manager will report provider as off if it doesn't know about it
- boolean expectedGps = gps && deviceHasProvider(LocationManager.GPS_PROVIDER);
- boolean expectedNlp = nlp && deviceHasProvider(LocationManager.NETWORK_PROVIDER);
-
- // Assert LocationManager returned the values from Settings.Secure (assuming the device has
- // the appropriate hardware).
- assertEquals("Inconsistent GPS values", expectedGps, lmGps);
- assertEquals("Inconsistent NLP values", expectedNlp, lmNlp);
-
- switch (mode) {
- case Settings.Secure.LOCATION_MODE_OFF:
- expectedGps = false;
- expectedNlp = false;
- break;
- case Settings.Secure.LOCATION_MODE_SENSORS_ONLY:
- expectedGps = true;
- expectedNlp = false;
- break;
- case Settings.Secure.LOCATION_MODE_BATTERY_SAVING:
- expectedGps = false;
- expectedNlp = true;
- break;
- case Settings.Secure.LOCATION_MODE_HIGH_ACCURACY:
- expectedGps = true;
- expectedNlp = true;
- break;
- }
-
- // Assert that isLocationProviderEnabled() values are consistent with the location mode
- assertEquals("Bad GPS for mode " + mode, expectedGps, gps);
- assertEquals("Bad NLP for mode " + mode, expectedNlp, nlp);
- }
-
- /**
* Returns true if the {@link LocationManager} reports that the device includes this flavor
* of location provider.
*/
diff --git a/tests/tests/location/src/android/location/cts/TestMeasurementUtil.java b/tests/tests/location/src/android/location/cts/TestMeasurementUtil.java
index e4fa41f..c9ffe61 100644
--- a/tests/tests/location/src/android/location/cts/TestMeasurementUtil.java
+++ b/tests/tests/location/src/android/location/cts/TestMeasurementUtil.java
@@ -72,6 +72,7 @@
// android/hardware/libhardware/include/hardware/gps.h
public static final Set<Integer> GNSS_NAVIGATION_MESSAGE_TYPE =
new HashSet<Integer>(Arrays.asList(
+ GnssNavigationMessage.TYPE_UNKNOWN,
GnssNavigationMessage.TYPE_GPS_L1CA,
GnssNavigationMessage.TYPE_GPS_L2CNAV,
GnssNavigationMessage.TYPE_GPS_L5CNAV,
diff --git a/tests/tests/media/Android.mk b/tests/tests/media/Android.mk
index 11d687d..dc77eed 100644
--- a/tests/tests/media/Android.mk
+++ b/tests/tests/media/Android.mk
@@ -85,7 +85,8 @@
LOCAL_JAVA_LIBRARIES += \
org.apache.http.legacy \
android.test.base.stubs \
- android.test.runner.stubs
+ android.test.runner.stubs \
+ updatable-media # TODO(b/112766913): replace with stub to prevent private API use.
# Tag this module as a cts test artifact
LOCAL_COMPATIBILITY_SUITE := cts vts general-tests cts_instant
diff --git a/tests/tests/media/AndroidManifest.xml b/tests/tests/media/AndroidManifest.xml
index c4bf99f..1b816d3 100644
--- a/tests/tests/media/AndroidManifest.xml
+++ b/tests/tests/media/AndroidManifest.xml
@@ -31,6 +31,8 @@
<uses-permission android:name="android.permission.SET_VOLUME_KEY_LONG_PRESS_LISTENER" />
<uses-permission android:name="android.permission.SET_MEDIA_KEY_LISTENER" />
+ <permission android:name="android.media.cts" android:protectionLevel="normal" />
+
<application android:networkSecurityConfig="@xml/network_security_config">
<uses-library android:name="android.test.runner" />
<uses-library android:name="org.apache.http.legacy" android:required="false" />
@@ -100,6 +102,12 @@
<action android:name="android.media.browse.MediaBrowserService" />
</intent-filter>
</service>
+ <service android:name="android.media.cts.StubMediaSession2Service"
+ android:permission="android.media.cts">
+ <intent-filter>
+ <action android:name="android.media.MediaSession2Service" />
+ </intent-filter>
+ </service>
</application>
<instrumentation android:name="android.support.test.runner.AndroidJUnitRunner"
diff --git a/tests/tests/media/src/android/media/cts/AdaptivePlaybackTest.java b/tests/tests/media/src/android/media/cts/AdaptivePlaybackTest.java
index da99a12..3391aa3 100644
--- a/tests/tests/media/src/android/media/cts/AdaptivePlaybackTest.java
+++ b/tests/tests/media/src/android/media/cts/AdaptivePlaybackTest.java
@@ -47,6 +47,7 @@
import java.util.Vector;
import java.util.zip.CRC32;
+@MediaHeavyPresubmitTest
@AppModeFull
public class AdaptivePlaybackTest extends MediaPlayerTestBase {
private static final String TAG = "AdaptivePlaybackTest";
diff --git a/tests/tests/media/src/android/media/cts/DecodeAccuracyTest.java b/tests/tests/media/src/android/media/cts/DecodeAccuracyTest.java
index 2a056e4..0f404d1 100644
--- a/tests/tests/media/src/android/media/cts/DecodeAccuracyTest.java
+++ b/tests/tests/media/src/android/media/cts/DecodeAccuracyTest.java
@@ -49,6 +49,7 @@
@TargetApi(24)
@RunWith(Parameterized.class)
+@MediaHeavyPresubmitTest
@AppModeFull(reason = "There should be no instant apps specific behavior related to accuracy")
public class DecodeAccuracyTest extends DecodeAccuracyTestBase {
diff --git a/tests/tests/media/src/android/media/cts/DecoderTest.java b/tests/tests/media/src/android/media/cts/DecoderTest.java
index 62d2fbd..8cb2a27 100755
--- a/tests/tests/media/src/android/media/cts/DecoderTest.java
+++ b/tests/tests/media/src/android/media/cts/DecoderTest.java
@@ -59,6 +59,7 @@
import static android.media.MediaCodecInfo.CodecProfileLevel.*;
+@MediaHeavyPresubmitTest
@AppModeFull(reason = "There should be no instant apps specific behavior related to decoders")
public class DecoderTest extends MediaPlayerTestBase {
private static final String TAG = "DecoderTest";
@@ -2429,7 +2430,19 @@
// start decode loop
MediaCodec.BufferInfo info = new MediaCodec.BufferInfo();
- final long kTimeOutUs = 5000; // 5ms timeout
+ MediaFormat outFormat = codec.getOutputFormat();
+ long kTimeOutUs = 5000; // 5ms timeout
+ String outMime = format.getString(MediaFormat.KEY_MIME);
+ if ((surface == null) && (outMime != null) && outMime.startsWith("video/")) {
+ int outWidth = outFormat.getInteger(MediaFormat.KEY_WIDTH);
+ int outHeight = outFormat.getInteger(MediaFormat.KEY_HEIGHT);
+ // in the 4K decoding case in byte buffer mode, set kTimeOutUs to 10ms as decode may
+ // involve a memcpy
+ if (outWidth * outHeight >= 8000000) {
+ kTimeOutUs = 10000;
+ }
+ }
+
boolean sawInputEOS = false;
boolean sawOutputEOS = false;
int deadDecoderCounter = 0;
diff --git a/tests/tests/media/src/android/media/cts/EncoderTest.java b/tests/tests/media/src/android/media/cts/EncoderTest.java
index cf2e8f6..7f08662 100644
--- a/tests/tests/media/src/android/media/cts/EncoderTest.java
+++ b/tests/tests/media/src/android/media/cts/EncoderTest.java
@@ -24,6 +24,8 @@
import android.media.MediaCodecList;
import android.media.MediaFormat;
import android.media.MediaMuxer;
+import android.platform.test.annotations.RequiresDevice;
+import android.support.test.filters.SmallTest;
import android.test.AndroidTestCase;
import android.util.Log;
@@ -41,6 +43,8 @@
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;
+@SmallTest
+@RequiresDevice
public class EncoderTest extends AndroidTestCase {
private static final String TAG = "EncoderTest";
private static final boolean VERBOSE = false;
@@ -151,18 +155,28 @@
MediaUtils.skipTest("no encoders found for " + Arrays.toString(formats));
return;
}
- ExecutorService pool = Executors.newFixedThreadPool(3);
+
+ int ThreadCount = 3;
+ int testsStarted = 0;
+ int allowPerTest = 30;
+
+ ExecutorService pool = Executors.newFixedThreadPool(ThreadCount);
for (String componentName : componentNames) {
for (MediaFormat format : formats) {
assertEquals(mime, format.getString(MediaFormat.KEY_MIME));
pool.execute(new EncoderRun(componentName, format));
+ testsStarted++;
}
}
try {
pool.shutdown();
+ int waitingSeconds = ((testsStarted + ThreadCount - 1) / ThreadCount) * allowPerTest;
+ waitingSeconds += 300;
+ Log.i(TAG, "waiting up to " + waitingSeconds + " seconds for "
+ + testsStarted + " sub-tests to finish");
assertTrue("timed out waiting for encoder threads",
- pool.awaitTermination(10, TimeUnit.MINUTES));
+ pool.awaitTermination(waitingSeconds, TimeUnit.SECONDS));
} catch (InterruptedException e) {
fail("interrupted while waiting for encoder threads");
}
diff --git a/tests/tests/media/src/android/media/cts/HandlerExecutor.java b/tests/tests/media/src/android/media/cts/HandlerExecutor.java
new file mode 100644
index 0000000..afeef51e
--- /dev/null
+++ b/tests/tests/media/src/android/media/cts/HandlerExecutor.java
@@ -0,0 +1,37 @@
+/*
+ * Copyright 2019 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.media.cts;
+
+import android.annotation.NonNull;
+import android.os.Handler;
+import android.os.Looper;
+
+import java.util.concurrent.Executor;
+import java.util.concurrent.RejectedExecutionException;
+
+public class HandlerExecutor extends Handler implements Executor {
+ public HandlerExecutor(@NonNull Looper looper) {
+ super(looper);
+ }
+
+ @Override
+ public void execute(Runnable command) {
+ if (!post(command)) {
+ throw new RejectedExecutionException(this + " is shutting down");
+ }
+ }
+}
diff --git a/tests/tests/media/src/android/media/cts/ImageReaderDecoderTest.java b/tests/tests/media/src/android/media/cts/ImageReaderDecoderTest.java
index 540e3ff..1dd77d9 100644
--- a/tests/tests/media/src/android/media/cts/ImageReaderDecoderTest.java
+++ b/tests/tests/media/src/android/media/cts/ImageReaderDecoderTest.java
@@ -38,6 +38,8 @@
import android.os.Handler;
import android.os.HandlerThread;
import android.os.Looper;
+import android.platform.test.annotations.RequiresDevice;
+import android.support.test.filters.SmallTest;
import android.test.AndroidTestCase;
import android.util.Log;
import android.view.Surface;
@@ -66,6 +68,8 @@
* test. For decoder test, hw and sw decoders are tested,
* </p>
*/
+@SmallTest
+@RequiresDevice
public class ImageReaderDecoderTest extends AndroidTestCase {
private static final String TAG = "ImageReaderDecoderTest";
private static final boolean VERBOSE = Log.isLoggable(TAG, Log.VERBOSE);
diff --git a/tests/tests/media/src/android/media/cts/MediaCodecTest.java b/tests/tests/media/src/android/media/cts/MediaCodecTest.java
index 4ac23a9..ec0c8f0 100644
--- a/tests/tests/media/src/android/media/cts/MediaCodecTest.java
+++ b/tests/tests/media/src/android/media/cts/MediaCodecTest.java
@@ -29,6 +29,7 @@
import android.media.MediaCodecList;
import android.media.MediaCrypto;
import android.media.MediaDrm;
+import android.media.MediaDrm.MediaDrmStateException;
import android.media.MediaExtractor;
import android.media.MediaFormat;
import android.media.MediaCodecInfo.CodecCapabilities;
@@ -49,6 +50,7 @@
import com.android.compatibility.common.util.MediaUtils;
import java.io.BufferedInputStream;
+import java.io.Closeable;
import java.io.IOException;
import java.io.InputStream;
import java.nio.ByteBuffer;
@@ -1945,11 +1947,70 @@
return actualEncoding;
}
- abstract class ByteBufferStream {
+ /*
+ * Simulate ERROR_LOST_STATE error during decryption, expected
+ * result is MediaCodec.CryptoException with errorCode == ERROR_LOST_STATE
+ */
+ public void testCryptoErrorLostSessionState() throws Exception {
+ if (!supportsCodec(MIME_TYPE, true)) {
+ Log.i(TAG, "No encoder found for mimeType= " + MIME_TYPE);
+ return;
+ }
+
+ MediaDrm drm = new MediaDrm(CLEARKEY_SCHEME_UUID);
+ drm.setPropertyString("drmErrorTest", "lostState");
+
+ byte[] sessionId = drm.openSession();
+ MediaCrypto crypto = new MediaCrypto(CLEARKEY_SCHEME_UUID, new byte[0]);
+ MediaCodec codec = MediaCodec.createDecoderByType(MIME_TYPE);
+
+ try {
+ crypto.setMediaDrmSession(sessionId);
+
+ MediaCodec.CryptoInfo cryptoInfo = new MediaCodec.CryptoInfo();
+ MediaFormat format = createMediaFormat();
+
+ codec.configure(format, null, crypto, 0);
+ codec.start();
+ int index = codec.dequeueInputBuffer(-1);
+ assertTrue(index >= 0);
+ ByteBuffer buffer = codec.getInputBuffer(index);
+ cryptoInfo.set(
+ 1,
+ new int[] { 0 },
+ new int[] { buffer.capacity() },
+ new byte[16],
+ new byte[16],
+ MediaCodec.CRYPTO_MODE_AES_CTR);
+ try {
+ codec.queueSecureInputBuffer(index, 0, cryptoInfo, 0, 0);
+ fail("queueSecureInputBuffer should fail when trying to decrypt " +
+ "after session lost state error.");
+ } catch (MediaCodec.CryptoException e) {
+ if (e.getErrorCode() != MediaCodec.CryptoException.ERROR_LOST_STATE) {
+ fail("expected MediaCodec.CryptoException.ERROR_LOST_STATE: " +
+ e.getErrorCode() + ": " + e.getMessage());
+ }
+ // received expected lost state exception
+ }
+ buffer = codec.getInputBuffer(index);
+ codec.stop();
+ } finally {
+ codec.release();
+ crypto.release();
+ try {
+ drm.closeSession(sessionId);
+ } catch (MediaDrmStateException e) {
+ // expected since session lost state
+ }
+ }
+ }
+
+ /* package */ static abstract class ByteBufferStream {
public abstract ByteBuffer read() throws IOException;
}
- class MediaCodecStream extends ByteBufferStream {
+ /* package */ static class MediaCodecStream extends ByteBufferStream implements Closeable {
private ByteBufferStream mBufferInputStream;
private InputStream mInputStream;
private MediaCodec mCodec;
@@ -2012,6 +2073,7 @@
mBufferInputStream = input;
}
+ @Override
public ByteBuffer read() throws IOException {
if (mSawOutputEOS) {
@@ -2102,6 +2164,7 @@
return ByteBuffer.allocate(0);
}
+ @Override
public void close() throws IOException {
try {
if (mInputStream != null) {
@@ -2128,7 +2191,7 @@
}
};
- class ByteBufferInputStream extends InputStream {
+ /* package */ static class ByteBufferInputStream extends InputStream {
ByteBufferStream mInput;
ByteBuffer mBuffer;
@@ -2152,7 +2215,7 @@
}
};
- class PcmAudioBufferStream extends ByteBufferStream {
+ /* package */ static class PcmAudioBufferStream extends ByteBufferStream {
public int mCount; // either 0 or 1 if the buffer has been delivered
public ByteBuffer mBuffer; // the audio buffer (furnished duplicated, read only).
@@ -2200,7 +2263,7 @@
}
}
- private int compareStreams(InputStream test, InputStream reference) {
+ /* package */ static int compareStreams(InputStream test, InputStream reference) {
Log.i(TAG, "compareStreams");
BufferedInputStream buffered_test = new BufferedInputStream(test);
BufferedInputStream buffered_reference = new BufferedInputStream(reference);
@@ -2229,52 +2292,51 @@
@SmallTest
public void testFlacIdentity() throws Exception {
- final int FRAMES = 1152 * 4; // FIXME: requires 4 flac frames to work with OMX codecs.
- final int SAMPLES = FRAMES * AUDIO_CHANNEL_COUNT;
+ final int PCM_FRAMES = 1152 * 4; // FIXME: requires 4 flac frames to work with OMX codecs.
+ final int SAMPLES = PCM_FRAMES * AUDIO_CHANNEL_COUNT;
+ final int[] SAMPLE_RATES = {AUDIO_SAMPLE_RATE, 192000}; // ensure 192kHz supported.
- final MediaFormat format = new MediaFormat();
- format.setString(MediaFormat.KEY_MIME, MediaFormat.MIMETYPE_AUDIO_FLAC);
- format.setInteger(MediaFormat.KEY_SAMPLE_RATE, AUDIO_SAMPLE_RATE);
- format.setInteger(MediaFormat.KEY_CHANNEL_COUNT, AUDIO_CHANNEL_COUNT);
+ for (int sampleRate : SAMPLE_RATES) {
+ final MediaFormat format = new MediaFormat();
+ format.setString(MediaFormat.KEY_MIME, MediaFormat.MIMETYPE_AUDIO_FLAC);
+ format.setInteger(MediaFormat.KEY_SAMPLE_RATE, sampleRate);
+ format.setInteger(MediaFormat.KEY_CHANNEL_COUNT, AUDIO_CHANNEL_COUNT);
- // this key is only needed for encode, ignored for decode
- format.setInteger(MediaFormat.KEY_FLAC_COMPRESSION_LEVEL, 5);
+ Log.d(TAG, "Trying sample rate: " + sampleRate
+ + " channel count: " + AUDIO_CHANNEL_COUNT);
+ // this key is only needed for encode, ignored for decode
+ format.setInteger(MediaFormat.KEY_FLAC_COMPRESSION_LEVEL, 5);
- for (int i = 0; i < 2; ++i) {
- final boolean useFloat = (i == 1);
- final PcmAudioBufferStream audioStream = new PcmAudioBufferStream(
- SAMPLES, AUDIO_SAMPLE_RATE, 1000 /* frequency */, 100 /* sweep */, useFloat);
+ for (int i = 0; i < 2; ++i) {
+ final boolean useFloat = (i == 1);
+ final PcmAudioBufferStream audioStream = new PcmAudioBufferStream(
+ SAMPLES, sampleRate, 1000 /* frequency */, 100 /* sweep */, useFloat);
- if (useFloat) {
- format.setInteger(
- MediaFormat.KEY_PCM_ENCODING, AudioFormat.ENCODING_PCM_FLOAT);
- }
+ if (useFloat) {
+ format.setInteger(
+ MediaFormat.KEY_PCM_ENCODING, AudioFormat.ENCODING_PCM_FLOAT);
+ }
- final MediaCodecStream rawToFlac = new MediaCodecStream(
+ final MediaCodecStream rawToFlac = new MediaCodecStream(
new ByteBufferInputStream(audioStream), format, true /* encode */);
- final MediaCodecStream flacToRaw = new MediaCodecStream(
+ final MediaCodecStream flacToRaw = new MediaCodecStream(
rawToFlac, format, false /* encode */);
- if (useFloat) {
- if (!rawToFlac.mIsFloat) {
- Log.d(TAG, "No floating point FLAC encoder");
+ if (useFloat) { // ensure float precision supported at the sample rate.
+ assertTrue("No float FLAC encoder at " + sampleRate,
+ rawToFlac.mIsFloat);
+ assertTrue("No float FLAC decoder at " + sampleRate,
+ flacToRaw.mIsFloat);
}
- if (!flacToRaw.mIsFloat) {
- Log.d(TAG, "No floating point FLAC decoder");
- }
- if (!rawToFlac.mIsFloat || !flacToRaw.mIsFloat) {
- break;
- }
- // TODO: should these be errors?
- }
- // Note: the existence of signed zero (as well as NAN) may make byte
- // comparisons invalid for floating point output. In our case, since the
- // floats come through integer to float conversion, it does not matter.
- assertEquals("not identical after compression",
- audioStream.sizeInBytes(),
- compareStreams(new ByteBufferInputStream(flacToRaw),
+ // Note: the existence of signed zero (as well as NAN) may make byte
+ // comparisons invalid for floating point output. In our case, since the
+ // floats come through integer to float conversion, it does not matter.
+ assertEquals("Audio data not identical after compression",
+ audioStream.sizeInBytes(),
+ compareStreams(new ByteBufferInputStream(flacToRaw),
new ByteBufferInputStream(new PcmAudioBufferStream(audioStream))));
+ }
}
}
diff --git a/tests/tests/media/src/android/media/cts/MediaController2Test.java b/tests/tests/media/src/android/media/cts/MediaController2Test.java
new file mode 100644
index 0000000..945c95a
--- /dev/null
+++ b/tests/tests/media/src/android/media/cts/MediaController2Test.java
@@ -0,0 +1,351 @@
+/*
+ * Copyright 2019 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.media.cts;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNull;
+import static org.junit.Assert.assertTrue;
+
+import android.content.Context;
+import android.media.MediaController2;
+import android.media.MediaSession2;
+import android.media.Session2Command;
+import android.media.Session2CommandGroup;
+import android.os.Bundle;
+import android.os.Handler;
+import android.os.HandlerThread;
+import android.support.test.InstrumentationRegistry;
+import android.support.test.filters.SmallTest;
+import android.support.test.runner.AndroidJUnit4;
+
+import org.junit.After;
+import org.junit.AfterClass;
+import org.junit.Before;
+import org.junit.BeforeClass;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.Executor;
+import java.util.concurrent.TimeUnit;
+
+/**
+ * Tests {@link android.media.MediaController2}.
+ */
+@RunWith(AndroidJUnit4.class)
+@SmallTest
+public class MediaController2Test {
+ private static final long WAIT_TIME_MS = 100L;
+
+ static final Object sTestLock = new Object();
+
+ static final int ALLOWED_COMMAND_CODE = 100;
+ static final Session2CommandGroup SESSION_ALLOWED_COMMANDS = new Session2CommandGroup.Builder()
+ .addCommand(ALLOWED_COMMAND_CODE).build();
+ static final int SESSION_RESULT_CODE = 100;
+ static final String SESSION_RESULT_KEY = "test_result_key";
+ static final String SESSION_RESULT_VALUE = "test_result_value";
+ static final Session2Command.Result SESSION_COMMAND_RESULT;
+
+ static {
+ Bundle resultData = new Bundle();
+ resultData.putString(SESSION_RESULT_KEY, SESSION_RESULT_VALUE);
+ SESSION_COMMAND_RESULT = new Session2Command.Result(SESSION_RESULT_CODE, resultData);
+ }
+
+ static Handler sHandler;
+ static Executor sHandlerExecutor;
+
+ private Context mContext;
+ private MediaSession2 mSession;
+ private Session2Callback mSessionCallback;
+
+ @BeforeClass
+ public static void setUpThread() {
+ synchronized (MediaSession2Test.class) {
+ if (sHandler != null) {
+ return;
+ }
+ HandlerThread handlerThread = new HandlerThread("MediaSessionTestBase");
+ handlerThread.start();
+ sHandler = new Handler(handlerThread.getLooper());
+ sHandlerExecutor = (runnable) -> {
+ Handler handler;
+ synchronized (MediaSession2Test.class) {
+ handler = sHandler;
+ }
+ if (handler != null) {
+ handler.post(() -> {
+ synchronized (sTestLock) {
+ runnable.run();
+ }
+ });
+ }
+ };
+ }
+ }
+
+ @AfterClass
+ public static void cleanUpThread() {
+ synchronized (MediaSession2Test.class) {
+ if (sHandler == null) {
+ return;
+ }
+ sHandler.getLooper().quitSafely();
+ sHandler = null;
+ sHandlerExecutor = null;
+ }
+ }
+
+ @Before
+ public void setUp() throws Exception {
+ mContext = InstrumentationRegistry.getContext();
+ mSessionCallback = new Session2Callback();
+ mSession = new MediaSession2.Builder(mContext)
+ .setSessionCallback(sHandlerExecutor, mSessionCallback)
+ .build();
+ }
+
+ @After
+ public void cleanUp() {
+ if (mSession != null) {
+ mSession.close();
+ mSession = null;
+ }
+ }
+
+ @Test
+ public void testGetConnectedToken() {
+ Controller2Callback controllerCallback = new Controller2Callback();
+ try (MediaController2 controller = new MediaController2(
+ mContext, mSession.getSessionToken(), sHandlerExecutor, controllerCallback)) {
+ assertTrue(controllerCallback.awaitOnConnected(WAIT_TIME_MS));
+ assertEquals(controller, controllerCallback.mController);
+ assertEquals(mSession.getSessionToken(), controller.getConnectedSessionToken());
+ } finally {
+ assertTrue(controllerCallback.awaitOnDisconnected(WAIT_TIME_MS));
+ assertNull(controllerCallback.mController.getConnectedSessionToken());
+ }
+ }
+
+ @Test
+ public void testCallback_onConnected_onDisconnected() {
+ Controller2Callback controllerCallback = new Controller2Callback();
+ try (MediaController2 controller = new MediaController2(
+ mContext, mSession.getSessionToken(), sHandlerExecutor, controllerCallback)) {
+ assertTrue(controllerCallback.awaitOnConnected(WAIT_TIME_MS));
+ assertEquals(controller, controllerCallback.mController);
+ assertTrue(controllerCallback.mAllowedCommands.hasCommand(ALLOWED_COMMAND_CODE));
+ } finally {
+ assertTrue(controllerCallback.awaitOnDisconnected(WAIT_TIME_MS));
+ }
+ }
+
+ @Test
+ public void testCallback_onSessionCommand() {
+ Controller2Callback controllerCallback = new Controller2Callback();
+ try (MediaController2 controller = new MediaController2(
+ mContext, mSession.getSessionToken(), sHandlerExecutor, controllerCallback)) {
+ assertTrue(controllerCallback.awaitOnConnected(WAIT_TIME_MS));
+
+ String commandStr = "test_command";
+ String commandExtraKey = "test_extra_key";
+ String commandExtraValue = "test_extra_value";
+ Bundle commandExtra = new Bundle();
+ commandExtra.putString(commandExtraKey, commandExtraValue);
+ Session2Command command = new Session2Command(commandStr, commandExtra);
+
+ String commandArgKey = "test_arg_key";
+ String commandArgValue = "test_arg_value";
+ Bundle commandArg = new Bundle();
+ commandArg.putString(commandArgKey, commandArgValue);
+ mSession.sendSessionCommand(mSessionCallback.mControllerInfo, command, commandArg);
+
+ assertTrue(controllerCallback.awaitOnSessionCommand(WAIT_TIME_MS));
+ assertEquals(controller, controllerCallback.mController);
+ assertEquals(commandStr, controllerCallback.mCommand.getCustomCommand());
+ assertEquals(commandExtraValue,
+ controllerCallback.mCommand.getExtras().getString(commandExtraKey));
+ assertEquals(commandArgValue, controllerCallback.mCommandArgs.getString(commandArgKey));
+ } finally {
+ assertTrue(controllerCallback.awaitOnDisconnected(WAIT_TIME_MS));
+ }
+ }
+
+ @Test
+ public void testCallback_onCommandResult() {
+ Controller2Callback controllerCallback = new Controller2Callback();
+ try (MediaController2 controller = new MediaController2(
+ mContext, mSession.getSessionToken(), sHandlerExecutor, controllerCallback)) {
+ assertTrue(controllerCallback.awaitOnConnected(WAIT_TIME_MS));
+
+ String commandStr = "test_command";
+ String commandExtraKey = "test_extra_key";
+ String commandExtraValue = "test_extra_value";
+ Bundle commandExtra = new Bundle();
+ commandExtra.putString(commandExtraKey, commandExtraValue);
+ Session2Command command = new Session2Command(commandStr, commandExtra);
+
+ String commandArgKey = "test_arg_key";
+ String commandArgValue = "test_arg_value";
+ Bundle commandArg = new Bundle();
+ commandArg.putString(commandArgKey, commandArgValue);
+ controller.sendSessionCommand(command, commandArg);
+
+ assertTrue(controllerCallback.awaitOnCommandResult(WAIT_TIME_MS));
+ assertEquals(controller, controllerCallback.mController);
+ assertEquals(SESSION_RESULT_CODE, controllerCallback.mCommandResult.getResultCode());
+ assertEquals(SESSION_RESULT_VALUE,
+ controllerCallback.mCommandResult.getResultData()
+ .getString(SESSION_RESULT_KEY));
+ } finally {
+ assertTrue(controllerCallback.awaitOnDisconnected(WAIT_TIME_MS));
+ }
+ }
+
+ @Test
+ public void testCancelSessionCommand() {
+ Controller2Callback controllerCallback = new Controller2Callback();
+ try (MediaController2 controller = new MediaController2(
+ mContext, mSession.getSessionToken(), sHandlerExecutor, controllerCallback)) {
+ assertTrue(controllerCallback.awaitOnConnected(WAIT_TIME_MS));
+
+ String commandStr = "test_command_";
+ String commandExtraKey = "test_extra_key_";
+ String commandExtraValue = "test_extra_value_";
+ Bundle commandExtra = new Bundle();
+ commandExtra.putString(commandExtraKey, commandExtraValue);
+ Session2Command command = new Session2Command(commandStr, commandExtra);
+
+ String commandArgKey = "test_arg_key_";
+ String commandArgValue = "test_arg_value_";
+ Bundle commandArg = new Bundle();
+ commandArg.putString(commandArgKey, commandArgValue);
+ synchronized (sTestLock) {
+ Object token = controller.sendSessionCommand(command, commandArg);
+ controller.cancelSessionCommand(token);
+ }
+ assertTrue(controllerCallback.awaitOnCommandResult(WAIT_TIME_MS));
+ assertEquals(Session2Command.RESULT_INFO_SKIPPED,
+ controllerCallback.mCommandResult.getResultCode());
+ } finally {
+ assertTrue(controllerCallback.awaitOnDisconnected(WAIT_TIME_MS));
+ }
+ }
+
+ class Session2Callback extends MediaSession2.SessionCallback {
+ MediaSession2.ControllerInfo mControllerInfo;
+
+ @Override
+ public Session2CommandGroup onConnect(MediaSession2 session,
+ MediaSession2.ControllerInfo controller) {
+ mControllerInfo = controller;
+ return SESSION_ALLOWED_COMMANDS;
+ }
+
+ @Override
+ public Session2Command.Result onSessionCommand(MediaSession2 session,
+ MediaSession2.ControllerInfo controller, Session2Command command, Bundle args) {
+ return SESSION_COMMAND_RESULT;
+ }
+ }
+
+ class Controller2Callback extends MediaController2.ControllerCallback {
+ CountDownLatch mOnConnectedLatch = new CountDownLatch(1);
+ CountDownLatch mOnDisconnectedLatch = new CountDownLatch(1);
+ private CountDownLatch mOnSessionCommandLatch = new CountDownLatch(1);
+ private CountDownLatch mOnCommandResultLatch = new CountDownLatch(1);
+
+ MediaController2 mController;
+ Session2Command mCommand;
+ Session2CommandGroup mAllowedCommands;
+ Bundle mCommandArgs;
+ Session2Command.Result mCommandResult;
+
+ public boolean await(long waitMs) {
+ try {
+ return mOnSessionCommandLatch.await(waitMs, TimeUnit.MILLISECONDS);
+ } catch (InterruptedException e) {
+ return false;
+ }
+ }
+
+ @Override
+ public void onConnected(MediaController2 controller, Session2CommandGroup allowedCommands) {
+ mController = controller;
+ mAllowedCommands = allowedCommands;
+ mOnConnectedLatch.countDown();
+ }
+
+ @Override
+ public void onDisconnected(MediaController2 controller) {
+ mController = controller;
+ mOnDisconnectedLatch.countDown();
+ }
+
+ @Override
+ public Session2Command.Result onSessionCommand(MediaController2 controller,
+ Session2Command command, Bundle args) {
+ mController = controller;
+ mCommand = command;
+ mCommandArgs = args;
+ mOnSessionCommandLatch.countDown();
+ return SESSION_COMMAND_RESULT;
+ }
+
+ @Override
+ public void onCommandResult(MediaController2 controller,Object token,
+ Session2Command command, Session2Command.Result result) {
+ mController = controller;
+ mCommand = command;
+ mCommandResult = result;
+ mOnCommandResultLatch.countDown();
+ }
+
+ public boolean awaitOnConnected(long waitTimeMs) {
+ try {
+ return mOnConnectedLatch.await(waitTimeMs, TimeUnit.MILLISECONDS);
+ } catch (InterruptedException e) {
+ return false;
+ }
+ }
+
+ public boolean awaitOnDisconnected(long waitTimeMs) {
+ try {
+ return mOnDisconnectedLatch.await(waitTimeMs, TimeUnit.MILLISECONDS);
+ } catch (InterruptedException e) {
+ return false;
+ }
+ }
+
+ public boolean awaitOnSessionCommand(long waitTimeMs) {
+ try {
+ return mOnSessionCommandLatch.await(waitTimeMs, TimeUnit.MILLISECONDS);
+ } catch (InterruptedException e) {
+ return false;
+ }
+ }
+
+ public boolean awaitOnCommandResult(long waitTimeMs) {
+ try {
+ return mOnCommandResultLatch.await(waitTimeMs, TimeUnit.MILLISECONDS);
+ } catch (InterruptedException e) {
+ return false;
+ }
+ }
+ }
+}
diff --git a/tests/tests/media/src/android/media/cts/MediaDrmClearkeyTest.java b/tests/tests/media/src/android/media/cts/MediaDrmClearkeyTest.java
index ec2be4d..16f8863 100644
--- a/tests/tests/media/src/android/media/cts/MediaDrmClearkeyTest.java
+++ b/tests/tests/media/src/android/media/cts/MediaDrmClearkeyTest.java
@@ -109,6 +109,7 @@
private MediaDrm mDrm = null;
private final Object mLock = new Object();
private SurfaceHolder mSurfaceHolder;
+ private boolean mLostStateReceived;
@Override
protected void setUp() throws Exception {
@@ -285,6 +286,20 @@
}
}
});
+ mDrm.setOnSessionLostStateListener(new MediaDrm.OnSessionLostStateListener() {
+ @Override
+ public void onSessionLostState(MediaDrm md, byte[] sid) {
+ if (md != mDrm) {
+ Log.e(TAG, "onSessionLostState callback: drm object mismatch");
+ } else if (!Arrays.equals(mSessionId, sid)) {
+ Log.e(TAG, "onSessionLostState callback: sessionId mismatch: |" +
+ Arrays.toString(mSessionId) + "| vs |" + Arrays.toString(sid) + "|");
+ } else {
+ mLostStateReceived = true;
+ }
+ }
+ }, null);
+
mLock.notify();
}
Looper.loop(); // Blocks forever until Looper.quit() is called.
@@ -1163,6 +1178,111 @@
}
}
+ /**
+ * Test that the framework handles a device returning
+ * ::android::hardware::drm@1.2::Status::ERROR_DRM_RESOURCE_CONTENTION.
+ * Expected behavior: throws MediaDrm.SessionException with
+ * errorCode ERROR_RESOURCE_CONTENTION
+ */
+ public void testResourceContentionError() {
+
+ if (watchHasNoClearkeySupport()) {
+ return;
+ }
+
+ MediaDrm drm = null;
+ boolean gotException = false;
+
+ try {
+ drm = new MediaDrm(CLEARKEY_SCHEME_UUID);
+ drm.setPropertyString("drmErrorTest", "resourceContention");
+ byte[] sessionId = drm.openSession();
+
+ try {
+ byte[] ignoredInitData = new byte[] { 1 };
+ drm.getKeyRequest(sessionId, ignoredInitData, "cenc", MediaDrm.KEY_TYPE_STREAMING, null);
+ } catch (MediaDrm.SessionException e) {
+ if (e.getErrorCode() != MediaDrm.SessionException.ERROR_RESOURCE_CONTENTION) {
+ throw new Error("Incorrect error code, expected ERROR_RESOURCE_CONTENTION");
+ }
+ gotException = true;
+ }
+ } catch(Exception e) {
+ throw new Error("Unexpected exception ", e);
+ } finally {
+ if (drm != null) {
+ drm.close();
+ }
+ }
+ if (!gotException) {
+ throw new Error("Didn't receive expected MediaDrm.SessionException");
+ }
+ }
+
+ /**
+ * Test that the framework handles a device returning invoking
+ * the ::android::hardware::drm@1.2::sendSessionLostState callback
+ * Expected behavior: OnSessionLostState is called with
+ * the sessionId
+ */
+ public void testSessionLostStateError() {
+
+ if (watchHasNoClearkeySupport()) {
+ return;
+ }
+
+ boolean gotException = false;
+ mLostStateReceived = false;
+
+ MediaDrm drm = startDrm(new byte[][] { CLEAR_KEY_CENC }, "cenc",
+ CLEARKEY_SCHEME_UUID, MediaDrm.KEY_TYPE_STREAMING);
+
+ mDrm.setPropertyString("drmErrorTest", "lostState");
+ mSessionId = openSession(drm);
+
+ // simulates session lost state here, detected by closeSession
+
+ try {
+ try {
+ closeSession(drm, mSessionId);
+ } catch (MediaDrmStateException e) {
+ gotException = true; // expected for lost state
+ }
+ // wait up to 2 seconds for event
+ for (int i = 0; i < 20 && !mLostStateReceived; i++) {
+ try {
+ Thread.sleep(100);
+ } catch (InterruptedException e) {
+ }
+ }
+ if (!mLostStateReceived) {
+ throw new Error("Callback for OnSessionLostStateListener not received");
+ }
+ } catch(Exception e) {
+ throw new Error("Unexpected exception ", e);
+ } finally {
+ stopDrm(drm);
+ }
+ if (!gotException) {
+ throw new Error("Didn't receive expected MediaDrmStateException");
+ }
+ }
+
+ public void testIsCryptoSchemeSupportedWithSecurityLevel() {
+ if (watchHasNoClearkeySupport()) {
+ return;
+ }
+
+ if (MediaDrm.isCryptoSchemeSupported(CLEARKEY_SCHEME_UUID, "cenc",
+ MediaDrm.SECURITY_LEVEL_HW_SECURE_ALL)) {
+ throw new Error("Clearkey claims to support SECURITY_LEVEL_HW_SECURE_ALL");
+ }
+ if (!MediaDrm.isCryptoSchemeSupported(CLEARKEY_SCHEME_UUID, "cenc",
+ MediaDrm.SECURITY_LEVEL_SW_SECURE_CRYPTO)) {
+ throw new Error("Clearkey claims not to support SECURITY_LEVEL_SW_SECURE_CRYPTO");
+ }
+ }
+
private String getClearkeyVersion(MediaDrm drm) {
try {
return drm.getPropertyString("version");
diff --git a/tests/tests/media/src/android/media/cts/MediaDrmMetricsTest.java b/tests/tests/media/src/android/media/cts/MediaDrmMetricsTest.java
index 87ae2c0..2ac83cf 100644
--- a/tests/tests/media/src/android/media/cts/MediaDrmMetricsTest.java
+++ b/tests/tests/media/src/android/media/cts/MediaDrmMetricsTest.java
@@ -20,11 +20,11 @@
import static org.hamcrest.Matchers.lessThanOrEqualTo;
import android.media.MediaDrm;
-import android.media.MediaDrm.MediaDrmStateException;
import android.os.PersistableBundle;
import android.test.AndroidTestCase;
import android.util.Log;
import com.google.common.io.BaseEncoding;
+import java.lang.IllegalArgumentException;
import java.util.Base64;
import java.util.HashSet;
import java.util.StringJoiner;
@@ -144,7 +144,7 @@
try {
drm.getKeyRequest(sid, null, "", 2, null);
- } catch (MediaDrmStateException e) {
+ } catch (IllegalArgumentException e) {
// Exception expected.
}
diff --git a/tests/tests/media/src/android/media/cts/MediaExtractorTest.java b/tests/tests/media/src/android/media/cts/MediaExtractorTest.java
index 6e5898d..c5cfeef 100644
--- a/tests/tests/media/src/android/media/cts/MediaExtractorTest.java
+++ b/tests/tests/media/src/android/media/cts/MediaExtractorTest.java
@@ -23,20 +23,26 @@
import android.content.res.AssetFileDescriptor;
import android.content.res.Resources;
import android.icu.util.ULocale;
+import android.media.AudioFormat;
import android.media.AudioPresentation;
import android.media.MediaDataSource;
import android.media.MediaExtractor;
import android.media.MediaFormat;
import android.os.PersistableBundle;
+import android.support.test.filters.SmallTest;
import android.test.AndroidTestCase;
import android.util.Log;
+import java.io.Closeable;
+import java.io.InputStream;
import java.io.IOException;
import java.nio.ByteBuffer;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
+import java.util.SortedMap;
+import java.util.TreeMap;
import java.io.InputStreamReader;
import java.io.BufferedReader;
import java.io.Reader;
@@ -295,4 +301,192 @@
strTok.nextToken();
} while (srcAdvance);
}
+
+ /* package */ static class ByteBufferDataSource extends MediaDataSource {
+ private final long mSize;
+ private TreeMap<Long, ByteBuffer> mMap = new TreeMap<Long, ByteBuffer>();
+
+ public ByteBufferDataSource(MediaCodecTest.ByteBufferStream bufferStream)
+ throws IOException {
+ long size = 0;
+ while (true) {
+ final ByteBuffer buffer = bufferStream.read();
+ if (buffer == null) break;
+ final int limit = buffer.limit();
+ if (limit == 0) continue;
+ size += limit;
+ mMap.put(size - 1, buffer); // key: last byte of validity for the buffer.
+ }
+ mSize = size;
+ }
+
+ @Override
+ public long getSize() {
+ return mSize;
+ }
+
+ @Override
+ public int readAt(long position, byte[] buffer, int offset, int size) {
+ Log.v(TAG, "reading at " + position + " offset " + offset + " size " + size);
+
+ // This chooses all buffers with key >= position (e.g. valid buffers)
+ final SortedMap<Long, ByteBuffer> map = mMap.tailMap(position);
+ int copied = 0;
+ for (Map.Entry<Long, ByteBuffer> e : map.entrySet()) {
+ // Get a read-only version of the byte buffer.
+ final ByteBuffer bb = e.getValue().asReadOnlyBuffer();
+ // Convert read position to an offset within that byte buffer, bboffs.
+ final long bboffs = position - e.getKey() + bb.limit() - 1;
+ if (bboffs >= bb.limit() || bboffs < 0) {
+ break; // (negative position)?
+ }
+ bb.position((int)bboffs); // cast is safe as bb.limit is int.
+ final int tocopy = Math.min(size, bb.remaining());
+ if (tocopy == 0) {
+ break; // (size == 0)?
+ }
+ bb.get(buffer, offset, tocopy);
+ copied += tocopy;
+ size -= tocopy;
+ offset += tocopy;
+ position += tocopy;
+ if (size == 0) {
+ break; // finished copying.
+ }
+ }
+ if (copied == 0) {
+ copied = -1; // signal end of file
+ }
+ return copied;
+ }
+
+ @Override
+ public void close() {
+ mMap = null;
+ }
+ }
+
+ /* package */ static class MediaExtractorStream
+ extends MediaCodecTest.ByteBufferStream implements Closeable {
+ public boolean mIsFloat;
+ public boolean mSawOutputEOS;
+ public MediaFormat mFormat;
+
+ private MediaExtractor mExtractor;
+
+ public MediaExtractorStream(
+ String mime,
+ MediaDataSource dataSource) throws Exception {
+ mExtractor = new MediaExtractor();
+ mExtractor.setDataSource(dataSource);
+ final int numTracks = mExtractor.getTrackCount();
+ // Single track?
+ // assertEquals("Number of tracks should be 1", 1, numTracks);
+ for (int i = 0; i < numTracks; ++i) {
+ final MediaFormat format = mExtractor.getTrackFormat(i);
+ final String actualMime = format.getString(MediaFormat.KEY_MIME);
+ if (mime.equals(actualMime)) {
+ mExtractor.selectTrack(i);
+ mFormat = format;
+ break;
+ }
+ }
+ assertNotNull("MediaExtractor cannot find mime type " + mime, mFormat);
+ Integer actualEncoding = null;
+ try {
+ actualEncoding = mFormat.getInteger(MediaFormat.KEY_PCM_ENCODING);
+ } catch (Exception e) {
+ ; // trying to get a non-existent key throws exception
+ }
+ mIsFloat = actualEncoding != null && actualEncoding == AudioFormat.ENCODING_PCM_FLOAT;
+ }
+
+ public MediaExtractorStream(
+ String mime,
+ MediaCodecTest.ByteBufferStream inputStream) throws Exception {
+ this(mime, new ByteBufferDataSource(inputStream));
+ }
+
+ @Override
+ public ByteBuffer read() throws IOException {
+ if (mSawOutputEOS) {
+ return null;
+ }
+
+ // To preserve codec-like behavior, we create ByteBuffers
+ // equal to the media sample size.
+ final long size = mExtractor.getSampleSize();
+ if (size >= 0) {
+ final ByteBuffer inputBuffer = ByteBuffer.allocate((int)size);
+ final int red = mExtractor.readSampleData(inputBuffer, 0 /* offset */); // sic
+ if (red >= 0) {
+ assertEquals("position must be zero", 0, inputBuffer.position());
+ assertEquals("limit must be read bytes", red, inputBuffer.limit());
+ mExtractor.advance();
+ return inputBuffer;
+ }
+ }
+ mSawOutputEOS = true;
+ return null;
+ }
+
+ @Override
+ public void close() throws IOException {
+ if (mExtractor != null) {
+ mExtractor.release();
+ mExtractor = null;
+ }
+ mFormat = null;
+ }
+
+ @Override
+ protected void finalize() throws Throwable {
+ if (mExtractor != null) {
+ Log.w(TAG, "MediaExtractorStream wasn't closed");
+ mExtractor.release();
+ }
+ mFormat = null;
+ }
+ }
+
+ @SmallTest
+ public void testFlacIdentity() throws Exception {
+ final int PCM_FRAMES = 1152 * 4; // FIXME: requires 4 flac frames to work with OMX codecs.
+ final int CHANNEL_COUNT = 2;
+ final int SAMPLES = PCM_FRAMES * CHANNEL_COUNT;
+ final int[] SAMPLE_RATES = {44100, 192000}; // ensure 192kHz supported.
+
+ for (int sampleRate : SAMPLE_RATES) {
+ final MediaFormat format = new MediaFormat();
+ format.setString(MediaFormat.KEY_MIME, MediaFormat.MIMETYPE_AUDIO_FLAC);
+ format.setInteger(MediaFormat.KEY_SAMPLE_RATE, sampleRate);
+ format.setInteger(MediaFormat.KEY_CHANNEL_COUNT, CHANNEL_COUNT);
+
+ Log.d(TAG, "Trying sample rate: " + sampleRate
+ + " channel count: " + CHANNEL_COUNT);
+ format.setInteger(MediaFormat.KEY_FLAC_COMPRESSION_LEVEL, 5);
+
+ // TODO: Add float mode when MediaExtractor supports float configuration.
+ final MediaCodecTest.PcmAudioBufferStream audioStream =
+ new MediaCodecTest.PcmAudioBufferStream(
+ SAMPLES, sampleRate, 1000 /* frequency */, 100 /* sweep */,
+ false /* useFloat */);
+
+ final MediaCodecTest.MediaCodecStream rawToFlac =
+ new MediaCodecTest.MediaCodecStream(
+ new MediaCodecTest.ByteBufferInputStream(audioStream),
+ format, true /* encode */);
+ final MediaExtractorStream flacToRaw =
+ new MediaExtractorStream("audio/raw", rawToFlac);
+
+ // Note: the existence of signed zero (as well as NAN) may make byte
+ // comparisons invalid for floating point output. In our case, since the
+ // floats come through integer to float conversion, it does not matter.
+ assertEquals("Audio data not identical after compression",
+ audioStream.sizeInBytes(),
+ MediaCodecTest.compareStreams(new MediaCodecTest.ByteBufferInputStream(flacToRaw),
+ new MediaCodecTest.ByteBufferInputStream(
+ new MediaCodecTest.PcmAudioBufferStream(audioStream))));
+ }
+ }
}
diff --git a/tests/tests/media/src/android/media/cts/MediaHeavyPresubmitTest.java b/tests/tests/media/src/android/media/cts/MediaHeavyPresubmitTest.java
new file mode 100644
index 0000000..7058344
--- /dev/null
+++ b/tests/tests/media/src/android/media/cts/MediaHeavyPresubmitTest.java
@@ -0,0 +1,30 @@
+/*
+ * Copyright (C) 2019 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.media.cts;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+/**
+ * Annotation for media heavy presubmit tests.
+ */
+@Retention(RetentionPolicy.RUNTIME)
+@Target({ElementType.METHOD, ElementType.TYPE})
+public @interface MediaHeavyPresubmitTest {
+}
diff --git a/tests/tests/media/src/android/media/cts/MediaMuxerTest.java b/tests/tests/media/src/android/media/cts/MediaMuxerTest.java
index 4265a37..0d1796a 100644
--- a/tests/tests/media/src/android/media/cts/MediaMuxerTest.java
+++ b/tests/tests/media/src/android/media/cts/MediaMuxerTest.java
@@ -605,14 +605,14 @@
MediaMetadataRetriever.METADATA_KEY_VIDEO_WIDTH);
String widthTest = retrieverTest.extractMetadata(
MediaMetadataRetriever.METADATA_KEY_VIDEO_WIDTH);
- assertEquals("Different height", widthSrc,
+ assertEquals("Different width", widthSrc,
widthTest);
String durationSrc = retrieverSrc.extractMetadata(
- MediaMetadataRetriever.METADATA_KEY_VIDEO_WIDTH);
+ MediaMetadataRetriever.METADATA_KEY_DURATION);
String durationTest = retrieverTest.extractMetadata(
- MediaMetadataRetriever.METADATA_KEY_VIDEO_WIDTH);
- assertEquals("Different height", durationSrc,
+ MediaMetadataRetriever.METADATA_KEY_DURATION);
+ assertEquals("Different duration", durationSrc,
durationTest);
retrieverSrc.release();
diff --git a/tests/tests/media/src/android/media/cts/MediaPlayer2DrmTest.java b/tests/tests/media/src/android/media/cts/MediaPlayer2DrmTest.java
index 3143e48..a5461e7 100644
--- a/tests/tests/media/src/android/media/cts/MediaPlayer2DrmTest.java
+++ b/tests/tests/media/src/android/media/cts/MediaPlayer2DrmTest.java
@@ -128,6 +128,14 @@
ModularDrmTestType.V3_ASYNC_DRMPREPARED_TEST);
}
+ @LargeTest
+ public void testCAR_CLEARKEY_AUDIO_DOWNLOADED_V5_ASYNC_CALLBACKS() throws Exception {
+ download(CENC_AUDIO_URL,
+ CENC_AUDIO_URL_DOWNLOADED,
+ RES_AUDIO,
+ ModularDrmTestType.V5_ASYNC_CALLBACKS_TEST);
+ }
+
// helpers
private void stream(Uri uri, Resolution res, ModularDrmTestType testType) throws Exception {
diff --git a/tests/tests/media/src/android/media/cts/MediaPlayer2DrmTestBase.java b/tests/tests/media/src/android/media/cts/MediaPlayer2DrmTestBase.java
index 9f083f2..c27b314 100644
--- a/tests/tests/media/src/android/media/cts/MediaPlayer2DrmTestBase.java
+++ b/tests/tests/media/src/android/media/cts/MediaPlayer2DrmTestBase.java
@@ -27,7 +27,9 @@
import android.media.MediaDrm;
import android.media.MediaPlayer2;
import android.media.MediaPlayer2.DrmInfo;
+import android.media.MediaPlayer2.DrmPreparationInfo;
import android.media.VideoSize;
+import android.media.MediaDrm.KeyRequest;
import android.media.cts.TestUtils.Monitor;
import android.net.Uri;
import android.os.SystemClock;
@@ -152,6 +154,7 @@
V2_SYNC_CONFIG_TEST,
V3_ASYNC_DRMPREPARED_TEST,
V4_SYNC_OFFLINE_KEY,
+ V5_ASYNC_CALLBACKS_TEST,
}
// TODO: After living on these tests for a while, we can consider grouping them based on
@@ -223,12 +226,14 @@
case V1_ASYNC_TEST:
case V2_SYNC_CONFIG_TEST:
case V3_ASYNC_DRMPREPARED_TEST:
+ case V5_ASYNC_CALLBACKS_TEST:
playLoadedModularDrmVideo_Generic(file, width, height, playTime, testType);
break;
case V4_SYNC_OFFLINE_KEY:
playLoadedModularDrmVideo_V4_offlineKey(file, width, height, playTime);
break;
+
}
}
@@ -303,6 +308,13 @@
case V3_ASYNC_DRMPREPARED_TEST:
preparePlayerAndDrm_V3_asyncDrmSetupPlusDrmPreparedListener(dsd);
break;
+
+ case V5_ASYNC_CALLBACKS_TEST:
+ preparePlayerAndDrm_V5_asyncDrmSetupCallbacks(dsd);
+ break;
+
+ default:
+ throw new IllegalArgumentException("invalid test type: " + testType);
}
} catch (IOException e) {
@@ -328,6 +340,7 @@
try {
Log.v(TAG, "playLoadedVideo: releaseDrm");
+ mPlayer.reset();
mPlayer.releaseDrm(dsd);
} catch (Exception e) {
e.printStackTrace();
@@ -354,15 +367,16 @@
private void preparePlayerAndDrm_V1_asyncDrmSetup(DataSourceDesc dsd) throws InterruptedException {
final AtomicBoolean asyncSetupDrmError = new AtomicBoolean(false);
- mPlayer.registerDrmEventCallback(mExecutor, new MediaPlayer2.DrmEventCallback() {
+ mPlayer.setDrmEventCallback(mExecutor, new MediaPlayer2.DrmEventCallback() {
@Override
- public void onDrmInfo(MediaPlayer2 mp, DataSourceDesc dsd2, DrmInfo drmInfo) {
+ public DrmPreparationInfo onDrmInfo(MediaPlayer2 mp, DataSourceDesc dsd2,
+ DrmInfo drmInfo) {
Log.v(TAG, "preparePlayerAndDrm_V1: onDrmInfo" + drmInfo);
if (dsd != dsd2) {
Log.e(TAG, "preparePlayerAndDrm_V1: onDrmInfo dsd mismatch");
asyncSetupDrmError.set(true);
mOnDrmInfoCalled.signal();
- return;
+ return null;
}
// in the callback (async mode) so handling exceptions here
@@ -376,6 +390,7 @@
mOnDrmInfoCalled.signal();
Log.v(TAG, "preparePlayerAndDrm_V1: onDrmInfo done!");
+ return null;
}
});
@@ -396,9 +411,9 @@
private void preparePlayerAndDrm_V2_syncDrmSetupPlusConfig(DataSourceDesc dsd)
throws Exception {
final AtomicBoolean drmConfigError = new AtomicBoolean(false);
- mPlayer.setOnDrmConfigHelper(new MediaPlayer2.OnDrmConfigHelper() {
+ mPlayer.setDrmEventCallback(mExecutor, new MediaPlayer2.DrmEventCallback() {
@Override
- public void onDrmConfig(MediaPlayer2 mp, DataSourceDesc dsd2) {
+ public void onDrmConfig(MediaPlayer2 mp, DataSourceDesc dsd2, MediaDrm drmObj) {
if (dsd != dsd2) {
Log.e(TAG, "preparePlayerAndDrm_V2: onDrmConfig dsd mismatch");
drmConfigError.set(true);
@@ -409,15 +424,13 @@
String securityLevelProperty = "securityLevel";
try {
- String level = mp.getDrmPropertyString(dsd2, securityLevelProperty);
+ String level = drmObj.getPropertyString(securityLevelProperty);
Log.v(TAG, "preparePlayerAndDrm_V2: getDrmPropertyString: "
+ securityLevelProperty + " -> " + level);
- mp.setDrmPropertyString(dsd2, securityLevelProperty, widevineSecurityLevel3);
- level = mp.getDrmPropertyString(dsd2, securityLevelProperty);
+ drmObj.setPropertyString(securityLevelProperty, widevineSecurityLevel3);
+ level = drmObj.getPropertyString(securityLevelProperty);
Log.v(TAG, "preparePlayerAndDrm_V2: getDrmPropertyString: "
+ securityLevelProperty + " -> " + level);
- } catch (MediaPlayer2.NoDrmSchemeException e) {
- Log.v(TAG, "preparePlayerAndDrm_V2: NoDrmSchemeException");
} catch (Exception e) {
Log.v(TAG, "preparePlayerAndDrm_V2: onDrmConfig EXCEPTION " + e);
}
@@ -448,9 +461,10 @@
throws InterruptedException {
final AtomicBoolean asyncSetupDrmError = new AtomicBoolean(false);
- mPlayer.registerDrmEventCallback(mExecutor, new MediaPlayer2.DrmEventCallback() {
+ mPlayer.setDrmEventCallback(mExecutor, new MediaPlayer2.DrmEventCallback() {
@Override
- public void onDrmInfo(MediaPlayer2 mp, DataSourceDesc dsd2, DrmInfo drmInfo) {
+ public DrmPreparationInfo onDrmInfo(MediaPlayer2 mp, DataSourceDesc dsd2,
+ DrmInfo drmInfo) {
Log.v(TAG, "preparePlayerAndDrm_V3: onDrmInfo" + drmInfo);
// DRM preperation
@@ -462,7 +476,7 @@
mOnDrmInfoCalled.signal();
// we won't call prepareDrm anymore but need to get passed the wait
mOnDrmPreparedCalled.signal();
- return;
+ return null;
}
// setting up with the first supported UUID
@@ -475,10 +489,12 @@
mOnDrmInfoCalled.signal();
Log.v(TAG, "preparePlayerAndDrm_V3: onDrmInfo done!");
+ return null;
}
@Override
- public void onDrmPrepared(MediaPlayer2 mp, DataSourceDesc dsd2, int status) {
+ public void onDrmPrepared(MediaPlayer2 mp, DataSourceDesc dsd2, int status,
+ byte[] keySetId) {
Log.v(TAG, "preparePlayerAndDrm_V3: onDrmPrepared status: " + status);
if (dsd != dsd2) {
@@ -524,6 +540,116 @@
}
}
+ private void preparePlayerAndDrm_V5_asyncDrmSetupCallbacks(DataSourceDesc dsd)
+ throws InterruptedException {
+ final AtomicBoolean drmCallbackError = new AtomicBoolean(false);
+
+ mPlayer.setDrmEventCallback(mExecutor, new MediaPlayer2.DrmEventCallback() {
+ @Override
+ public DrmPreparationInfo onDrmInfo(MediaPlayer2 mp, DataSourceDesc dsd2,
+ DrmInfo drmInfo) {
+ Log.v(TAG, "preparePlayerAndDrm_V5: onDrmInfo" + drmInfo);
+
+ // DRM preparation
+ UUID drmScheme = CLEARKEY_SCHEME_UUID;
+ List<UUID> supportedSchemes = drmInfo.getSupportedSchemes();
+ if (dsd != dsd2 || supportedSchemes.isEmpty()) {
+ String msg = dsd != dsd2 ? "dsd mismatch" : "No supportedSchemes";
+ Log.e(TAG, "preparePlayerAndDrm_V5: onDrmInfo " + msg);
+ drmCallbackError.set(true);
+ return null;
+ }
+
+ // setting up with the first supported UUID
+ // instead of supportedSchemes[0] in GTS
+ DrmPreparationInfo.Builder drmBuilder = new DrmPreparationInfo.Builder();
+ drmBuilder.setUuid(drmScheme);
+ drmBuilder.setMimeType("cenc");
+ drmBuilder.setKeyType(MediaDrm.KEY_TYPE_STREAMING);
+
+ byte[] psshData = drmInfo.getPssh().get(drmScheme);
+ byte[] initData;
+ // diverging from GTS
+ if (psshData == null) {
+ initData = mClearKeyPssh;
+ Log.d(TAG, "preparePlayerAndDrm_V5: CLEARKEY scheme not found in PSSH."
+ + " Using default data.");
+ } else {
+ // Can skip conversion if ClearKey adds support for BMFF initData b/64863112
+ initData = makeCencPSSH(drmScheme, psshData);
+ }
+ drmBuilder.setInitData(initData);
+ Log.d(TAG, "preparePlayerAndDrm_V5: initData[" + drmScheme + "]: "
+ + Arrays.toString(initData));
+
+ Log.v(TAG, "preparePlayerAndDrm_V5: onDrmInfo done!");
+ return drmBuilder.build();
+ }
+
+ @Override
+ public void onDrmConfig(MediaPlayer2 mp, DataSourceDesc dsd2, MediaDrm drmObj) {
+ if (dsd != dsd2) {
+ Log.e(TAG, "preparePlayerAndDrm_V5: onDrmConfig dsd mismatch");
+ drmCallbackError.set(true);
+ return;
+ }
+
+ String widevineSecurityLevel3 = "L3";
+ String securityLevelProperty = "securityLevel";
+
+ try {
+ String level = drmObj.getPropertyString(securityLevelProperty);
+ Log.v(TAG, "preparePlayerAndDrm_V5: getDrmPropertyString: "
+ + securityLevelProperty + " -> " + level);
+ drmObj.setPropertyString(securityLevelProperty, widevineSecurityLevel3);
+ level = drmObj.getPropertyString(securityLevelProperty);
+ Log.v(TAG, "preparePlayerAndDrm_V5: getDrmPropertyString: "
+ + securityLevelProperty + " -> " + level);
+ } catch (Exception e) {
+ Log.v(TAG, "preparePlayerAndDrm_V5: onDrmConfig EXCEPTION " + e);
+ }
+ }
+
+ @Override
+ public byte[] onDrmKeyRequest(MediaPlayer2 mp, DataSourceDesc dsd, KeyRequest req) {
+ byte[][] clearKeys = new byte[][] { CLEAR_KEY_CENC };
+ byte[] response = createKeysResponse(req, clearKeys);
+ return response;
+ }
+
+ @Override
+ public void onDrmPrepared(MediaPlayer2 mp, DataSourceDesc dsd2, int status,
+ byte[] keySetId) {
+ Log.v(TAG, "preparePlayerAndDrm_V5: onDrmPrepared status: " + status);
+ String errMsg = null;
+ if (dsd != dsd2) {
+ errMsg = "dsd mismatch";
+ }
+ if (status != MediaPlayer2.PREPARE_DRM_STATUS_SUCCESS) {
+ errMsg = "drm prepare failed";
+ }
+ if (keySetId != null && keySetId.length > 0) {
+ errMsg = "unexpected keySetId";
+ }
+ if (errMsg != null) {
+ drmCallbackError.set(true);
+ Log.e(TAG, "preparePlayerAndDrm_V5: onDrmPrepared " + errMsg);
+ }
+ }
+ });
+
+ Log.v(TAG, "preparePlayerAndDrm_V5: calling prepare()");
+ mPlayer.prepare();
+
+ // Waiting till the player is prepared
+ mOnPreparedCalled.waitForSignal();
+
+ // handle error (async) in main thread rather than callbacks
+ if (drmCallbackError.get()) {
+ fail("preparePlayerAndDrm_V5: setupDrm");
+ }
+ }
+
private void playLoadedModularDrmVideo_V4_offlineKey(final Uri file, final Integer width,
final Integer height, int playTime) throws Exception {
final float volume = 0.5f;
@@ -680,11 +806,11 @@
if (prepareDrm) {
final Monitor drmPrepared = new Monitor();
- mPlayer.registerDrmEventCallback(
+ mPlayer.setDrmEventCallback(
mExecutor, new MediaPlayer2.DrmEventCallback() {
@Override
- public void onDrmPrepared(
- MediaPlayer2 mp, DataSourceDesc dsd2, int status) {
+ public void onDrmPrepared(MediaPlayer2 mp, DataSourceDesc dsd2,
+ int status, byte[] keySetId) {
if (status != MediaPlayer2.PREPARE_DRM_STATUS_SUCCESS
|| dsd != dsd2) {
prepareDrmFailed.set(true);
@@ -784,11 +910,11 @@
Log.d(TAG, "setupDrmRestore: selected " + drmScheme);
final Monitor drmPrepared = new Monitor();
- mPlayer.registerDrmEventCallback(
+ mPlayer.setDrmEventCallback(
mExecutor, new MediaPlayer2.DrmEventCallback() {
@Override
public void onDrmPrepared(
- MediaPlayer2 mp, DataSourceDesc dsd2, int status) {
+ MediaPlayer2 mp, DataSourceDesc dsd2, int status, byte[] keySetId) {
if (status != MediaPlayer2.PREPARE_DRM_STATUS_SUCCESS
|| dsd != dsd2) {
prepareDrmFailed.set(true);
diff --git a/tests/tests/media/src/android/media/cts/MediaPlayer2Test.java b/tests/tests/media/src/android/media/cts/MediaPlayer2Test.java
index 799eef0..3c780ca 100644
--- a/tests/tests/media/src/android/media/cts/MediaPlayer2Test.java
+++ b/tests/tests/media/src/android/media/cts/MediaPlayer2Test.java
@@ -956,7 +956,7 @@
return; // skip
}
- int resid = R.raw.testvideo;
+ int resid = R.raw.video_176x144_3gp_h263_300kbps_12fps_aac_mono_24kbps_11025hz;
if (!MediaUtils.hasCodecsForResource(mContext, resid)) {
return; // skip
}
@@ -1053,7 +1053,7 @@
return; // skip
}
- int resid = R.raw.testvideo;
+ int resid = R.raw.video_176x144_3gp_h263_300kbps_12fps_aac_mono_24kbps_11025hz;
if (!MediaUtils.hasCodecsForResource(mContext, resid)) {
return; // skip
}
@@ -1160,7 +1160,7 @@
return; // skip
}
- int resid = R.raw.testvideo;
+ int resid = R.raw.video_176x144_3gp_h263_300kbps_12fps_aac_mono_24kbps_11025hz;
if (!MediaUtils.hasCodecsForResource(mContext, resid)) {
return; // skip
}
@@ -1184,22 +1184,22 @@
public void onInfo(MediaPlayer2 mp, DataSourceDesc dsd, int what, int extra) {
if (what == MediaPlayer2.MEDIA_INFO_DATA_SOURCE_START) {
if (dsd == dsd2) {
- Log.i(LOG_TAG, "testPlaylist: MEDIA_INFO_DATA_SOURCE_START dsd2");
+ Log.i(LOG_TAG, "testClearNextDataSources: DATA_SOURCE_START dsd2");
onStart2Called.signal();
} else {
- Log.i(LOG_TAG, "testPlaylist: MEDIA_INFO_DATA_SOURCE_START other");
+ Log.i(LOG_TAG, "testClearNextDataSources: DATA_SOURCE_START other");
onStartCalled.signal();
}
} else if (what == MediaPlayer2.MEDIA_INFO_DATA_SOURCE_END) {
if (dsd == dsd2) {
- Log.i(LOG_TAG, "testPlaylist: MEDIA_INFO_DATA_SOURCE_END dsd2");
+ Log.i(LOG_TAG, "testClearNextDataSources: DATA_SOURCE_END dsd2");
onCompletion2Called.signal();
} else {
- Log.i(LOG_TAG, "testPlaylist: MEDIA_INFO_DATA_SOURCE_END other");
+ Log.i(LOG_TAG, "testClearNextDataSources: DATA_SOURCE_END other");
mOnCompletionCalled.signal();
}
} else if (what == MediaPlayer2.MEDIA_INFO_DATA_SOURCE_LIST_END) {
- Log.i(LOG_TAG, "testPlaylist: MEDIA_INFO_DATA_SOURCE_LIST_END");
+ Log.i(LOG_TAG, "testClearNextDataSources: DATA_SOURCE_LIST_END");
onListCompletionCalled.signal();
}
}
@@ -2053,6 +2053,7 @@
Thread.sleep(10000);
assertTrue("MediaPlayer2 should still be playing",
mPlayer.getState() == MediaPlayer2.PLAYER_STATE_PLAYING);
+ mPlayer.unregisterEventCallback(ecb);
mPlayer.reset();
assertEquals("wrong number of repetitions", 1, mOnCompletionCalled.getNumSignal());
return 1;
diff --git a/tests/tests/media/src/android/media/cts/MediaRandomTest.java b/tests/tests/media/src/android/media/cts/MediaRandomTest.java
index e016730..3db1d13 100644
--- a/tests/tests/media/src/android/media/cts/MediaRandomTest.java
+++ b/tests/tests/media/src/android/media/cts/MediaRandomTest.java
@@ -15,18 +15,15 @@
*/
package android.media.cts;
-
-import android.media.cts.R;
-
-import android.media.MediaRecorder;
-import android.media.MediaPlayer;
-import android.platform.test.annotations.AppModeFull;
-import android.view.SurfaceHolder;
-import android.test.ActivityInstrumentationTestCase2;
-import android.os.Environment;
import android.content.res.AssetFileDescriptor;
import android.content.res.Resources;
+import android.media.MediaRecorder;
+import android.media.MediaPlayer;
+import android.os.Environment;
+import android.platform.test.annotations.AppModeFull;
+import android.test.ActivityInstrumentationTestCase2;
import android.util.Log;
+import android.view.SurfaceHolder;
import java.util.Random;
@@ -41,6 +38,7 @@
* Blender Foundation / www.bigbuckbunny.org, and are licensed under the Creative Commons
* Attribution 3.0 License at http://creativecommons.org/licenses/by/3.0/us/.
*/
+@MediaHeavyPresubmitTest
@AppModeFull(reason = "TODO: evaluate and port to instant")
public class MediaRandomTest extends ActivityInstrumentationTestCase2<MediaStubActivity> {
private static final String TAG = "MediaRandomTest";
diff --git a/tests/tests/media/src/android/media/cts/MediaRecorderTest.java b/tests/tests/media/src/android/media/cts/MediaRecorderTest.java
index f1ad46c..042881c 100644
--- a/tests/tests/media/src/android/media/cts/MediaRecorderTest.java
+++ b/tests/tests/media/src/android/media/cts/MediaRecorderTest.java
@@ -675,6 +675,7 @@
assertTrue(MediaRecorder.AudioSource.VOICE_RECOGNITION <= max);
assertTrue(MediaRecorder.AudioSource.VOICE_UPLINK <= max);
assertTrue(MediaRecorder.AudioSource.UNPROCESSED <= max);
+ assertTrue(MediaRecorder.AudioSource.VOICE_PERFORMANCE <= max);
}
public void testRecorderAudio() throws Exception {
diff --git a/tests/tests/media/src/android/media/cts/MediaScannerNotificationTest.java b/tests/tests/media/src/android/media/cts/MediaScannerNotificationTest.java
index 52da641..3eb1ab4 100644
--- a/tests/tests/media/src/android/media/cts/MediaScannerNotificationTest.java
+++ b/tests/tests/media/src/android/media/cts/MediaScannerNotificationTest.java
@@ -18,8 +18,6 @@
import android.content.Intent;
import android.content.IntentFilter;
-import android.net.Uri;
-import android.os.Bundle;
import android.os.Environment;
import android.platform.test.annotations.AppModeFull;
import android.test.AndroidTestCase;
@@ -27,8 +25,6 @@
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
-import java.util.concurrent.CountDownLatch;
-import java.util.concurrent.TimeUnit;
@AppModeFull(reason = "TODO: evaluate and port to instant")
public class MediaScannerNotificationTest extends AndroidTestCase {
@@ -50,13 +46,7 @@
String [] temps = new String[] { "avi", "gif", "jpg", "dat", "mp3", "mp4", "txt" };
String tmpPath = createTempFiles(temps);
- Bundle args = new Bundle();
- args.putString("volume", "external");
- Intent i = new Intent("android.media.IMediaScannerService").putExtras(args);
- i.setClassName("com.android.providers.media",
- "com.android.providers.media.MediaScannerService");
- mContext.startService(i);
-
+ MediaScannerTest.startMediaScan();
startedReceiver.waitForBroadcast();
finishedReceiver.waitForBroadcast();
@@ -71,7 +61,7 @@
}
startedReceiver.reset();
finishedReceiver.reset();
- mContext.startService(i);
+ MediaScannerTest.startMediaScan();
startedReceiver.waitForBroadcast();
finishedReceiver.waitForBroadcast();
@@ -82,7 +72,7 @@
// scan one more time just to clean everything up nicely
startedReceiver.reset();
finishedReceiver.reset();
- mContext.startService(i);
+ MediaScannerTest.startMediaScan();
startedReceiver.waitForBroadcast();
finishedReceiver.waitForBroadcast();
diff --git a/tests/tests/media/src/android/media/cts/MediaScannerTest.java b/tests/tests/media/src/android/media/cts/MediaScannerTest.java
index 72ed274..1b0d6fc 100644
--- a/tests/tests/media/src/android/media/cts/MediaScannerTest.java
+++ b/tests/tests/media/src/android/media/cts/MediaScannerTest.java
@@ -19,7 +19,6 @@
import android.content.ComponentName;
import android.content.ContentResolver;
import android.content.ContentUris;
-import android.content.ContentValues;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
@@ -29,13 +28,13 @@
import android.media.MediaScannerConnection;
import android.media.MediaScannerConnection.MediaScannerConnectionClient;
import android.net.Uri;
-import android.os.Bundle;
import android.os.Environment;
import android.os.IBinder;
import android.os.SystemClock;
import android.platform.test.annotations.AppModeFull;
import android.platform.test.annotations.RequiresDevice;
import android.provider.MediaStore;
+import android.support.test.InstrumentationRegistry;
import android.test.AndroidTestCase;
import android.test.suitebuilder.annotation.SmallTest;
import android.util.Log;
@@ -372,6 +371,10 @@
}
private void canonicalizeTest(int resId) throws Exception {
+ // erase all audio files that might confuse us below
+ mContext.getContentResolver().delete(MediaStore.Audio.Media.EXTERNAL_CONTENT_URI,
+ null, null);
+
// write file and scan to insert into database
String fileDir = Environment.getExternalStorageDirectory() + "/"
+ getClass().getCanonicalName() + "/canonicaltest-" + System.currentTimeMillis();
@@ -612,6 +615,14 @@
}
}
+ static void startMediaScan() {
+ // Ugh, the best proxy we have is pretending that it was just mounted
+ InstrumentationRegistry.getInstrumentation().getUiAutomation().executeShellCommand(
+ "am broadcast -a android.intent.action.MEDIA_SCANNER_SCAN_VOLUME "
+ + "--receiver-include-background -d "
+ + Uri.fromFile(Environment.getExternalStorageDirectory()));
+ }
+
private void startMediaScanAndWait() throws InterruptedException {
ScannerNotificationReceiver finishedReceiver = new ScannerNotificationReceiver(
Intent.ACTION_MEDIA_SCANNER_FINISHED);
@@ -619,12 +630,7 @@
finishedIntentFilter.addDataScheme("file");
mContext.registerReceiver(finishedReceiver, finishedIntentFilter);
- Bundle args = new Bundle();
- args.putString("volume", "external");
- Intent i = new Intent("android.media.IMediaScannerService").putExtras(args);
- i.setClassName("com.android.providers.media",
- "com.android.providers.media.MediaScannerService");
- mContext.startService(i);
+ startMediaScan();
finishedReceiver.waitForBroadcast();
mContext.unregisterReceiver(finishedReceiver);
@@ -683,6 +689,7 @@
}
public void onScanCompleted(String path, Uri uri) {
+ Log.v("MediaScannerTest", "onScanCompleted for " + path + " to " + uri);
mediaPath = path;
if (uri != null) {
mediaUri = uri;
diff --git a/tests/tests/media/src/android/media/cts/MediaSession2ServiceTest.java b/tests/tests/media/src/android/media/cts/MediaSession2ServiceTest.java
new file mode 100644
index 0000000..d8a34a0
--- /dev/null
+++ b/tests/tests/media/src/android/media/cts/MediaSession2ServiceTest.java
@@ -0,0 +1,293 @@
+/*
+ * Copyright 2019 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.media.cts;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNotEquals;
+import static org.junit.Assert.assertTrue;
+
+import android.content.ComponentName;
+import android.content.Context;
+import android.media.MediaController2;
+import android.media.MediaSession2;
+import android.media.MediaSession2Service;
+import android.media.Session2CommandGroup;
+import android.media.Session2Token;
+import android.os.CountDownTimer;
+import android.os.HandlerThread;
+import android.os.Process;
+import android.support.test.InstrumentationRegistry;
+import android.support.test.filters.SmallTest;
+import android.support.test.runner.AndroidJUnit4;
+
+import org.junit.After;
+import org.junit.AfterClass;
+import org.junit.Before;
+import org.junit.BeforeClass;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.TimeUnit;
+
+/**
+ * Tests {@link MediaSession2Service}.
+ */
+@RunWith(AndroidJUnit4.class)
+@SmallTest
+public class MediaSession2ServiceTest {
+ private static final long TIMEOUT_MS = 3000L;
+
+ private static HandlerExecutor sHandlerExecutor;
+ private final List<MediaController2> mControllers = new ArrayList<>();
+ private Context mContext;
+ private Session2Token mToken;
+
+ @BeforeClass
+ public static void setUpThread() {
+ synchronized (MediaSession2ServiceTest.class) {
+ if (sHandlerExecutor != null) {
+ return;
+ }
+ HandlerThread handlerThread = new HandlerThread("MediaSession2ServiceTest");
+ handlerThread.start();
+ sHandlerExecutor = new HandlerExecutor(handlerThread.getLooper());
+ StubMediaSession2Service.setHandlerExecutor(sHandlerExecutor);
+ }
+ }
+
+ @AfterClass
+ public static void cleanUpThread() {
+ synchronized (MediaSession2Test.class) {
+ if (sHandlerExecutor == null) {
+ return;
+ }
+ StubMediaSession2Service.setHandlerExecutor(null);
+ sHandlerExecutor.getLooper().quitSafely();
+ sHandlerExecutor = null;
+ }
+ }
+
+ @Before
+ public void setUp() throws Exception {
+ mContext = InstrumentationRegistry.getContext();
+ mToken = new Session2Token(mContext,
+ new ComponentName(mContext, StubMediaSession2Service.class));
+ }
+
+ @After
+ public void cleanUp() throws Exception {
+ for (MediaController2 controller : mControllers) {
+ controller.close();
+ }
+ mControllers.clear();
+
+ StubMediaSession2Service.setTestInjector(null);
+ }
+
+ /**
+ * Tests whether {@link MediaSession2Service#onGetPrimarySession()} is called whenever a
+ * controller is created with the service's token.
+ */
+ @Test
+ public void testOnGetPrimarySession() throws InterruptedException {
+ MediaController2 controller1 = createConnectedController(mToken);
+ MediaController2 controller2 = createConnectedController(mToken);
+ assertNotEquals(mToken, controller1.getConnectedSessionToken());
+ assertEquals(Session2Token.TYPE_SESSION,
+ controller1.getConnectedSessionToken().getType());
+ assertEquals(controller1.getConnectedSessionToken(),
+ controller2.getConnectedSessionToken());
+ }
+
+ /**
+ * Tests whether {@link MediaSession2Service#onGetPrimarySession()} is called whenever a
+ * controller is created with the service's token.
+ */
+ @Test
+ public void testOnGetPrimarySession_multipleSessions() throws InterruptedException {
+ final List<Session2Token> tokens = new ArrayList<>();
+ StubMediaSession2Service.setTestInjector(
+ new StubMediaSession2Service.TestInjector() {
+ @Override
+ MediaSession2 onGetPrimarySession() {
+ MediaSession2 session = new MediaSession2.Builder(mContext)
+ .setId("testOnGetPrimarySession_multipleSession"
+ + System.currentTimeMillis())
+ .setSessionCallback(sHandlerExecutor, new SessionCallback())
+ .build();
+ tokens.add(session.getSessionToken());
+ return session;
+ }
+ });
+
+ MediaController2 controller1 = createConnectedController(mToken);
+ MediaController2 controller2 = createConnectedController(mToken);
+
+ assertNotEquals(mToken, controller1.getConnectedSessionToken());
+ assertNotEquals(mToken, controller2.getConnectedSessionToken());
+
+ assertNotEquals(controller1.getConnectedSessionToken(),
+ controller2.getConnectedSessionToken());
+ assertEquals(2, tokens.size());
+ assertEquals(tokens.get(0), controller1.getConnectedSessionToken());
+ assertEquals(tokens.get(1), controller2.getConnectedSessionToken());
+ }
+
+ @Test
+ public void testAllControllersDisconnected_oneSession() throws InterruptedException {
+ final CountDownLatch latch = new CountDownLatch(1);
+ StubMediaSession2Service.setTestInjector(
+ new StubMediaSession2Service.TestInjector() {
+ @Override
+ void onServiceDestroyed() {
+ latch.countDown();
+ }
+ });
+ MediaController2 controller1 = createConnectedController(mToken);
+ MediaController2 controller2 = createConnectedController(mToken);
+ controller1.close();
+ controller2.close();
+
+ assertTrue(latch.await(TIMEOUT_MS, TimeUnit.MILLISECONDS));
+ }
+
+ @Test
+ public void testAllControllersDisconnected_multipleSession() throws InterruptedException {
+ final CountDownLatch latch = new CountDownLatch(1);
+ StubMediaSession2Service.setTestInjector(new StubMediaSession2Service.TestInjector() {
+ @Override
+ MediaSession2 onGetPrimarySession() {
+ return new MediaSession2.Builder(mContext)
+ .setId("testAllControllersDisconnected_multipleSession"
+ + System.currentTimeMillis())
+ .setSessionCallback(sHandlerExecutor, new SessionCallback())
+ .build();
+ }
+
+ @Override
+ void onServiceDestroyed() {
+ latch.countDown();
+ }
+ });
+
+ MediaController2 controller1 = createConnectedController(mToken);
+ MediaController2 controller2 = createConnectedController(mToken);
+ controller1.close();
+ controller2.close();
+
+ assertTrue(latch.await(TIMEOUT_MS, TimeUnit.MILLISECONDS));
+ }
+
+ @Test
+ public void testGetSessions() throws InterruptedException {
+ MediaController2 controller = createConnectedController(mToken);
+ MediaSession2Service service = StubMediaSession2Service.getInstance();
+ try (MediaSession2 session = new MediaSession2.Builder(mContext)
+ .setId("testGetSessions")
+ .setSessionCallback(sHandlerExecutor, new SessionCallback())
+ .build()) {
+ service.addSession(session);
+ List<MediaSession2> sessions = service.getSessions();
+ assertTrue(sessions.contains(session));
+ assertEquals(2, sessions.size());
+
+ service.removeSession(session);
+ sessions = service.getSessions();
+ assertFalse(sessions.contains(session));
+ }
+ }
+
+ @Test
+ public void testAddSessions_removedWhenClose() throws InterruptedException {
+ MediaController2 controller = createConnectedController(mToken);
+ MediaSession2Service service = StubMediaSession2Service.getInstance();
+ try (MediaSession2 session = new MediaSession2.Builder(mContext)
+ .setId("testAddSessions_removedWhenClose")
+ .setSessionCallback(sHandlerExecutor, new SessionCallback())
+ .build()) {
+ service.addSession(session);
+ List<MediaSession2> sessions = service.getSessions();
+ assertTrue(sessions.contains(session));
+ assertEquals(2, sessions.size());
+
+ session.close();
+ sessions = service.getSessions();
+ assertFalse(sessions.contains(session));
+ }
+ }
+
+ @Test
+ public void testOnUpdateNotification() throws InterruptedException {
+ MediaController2 controller = createConnectedController(mToken);
+ MediaSession2Service service = StubMediaSession2Service.getInstance();
+ MediaSession2 primarySession = service.getSessions().get(0);
+ CountDownLatch latch = new CountDownLatch(2);
+
+ StubMediaSession2Service.setTestInjector(
+ new StubMediaSession2Service.TestInjector() {
+ @Override
+ MediaSession2Service.MediaNotification onUpdateNotification(
+ MediaSession2 session) {
+ assertEquals(primarySession, session);
+ switch ((int) latch.getCount()) {
+ case 2:
+
+ break;
+ case 1:
+ }
+ latch.countDown();
+ return super.onUpdateNotification(session);
+ }
+ });
+
+ primarySession.setPlaybackActive(true);
+ primarySession.setPlaybackActive(false);
+ assertTrue(latch.await(TIMEOUT_MS, TimeUnit.MILLISECONDS));
+ }
+
+ private MediaController2 createConnectedController(Session2Token token)
+ throws InterruptedException {
+ CountDownLatch latch = new CountDownLatch(1);
+ MediaController2 controller = new MediaController2(mContext, token, sHandlerExecutor,
+ new MediaController2.ControllerCallback() {
+ @Override
+ public void onConnected(MediaController2 controller,
+ Session2CommandGroup allowedCommands) {
+ latch.countDown();
+ super.onConnected(controller, allowedCommands);
+ }
+ });
+ mControllers.add(controller);
+ assertTrue(latch.await(TIMEOUT_MS, TimeUnit.MILLISECONDS));
+ return controller;
+ }
+
+ private static class SessionCallback extends MediaSession2.SessionCallback {
+ @Override
+ public Session2CommandGroup onConnect(MediaSession2 session,
+ MediaSession2.ControllerInfo controller) {
+ if (controller.getUid() == Process.myUid()) {
+ return new Session2CommandGroup.Builder().build();
+ }
+ return null;
+ }
+ }
+}
diff --git a/tests/tests/media/src/android/media/cts/MediaSession2Test.java b/tests/tests/media/src/android/media/cts/MediaSession2Test.java
new file mode 100644
index 0000000..9738f65
--- /dev/null
+++ b/tests/tests/media/src/android/media/cts/MediaSession2Test.java
@@ -0,0 +1,495 @@
+/*
+ * Copyright 2019 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.media.cts;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNull;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
+
+import android.content.Context;
+import android.media.MediaController2;
+import android.media.MediaSession2;
+import android.media.Session2Command;
+import android.media.Session2CommandGroup;
+import android.media.Session2Token;
+import android.os.Bundle;
+import android.os.Handler;
+import android.os.HandlerThread;
+import android.os.Process;
+import android.support.test.InstrumentationRegistry;
+import android.support.test.filters.SmallTest;
+import android.support.test.runner.AndroidJUnit4;
+
+import org.junit.AfterClass;
+import org.junit.Before;
+import org.junit.BeforeClass;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.Executor;
+import java.util.concurrent.TimeUnit;
+
+/**
+ * Tests {@link android.media.MediaSession2}.
+ */
+@RunWith(AndroidJUnit4.class)
+@SmallTest
+public class MediaSession2Test {
+ private static final long WAIT_TIME_MS = 300L;
+
+ static Handler sHandler;
+ static Executor sHandlerExecutor;
+ final static Object sTestLock = new Object();
+
+ private Context mContext;
+
+ @BeforeClass
+ public static void setUpThread() {
+ synchronized (MediaSession2Test.class) {
+ if (sHandler != null) {
+ return;
+ }
+ HandlerThread handlerThread = new HandlerThread("MediaSessionTestBase");
+ handlerThread.start();
+ sHandler = new Handler(handlerThread.getLooper());
+ sHandlerExecutor = (runnable) -> {
+ Handler handler;
+ synchronized (MediaSession2Test.class) {
+ handler = sHandler;
+ }
+ if (handler != null) {
+ handler.post(() -> {
+ synchronized (sTestLock) {
+ runnable.run();
+ }
+ });
+ }
+ };
+ }
+ }
+
+ @AfterClass
+ public static void cleanUpThread() {
+ synchronized (MediaSession2Test.class) {
+ if (sHandler == null) {
+ return;
+ }
+ sHandler.getLooper().quitSafely();
+ sHandler = null;
+ sHandlerExecutor = null;
+ }
+ }
+
+ @Before
+ public void setUp() throws Exception {
+ mContext = InstrumentationRegistry.getContext();
+ }
+
+ @Test
+ public void testBuilder_setIllegalArguments() {
+ MediaSession2.Builder builder;
+ try {
+ builder = new MediaSession2.Builder(null);
+ fail("null context shouldn't be allowed");
+ } catch (IllegalArgumentException e) {
+ // expected. pass-through
+ }
+ try {
+ builder = new MediaSession2.Builder(mContext);
+ builder.setId(null);
+ fail("null id shouldn't be allowed");
+ } catch (IllegalArgumentException e) {
+ // expected. pass-through
+ }
+ }
+
+ @Test
+ public void testBuilder_createSessionWithoutId() {
+ try (MediaSession2 session = new MediaSession2.Builder(mContext).build()) {
+ assertEquals("", session.getSessionId());
+ }
+ }
+
+ @Test
+ public void testBuilder_createSessionWithDupId() {
+ final String dupSessionId = "TEST_SESSION_DUP_ID";
+ MediaSession2.Builder builder = new MediaSession2.Builder(mContext).setId(dupSessionId);
+ try (
+ MediaSession2 session1 = builder.build();
+ MediaSession2 session2 = builder.build()
+ ) {
+ fail("Duplicated id shouldn't be allowed");
+ } catch (IllegalStateException e) {
+ // expected. pass-through
+ }
+ }
+
+ @Test
+ public void testSession2Token() {
+ try (MediaSession2 session = new MediaSession2.Builder(mContext).build()) {
+ Session2Token token = session.getSessionToken();
+ assertEquals(Process.myUid(), token.getUid());
+ assertEquals(mContext.getPackageName(), token.getPackageName());
+ assertNull(token.getServiceName());
+ assertEquals(Session2Token.TYPE_SESSION, token.getType());
+ }
+ }
+
+ @Test
+ public void testCallback_onConnect_onDisconnect() throws Exception {
+ Session2Callback sessionCallback = new Session2Callback();
+ try (MediaSession2 session = new MediaSession2.Builder(mContext)
+ .setSessionCallback(sHandlerExecutor, sessionCallback)
+ .build()) {
+ // Test onConnect
+ Controller2Callback controllerCallback = new Controller2Callback();
+ MediaController2 controller = new MediaController2(
+ mContext, session.getSessionToken(), sHandlerExecutor, controllerCallback);
+ assertTrue(controllerCallback.awaitOnConnected(WAIT_TIME_MS));
+ assertTrue(sessionCallback.awaitOnConnect(WAIT_TIME_MS));
+ assertEquals(session, sessionCallback.mSession);
+ MediaSession2.ControllerInfo controllerInfo = sessionCallback.mController;
+
+ // Test onDisconnect
+ controller.close();
+ assertTrue(controllerCallback.awaitOnDisconnected(WAIT_TIME_MS));
+ assertTrue(sessionCallback.awaitOnDisconnect(WAIT_TIME_MS));
+ assertEquals(session, sessionCallback.mSession);
+ assertEquals(controllerInfo, sessionCallback.mController);
+ }
+ }
+
+ @Test
+ public void testCallback_onSessionCommand() {
+ Session2Callback sessionCallback = new Session2Callback();
+
+ try (MediaSession2 session = new MediaSession2.Builder(mContext)
+ .setSessionCallback(sHandlerExecutor, sessionCallback)
+ .build()) {
+ Controller2Callback controllerCallback = new Controller2Callback();
+ MediaController2 controller = new MediaController2(
+ mContext, session.getSessionToken(), sHandlerExecutor, controllerCallback);
+ // Wait for connection
+ assertTrue(controllerCallback.awaitOnConnected(WAIT_TIME_MS));
+ assertTrue(sessionCallback.awaitOnConnect(WAIT_TIME_MS));
+ MediaSession2.ControllerInfo controllerInfo = sessionCallback.mController;
+
+ // Test onSessionCommand
+ String commandStr = "test_command";
+ String commandExtraKey = "test_extra_key";
+ String commandExtraValue = "test_extra_value";
+ Bundle commandExtra = new Bundle();
+ commandExtra.putString(commandExtraKey, commandExtraValue);
+ Session2Command command = new Session2Command(commandStr, commandExtra);
+
+ String commandArgKey = "test_arg_key";
+ String commandArgValue = "test_arg_value";
+ Bundle commandArg = new Bundle();
+ commandArg.putString(commandArgKey, commandArgValue);
+ controller.sendSessionCommand(command, commandArg);
+
+ assertTrue(sessionCallback.awaitOnSessionCommand(WAIT_TIME_MS));
+ assertEquals(session, sessionCallback.mSession);
+ assertEquals(controllerInfo, sessionCallback.mController);
+ assertEquals(commandStr, sessionCallback.mCommand.getCustomCommand());
+ assertEquals(commandExtraValue,
+ sessionCallback.mCommand.getExtras().getString(commandExtraKey));
+ assertEquals(commandArgValue, sessionCallback.mCommandArgs.getString(commandArgKey));
+
+ controller.close();
+ assertTrue(controllerCallback.awaitOnDisconnected(WAIT_TIME_MS));
+ }
+ }
+
+ @Test
+ public void testCallback_onCommandResult() {
+ Session2Callback sessionCallback = new Session2Callback();
+
+ int resultCode = 100;
+ String commandResultKey = "test_result_key";
+ String commandResultValue = "test_result_value";
+ Bundle resultData = new Bundle();
+ resultData.putString(commandResultKey, commandResultValue);
+ Session2Command.Result commandResult = new Session2Command.Result(resultCode, resultData);
+
+ try (MediaSession2 session = new MediaSession2.Builder(mContext)
+ .setSessionCallback(sHandlerExecutor, sessionCallback)
+ .build()) {
+ Controller2Callback controllerCallback = new Controller2Callback() {
+ @Override
+ public Session2Command.Result onSessionCommand(MediaController2 controller,
+ Session2Command command, Bundle args) {
+ return commandResult;
+ }
+ };
+ MediaController2 controller = new MediaController2(
+ mContext, session.getSessionToken(), sHandlerExecutor, controllerCallback);
+ // Wait for connection
+ assertTrue(sessionCallback.awaitOnConnect(WAIT_TIME_MS));
+ MediaSession2.ControllerInfo controllerInfo = sessionCallback.mController;
+
+ // Test onCommandResult
+ String commandStr = "test_command";
+ String commandExtraKey = "test_extra_key";
+ String commandExtraValue = "test_extra_value";
+ Bundle commandExtra = new Bundle();
+ commandExtra.putString(commandExtraKey, commandExtraValue);
+ Session2Command command = new Session2Command(commandStr, commandExtra);
+
+ String commandArgKey = "test_arg_key";
+ String commandArgValue = "test_arg_value";
+ Bundle commandArg = new Bundle();
+ commandArg.putString(commandArgKey, commandArgValue);
+ session.sendSessionCommand(controllerInfo, command, commandArg);
+
+ assertTrue(sessionCallback.awaitOnCommandResult(WAIT_TIME_MS));
+ assertEquals(session, sessionCallback.mSession);
+ assertEquals(controllerInfo, sessionCallback.mController);
+ assertEquals(resultCode, sessionCallback.mCommandResult.getResultCode());
+ assertEquals(commandResultValue,
+ sessionCallback.mCommandResult.getResultData().getString(commandResultKey));
+
+ controller.close();
+ assertTrue(controllerCallback.awaitOnDisconnected(WAIT_TIME_MS));
+ }
+ }
+
+ @Test
+ public void testSetPlaybackActive() {
+ final boolean testInitialPlaybackActive = true;
+ final boolean testPlaybackActive = false;
+ Session2Callback sessionCallback = new Session2Callback();
+ try (MediaSession2 session = new MediaSession2.Builder(mContext)
+ .setSessionCallback(sHandlerExecutor, sessionCallback)
+ .build()) {
+ session.setPlaybackActive(testInitialPlaybackActive);
+
+ Controller2Callback controllerCallback = new Controller2Callback();
+ MediaController2 controller = new MediaController2(mContext, session.getSessionToken(),
+ sHandlerExecutor, controllerCallback);
+ // Wait for connection
+ assertTrue(controllerCallback.awaitOnConnected(WAIT_TIME_MS));
+
+ // Check initial value
+ assertEquals(testInitialPlaybackActive, controller.isPlaybackActive());
+
+ // Change playback active change and wait for changes
+ session.setPlaybackActive(testPlaybackActive);
+ assertTrue(controllerCallback.awaitOnPlaybackActiveChanged(WAIT_TIME_MS));
+
+ assertEquals(testPlaybackActive, controllerCallback.getNotifiedPlaybackActive());
+ assertEquals(testPlaybackActive, controller.isPlaybackActive());
+
+ controller.close();
+ assertTrue(controllerCallback.awaitOnDisconnected(WAIT_TIME_MS));
+ }
+ }
+
+ @Test
+ public void testCancelSessionCommand() {
+ Session2Callback sessionCallback = new Session2Callback();
+ try (MediaSession2 session = new MediaSession2.Builder(mContext)
+ .setSessionCallback(sHandlerExecutor, sessionCallback)
+ .build()) {
+ Controller2Callback controllerCallback = new Controller2Callback();
+ MediaController2 controller = new MediaController2(mContext, session.getSessionToken(),
+ sHandlerExecutor, controllerCallback);
+ // Wait for connection
+ assertTrue(sessionCallback.awaitOnConnect(WAIT_TIME_MS));
+ MediaSession2.ControllerInfo controllerInfo = sessionCallback.mController;
+
+ String commandStr = "test_command_";
+ String commandExtraKey = "test_extra_key_";
+ String commandExtraValue = "test_extra_value_";
+ Bundle commandExtra = new Bundle();
+ commandExtra.putString(commandExtraKey, commandExtraValue);
+ Session2Command command = new Session2Command(commandStr, commandExtra);
+
+ String commandArgKey = "test_arg_key_";
+ String commandArgValue = "test_arg_value_";
+ Bundle commandArg = new Bundle();
+ commandArg.putString(commandArgKey, commandArgValue);
+ synchronized (sTestLock) {
+ Object token = session.sendSessionCommand(controllerInfo, command, commandArg);
+ session.cancelSessionCommand(controllerInfo, token);
+ }
+ assertTrue(sessionCallback.awaitOnCommandResult(WAIT_TIME_MS));
+ assertEquals(Session2Command.RESULT_INFO_SKIPPED,
+ sessionCallback.mCommandResult.getResultCode());
+
+ controller.close();
+ assertTrue(controllerCallback.awaitOnDisconnected(WAIT_TIME_MS));
+ }
+ }
+
+ class Controller2Callback extends MediaController2.ControllerCallback {
+ private final CountDownLatch mOnConnectedLatch = new CountDownLatch(1);
+ private final CountDownLatch mOnDisconnectedLatch = new CountDownLatch(1);
+ private final CountDownLatch mOnPlaybackActiveChangedLatch = new CountDownLatch(1);
+
+ private boolean mPlaybackActive;
+
+ @Override
+ public void onConnected(MediaController2 controller,
+ Session2CommandGroup allowedCommands) {
+ mOnConnectedLatch.countDown();
+ }
+
+ @Override
+ public void onDisconnected(MediaController2 controller) {
+ mOnDisconnectedLatch.countDown();
+ }
+
+ @Override
+ public void onPlaybackActiveChanged(MediaController2 controller, boolean playbackActive) {
+ mPlaybackActive = playbackActive;
+ mOnPlaybackActiveChangedLatch.countDown();
+ }
+
+ public boolean awaitOnConnected(long waitTimeMs) {
+ try {
+ return mOnConnectedLatch.await(waitTimeMs, TimeUnit.MILLISECONDS);
+ } catch (InterruptedException e) {
+ return false;
+ }
+ }
+
+ public boolean awaitOnDisconnected(long waitTimeMs) {
+ try {
+ return mOnDisconnectedLatch.await(waitTimeMs, TimeUnit.MILLISECONDS);
+ } catch (InterruptedException e) {
+ return false;
+ }
+ }
+
+ public boolean awaitOnPlaybackActiveChanged(long waitTimeMs) {
+ try {
+ return mOnPlaybackActiveChangedLatch.await(waitTimeMs, TimeUnit.MILLISECONDS);
+ } catch (InterruptedException e) {
+ return false;
+ }
+ }
+
+ public boolean getNotifiedPlaybackActive() {
+ return mPlaybackActive;
+ }
+ }
+
+ class Session2Callback extends MediaSession2.SessionCallback {
+ private final CountDownLatch mOnConnectLatch = new CountDownLatch(1);
+ private final CountDownLatch mOnDisconnectLatch = new CountDownLatch(1);
+ private final CountDownLatch mOnSessionCommandLatch = new CountDownLatch(1);
+ private final CountDownLatch mOnCommandResultLatch = new CountDownLatch(1);
+
+ MediaSession2 mSession;
+ MediaSession2.ControllerInfo mController;
+ Session2Command mCommand;
+ Bundle mCommandArgs;
+ Session2Command.Result mCommandResult;
+
+ @Override
+ public Session2CommandGroup onConnect(MediaSession2 session,
+ MediaSession2.ControllerInfo controller) {
+ if (controller.getUid() != Process.myUid()) {
+ return null;
+ }
+ mSession = session;
+ mController = controller;
+ mOnConnectLatch.countDown();
+ return new Session2CommandGroup.Builder().build();
+ }
+
+ @Override
+ public void onDisconnected(MediaSession2 session, MediaSession2.ControllerInfo controller) {
+ if (controller.getUid() != Process.myUid()) {
+ return;
+ }
+ mSession = session;
+ mController = controller;
+ mOnDisconnectLatch.countDown();
+ }
+
+ @Override
+ public Session2Command.Result onSessionCommand(MediaSession2 session,
+ MediaSession2.ControllerInfo controller, Session2Command command, Bundle args) {
+ if (controller.getUid() != Process.myUid()) {
+ return null;
+ }
+ mSession = session;
+ mController = controller;
+ mCommand = command;
+ mCommandArgs = args;
+ mOnSessionCommandLatch.countDown();
+
+ int resultCode = 100;
+ String commandResultKey = "test_result_key";
+ String commandResultValue = "test_result_value";
+ Bundle resultData = new Bundle();
+ resultData.putString(commandResultKey, commandResultValue);
+ Session2Command.Result commandResult =
+ new Session2Command.Result(resultCode, resultData);
+ return commandResult;
+ }
+
+ @Override
+ public void onCommandResult(MediaSession2 session, MediaSession2.ControllerInfo controller,
+ Object token, Session2Command command, Session2Command.Result result) {
+ if (controller.getUid() != Process.myUid()) {
+ return;
+ }
+ mSession = session;
+ mController = controller;
+ mCommand = command;
+ mCommandResult = result;
+ mOnCommandResultLatch.countDown();
+ }
+
+ public boolean awaitOnConnect(long waitTimeMs) {
+ try {
+ return mOnConnectLatch.await(waitTimeMs, TimeUnit.MILLISECONDS);
+ } catch (InterruptedException e) {
+ return false;
+ }
+ }
+
+ public boolean awaitOnDisconnect(long waitTimeMs) {
+ try {
+ return mOnDisconnectLatch.await(waitTimeMs, TimeUnit.MILLISECONDS);
+ } catch (InterruptedException e) {
+ return false;
+ }
+ }
+
+ public boolean awaitOnSessionCommand(long waitTimeMs) {
+ try {
+ return mOnSessionCommandLatch.await(waitTimeMs, TimeUnit.MILLISECONDS);
+ } catch (InterruptedException e) {
+ return false;
+ }
+ }
+
+ public boolean awaitOnCommandResult(long waitTimeMs) {
+ try {
+ return mOnCommandResultLatch.await(waitTimeMs, TimeUnit.MILLISECONDS);
+ } catch (InterruptedException e) {
+ return false;
+ }
+ }
+ }
+}
diff --git a/tests/tests/media/src/android/media/cts/MediaSessionManagerTest.java b/tests/tests/media/src/android/media/cts/MediaSessionManagerTest.java
index 926abd8..c38f3d0 100644
--- a/tests/tests/media/src/android/media/cts/MediaSessionManagerTest.java
+++ b/tests/tests/media/src/android/media/cts/MediaSessionManagerTest.java
@@ -22,6 +22,9 @@
import android.content.Intent;
import android.content.pm.PackageManager;
import android.content.res.Resources;
+import android.media.MediaSession2;
+import android.media.Session2CommandGroup;
+import android.media.Session2Token;
import android.media.session.MediaController;
import android.media.session.MediaSession;
import android.media.session.MediaSessionManager;
@@ -29,14 +32,17 @@
import android.os.Handler;
import android.os.HandlerThread;
import android.os.Looper;
+import android.os.UserHandle;
import android.test.InstrumentationTestCase;
import android.test.UiThreadTest;
import android.view.KeyEvent;
+import android.util.Log;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.Executor;
import java.util.concurrent.TimeUnit;
@AppModeFull(reason = "TODO: evaluate and port to instant")
@@ -54,6 +60,11 @@
.getSystemService(Context.MEDIA_SESSION_SERVICE);
}
+ @Override
+ protected void tearDown() throws Exception {
+ super.tearDown();
+ }
+
public void testGetActiveSessions() throws Exception {
try {
List<MediaController> controllers = mSessionManager.getActiveSessions(null);
@@ -114,10 +125,7 @@
// events directly to the audio service to change the system volume.
return;
}
-
- HandlerThread handlerThread = new HandlerThread(TAG);
- handlerThread.start();
- Handler handler = new Handler(handlerThread.getLooper());
+ Handler handler = createHandler();
// Ensure that the listener is called for long-press.
VolumeKeyLongPressListener listener = new VolumeKeyLongPressListener(3, handler);
@@ -144,13 +152,12 @@
injectInputEvent(KeyEvent.KEYCODE_VOLUME_DOWN, true);
assertFalse(listener.mCountDownLatch.await(WAIT_MS, TimeUnit.MILLISECONDS));
assertEquals(listener.mKeyEvents.size(), 0);
+
+ removeHandler(handler);
}
public void testSetOnMediaKeyListener() throws Exception {
- HandlerThread handlerThread = new HandlerThread(TAG);
- handlerThread.start();
- Handler handler = new Handler(handlerThread.getLooper());
-
+ Handler handler = createHandler();
MediaSession session = null;
try {
session = new MediaSession(getInstrumentation().getTargetContext(), TAG);
@@ -210,14 +217,13 @@
if (session != null) {
session.release();
}
+ removeHandler(handler);
}
}
public void testRemoteUserInfo() throws Exception {
final Context context = getInstrumentation().getTargetContext();
- HandlerThread handlerThread = new HandlerThread(TAG);
- handlerThread.start();
- Handler handler = new Handler(handlerThread.getLooper());
+ Handler handler = createHandler();
MediaSession session = null;
try {
@@ -264,9 +270,116 @@
if (session != null) {
session.release();
}
+ removeHandler(handler);
}
}
+ public void testGetSession2Tokens() throws Exception {
+ final Context context = getInstrumentation().getTargetContext();
+ Handler handler = createHandler();
+
+ Session2TokenListener listener = new Session2TokenListener();
+ mSessionManager.addOnSession2TokensChangedListener(listener, handler);
+
+ Session2Callback sessionCallback = new Session2Callback();
+ try (MediaSession2 session = new MediaSession2.Builder(context)
+ .setSessionCallback(new HandlerExecutor(handler.getLooper()), sessionCallback)
+ .build()) {
+ assertTrue(sessionCallback.mCountDownLatch.await(TIMEOUT_MS, TimeUnit.MILLISECONDS));
+ assertTrue(listener.mCountDownLatch.await(TIMEOUT_MS, TimeUnit.MILLISECONDS));
+
+ Session2Token currentToken = session.getSessionToken();
+ assertTrue(listContainsToken(listener.mTokens, currentToken));
+ assertTrue(listContainsToken(mSessionManager.getSession2Tokens(), currentToken));
+ }
+ }
+
+ public void testAddAndRemoveSession2TokensListener() throws Exception {
+ final Context context = getInstrumentation().getTargetContext();
+ Handler handler = createHandler();
+
+ Session2TokenListener listener1 = new Session2TokenListener();
+ mSessionManager.addOnSession2TokensChangedListener(listener1, handler);
+
+ Session2Callback sessionCallback = new Session2Callback();
+ try (MediaSession2 session = new MediaSession2.Builder(context)
+ .setSessionCallback(new HandlerExecutor(handler.getLooper()), sessionCallback)
+ .build()) {
+ assertTrue(listener1.mCountDownLatch.await(TIMEOUT_MS, TimeUnit.MILLISECONDS));
+ Session2Token currentToken = session.getSessionToken();
+ assertTrue(listContainsToken(listener1.mTokens, currentToken));
+
+ // Test removing listener
+ listener1.resetCountDownLatch();
+ Session2TokenListener listener2 = new Session2TokenListener();
+ mSessionManager.addOnSession2TokensChangedListener(listener2, handler);
+ mSessionManager.removeOnSession2TokensChangedListener(listener1);
+
+ session.close();
+ assertFalse(listener1.mCountDownLatch.await(TIMEOUT_MS, TimeUnit.MILLISECONDS));
+ assertTrue(listener2.mCountDownLatch.await(TIMEOUT_MS, TimeUnit.MILLISECONDS));
+ }
+ }
+
+ public void testNotifySession2Created_withDestroyedToken_shouldThrowIAE() {
+ final Context context = getInstrumentation().getTargetContext();
+
+ MediaSession2 session = new MediaSession2.Builder(context)
+ .setSessionCallback(new HandlerExecutor(createHandler().getLooper()),
+ new Session2Callback())
+ .build();
+ session.close();
+ Session2Token destroyedToken = session.getSessionToken();
+
+ try {
+ mSessionManager.notifySession2Created(destroyedToken);
+ fail("notifySession2Created should throw IAE");
+ } catch (IllegalArgumentException ex) {
+ // Expected.
+ }
+ }
+
+ public void testNotifySession2Destroyed_withLiveToken_shouldThrowIAE() {
+ final Context context = getInstrumentation().getTargetContext();
+
+ MediaSession2 session = new MediaSession2.Builder(context)
+ .setSessionCallback(new HandlerExecutor(createHandler().getLooper()),
+ new Session2Callback())
+ .build();
+ Session2Token liveToken = session.getSessionToken();
+
+ try {
+ mSessionManager.notifySession2Destroyed(liveToken);
+ fail("notifySession2Destroyed should throw IAE");
+ } catch (IllegalArgumentException ex) {
+ // Expected.
+ } finally {
+ session.close();
+ }
+ }
+
+ private boolean listContainsToken(List<Session2Token> tokens, Session2Token token) {
+ for (int i = 0; i < tokens.size(); i++) {
+ if (tokens.get(i).equals(token)) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ private Handler createHandler() {
+ HandlerThread handlerThread = new HandlerThread("MediaSessionManagerTest");
+ handlerThread.start();
+ return new Handler(handlerThread.getLooper());
+ }
+
+ private void removeHandler(Handler handler) {
+ if (handler == null) {
+ return;
+ }
+ handler.getLooper().quitSafely();
+ }
+
private class VolumeKeyLongPressListener
implements MediaSessionManager.OnVolumeKeyLongPressListener {
private final List<KeyEvent> mKeyEvents = new ArrayList<>();
@@ -330,4 +443,39 @@
return true;
}
}
+
+ private class Session2Callback extends MediaSession2.SessionCallback {
+ private CountDownLatch mCountDownLatch;
+
+ private Session2Callback() {
+ mCountDownLatch = new CountDownLatch(1);
+ }
+
+ @Override
+ public Session2CommandGroup onConnect(MediaSession2 session,
+ MediaSession2.ControllerInfo controller) {
+ mCountDownLatch.countDown();
+ return new Session2CommandGroup.Builder().build();
+ }
+ }
+
+ private class Session2TokenListener implements
+ MediaSessionManager.OnSession2TokensChangedListener {
+ private CountDownLatch mCountDownLatch;
+ private List<Session2Token> mTokens;
+
+ private Session2TokenListener() {
+ mCountDownLatch = new CountDownLatch(1);
+ }
+
+ @Override
+ public void onSession2TokensChanged(List<Session2Token> tokens) {
+ mTokens = tokens;
+ mCountDownLatch.countDown();
+ }
+
+ public void resetCountDownLatch() {
+ mCountDownLatch = new CountDownLatch(1);
+ }
+ }
}
diff --git a/tests/tests/media/src/android/media/cts/MediaSyncTest.java b/tests/tests/media/src/android/media/cts/MediaSyncTest.java
index fe752f8..cc71e1e 100644
--- a/tests/tests/media/src/android/media/cts/MediaSyncTest.java
+++ b/tests/tests/media/src/android/media/cts/MediaSyncTest.java
@@ -36,6 +36,8 @@
import android.os.Handler;
import android.os.HandlerThread;
import android.platform.test.annotations.AppModeFull;
+import android.platform.test.annotations.RequiresDevice;
+import android.support.test.filters.SmallTest;
import android.test.ActivityInstrumentationTestCase2;
import android.util.Log;
import android.view.Surface;
@@ -58,6 +60,8 @@
* Blender Foundation / www.bigbuckbunny.org, and are licensed under the Creative Commons
* Attribution 3.0 License at http://creativecommons.org/licenses/by/3.0/us/.
*/
+@SmallTest
+@RequiresDevice
@AppModeFull(reason = "TODO: evaluate and port to instant")
public class MediaSyncTest extends ActivityInstrumentationTestCase2<MediaStubActivity> {
private static final String LOG_TAG = "MediaSyncTest";
diff --git a/tests/tests/media/src/android/media/cts/NativeDecoderTest.java b/tests/tests/media/src/android/media/cts/NativeDecoderTest.java
index 5e4f598..52b6d5d 100644
--- a/tests/tests/media/src/android/media/cts/NativeDecoderTest.java
+++ b/tests/tests/media/src/android/media/cts/NativeDecoderTest.java
@@ -32,6 +32,8 @@
import android.os.Environment;
import android.os.ParcelFileDescriptor;
import android.platform.test.annotations.AppModeFull;
+import android.platform.test.annotations.RequiresDevice;
+import android.support.test.filters.SmallTest;
import android.util.Log;
import android.view.Surface;
import android.webkit.cts.CtsTestServer;
@@ -65,6 +67,8 @@
import org.apache.http.params.HttpParams;
import org.apache.http.util.CharArrayBuffer;
+@SmallTest
+@RequiresDevice
@AppModeFull(reason = "TODO: evaluate and port to instant")
public class NativeDecoderTest extends MediaPlayerTestBase {
private static final String TAG = "DecoderTest";
diff --git a/tests/tests/media/src/android/media/cts/Session2CommandGroupTest.java b/tests/tests/media/src/android/media/cts/Session2CommandGroupTest.java
new file mode 100644
index 0000000..cff9f08
--- /dev/null
+++ b/tests/tests/media/src/android/media/cts/Session2CommandGroupTest.java
@@ -0,0 +1,118 @@
+/*
+ * Copyright 2019 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.media.cts;
+
+import static org.junit.Assert.assertArrayEquals;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+
+import android.media.Session2Command;
+import android.media.Session2CommandGroup;
+import android.os.Bundle;
+import android.os.Parcel;
+import android.support.test.filters.SmallTest;
+import android.support.test.runner.AndroidJUnit4;
+
+import java.util.Collection;
+import java.util.Set;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+/**
+ * Tests {@link android.media.Session2CommandGroup}.
+ */
+@RunWith(AndroidJUnit4.class)
+@SmallTest
+public class Session2CommandGroupTest {
+ private final int TEST_COMMAND_CODE_1 = 10000;
+ private final int TEST_COMMAND_CODE_2 = 10001;
+ private final int TEST_COMMAND_CODE_3 = 10002;
+
+ @Test
+ public void testHasCommand() {
+ Session2Command testCommand = new Session2Command(TEST_COMMAND_CODE_1);
+ Session2CommandGroup.Builder builder = new Session2CommandGroup.Builder()
+ .addCommand(TEST_COMMAND_CODE_1);
+ Session2CommandGroup commandGroup = builder.build();
+ assertTrue(commandGroup.hasCommand(TEST_COMMAND_CODE_1));
+ assertTrue(commandGroup.hasCommand(testCommand));
+ assertFalse(commandGroup.hasCommand(TEST_COMMAND_CODE_2));
+ }
+
+ @Test
+ public void testGetCommands() {
+ Session2CommandGroup.Builder builder = new Session2CommandGroup.Builder()
+ .addCommand(TEST_COMMAND_CODE_1);
+ Session2CommandGroup commandGroup = builder.build();
+
+ Set<Session2Command> commands = commandGroup.getCommands();
+ assertTrue(commands.contains(new Session2Command(TEST_COMMAND_CODE_1)));
+ assertFalse(commands.contains(new Session2Command(TEST_COMMAND_CODE_2)));
+ }
+
+ @Test
+ public void testDescribeContents() {
+ final int expected = 0;
+ Session2Command command = new Session2Command(TEST_COMMAND_CODE_1);
+ Session2CommandGroup.Builder builder = new Session2CommandGroup.Builder()
+ .addCommand(TEST_COMMAND_CODE_1);
+ Session2CommandGroup commandGroup = builder.build();
+ assertEquals(expected, commandGroup.describeContents());
+ }
+
+ @Test
+ public void testWriteToParcel() {
+ Session2CommandGroup.Builder builder = new Session2CommandGroup.Builder()
+ .addCommand(TEST_COMMAND_CODE_1)
+ .addCommand(TEST_COMMAND_CODE_2);
+ Session2CommandGroup commandGroup = builder.build();
+ Parcel dest = Parcel.obtain();
+ commandGroup.writeToParcel(dest, 0);
+ dest.setDataPosition(0);
+ Session2CommandGroup commandGroupFromParcel =
+ Session2CommandGroup.CREATOR.createFromParcel(dest);
+ assertEquals(commandGroup.getCommands(), commandGroupFromParcel.getCommands());
+ dest.recycle();
+ }
+
+ @Test
+ public void testBuilder() {
+ Session2CommandGroup.Builder builder = new Session2CommandGroup.Builder()
+ .addCommand(TEST_COMMAND_CODE_1);
+ Session2CommandGroup commandGroup = builder.build();
+ Session2CommandGroup.Builder newBuilder = new Session2CommandGroup.Builder(commandGroup);
+ Session2CommandGroup newCommandGroup = newBuilder.build();
+ assertEquals(commandGroup.getCommands(), newCommandGroup.getCommands());
+ }
+
+ @Test
+ public void testAddAndRemoveCommand() {
+ Session2Command testCommand = new Session2Command(TEST_COMMAND_CODE_1);
+ Session2CommandGroup.Builder builder = new Session2CommandGroup.Builder()
+ .addCommand(testCommand)
+ .addCommand(TEST_COMMAND_CODE_2)
+ .addCommand(TEST_COMMAND_CODE_3);
+ builder.removeCommand(testCommand)
+ .removeCommand(TEST_COMMAND_CODE_2);
+ Session2CommandGroup commandGroup = builder.build();
+ assertFalse(commandGroup.hasCommand(testCommand));
+ assertFalse(commandGroup.hasCommand(TEST_COMMAND_CODE_2));
+ assertTrue(commandGroup.hasCommand(TEST_COMMAND_CODE_3));
+ }
+}
diff --git a/tests/tests/media/src/android/media/cts/StubMediaSession2Service.java b/tests/tests/media/src/android/media/cts/StubMediaSession2Service.java
new file mode 100644
index 0000000..c2bd7ef
--- /dev/null
+++ b/tests/tests/media/src/android/media/cts/StubMediaSession2Service.java
@@ -0,0 +1,136 @@
+/*
+ * Copyright 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.media.cts;
+
+import android.media.MediaSession2;
+import android.media.MediaSession2Service;
+import android.media.Session2CommandGroup;
+import android.os.Process;
+
+import com.android.internal.annotations.GuardedBy;
+
+import java.util.List;
+
+/**
+ * Stub implementation of {@link MediaSession2Service} for testing.
+ */
+public class StubMediaSession2Service extends MediaSession2Service {
+ /**
+ * ID of the session that this service will create.
+ */
+ private static final String ID = "StubMediaSession2Service";
+
+ @GuardedBy("StubMediaSession2Service.class")
+ private static HandlerExecutor sHandlerExecutor;
+ @GuardedBy("StubMediaSession2Service.class")
+ private static StubMediaSession2Service sInstance;
+ @GuardedBy("StubMediaSession2Service.class")
+ private static TestInjector sTestInjector;
+
+ public static void setHandlerExecutor(HandlerExecutor handlerExecutor) {
+ synchronized (StubMediaSession2Service.class) {
+ sHandlerExecutor = handlerExecutor;
+ }
+ }
+
+ public static StubMediaSession2Service getInstance() {
+ synchronized (StubMediaSession2Service.class) {
+ return sInstance;
+ }
+ }
+
+ public static void setTestInjector(TestInjector injector) {
+ synchronized (StubMediaSession2Service.class) {
+ sTestInjector = injector;
+ }
+ }
+
+ @Override
+ public void onCreate() {
+ super.onCreate();
+ synchronized (StubMediaSession2Service.class) {
+ sInstance = this;
+ }
+ }
+
+ @Override
+ public void onDestroy() {
+ List<MediaSession2> sessions = getSessions();
+ for (MediaSession2 session : sessions) {
+ session.close();
+ }
+ synchronized (StubMediaSession2Service.class) {
+ if (sTestInjector != null) {
+ sTestInjector.onServiceDestroyed();
+ }
+ sInstance = null;
+ }
+ super.onDestroy();
+ }
+
+ @Override
+ public MediaNotification onUpdateNotification(MediaSession2 session) {
+ synchronized (StubMediaSession2Service.class) {
+ if (sTestInjector != null) {
+ sTestInjector.onUpdateNotification(session);
+ }
+ sInstance = null;
+ }
+ return null;
+ }
+
+ @Override
+ public MediaSession2 onGetPrimarySession() {
+ synchronized (StubMediaSession2Service.class) {
+ if (sTestInjector != null) {
+ MediaSession2 session = sTestInjector.onGetPrimarySession();
+ if (session != null) {
+ return session;
+ }
+ }
+ }
+ if (getSessions().size() > 0) {
+ return getSessions().get(0);
+ }
+ return new MediaSession2.Builder(this)
+ .setId(ID)
+ .setSessionCallback(sHandlerExecutor, new MediaSession2.SessionCallback() {
+ @Override
+ public Session2CommandGroup onConnect(MediaSession2 session,
+ MediaSession2.ControllerInfo controller) {
+ if (controller.getUid() == Process.myUid()) {
+ return new Session2CommandGroup.Builder().build();
+ }
+ return null;
+ }
+ }).build();
+ }
+
+ public static abstract class TestInjector {
+ MediaSession2 onGetPrimarySession() {
+ return null;
+ }
+
+ MediaNotification onUpdateNotification(MediaSession2 session) {
+ return null;
+ }
+
+ void onServiceDestroyed() {
+ // no-op
+ }
+ }
+}
\ No newline at end of file
diff --git a/tests/tests/media/src/android/media/cts/VideoDecoderPerfTest.java b/tests/tests/media/src/android/media/cts/VideoDecoderPerfTest.java
index ce97379..57ff9d3 100644
--- a/tests/tests/media/src/android/media/cts/VideoDecoderPerfTest.java
+++ b/tests/tests/media/src/android/media/cts/VideoDecoderPerfTest.java
@@ -40,6 +40,7 @@
import java.util.Arrays;
import java.util.LinkedList;
+@MediaHeavyPresubmitTest
@AppModeFull(reason = "TODO: evaluate and port to instant")
public class VideoDecoderPerfTest extends MediaPlayerTestBase {
private static final String TAG = "VideoDecoderPerfTest";
diff --git a/tests/tests/media/src/android/media/cts/VideoEncoderTest.java b/tests/tests/media/src/android/media/cts/VideoEncoderTest.java
index 3a2165d..818c95d 100644
--- a/tests/tests/media/src/android/media/cts/VideoEncoderTest.java
+++ b/tests/tests/media/src/android/media/cts/VideoEncoderTest.java
@@ -55,6 +55,7 @@
import java.util.Map;
import java.util.Set;
+@MediaHeavyPresubmitTest
@AppModeFull(reason = "TODO: evaluate and port to instant")
public class VideoEncoderTest extends MediaPlayerTestBase {
private static final int MAX_SAMPLE_SIZE = 256 * 1024;
diff --git a/tests/tests/media/src/android/media/cts/VpxEncoderTest.java b/tests/tests/media/src/android/media/cts/VpxEncoderTest.java
index 38a8403..654875f 100644
--- a/tests/tests/media/src/android/media/cts/VpxEncoderTest.java
+++ b/tests/tests/media/src/android/media/cts/VpxEncoderTest.java
@@ -36,6 +36,7 @@
* The stream is later decoded by vp8/vp9 decoder to verify frames are decodable and to
* calculate PSNR values for various bitrates.
*/
+@MediaHeavyPresubmitTest
@AppModeFull(reason = "TODO: evaluate and port to instant")
public class VpxEncoderTest extends VpxCodecTestBase {
diff --git a/tests/tests/nativemedia/aaudio/jni/test_aaudio_attributes.cpp b/tests/tests/nativemedia/aaudio/jni/test_aaudio_attributes.cpp
index d48aeab..4e4d022 100644
--- a/tests/tests/nativemedia/aaudio/jni/test_aaudio_attributes.cpp
+++ b/tests/tests/nativemedia/aaudio/jni/test_aaudio_attributes.cpp
@@ -130,6 +130,7 @@
AAUDIO_INPUT_PRESET_VOICE_RECOGNITION,
AAUDIO_INPUT_PRESET_VOICE_COMMUNICATION,
AAUDIO_INPUT_PRESET_UNPROCESSED,
+ AAUDIO_INPUT_PRESET_VOICE_PERFORMANCE,
};
diff --git a/tests/tests/nativemedia/aaudio/jni/test_aaudio_misc.cpp b/tests/tests/nativemedia/aaudio/jni/test_aaudio_misc.cpp
index 01ed9f6..9bb5484 100644
--- a/tests/tests/nativemedia/aaudio/jni/test_aaudio_misc.cpp
+++ b/tests/tests/nativemedia/aaudio/jni/test_aaudio_misc.cpp
@@ -99,4 +99,5 @@
static_assert(6 == AAUDIO_INPUT_PRESET_VOICE_RECOGNITION, ENUM_CANNOT_CHANGE);
static_assert(7 == AAUDIO_INPUT_PRESET_VOICE_COMMUNICATION, ENUM_CANNOT_CHANGE);
static_assert(9 == AAUDIO_INPUT_PRESET_UNPROCESSED, ENUM_CANNOT_CHANGE);
+ static_assert(10 == AAUDIO_INPUT_PRESET_VOICE_PERFORMANCE, ENUM_CANNOT_CHANGE);
}
diff --git a/tests/tests/net/native/dns/NativeDnsAsyncTest.cpp b/tests/tests/net/native/dns/NativeDnsAsyncTest.cpp
index 6ce89a0..2fc9ff8f 100644
--- a/tests/tests/net/native/dns/NativeDnsAsyncTest.cpp
+++ b/tests/tests/net/native/dns/NativeDnsAsyncTest.cpp
@@ -44,6 +44,10 @@
revents = wait_fd[0].revents;
if (revents & POLLIN) {
int n = android_res_nresult(fd, rcode, buf, bufLen);
+ // Verify that android_res_nresult() closed the fd
+ char dummy;
+ EXPECT_EQ(-1, read(fd, &dummy, sizeof dummy));
+ EXPECT_EQ(EBADF, errno);
return n;
}
@@ -78,7 +82,6 @@
EXPECT_GE(res, 0);
EXPECT_EQ(rcode, expectedRcode);
-
if (expectedRcode == ns_r_noerror) {
auto answers = extractIpAddressAnswers(buf, res, ipType);
EXPECT_GE(answers.size(), 0U);
@@ -101,20 +104,20 @@
TEST (NativeDnsAsyncTest, Async_Query) {
// V4
int fd1 = android_res_nquery(
- NETWORK_UNSPECIFIED, "www.google.com", ns_c_in, ns_t_a, ResNsendFlags(0));
+ NETWORK_UNSPECIFIED, "www.google.com", ns_c_in, ns_t_a, 0);
EXPECT_GE(fd1, 0);
int fd2 = android_res_nquery(
- NETWORK_UNSPECIFIED, "www.youtube.com", ns_c_in, ns_t_a, ResNsendFlags(0));
+ NETWORK_UNSPECIFIED, "www.youtube.com", ns_c_in, ns_t_a, 0);
EXPECT_GE(fd2, 0);
expectAnswersValid(fd2, AF_INET, ns_r_noerror);
expectAnswersValid(fd1, AF_INET, ns_r_noerror);
// V6
fd1 = android_res_nquery(
- NETWORK_UNSPECIFIED, "www.google.com", ns_c_in, ns_t_aaaa, ResNsendFlags(0));
+ NETWORK_UNSPECIFIED, "www.google.com", ns_c_in, ns_t_aaaa, 0);
EXPECT_GE(fd1, 0);
fd2 = android_res_nquery(
- NETWORK_UNSPECIFIED, "www.youtube.com", ns_c_in, ns_t_aaaa, ResNsendFlags(0));
+ NETWORK_UNSPECIFIED, "www.youtube.com", ns_c_in, ns_t_aaaa, 0);
EXPECT_GE(fd2, 0);
expectAnswersValid(fd2, AF_INET6, ns_r_noerror);
expectAnswersValid(fd1, AF_INET6, ns_r_noerror);
@@ -132,9 +135,9 @@
ns_c_in, ns_t_a, nullptr, 0, nullptr, buf2, sizeof(buf2));
EXPECT_GT(len2, 0);
- int fd1 = android_res_nsend(NETWORK_UNSPECIFIED, buf1, len1, ResNsendFlags(0));
+ int fd1 = android_res_nsend(NETWORK_UNSPECIFIED, buf1, len1, 0);
EXPECT_GE(fd1, 0);
- int fd2 = android_res_nsend(NETWORK_UNSPECIFIED, buf2, len2, ResNsendFlags(0));
+ int fd2 = android_res_nsend(NETWORK_UNSPECIFIED, buf2, len2, 0);
EXPECT_GE(fd2, 0);
expectAnswersValid(fd2, AF_INET, ns_r_noerror);
@@ -150,9 +153,9 @@
ns_c_in, ns_t_aaaa, nullptr, 0, nullptr, buf2, sizeof(buf2));
EXPECT_GT(len2, 0);
- fd1 = android_res_nsend(NETWORK_UNSPECIFIED, buf1, len1, ResNsendFlags(0));
+ fd1 = android_res_nsend(NETWORK_UNSPECIFIED, buf1, len1, 0);
EXPECT_GE(fd1, 0);
- fd2 = android_res_nsend(NETWORK_UNSPECIFIED, buf2, len2, ResNsendFlags(0));
+ fd2 = android_res_nsend(NETWORK_UNSPECIFIED, buf2, len2, 0);
EXPECT_GE(fd2, 0);
expectAnswersValid(fd2, AF_INET6, ns_r_noerror);
@@ -190,7 +193,7 @@
TEST (NativeDnsAsyncTest, Async_Cancel) {
int fd = android_res_nquery(
- NETWORK_UNSPECIFIED, "www.google.com", ns_c_in, ns_t_a, ResNsendFlags(0));
+ NETWORK_UNSPECIFIED, "www.google.com", ns_c_in, ns_t_a, 0);
int rcode = -1;
uint8_t buf[MAXPACKET] = {};
android_res_cancel(fd);
@@ -204,7 +207,7 @@
// Empty string to create BLOB and query, we will get empty result and rcode = 0
// on DNSTLS.
int fd = android_res_nquery(
- NETWORK_UNSPECIFIED, "", ns_c_in, ns_t_a, ResNsendFlags(0));
+ NETWORK_UNSPECIFIED, "", ns_c_in, ns_t_a, 0);
EXPECT_GE(fd, 0);
expectAnswersValid(fd, AF_INET, ns_r_noerror);
@@ -212,44 +215,44 @@
std::string exceedingDomainQuery = "www." + std::string(255, 'g') + ".com";
fd = android_res_nquery(NETWORK_UNSPECIFIED,
- exceedingLabelQuery.c_str(), ns_c_in, ns_t_a, ResNsendFlags(0));
+ exceedingLabelQuery.c_str(), ns_c_in, ns_t_a, 0);
EXPECT_EQ(-EMSGSIZE, fd);
fd = android_res_nquery(NETWORK_UNSPECIFIED,
- exceedingDomainQuery.c_str(), ns_c_in, ns_t_a, ResNsendFlags(0));
+ exceedingDomainQuery.c_str(), ns_c_in, ns_t_a, 0);
EXPECT_EQ(-EMSGSIZE, fd);
}
TEST (NativeDnsAsyncTest, Async_Send_MALFORMED) {
uint8_t buf[10] = {};
// empty BLOB
- int fd = android_res_nsend(NETWORK_UNSPECIFIED, buf, 10, ResNsendFlags(0));
+ int fd = android_res_nsend(NETWORK_UNSPECIFIED, buf, 10, 0);
EXPECT_GE(fd, 0);
expectAnswersNotValid(fd, -EINVAL);
std::vector<uint8_t> largeBuf(2 * MAXPACKET, 0);
// A buffer larger than 8KB
fd = android_res_nsend(
- NETWORK_UNSPECIFIED, largeBuf.data(), largeBuf.size(), ResNsendFlags(0));
+ NETWORK_UNSPECIFIED, largeBuf.data(), largeBuf.size(), 0);
EXPECT_EQ(-EMSGSIZE, fd);
// 1000 bytes filled with 0. This returns EMSGSIZE because FrameworkListener limits the size of
// commands to 1024 bytes. TODO: fix this.
- fd = android_res_nsend(NETWORK_UNSPECIFIED, largeBuf.data(), 1000, ResNsendFlags(0));
+ fd = android_res_nsend(NETWORK_UNSPECIFIED, largeBuf.data(), 1000, 0);
EXPECT_EQ(-EMSGSIZE, fd);
// 500 bytes filled with 0
- fd = android_res_nsend(NETWORK_UNSPECIFIED, largeBuf.data(), 500, ResNsendFlags(0));
+ fd = android_res_nsend(NETWORK_UNSPECIFIED, largeBuf.data(), 500, 0);
EXPECT_GE(fd, 0);
expectAnswersNotValid(fd, -EINVAL);
// 1000 bytes filled with 0xFF
- std::vector<uint8_t> ffBuf(1000, 255);
+ std::vector<uint8_t> ffBuf(1000, 0xFF);
fd = android_res_nsend(
- NETWORK_UNSPECIFIED, ffBuf.data(), ffBuf.size(), ResNsendFlags(0));
+ NETWORK_UNSPECIFIED, ffBuf.data(), ffBuf.size(), 0);
EXPECT_EQ(-EMSGSIZE, fd);
// 500 bytes filled with 0xFF
- fd = android_res_nsend(NETWORK_UNSPECIFIED, ffBuf.data(), 500, ResNsendFlags(0));
+ fd = android_res_nsend(NETWORK_UNSPECIFIED, ffBuf.data(), 500, 0);
EXPECT_GE(fd, 0);
expectAnswersNotValid(fd, -EINVAL);
-}
\ No newline at end of file
+}
diff --git a/tests/tests/net/src/android/net/cts/DnsResolverTest.java b/tests/tests/net/src/android/net/cts/DnsResolverTest.java
new file mode 100644
index 0000000..2e40584
--- /dev/null
+++ b/tests/tests/net/src/android/net/cts/DnsResolverTest.java
@@ -0,0 +1,161 @@
+/*
+ * Copyright (C) 2019 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.net.cts;
+
+import static android.net.DnsResolver.CLASS_IN;
+import static android.net.DnsResolver.TYPE_A;
+import static android.net.DnsResolver.TYPE_AAAA;
+import static android.net.DnsResolver.FLAG_NO_CACHE_LOOKUP;
+
+import android.content.Context;
+import android.net.ConnectivityManager;
+import android.net.DnsResolver;
+import android.net.Network;
+import android.net.NetworkCapabilities;
+import android.net.NetworkUtils;
+import android.os.Handler;
+import android.os.Looper;
+import android.system.ErrnoException;
+import android.test.AndroidTestCase;
+import android.util.Log;
+
+import java.net.InetAddress;
+import java.util.ArrayList;
+import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.TimeUnit;
+
+public class DnsResolverTest extends AndroidTestCase {
+ private static final String TAG = "DnsResolverTest";
+ private static final char[] HEX_CHARS = {
+ '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F'
+ };
+ private ConnectivityManager mCM;
+ private Handler mHandler;
+ private DnsResolver mDns;
+
+ protected void setUp() throws Exception {
+ super.setUp();
+ mCM = (ConnectivityManager) getContext().getSystemService(Context.CONNECTIVITY_SERVICE);
+ mHandler = new Handler(Looper.getMainLooper());
+ mDns = DnsResolver.getInstance();
+ }
+
+ private static String bytesArrayToHexString(byte[] bytes) {
+ char[] hexChars = new char[bytes.length * 2];
+ for (int i = 0; i < bytes.length; ++i) {
+ int b = bytes[i] & 0xFF;
+ hexChars[i * 2] = HEX_CHARS[b >>> 4];
+ hexChars[i * 2 + 1] = HEX_CHARS[b & 0x0F];
+ }
+ return new String(hexChars);
+ }
+
+ private Network[] getTestableNetworks() {
+ final ArrayList<Network> testableNetworks = new ArrayList<Network>();
+ for (Network network : mCM.getAllNetworks()) {
+ final NetworkCapabilities nc = mCM.getNetworkCapabilities(network);
+ if (nc != null
+ && nc.hasCapability(NetworkCapabilities.NET_CAPABILITY_NOT_RESTRICTED)
+ && nc.hasCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET)) {
+ testableNetworks.add(network);
+ }
+ }
+
+ assertTrue(
+ "This test requires that at least one network be connected. " +
+ "Please ensure that the device is connected to a network.",
+ testableNetworks.size() >= 1);
+ return testableNetworks.toArray(new Network[0]);
+ }
+
+ public void testInetAddressQuery() throws ErrnoException {
+ for (Network network : getTestableNetworks()) {
+ CountDownLatch latch = new CountDownLatch(1);
+ final int TIMEOUT_MS = 5_000;
+ final String dname = "www.google.com";
+
+ mDns.query(network, dname, FLAG_NO_CACHE_LOOKUP, mHandler, answerList -> {
+ if (answerList.size() != 0) {
+ latch.countDown();
+ for (InetAddress addr : answerList) {
+ Log.e(TAG, "Reported addr:" + addr.toString());
+ }
+ }
+ }
+ );
+ String msg = "InetAddress query " + dname + " but no valid answer after "
+ + TIMEOUT_MS + "ms.";
+ try {
+ assertTrue(msg, latch.await(TIMEOUT_MS, TimeUnit.MILLISECONDS));
+ } catch (InterruptedException e) {}
+ }
+ }
+
+ public void testRawQuery() throws ErrnoException {
+ for (Network network : getTestableNetworks()) {
+ CountDownLatch latch = new CountDownLatch(1);
+ final int TIMEOUT_MS = 5_000;
+ final String dname = "www.google.com";
+
+ mDns.query(network, dname, CLASS_IN, TYPE_AAAA, FLAG_NO_CACHE_LOOKUP, mHandler, answer -> {
+ if (answer != null) {
+ latch.countDown();
+ Log.e(TAG, "Reported blob:" + bytesArrayToHexString(answer));
+ }
+ }
+ );
+ String msg = "Raw query " + dname + " but no valid answer after " + TIMEOUT_MS + "ms.";
+ try {
+ assertTrue(msg, latch.await(TIMEOUT_MS, TimeUnit.MILLISECONDS));
+ } catch (InterruptedException e) {}
+ }
+ }
+
+ public void testRawQueryWithBlob() throws ErrnoException {
+ for (Network network : getTestableNetworks()) {
+ CountDownLatch latch = new CountDownLatch(1);
+ final int TIMEOUT_MS = 5_000;
+ final byte[] blob = new byte[] {
+ /* Header */
+ 0x55, 0x66, /* Transaction ID */
+ 0x01, 0x00, /* Flags */
+ 0x00, 0x01, /* Questions */
+ 0x00, 0x00, /* Answer RRs */
+ 0x00, 0x00, /* Authority RRs */
+ 0x00, 0x00, /* Additional RRs */
+ /* Queries */
+ 0x03, 0x77, 0x77, 0x77, 0x06, 0x67, 0x6F, 0x6F, 0x67, 0x6c, 0x65,
+ 0x03, 0x63, 0x6f, 0x6d, 0x00, /* Name */
+ 0x00, 0x01, /* Type */
+ 0x00, 0x01 /* Class */
+ };
+
+ mDns.query(network, blob, FLAG_NO_CACHE_LOOKUP, mHandler, answer -> {
+ if (answer != null) {
+ latch.countDown();
+ Log.e(TAG, "Reported blob:" + bytesArrayToHexString(answer));
+ }
+ }
+ );
+ String msg = "Raw query with blob " + bytesArrayToHexString(blob) +
+ " but no valid answer after " + TIMEOUT_MS + "ms.";
+ try {
+ assertTrue(msg, latch.await(TIMEOUT_MS, TimeUnit.MILLISECONDS));
+ } catch (InterruptedException e) {}
+ }
+ }
+}
diff --git a/tests/tests/net/src/android/net/wifi/cts/WifiInfoTest.java b/tests/tests/net/src/android/net/wifi/cts/WifiInfoTest.java
index 608475b..77598ed 100644
--- a/tests/tests/net/src/android/net/wifi/cts/WifiInfoTest.java
+++ b/tests/tests/net/src/android/net/wifi/cts/WifiInfoTest.java
@@ -139,6 +139,8 @@
wifiInfo.getBSSID();
wifiInfo.getIpAddress();
wifiInfo.getLinkSpeed();
+ wifiInfo.getTxLinkSpeedMbps();
+ wifiInfo.getRxLinkSpeedMbps();
wifiInfo.getRssi();
wifiInfo.getHiddenSSID();
wifiInfo.getMacAddress();
diff --git a/tests/tests/net/src/android/net/wifi/cts/WifiManagerTest.java b/tests/tests/net/src/android/net/wifi/cts/WifiManagerTest.java
index 8ea72e0..0337119 100644
--- a/tests/tests/net/src/android/net/wifi/cts/WifiManagerTest.java
+++ b/tests/tests/net/src/android/net/wifi/cts/WifiManagerTest.java
@@ -1023,6 +1023,30 @@
}
}
+ /**
+ * Verify that the {@link android.Manifest.permission#WIFI_UPDATE_USABILITY_STATS_SCORE}
+ * permission is held by at most one application.
+ */
+ public void testUpdateWifiUsabilityStatsScorePermission() {
+ final PackageManager pm = getContext().getPackageManager();
+
+ final List<PackageInfo> holding = pm.getPackagesHoldingPermissions(new String[] {
+ android.Manifest.permission.WIFI_UPDATE_USABILITY_STATS_SCORE
+ }, PackageManager.MATCH_UNINSTALLED_PACKAGES);
+
+ List<String> uniquePackageNames = holding
+ .stream()
+ .map(pi -> pi.packageName)
+ .distinct()
+ .collect(Collectors.toList());
+
+ if (uniquePackageNames.size() > 1) {
+ fail("The WIFI_UPDATE_USABILITY_STATS_SCORE permission must not be held by more than "
+ + "one application, but is held by " + uniquePackageNames.size() + " applications: "
+ + String.join(", ", uniquePackageNames));
+ }
+ }
+
private void turnScreenOnNoDelay() throws Exception {
mUiDevice.executeShellCommand("input keyevent KEYCODE_WAKEUP");
mUiDevice.executeShellCommand("wm dismiss-keyguard");
diff --git a/tests/tests/neuralnetworks/Android.mk b/tests/tests/neuralnetworks/Android.mk
index d8b2be2..4b27e7b 100644
--- a/tests/tests/neuralnetworks/Android.mk
+++ b/tests/tests/neuralnetworks/Android.mk
@@ -69,3 +69,5 @@
LOCAL_NDK_STL_VARIANT := c++_static
include $(BUILD_CTS_EXECUTABLE)
+
+include $(nnapi_cts_dir)/benchmark/Android.mk
diff --git a/tests/tests/neuralnetworks/benchmark/Android.mk b/tests/tests/neuralnetworks/benchmark/Android.mk
new file mode 100644
index 0000000..9670236
--- /dev/null
+++ b/tests/tests/neuralnetworks/benchmark/Android.mk
@@ -0,0 +1,41 @@
+# Copyright (C) 2019 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_PACKAGE_NAME := CtsNNAPIBenchmarkTestCases
+
+# Don't include this package in any target
+LOCAL_MODULE_TAGS := optional
+# 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
+
+# Tag this module as a cts test artifact
+LOCAL_COMPATIBILITY_SUITE := cts vts general-tests
+
+LOCAL_STATIC_JAVA_LIBRARIES := android-support-test androidx.test.rules \
+ compatibility-device-util ctstestrunner junit NeuralNetworksApiBenchmark_Lib
+LOCAL_JNI_SHARED_LIBRARIES := libnnbenchmark_jni
+
+LOCAL_SRC_FILES := $(call all-java-files-under, src)
+LOCAL_ASSET_DIR := test/mlts/models/assets
+
+LOCAL_SDK_VERSION := current
+
+include $(BUILD_CTS_PACKAGE)
diff --git a/tests/tests/neuralnetworks/benchmark/AndroidManifest.xml b/tests/tests/neuralnetworks/benchmark/AndroidManifest.xml
new file mode 100644
index 0000000..b2973a9
--- /dev/null
+++ b/tests/tests/neuralnetworks/benchmark/AndroidManifest.xml
@@ -0,0 +1,35 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2019 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.nn.benchmark.cts">
+
+ <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
+ <uses-sdk android:minSdkVersion="27"/>
+
+ <application android:name=".NNAccuracyApplication">
+ <activity android:name=".NNAccuracyActivity">
+ <intent-filter>
+ <action android:name="android.intent.action.MAIN"/>
+ </intent-filter>
+ </activity>
+ </application>
+
+ <instrumentation
+ android:name="android.support.test.runner.AndroidJUnitRunner"
+ android:targetPackage="com.android.nn.benchmark.cts"
+ android:label="CTS tests of NNAPI accuracy benchmark"/>
+</manifest>
diff --git a/tests/libcore/coreplatformapi/AndroidTest.xml b/tests/tests/neuralnetworks/benchmark/AndroidTest.xml
similarity index 69%
copy from tests/libcore/coreplatformapi/AndroidTest.xml
copy to tests/tests/neuralnetworks/benchmark/AndroidTest.xml
index 907fb2d..dd309c7 100644
--- a/tests/libcore/coreplatformapi/AndroidTest.xml
+++ b/tests/tests/neuralnetworks/benchmark/AndroidTest.xml
@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2018 The Android Open Source Project
+<!-- Copyright (C) 2019 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.
@@ -13,16 +13,15 @@
See the License for the specific language governing permissions and
limitations under the License.
-->
-<configuration description="Config for CTS Libcore core platform API test cases">
+<configuration description="Configuration for CTS NNAPI Benchmark Tests">
<option name="test-suite-tag" value="cts" />
- <option name="config-descriptor:metadata" key="component" value="libcore" />
+ <option name="config-descriptor:metadata" key="component" value="neuralnetworks" />
<target_preparer class="com.android.tradefed.targetprep.suite.SuiteApkInstaller">
<option name="cleanup-apks" value="true" />
- <option name="test-file-name" value="CtsLibcoreCorePlatformApiTestCases.apk" />
+ <option name="test-file-name" value="CtsNNAPIBenchmarkTestCases.apk" />
</target_preparer>
+
<test class="com.android.tradefed.testtype.AndroidJUnitTest" >
- <option name="package" value="android.libcore.cts.coreplatformapi" />
- <option name="runtime-hint" value="1m"/>
- <option name="hidden-api-checks" value="false"/>
+ <option name="package" value="com.android.nn.benchmark.cts" />
</test>
</configuration>
diff --git a/tests/tests/neuralnetworks/benchmark/src/com/android/nn/benchmark/cts/NNAccuracyActivity.java b/tests/tests/neuralnetworks/benchmark/src/com/android/nn/benchmark/cts/NNAccuracyActivity.java
new file mode 100644
index 0000000..29877c7
--- /dev/null
+++ b/tests/tests/neuralnetworks/benchmark/src/com/android/nn/benchmark/cts/NNAccuracyActivity.java
@@ -0,0 +1,21 @@
+/*
+ * Copyright (C) 2019 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.nn.benchmark.cts;
+
+import android.app.Activity;
+
+public class NNAccuracyActivity extends Activity {}
diff --git a/tests/tests/neuralnetworks/benchmark/src/com/android/nn/benchmark/cts/NNAccuracyApplication.java b/tests/tests/neuralnetworks/benchmark/src/com/android/nn/benchmark/cts/NNAccuracyApplication.java
new file mode 100644
index 0000000..78e0b1a
--- /dev/null
+++ b/tests/tests/neuralnetworks/benchmark/src/com/android/nn/benchmark/cts/NNAccuracyApplication.java
@@ -0,0 +1,35 @@
+/*
+ * Copyright (C) 2019 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.nn.benchmark.cts;
+
+import android.app.Application;
+import com.android.nn.benchmark.core.TestModelsListLoader;
+import java.io.IOException;
+
+/** Application class for NNAccuracyTest. */
+public class NNAccuracyApplication extends Application {
+
+@Override
+ public void onCreate() {
+ super.onCreate();
+ try {
+ TestModelsListLoader.parseFromAssets(getAssets());
+ } catch (IOException e) {
+ throw new IllegalStateException("Failed to load test models json", e);
+ }
+ }
+}
diff --git a/tests/tests/neuralnetworks/benchmark/src/com/android/nn/benchmark/cts/NNAccuracyTest.java b/tests/tests/neuralnetworks/benchmark/src/com/android/nn/benchmark/cts/NNAccuracyTest.java
new file mode 100644
index 0000000..be6d40e
--- /dev/null
+++ b/tests/tests/neuralnetworks/benchmark/src/com/android/nn/benchmark/cts/NNAccuracyTest.java
@@ -0,0 +1,132 @@
+/*
+ * Copyright (C) 2019 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.nn.benchmark.cts;
+
+import static junit.framework.TestCase.assertFalse;
+
+import android.app.Activity;
+import android.content.Intent;
+import android.os.Bundle;
+import android.support.test.filters.LargeTest;
+import android.support.test.rule.ActivityTestRule;
+import android.util.Pair;
+
+import androidx.test.InstrumentationRegistry;
+
+import com.android.nn.benchmark.core.BenchmarkException;
+import com.android.nn.benchmark.core.BenchmarkResult;
+import com.android.nn.benchmark.core.InferenceInOutSequence;
+import com.android.nn.benchmark.core.InferenceResult;
+import com.android.nn.benchmark.core.NNTestBase;
+import com.android.nn.benchmark.core.TestModels;
+import com.android.nn.benchmark.util.TestExternalStorageActivity;
+
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.Parameterized;
+import org.junit.runners.Parameterized.Parameters;
+
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+
+/**
+ * Tests the accuracy of the model outputs.
+ */
+@RunWith(Parameterized.class)
+public class NNAccuracyTest {
+
+ @Rule
+ public ActivityTestRule<NNAccuracyActivity> mActivityRule =
+ new ActivityTestRule<>(NNAccuracyActivity.class);
+
+ @Parameterized.Parameter(0)
+ public TestModels.TestModelEntry mModel;
+
+ private Activity mActivity;
+
+ // TODO(vddang): Add mobilenet_v1_0.25_128_quant_topk_aosp
+ private static final String[] MODEL_NAMES = new String[]{
+ "tts_float",
+ "asr_float",
+ "mobilenet_v1_1.0_224_quant_topk_aosp",
+ "mobilenet_v1_1.0_224_topk_aosp",
+ "mobilenet_v1_0.75_192_quant_topk_aosp",
+ "mobilenet_v1_0.75_192_topk_aosp",
+ "mobilenet_v1_0.5_160_quant_topk_aosp",
+ "mobilenet_v1_0.5_160_topk_aosp",
+ "mobilenet_v1_0.25_128_topk_aosp",
+ "mobilenet_v2_0.35_128_topk_aosp",
+ "mobilenet_v2_0.5_160_topk_aosp",
+ "mobilenet_v2_0.75_192_topk_aosp",
+ "mobilenet_v2_1.0_224_quant_topk_aosp",
+ "mobilenet_v2_1.0_224_topk_aosp",
+ };
+
+ @Parameters(name = "{0}")
+ public static List<TestModels.TestModelEntry> modelsList() {
+ List<TestModels.TestModelEntry> models = new ArrayList<>();
+ for (String modelName : MODEL_NAMES) {
+ models.add(TestModels.getModelByName(modelName));
+ }
+ return Collections.unmodifiableList(models);
+ }
+
+ @Before
+ public void setUp() throws Exception {
+ mActivity = mActivityRule.getActivity();
+ }
+
+ @Test
+ @LargeTest
+ public void testTFLite() throws BenchmarkException, IOException {
+ NNTestBase test = mModel.createNNTestBase(/*useNNAPI=*/false,
+ /*enableIntermediateTensorsDump=*/false);
+ test.setupModel(mActivity);
+ Pair<List<InferenceInOutSequence>, List<InferenceResult>> inferenceResults =
+ test.runBenchmarkCompleteInputSet(/*setRepeat=*/1, /*timeoutSec=*/3600);
+ BenchmarkResult benchmarkResult =
+ BenchmarkResult.fromInferenceResults(
+ mModel.mModelName,
+ BenchmarkResult.BACKEND_TFLITE_CPU,
+ inferenceResults.first,
+ inferenceResults.second,
+ test.getEvaluator());
+ assertFalse(benchmarkResult.hasValidationErrors());
+ }
+
+ @Test
+ @LargeTest
+ public void testNNAPI() throws BenchmarkException, IOException {
+ NNTestBase test = mModel.createNNTestBase(/*useNNAPI=*/true,
+ /*enableIntermediateTensorsDump=*/false);
+ test.setupModel(mActivity);
+ Pair<List<InferenceInOutSequence>, List<InferenceResult>> inferenceResults =
+ test.runBenchmarkCompleteInputSet(/*setRepeat=*/1, /*timeoutSec=*/3600);
+ BenchmarkResult benchmarkResult =
+ BenchmarkResult.fromInferenceResults(
+ mModel.mModelName,
+ BenchmarkResult.BACKEND_TFLITE_NNAPI,
+ inferenceResults.first,
+ inferenceResults.second,
+ test.getEvaluator());
+ assertFalse(benchmarkResult.hasValidationErrors());
+ }
+}
diff --git a/tests/tests/notificationlegacy/notificationlegacy29/AndroidManifest.xml b/tests/tests/notificationlegacy/notificationlegacy29/AndroidManifest.xml
index 6b52e7a..fb804ef 100644
--- a/tests/tests/notificationlegacy/notificationlegacy29/AndroidManifest.xml
+++ b/tests/tests/notificationlegacy/notificationlegacy29/AndroidManifest.xml
@@ -22,6 +22,24 @@
<application>
<uses-library android:name="android.test.runner" />
+ <service android:name="android.app.notification.legacy29.cts.TestNotificationListener"
+ android:exported="true"
+ android:label="TestNotificationListener"
+ android:permission="android.permission.BIND_NOTIFICATION_LISTENER_SERVICE">
+ <intent-filter>
+ <action android:name="android.service.notification.NotificationListenerService" />
+ </intent-filter>
+ </service>
+
+ <service android:name="android.app.notification.legacy29.cts.TestNotificationAssistant"
+ android:exported="true"
+ android:label="TestNotificationAssistant"
+ android:permission="android.permission.BIND_NOTIFICATION_ASSISTANT_SERVICE">
+ <intent-filter>
+ <action android:name="android.service.notification.NotificationAssistantService" />
+ </intent-filter>
+ </service>
+
</application>
<instrumentation android:name="android.support.test.runner.AndroidJUnitRunner"
diff --git a/tests/tests/notificationlegacy/notificationlegacy29/src/android/app/notification/legacy29/cts/NotificationAssistantServiceTest.java b/tests/tests/notificationlegacy/notificationlegacy29/src/android/app/notification/legacy29/cts/NotificationAssistantServiceTest.java
new file mode 100644
index 0000000..2738e01
--- /dev/null
+++ b/tests/tests/notificationlegacy/notificationlegacy29/src/android/app/notification/legacy29/cts/NotificationAssistantServiceTest.java
@@ -0,0 +1,352 @@
+/*
+ * Copyright (C) 2019 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.notification.legacy29.cts;
+
+import static junit.framework.Assert.assertFalse;
+import static junit.framework.Assert.assertTrue;
+import static junit.framework.Assert.assertEquals;
+import static junit.framework.TestCase.assertNotNull;
+
+import static org.junit.Assert.assertNotEquals;
+
+import android.app.Instrumentation;
+import android.app.Notification;
+import android.app.NotificationChannel;
+import android.app.NotificationManager;
+import android.app.PendingIntent;
+import android.app.UiAutomation;
+import android.content.ComponentName;
+import android.content.Context;
+import android.content.Intent;
+import android.os.Bundle;
+import android.os.ParcelFileDescriptor;
+import android.provider.Telephony;
+import android.service.notification.Adjustment;
+import android.service.notification.NotificationListenerService;
+import android.service.notification.StatusBarNotification;
+import android.support.test.InstrumentationRegistry;
+import android.support.test.runner.AndroidJUnit4;
+
+import junit.framework.Assert;
+
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import java.io.FileInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.concurrent.TimeUnit;
+
+@RunWith(AndroidJUnit4.class)
+public class NotificationAssistantServiceTest {
+
+ final String TAG = "NotAsstServiceTest";
+ final String NOTIFICATION_CHANNEL_ID = "NotificationAssistantServiceTest";
+ final int ICON_ID = android.R.drawable.sym_def_app_icon;
+ final long SLEEP_TIME = 500; // milliseconds
+
+ private TestNotificationAssistant mNotificationAssistantService;
+ private TestNotificationListener mNotificationListenerService;
+ private NotificationManager mNotificationManager;
+ private Context mContext;
+
+ @Before
+ public void setUp() throws IOException {
+ mContext = InstrumentationRegistry.getContext();
+ toggleAssistantAccess(false);
+ toggleListenerAccess(false);
+
+ mNotificationManager = (NotificationManager) mContext.getSystemService(
+ Context.NOTIFICATION_SERVICE);
+ mNotificationManager.createNotificationChannel(new NotificationChannel(
+ NOTIFICATION_CHANNEL_ID, "name", NotificationManager.IMPORTANCE_DEFAULT));
+ }
+
+ @After
+ public void tearDown() throws IOException {
+ if (mNotificationListenerService != null) mNotificationListenerService.resetData();
+ toggleListenerAccess(false);
+ toggleAssistantAccess(false);
+ }
+
+ @Test
+ public void testOnNotificationEnqueued() throws Exception {
+ toggleListenerAccess(true);
+ Thread.sleep(SLEEP_TIME);
+ mNotificationListenerService = TestNotificationListener.getInstance();
+
+ sendNotification(1, ICON_ID);
+ StatusBarNotification sbn = getFirstNotificationFromPackage(TestNotificationListener.PKG);
+ NotificationListenerService.Ranking out = new NotificationListenerService.Ranking();
+ mNotificationListenerService.mRankingMap.getRanking(sbn.getKey(), out);
+
+ // No modification because the Notification Assistant is not enabled
+ assertEquals(NotificationListenerService.Ranking.USER_SENTIMENT_NEUTRAL,
+ out.getUserSentiment());
+ mNotificationListenerService.resetData();
+
+ toggleAssistantAccess(true);
+ Thread.sleep(SLEEP_TIME); // wait for listener and assistant to be allowed
+ mNotificationAssistantService = TestNotificationAssistant.getInstance();
+
+ sendNotification(1, ICON_ID);
+ sbn = getFirstNotificationFromPackage(TestNotificationListener.PKG);
+ mNotificationListenerService.mRankingMap.getRanking(sbn.getKey(), out);
+
+ // Assistant modifies notification
+ assertEquals(NotificationListenerService.Ranking.USER_SENTIMENT_POSITIVE,
+ out.getUserSentiment());
+ }
+
+ @Test
+ public void testAdjustNotification_userSentimentKey() throws Exception {
+ setUpListeners();
+
+ sendNotification(1, ICON_ID);
+ StatusBarNotification sbn = getFirstNotificationFromPackage(TestNotificationListener.PKG);
+ NotificationListenerService.Ranking out = new NotificationListenerService.Ranking();
+ mNotificationListenerService.mRankingMap.getRanking(sbn.getKey(), out);
+
+ assertEquals(NotificationListenerService.Ranking.USER_SENTIMENT_POSITIVE,
+ out.getUserSentiment());
+
+ Bundle signals = new Bundle();
+ signals.putInt(Adjustment.KEY_USER_SENTIMENT,
+ NotificationListenerService.Ranking.USER_SENTIMENT_NEGATIVE);
+ Adjustment adjustment = new Adjustment(sbn.getPackageName(), sbn.getKey(), signals, "",
+ sbn.getUserId());
+
+ mNotificationAssistantService.adjustNotification(adjustment);
+ Thread.sleep(SLEEP_TIME); // wait for adjustment to be processed
+
+ mNotificationListenerService.mRankingMap.getRanking(sbn.getKey(), out);
+
+ assertEquals(NotificationListenerService.Ranking.USER_SENTIMENT_NEGATIVE,
+ out.getUserSentiment());
+ }
+
+ @Test
+ public void testAdjustNotification_importanceKey() throws Exception {
+ setUpListeners();
+
+ sendNotification(1, ICON_ID);
+ StatusBarNotification sbn = getFirstNotificationFromPackage(TestNotificationListener.PKG);
+ NotificationListenerService.Ranking out = new NotificationListenerService.Ranking();
+ mNotificationListenerService.mRankingMap.getRanking(sbn.getKey(), out);
+
+ int currentImportance = out.getImportance();
+ int newImportance = currentImportance == NotificationManager.IMPORTANCE_DEFAULT
+ ? NotificationManager.IMPORTANCE_HIGH : NotificationManager.IMPORTANCE_DEFAULT;
+
+ Bundle signals = new Bundle();
+ signals.putInt(Adjustment.KEY_IMPORTANCE, newImportance);
+ Adjustment adjustment = new Adjustment(sbn.getPackageName(), sbn.getKey(), signals, "",
+ sbn.getUserId());
+
+ mNotificationAssistantService.adjustNotification(adjustment);
+ Thread.sleep(SLEEP_TIME); // wait for adjustment to be processed
+
+ mNotificationListenerService.mRankingMap.getRanking(sbn.getKey(), out);
+
+ assertEquals(newImportance, out.getImportance());
+ }
+
+ @Test
+ public void testAdjustNotification_smartActionKey() throws Exception {
+ setUpListeners();
+ PendingIntent sendIntent = PendingIntent.getActivity(mContext, 0,
+ new Intent(Intent.ACTION_SEND), 0);
+ Notification.Action sendAction = new Notification.Action.Builder(ICON_ID, "SEND",
+ sendIntent).build();
+
+ sendNotification(1, ICON_ID);
+ StatusBarNotification sbn = getFirstNotificationFromPackage(TestNotificationListener.PKG);
+ NotificationListenerService.Ranking out = new NotificationListenerService.Ranking();
+ mNotificationListenerService.mRankingMap.getRanking(sbn.getKey(), out);
+
+ List<Notification.Action> smartActions = out.getSmartActions();
+ if (smartActions != null) {
+ for (int i = 0; i < smartActions.size(); i++) {
+ Notification.Action action = smartActions.get(i);
+ assertNotEquals(sendIntent, action.actionIntent);
+ }
+ }
+
+ ArrayList<Notification.Action> extraAction = new ArrayList<>();
+ extraAction.add(sendAction);
+ Bundle signals = new Bundle();
+ signals.putParcelableArrayList(Adjustment.KEY_SMART_ACTIONS, extraAction);
+ Adjustment adjustment = new Adjustment(sbn.getPackageName(), sbn.getKey(), signals, "",
+ sbn.getUserId());
+
+ mNotificationAssistantService.adjustNotification(adjustment);
+ Thread.sleep(SLEEP_TIME); //wait for adjustment to be processed
+
+ mNotificationListenerService.mRankingMap.getRanking(sbn.getKey(), out);
+
+ boolean actionFound = false;
+ smartActions = out.getSmartActions();
+ for (int i = 0; i < smartActions.size(); i++) {
+ Notification.Action action = smartActions.get(i);
+ actionFound = actionFound || action.actionIntent.equals(sendIntent);
+ }
+ assertTrue(actionFound);
+ }
+
+ @Test
+ public void testAdjustNotification_smartReplyKey() throws Exception {
+ setUpListeners();
+ CharSequence smartReply = "Smart Reply!";
+
+ sendNotification(1, ICON_ID);
+ StatusBarNotification sbn = getFirstNotificationFromPackage(TestNotificationListener.PKG);
+ NotificationListenerService.Ranking out = new NotificationListenerService.Ranking();
+ mNotificationListenerService.mRankingMap.getRanking(sbn.getKey(), out);
+
+ List<CharSequence> smartReplies = out.getSmartReplies();
+ if (smartReplies != null) {
+ for (int i = 0; i < smartReplies.size(); i++) {
+ CharSequence reply = smartReplies.get(i);
+ assertNotEquals(smartReply, reply);
+ }
+ }
+
+ ArrayList<CharSequence> extraReply = new ArrayList<>();
+ extraReply.add(smartReply);
+ Bundle signals = new Bundle();
+ signals.putCharSequenceArrayList(Adjustment.KEY_SMART_REPLIES, extraReply);
+ Adjustment adjustment = new Adjustment(sbn.getPackageName(), sbn.getKey(), signals, "",
+ sbn.getUserId());
+
+ mNotificationAssistantService.adjustNotification(adjustment);
+ Thread.sleep(SLEEP_TIME); //wait for adjustment to be processed
+
+ mNotificationListenerService.mRankingMap.getRanking(sbn.getKey(), out);
+
+ boolean replyFound = false;
+ smartReplies = out.getSmartReplies();
+ for (int i = 0; i < smartReplies.size(); i++) {
+ CharSequence reply = smartReplies.get(i);
+ replyFound = replyFound || reply.equals(smartReply);
+ }
+ assertTrue(replyFound);
+ }
+
+ private StatusBarNotification getFirstNotificationFromPackage(String PKG)
+ throws InterruptedException {
+ StatusBarNotification sbn = mNotificationListenerService.mPosted.poll(SLEEP_TIME,
+ TimeUnit.MILLISECONDS);
+ assertNotNull(sbn);
+ while (!sbn.getPackageName().equals(PKG)) {
+ sbn = mNotificationListenerService.mPosted.poll(SLEEP_TIME, TimeUnit.MILLISECONDS);
+ }
+ assertNotNull(sbn);
+ return sbn;
+ }
+
+ private void setUpListeners() throws Exception {
+ toggleListenerAccess(true);
+ toggleAssistantAccess(true);
+ Thread.sleep(2 * SLEEP_TIME); // wait for listener and assistant to be allowed
+
+ mNotificationListenerService = TestNotificationListener.getInstance();
+ mNotificationAssistantService = TestNotificationAssistant.getInstance();
+
+ assertNotNull(mNotificationListenerService);
+ assertNotNull(mNotificationAssistantService);
+ }
+
+ private void sendNotification(final int id, final int icon) throws Exception {
+ sendNotification(id, null, icon);
+ }
+
+ private void sendNotification(final int id, String groupKey, final int icon) throws Exception {
+ final Intent intent = new Intent(Intent.ACTION_MAIN, Telephony.Threads.CONTENT_URI);
+
+ intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_SINGLE_TOP
+ | Intent.FLAG_ACTIVITY_CLEAR_TOP);
+ intent.setAction(Intent.ACTION_MAIN);
+
+ final PendingIntent pendingIntent = PendingIntent.getActivity(mContext, 0, intent, 0);
+ final Notification notification =
+ new Notification.Builder(mContext, NOTIFICATION_CHANNEL_ID)
+ .setSmallIcon(icon)
+ .setWhen(System.currentTimeMillis())
+ .setContentTitle("notify#" + id)
+ .setContentText("This is #" + id + "notification ")
+ .setContentIntent(pendingIntent)
+ .setGroup(groupKey)
+ .build();
+ mNotificationManager.notify(id, notification);
+ }
+
+ private void toggleListenerAccess(boolean on) throws IOException {
+
+ Instrumentation instrumentation = InstrumentationRegistry.getInstrumentation();
+ String componentName = TestNotificationListener.getId();
+
+ String command = " cmd notification " + (on ? "allow_listener " : "disallow_listener ")
+ + componentName;
+
+ runCommand(command, instrumentation);
+
+ final ComponentName listenerComponent = TestNotificationListener.getComponentName();
+ final NotificationManager nm = mContext.getSystemService(NotificationManager.class);
+ Assert.assertTrue(listenerComponent + " has not been " + (on ? "allowed" : "disallowed"),
+ nm.isNotificationListenerAccessGranted(listenerComponent) == on);
+ }
+
+ private void toggleAssistantAccess(boolean on) throws IOException {
+
+ Instrumentation instrumentation = InstrumentationRegistry.getInstrumentation();
+ String componentName = TestNotificationAssistant.getId();
+
+ String command = " cmd notification " + (on ? "allow_assistant " : "disallow_assistant ")
+ + componentName;
+
+ runCommand(command, instrumentation);
+
+ final ComponentName assistantComponent = TestNotificationAssistant.getComponentName();
+ final NotificationManager nm = mContext.getSystemService(NotificationManager.class);
+ assertTrue(assistantComponent + " has not been " + (on ? "allowed" : "disallowed"),
+ nm.isNotificationAssistantAccessGranted(assistantComponent) == on);
+ }
+
+ private void runCommand(String command, Instrumentation instrumentation) throws IOException {
+ UiAutomation uiAutomation = instrumentation.getUiAutomation();
+ // Execute command
+ try (ParcelFileDescriptor fd = uiAutomation.executeShellCommand(command)) {
+ assertNotNull("Failed to execute shell command: " + command, fd);
+ // Wait for the command to finish by reading until EOF
+ try (InputStream in = new FileInputStream(fd.getFileDescriptor())) {
+ byte[] buffer = new byte[4096];
+ while (in.read(buffer) > 0) {
+ }
+ } catch (IOException e) {
+ throw new IOException("Could not read stdout of command: " + command, e);
+ }
+ } finally {
+ uiAutomation.destroy();
+ }
+ }
+
+
+}
\ No newline at end of file
diff --git a/tests/tests/notificationlegacy/notificationlegacy29/src/android/app/notification/legacy29/cts/TestNotificationAssistant.java b/tests/tests/notificationlegacy/notificationlegacy29/src/android/app/notification/legacy29/cts/TestNotificationAssistant.java
new file mode 100644
index 0000000..745046d
--- /dev/null
+++ b/tests/tests/notificationlegacy/notificationlegacy29/src/android/app/notification/legacy29/cts/TestNotificationAssistant.java
@@ -0,0 +1,74 @@
+/*
+ * Copyright (C) 2019 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.notification.legacy29.cts;
+
+import android.content.ComponentName;
+import android.os.Bundle;
+import android.service.notification.Adjustment;
+import android.service.notification.NotificationAssistantService;
+import android.service.notification.StatusBarNotification;
+
+public class TestNotificationAssistant extends NotificationAssistantService {
+ public static final String TAG = "TestNotificationAssistant";
+ public static final String PKG = "android.app.notification.legacy29.cts";
+
+ private static TestNotificationAssistant sNotificationAssistantInstance = null;
+ boolean isConnected;
+
+ public static String getId() {
+ return String.format("%s/%s", TestNotificationAssistant.class.getPackage().getName(),
+ TestNotificationAssistant.class.getName());
+ }
+
+ public static ComponentName getComponentName() {
+ return new ComponentName(TestNotificationAssistant.class.getPackage().getName(),
+ TestNotificationAssistant.class.getName());
+ }
+
+ @Override
+ public void onCreate() {
+ super.onCreate();
+ }
+
+ @Override
+ public void onListenerConnected() {
+ super.onListenerConnected();
+ sNotificationAssistantInstance = this;
+ isConnected = true;
+ }
+
+ @Override
+ public void onListenerDisconnected() {
+ isConnected = false;
+ }
+
+ public static TestNotificationAssistant getInstance() {
+ return sNotificationAssistantInstance;
+ }
+
+ public void onNotificationSnoozedUntilContext(StatusBarNotification statusBarNotification,
+ String s) {
+ }
+
+ @Override
+ public Adjustment onNotificationEnqueued(StatusBarNotification sbn) {
+ Bundle signals = new Bundle();
+ signals.putInt(Adjustment.KEY_USER_SENTIMENT, Ranking.USER_SENTIMENT_POSITIVE);
+ return new Adjustment(sbn.getPackageName(), sbn.getKey(), signals, "",
+ sbn.getUserId());
+ }
+}
\ No newline at end of file
diff --git a/tests/tests/notificationlegacy/notificationlegacy29/src/android/app/notification/legacy29/cts/TestNotificationListener.java b/tests/tests/notificationlegacy/notificationlegacy29/src/android/app/notification/legacy29/cts/TestNotificationListener.java
new file mode 100644
index 0000000..aea3914
--- /dev/null
+++ b/tests/tests/notificationlegacy/notificationlegacy29/src/android/app/notification/legacy29/cts/TestNotificationListener.java
@@ -0,0 +1,99 @@
+/*
+ * Copyright (C) 2019 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.notification.legacy29.cts;
+
+import android.content.ComponentName;
+import android.service.notification.NotificationListenerService;
+import android.service.notification.StatusBarNotification;
+
+import java.util.ArrayList;
+import java.util.concurrent.ArrayBlockingQueue;
+import java.util.concurrent.BlockingQueue;
+
+public class TestNotificationListener extends NotificationListenerService {
+ public static final String TAG = "TestNotificationListener";
+ public static final String PKG = "android.app.notification.legacy29.cts";
+
+ private ArrayList<String> mTestPackages = new ArrayList<>();
+
+ public BlockingQueue<StatusBarNotification> mPosted = new ArrayBlockingQueue<>(10);
+ public ArrayList<StatusBarNotification> mRemoved = new ArrayList<>();
+ public RankingMap mRankingMap;
+
+ private static TestNotificationListener
+ sNotificationListenerInstance = null;
+ boolean isConnected;
+
+ public static String getId() {
+ return String.format("%s/%s", TestNotificationListener.class.getPackage().getName(),
+ TestNotificationListener.class.getName());
+ }
+
+ public static ComponentName getComponentName() {
+ return new ComponentName(TestNotificationListener.class.getPackage().getName(),
+ TestNotificationListener.class.getName());
+ }
+
+ @Override
+ public void onCreate() {
+ super.onCreate();
+ mTestPackages.add(PKG);
+ }
+
+ @Override
+ public void onListenerConnected() {
+ super.onListenerConnected();
+ sNotificationListenerInstance = this;
+ isConnected = true;
+ }
+
+ @Override
+ public void onListenerDisconnected() {
+ isConnected = false;
+ }
+
+ public static TestNotificationListener getInstance() {
+ return sNotificationListenerInstance;
+ }
+
+ public void resetData() {
+ mPosted.clear();
+ mRemoved.clear();
+ }
+
+ @Override
+ public void onNotificationPosted(StatusBarNotification sbn, RankingMap rankingMap) {
+ if (!PKG.equals(sbn.getPackageName())) {
+ return;
+ }
+ mRankingMap = rankingMap;
+ mPosted.add(sbn);
+ }
+
+ @Override
+ public void onNotificationRemoved(StatusBarNotification sbn, RankingMap rankingMap) {
+ if (!mTestPackages.contains(sbn.getPackageName())) {
+ return;
+ }
+ mRankingMap = rankingMap;
+ mRemoved.add(sbn);
+ }
+
+ @Override
+ public void onNotificationRankingUpdate(RankingMap rankingMap) {
+ mRankingMap = rankingMap;
+ }
+}
diff --git a/tests/tests/opengl/src/android/opengl/cts/OpenGlEsVersionTest.java b/tests/tests/opengl/src/android/opengl/cts/OpenGlEsVersionTest.java
index 5a2512d..322d60b 100644
--- a/tests/tests/opengl/src/android/opengl/cts/OpenGlEsVersionTest.java
+++ b/tests/tests/opengl/src/android/opengl/cts/OpenGlEsVersionTest.java
@@ -298,6 +298,63 @@
}
}
+ @CddTest(requirement="7.1.4.5/C-1-4")
+ @Test
+ public void testRequiredGLESVersion() {
+ // This requirement only applies if device claims to be wide color capable.
+ boolean isWideColorCapable =
+ mActivity.getResources().getConfiguration().isScreenWideColorGamut();
+ if (!isWideColorCapable)
+ return;
+
+ int reportedVersion = getVersionFromActivityManager(mActivity);
+ assertEquals("Reported OpenGL ES major version doesn't meet the requirement of" +
+ " CDD 7.1.4.5/C-1-4", 3, getMajorVersion(reportedVersion));
+ assertTrue("Reported OpenGL ES minor version doesn't meet the requirement of" +
+ " CDD 7.1.4.5/C-1-4", 1 == getMinorVersion(reportedVersion) ||
+ 2 == getMinorVersion(reportedVersion));
+ }
+
+ @CddTest(requirement="7.1.4.5/C-1-5")
+ @Test
+ public void testRequiredEglExtensionsForWideColorDisplay() {
+ // See CDD section 7.1.4.5
+ // This test covers the EGL portion of the CDD requirement. The VK portion of the
+ // requirement is covered elsewhere.
+ final String requiredEglList[] = {
+ "EGL_KHR_no_config_context",
+ "EGL_EXT_pixel_format_float",
+ "EGL_KHR_gl_colorspace",
+ "EGL_EXT_gl_colorspace_scrgb",
+ "EGL_EXT_gl_colorspace_scrgb_linear",
+ "EGL_EXT_gl_colorspace_display_p3",
+ "EGL_EXT_gl_colorspace_display_p3_linear",
+ "EGL_EXT_gl_colorspace_display_p3_passthrough",
+ };
+
+ // This requirement only applies if device claims to be wide color capable.
+ boolean isWideColorCapable = mActivity.getResources().getConfiguration().isScreenWideColorGamut();
+ if (!isWideColorCapable)
+ return;
+
+ EGL10 egl = (EGL10) EGLContext.getEGL();
+ EGLDisplay display = egl.eglGetDisplay(EGL10.EGL_DEFAULT_DISPLAY);
+
+ if (egl.eglInitialize(display, null)) {
+ try {
+ String eglExtensions = egl.eglQueryString(display, EGL10.EGL_EXTENSIONS);
+ for (int i = 0; i < requiredEglList.length; ++i) {
+ assertTrue("EGL extension required by CDD section 7.1.4.5 missing: " +
+ requiredEglList[i], hasExtension(eglExtensions, requiredEglList[i]));
+ }
+ } finally {
+ egl.eglTerminate(display);
+ }
+ } else {
+ Log.e(TAG, "Couldn't initialize EGL.");
+ }
+ }
+
private boolean isHandheld() {
// handheld nature is not exposed to package manager, for now
// we check for touchscreen and NOT watch and NOT tv
diff --git a/tests/tests/os/Android.mk b/tests/tests/os/Android.mk
index 1fb4056..a524005 100644
--- a/tests/tests/os/Android.mk
+++ b/tests/tests/os/Android.mk
@@ -25,6 +25,7 @@
LOCAL_MULTILIB := both
LOCAL_STATIC_JAVA_LIBRARIES := \
+ android.hidl.manager-V1.0-java \
android-support-test \
compatibility-device-util \
ctstestrunner \
diff --git a/tests/tests/os/src/android/os/cts/HwBinderTest.java b/tests/tests/os/src/android/os/cts/HwBinderTest.java
new file mode 100644
index 0000000..d3ebe70
--- /dev/null
+++ b/tests/tests/os/src/android/os/cts/HwBinderTest.java
@@ -0,0 +1,218 @@
+/*
+ * Copyright (C) 2019 Google Inc.
+ *
+ * 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.os.cts;
+
+import android.hidl.manager.V1_0.IServiceManager;
+import android.hidl.manager.V1_0.IServiceNotification;
+import android.os.HwBlob;
+import android.os.RemoteException;
+
+import junit.framework.TestCase;
+
+import java.util.Calendar;
+import java.util.concurrent.locks.Condition;
+import java.util.concurrent.locks.Lock;
+import java.util.concurrent.locks.ReentrantLock;
+
+/**
+ * Unit tests for HwBinder.
+ *
+ * If you want to create a real hwbinder service, using hidl-gen will be
+ * *much* *much* easier. Using something like this is strongly not recommended
+ * because you can't take advantage of the versioning tools, the C++ and Java
+ * interoperability, etc..
+ */
+public class HwBinderTest extends TestCase {
+
+ private static class MarshalCase {
+ interface DoMarshalCase {
+ void test(HwBlob blob, int offset);
+ }
+
+ MarshalCase(String name, int size, DoMarshalCase method) {
+ mName = name;
+ mSize = size;
+ mMethod = method;
+ }
+
+ private String mName;
+ private int mSize;
+ private DoMarshalCase mMethod;
+
+ public String getName() {
+ return mName;
+ }
+
+ void test(int deltaSize, int offset) {
+ HwBlob blob = new HwBlob(mSize + deltaSize);
+ mMethod.test(blob, offset);
+ }
+ }
+
+ private static final MarshalCase[] sMarshalCases = {
+ new MarshalCase("Bool", 1, (blob, offset) -> {
+ blob.putBool(offset, true);
+ assertEquals(true, blob.getBool(offset));
+ }),
+ new MarshalCase("Int8", 1, (blob, offset) -> {
+ blob.putInt8(offset, (byte) 3);
+ assertEquals((byte) 3, blob.getInt8(offset));
+ }),
+ new MarshalCase("Int16", 2, (blob, offset) -> {
+ blob.putInt16(offset, (short) 3);
+ assertEquals((short) 3, blob.getInt16(offset));
+ }),
+ new MarshalCase("Int32", 4, (blob, offset) -> {
+ blob.putInt32(offset, 3);
+ assertEquals(3, blob.getInt32(offset));
+ }),
+ new MarshalCase("Int64", 8, (blob, offset) -> {
+ blob.putInt64(offset, 3);
+ assertEquals(3, blob.getInt64(offset));
+ }),
+ new MarshalCase("Float", 4, (blob, offset) -> {
+ blob.putFloat(offset, 3.0f);
+ assertEquals(3.0f, blob.getFloat(offset));
+ }),
+ new MarshalCase("Double", 8, (blob, offset) -> {
+ blob.putDouble(offset, 3.0);
+ assertEquals(3.0, blob.getDouble(offset));
+ }),
+ new MarshalCase("String", 16, (blob, offset) -> {
+ blob.putString(offset, "foo");
+ assertEquals("foo", blob.getString(offset));
+ }),
+ new MarshalCase("BoolArray", 2, (blob, offset) -> {
+ blob.putBoolArray(offset, new boolean[]{true, false});
+ assertEquals(true, blob.getBool(offset));
+ assertEquals(false, blob.getBool(offset + 1));
+ }),
+ new MarshalCase("Int8Array", 2, (blob, offset) -> {
+ blob.putInt8Array(offset, new byte[]{(byte) 3, (byte) 2});
+ assertEquals((byte) 3, blob.getInt8(offset));
+ assertEquals((byte) 2, blob.getInt8(offset + 1));
+ }),
+ new MarshalCase("Int16Array", 4, (blob, offset) -> {
+ blob.putInt16Array(offset, new short[]{(short) 3, (short) 2});
+ assertEquals((short) 3, blob.getInt16(offset));
+ assertEquals((short) 2, blob.getInt16(offset + 2));
+ }),
+ new MarshalCase("Int32Array", 8, (blob, offset) -> {
+ blob.putInt32Array(offset, new int[]{3, 2});
+ assertEquals(3, blob.getInt32(offset));
+ assertEquals(2, blob.getInt32(offset + 4));
+ }),
+ new MarshalCase("Int64Array", 16, (blob, offset) -> {
+ blob.putInt64Array(offset, new long[]{3, 2});
+ assertEquals(3, blob.getInt64(offset));
+ assertEquals(2, blob.getInt64(offset + 8));
+ }),
+ new MarshalCase("FloatArray", 8, (blob, offset) -> {
+ blob.putFloatArray(offset, new float[]{3.0f, 2.0f});
+ assertEquals(3.0f, blob.getFloat(offset));
+ assertEquals(2.0f, blob.getFloat(offset + 4));
+ }),
+ new MarshalCase("DoubleArray", 16, (blob, offset) -> {
+ blob.putDoubleArray(offset, new double[]{3.0, 2.0});
+ assertEquals(3.0, blob.getDouble(offset));
+ assertEquals(2.0, blob.getDouble(offset + 8));
+ }),
+ };
+
+ public void testAccurateMarshall() {
+ for (MarshalCase marshalCase : sMarshalCases) {
+ marshalCase.test(0 /* deltaSize */, 0 /* offset */);
+ }
+ }
+ public void testAccurateMarshallWithExtraSpace() {
+ for (MarshalCase marshalCase : sMarshalCases) {
+ marshalCase.test(1 /* deltaSize */, 0 /* offset */);
+ }
+ }
+ public void testAccurateMarshallWithExtraSpaceAndOffset() {
+ for (MarshalCase marshalCase : sMarshalCases) {
+ marshalCase.test(1 /* deltaSize */, 1 /* offset */);
+ }
+ }
+ public void testNotEnoughSpaceBecauseOfSize() {
+ for (MarshalCase marshalCase : sMarshalCases) {
+ try {
+ marshalCase.test(-1 /* deltaSize */, 0 /* offset */);
+ fail("Marshal succeeded but not enough space for " + marshalCase.getName());
+ } catch (IndexOutOfBoundsException e) {
+ // we expect to see this
+ }
+ }
+ }
+ public void testNotEnoughSpaceBecauseOfOffset() {
+ for (MarshalCase marshalCase : sMarshalCases) {
+ try {
+ marshalCase.test(0 /* deltaSize */, 1 /* offset */);
+ fail("Marshal succeeded but not enough space for " + marshalCase.getName());
+ } catch (IndexOutOfBoundsException e) {
+ // we expect to see this
+ }
+ }
+ }
+ public void testNotEnoughSpaceBecauseOfSizeAndOffset() {
+ for (MarshalCase marshalCase : sMarshalCases) {
+ try {
+ marshalCase.test(-1 /* deltaSize */, 1 /* offset */);
+ fail("Marshal succeeded but not enough space for " + marshalCase.getName());
+ } catch (IndexOutOfBoundsException e) {
+ // we expect to see this
+ }
+ }
+ }
+
+ private static class ServiceNotification extends IServiceNotification.Stub {
+ public Lock lock = new ReentrantLock();
+ public Condition condition = lock.newCondition();
+ public boolean registered = false;
+
+ @Override
+ public void onRegistration(String fqName, String name, boolean preexisting) {
+ registered = true;
+ condition.signal();
+ }
+ }
+
+ public void testHwBinder() throws RemoteException {
+ ServiceNotification notification = new ServiceNotification();
+
+ IServiceManager manager = IServiceManager.getService();
+ manager.registerForNotifications(IServiceManager.kInterfaceName, "default", notification);
+
+ Calendar deadline = Calendar.getInstance();
+ deadline.add(Calendar.SECOND, 10);
+
+ notification.lock.lock();
+ try {
+ while (!notification.registered && Calendar.getInstance().before(deadline)) {
+ try {
+ notification.condition.awaitUntil(deadline.getTime());
+ } catch (InterruptedException e) {
+
+ }
+ }
+ } finally {
+ notification.lock.unlock();
+ }
+
+ assertTrue(notification.registered);
+ }
+}
diff --git a/tests/tests/permission/AndroidManifest.xml b/tests/tests/permission/AndroidManifest.xml
index 0de5496..928da95 100644
--- a/tests/tests/permission/AndroidManifest.xml
+++ b/tests/tests/permission/AndroidManifest.xml
@@ -36,8 +36,8 @@
<permission android:name="android.permission.cts.D"
android:usageInfoRequired="true" />
- <!-- for android.permission.cts.PermissionUsage -->
- <uses-permission android:name="android.permission.READ_CONTACTS"
+ <!-- for android.permission.cts.PermissionUsage and LocationAccessCheckTest -->
+ <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"
android:dataSentOffDevice="no"
android:dataSharedWithThirdParty="no"
android:dataUsedForMonetization="no"
@@ -60,9 +60,6 @@
<!-- for android.permission.cts.PermissionUsage -->
<uses-permission android:name="android.permission.READ_CALENDAR" />
- <!-- for android.permission.cts.LocationAccessCheckTest -->
- <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
-
<!-- for android.permission.cts.PermissionGroupChange -->
<permission-group android:description="@string/perm_group_b"
android:label="@string/perm_group_b"
diff --git a/tests/tests/permission/src/android/permission/cts/FileSystemPermissionTest.java b/tests/tests/permission/src/android/permission/cts/FileSystemPermissionTest.java
index 5203705..7661585d 100644
--- a/tests/tests/permission/src/android/permission/cts/FileSystemPermissionTest.java
+++ b/tests/tests/permission/src/android/permission/cts/FileSystemPermissionTest.java
@@ -1040,6 +1040,21 @@
}
@Test
+ public void testProcUUIDReadable() throws Exception {
+ File f = new File("/proc/sys/kernel/random/uuid");
+
+ assertTrue(f + " cannot be opened for reading", canOpenForReading(f));
+ assertFalse(f + " can be opened for writing", canOpenForWriting(f));
+
+ FileUtils.FileStatus status = new FileUtils.FileStatus();
+ assertTrue(FileUtils.getFileStatus(f.getPath(), status, false));
+ assertTrue(
+ f + " not 0444. Actual mode: 0"
+ + Integer.toString(status.mode, 8),
+ (status.mode & 0666) == 0444);
+ }
+
+ @Test
public void testDevHwRandomLockedDown() throws Exception {
File f = new File("/dev/hw_random");
if (!f.exists()) {
diff --git a/tests/tests/permission/src/android/permission/cts/PermissionUsageTest.java b/tests/tests/permission/src/android/permission/cts/PermissionUsageTest.java
index 5752801..39c66a6 100644
--- a/tests/tests/permission/src/android/permission/cts/PermissionUsageTest.java
+++ b/tests/tests/permission/src/android/permission/cts/PermissionUsageTest.java
@@ -54,7 +54,7 @@
}
public void testBasic() throws Exception {
- UsesPermissionInfo upi = getUsesPermissionInfo(Manifest.permission.READ_CONTACTS);
+ UsesPermissionInfo upi = getUsesPermissionInfo(Manifest.permission.ACCESS_FINE_LOCATION);
assertEquals(UsesPermissionInfo.USAGE_NO, upi.getDataSentOffDevice());
assertEquals(UsesPermissionInfo.USAGE_NO, upi.getDataSharedWithThirdParty());
assertEquals(UsesPermissionInfo.USAGE_NO, upi.getDataUsedForMonetization());
diff --git a/tests/tests/permission/src/android/permission/cts/ProviderPermissionTest.java b/tests/tests/permission/src/android/permission/cts/ProviderPermissionTest.java
index b8f587a..b203f14 100644
--- a/tests/tests/permission/src/android/permission/cts/ProviderPermissionTest.java
+++ b/tests/tests/permission/src/android/permission/cts/ProviderPermissionTest.java
@@ -16,7 +16,7 @@
package android.permission.cts;
-import static com.google.common.truth.Truth.assertThat;
+import static android.Manifest.permission.WRITE_MEDIA_STORAGE;
import android.content.ContentValues;
import android.content.Intent;
@@ -29,6 +29,7 @@
import android.provider.CallLog;
import android.provider.Contacts;
import android.provider.ContactsContract;
+import android.provider.MediaStore;
import android.provider.Settings;
import android.provider.Telephony;
import android.test.AndroidTestCase;
@@ -217,18 +218,34 @@
}
/**
- * Verify that the holder of the MANAGE_DOCUMENTS permission is com.android.documentsui.
+ * The {@link android.Manifest.permission#WRITE_MEDIA_STORAGE} permission is
+ * a very powerful permission that grants raw storage access to all devices,
+ * and as such it's only appropriate to be granted to the media stack. Any
+ * apps with a user-visible component (such as Camera or Gallery apps) must
+ * go through public {@link MediaStore} APIs, to ensure that users have
+ * meaningful permission controls.
+ * <p>
+ * For example, if the end user revokes the "Music" permission from an app,
+ * but that app still has raw access to music via
+ * {@link android.Manifest.permission#WRITE_MEDIA_STORAGE}, that would be a
+ * privacy incident.
*/
- public void testManageDocumentsMustIncludedInDocumentUi() {
+ public void testMediaStackPermissions() throws Exception {
+ // The only apps holding this permission should be the internal media
+ // stack, and the best way to identify them is having no launchable UI.
final PackageManager pm = getContext().getPackageManager();
-
- final List<PackageInfo> holding = pm.getPackagesHoldingPermissions(new String[] {
- android.Manifest.permission.MANAGE_DOCUMENTS
- }, PackageManager.MATCH_UNINSTALLED_PACKAGES);
-
- assertThat(holding.size()).isAtMost(1);
- if (holding.size() == 1) {
- assertThat(holding.get(0).packageName).isEqualTo("com.android.documentsui");
+ final List<PackageInfo> pkgs = pm
+ .getInstalledPackages(PackageManager.MATCH_UNINSTALLED_PACKAGES);
+ for (PackageInfo pkg : pkgs) {
+ final boolean isSystem = pkg.applicationInfo.uid == android.os.Process.SYSTEM_UID;
+ final boolean hasFrontDoor = pm.getLaunchIntentForPackage(pkg.packageName) != null;
+ final boolean hasPermission = pm.checkPermission(WRITE_MEDIA_STORAGE,
+ pkg.packageName) == PackageManager.PERMISSION_GRANTED;
+ if (!isSystem && hasFrontDoor && hasPermission) {
+ fail("Found " + pkg.packageName + " holding WRITE_MEDIA_STORAGE permission while "
+ + "also having user-visible UI; this permission must only be held by "
+ + "the core media stack, and must not be granted to user-launchable apps");
+ }
}
}
}
diff --git a/tests/tests/permission2/res/raw/android_manifest.xml b/tests/tests/permission2/res/raw/android_manifest.xml
index 380407c..3b367fc 100644
--- a/tests/tests/permission2/res/raw/android_manifest.xml
+++ b/tests/tests/permission2/res/raw/android_manifest.xml
@@ -1622,6 +1622,12 @@
<permission android:name="android.permission.WIFI_SET_DEVICE_MOBILITY_STATE"
android:protectionLevel="signature|privileged" />
+ <!-- #SystemApi @hide Allows privileged system APK to update Wifi usability stats and score.
+ <p>Not for use by third-party applications. This should only be used by a privileged app.
+ -->
+ <permission android:name="android.permission.WIFI_UPDATE_USABILITY_STATS_SCORE"
+ android:protectionLevel="signature|privileged" />
+
<!-- #SystemApi @hide Allows applications to access information about LoWPAN interfaces.
<p>Not for use by third-party applications. -->
<permission android:name="android.permission.ACCESS_LOWPAN_STATE"
@@ -2212,8 +2218,9 @@
<permission android:name="android.permission.INTERACT_ACROSS_USERS_FULL"
android:protectionLevel="signature|installer" />
- <!-- @SystemApi Allows an application to start an activity within its managed profile from
- the personal profile.
+ <!-- @SystemApi Allows an application to start its own activities, but on a different profile
+ associated with the user. For example, an application running on the main profile of a user
+ can start an activity on a managed profile of that user.
This permission is not available to third party applications.
@hide -->
<permission android:name="android.permission.INTERACT_ACROSS_PROFILES"
@@ -2272,6 +2279,11 @@
<permission android:name="android.permission.START_ANY_ACTIVITY"
android:protectionLevel="signature" />
+ <!-- Allows an application to start activities from background
+ @hide -->
+ <permission android:name="android.permission.START_ACTIVITIES_FROM_BACKGROUND"
+ android:protectionLevel="signature|privileged|vendorPrivileged|oem" />
+
<!-- @SystemApi Must be required by activities that handle the intent action
{@link Intent#ACTION_SEND_SHOW_SUSPENDED_APP_DETAILS}. This is for use by apps that
hold {@link Manifest.permission#SUSPEND_APPS} to interact with the system.
@@ -2530,6 +2542,16 @@
<permission android:name="android.permission.WRITE_GSERVICES"
android:protectionLevel="signature|privileged" />
+ <!-- @SystemApi @hide Allows an application to modify config settings.
+ <p>Not for use by third-party applications. -->
+ <permission android:name="android.permission.WRITE_DEVICE_CONFIG"
+ android:protectionLevel="signature|configurator"/>
+
+ <!-- @SystemApi @hide Allows an application to read config settings.
+ <p>Not for use by third-party applications. -->
+ <permission android:name="android.permission.READ_DEVICE_CONFIG"
+ android:protectionLevel="signature|preinstalled" />
+
<!-- @SystemApi @TestApi Allows an application to call
{@link android.app.ActivityManager#forceStopPackage}.
@hide -->
@@ -3048,6 +3070,14 @@
<permission android:name="android.permission.BIND_TEXT_SERVICE"
android:protectionLevel="signature" />
+ <!-- @SystemApi Must be required by a AttentionService
+ to ensure that only the system can bind to it.
+ <p>Protection level: signature
+ @hide
+ -->
+ <permission android:name="android.permission.BIND_ATTENTION_SERVICE"
+ android:protectionLevel="signature" />
+
<!-- Must be required by a {@link android.net.VpnService},
to ensure that only the system can bind to it.
<p>Protection level: signature
@@ -3199,9 +3229,10 @@
<!-- @SystemApi Required to add or remove another application as a device admin.
<p>Not for use by third-party applications.
- @hide -->
+ @hide
+ @removed -->
<permission android:name="android.permission.MANAGE_DEVICE_ADMINS"
- android:protectionLevel="signature|privileged" />
+ android:protectionLevel="signature" />
<!-- @SystemApi Allows an app to reset the device password.
<p>Not for use by third-party applications.
@@ -3523,19 +3554,25 @@
<permission android:name="android.permission.MODIFY_DEFAULT_AUDIO_EFFECTS"
android:protectionLevel="signature|privileged" />
+ <!-- @SystemApi Allows an application to provide remote displays.
+ <p>Not for use by third-party applications.</p>
+ @hide -->
+ <permission android:name="android.permission.REMOTE_DISPLAY_PROVIDER"
+ android:protectionLevel="signature|privileged" />
+
<!-- Allows an application to capture video output.
<p>Not for use by third-party applications.</p>
@hide
@removed -->
<permission android:name="android.permission.CAPTURE_VIDEO_OUTPUT"
- android:protectionLevel="signature|privileged" />
+ android:protectionLevel="signature" />
<!-- Allows an application to capture secure video output.
<p>Not for use by third-party applications.</p>
@hide
@removed -->
<permission android:name="android.permission.CAPTURE_SECURE_VIDEO_OUTPUT"
- android:protectionLevel="signature|privileged" />
+ android:protectionLevel="signature" />
<!-- @SystemApi Allows an application to know what content is playing and control its playback.
<p>Not for use by third-party applications due to privacy of media consumption</p> -->
@@ -3870,7 +3907,7 @@
<!-- @SystemApi @hide Allows managing apk level rollbacks. -->
<permission android:name="android.permission.MANAGE_ROLLBACKS"
- android:protectionLevel="signature|installer" />
+ android:protectionLevel="signature|verifier" />
<!-- @SystemApi @hide Allows an application to mark other applications as harmful -->
<permission android:name="android.permission.SET_HARMFUL_APP_WARNINGS"
@@ -4395,6 +4432,11 @@
<permission android:name="android.permission.AMBIENT_WALLPAPER"
android:protectionLevel="signature|preinstalled" />
+ <!-- Allows the device to be reset, clearing all data and enables Test Harness Mode.
+ @hide-->
+ <permission android:name="android.permission.ENABLE_TEST_HARNESS_MODE"
+ android:protectionLevel="signature" />
+
<application android:process="system"
android:persistent="true"
android:hasCode="false"
diff --git a/tests/tests/permission/src/android/permission/cts/NoLocationPermissionTest.java b/tests/tests/permission2/src/android/permission2/cts/NoLocationPermissionTest.java
similarity index 95%
rename from tests/tests/permission/src/android/permission/cts/NoLocationPermissionTest.java
rename to tests/tests/permission2/src/android/permission2/cts/NoLocationPermissionTest.java
index df69c94..d1d42bc 100644
--- a/tests/tests/permission/src/android/permission/cts/NoLocationPermissionTest.java
+++ b/tests/tests/permission2/src/android/permission2/cts/NoLocationPermissionTest.java
@@ -14,7 +14,7 @@
* limitations under the License.
*/
-package android.permission.cts;
+package android.permission2.cts;
import android.app.PendingIntent;
import android.content.Context;
@@ -374,24 +374,6 @@
}
/**
- * Verify that checking clearTestProviderLocation for network requires
- * permissions.
- * <p>
- * Requires Permission:
- * {@link android.Manifest.permission#ACCESS_MOCK_LOCATION}.
- */
- @SmallTest
- public void testClearTestProviderLocation() {
- try {
- mLocationManager.clearTestProviderLocation(TEST_PROVIDER_NAME);
- fail("LocationManager.clearTestProviderLocation did not throw SecurityException as"
- + " expected");
- } catch (SecurityException e) {
- // expected
- }
- }
-
- /**
* Verify that checking setTestProviderEnabled requires permissions.
* <p>
* Requires Permission:
diff --git a/tests/tests/permission2/src/android/permission2/cts/PermissionPolicyTest.java b/tests/tests/permission2/src/android/permission2/cts/PermissionPolicyTest.java
index 6916f83..b0ba8fa 100644
--- a/tests/tests/permission2/src/android/permission2/cts/PermissionPolicyTest.java
+++ b/tests/tests/permission2/src/android/permission2/cts/PermissionPolicyTest.java
@@ -303,6 +303,9 @@
case "privileged": {
protectionLevel |= PermissionInfo.PROTECTION_FLAG_PRIVILEGED;
} break;
+ case "oem": {
+ protectionLevel |= PermissionInfo.PROTECTION_FLAG_OEM;
+ } break;
case "vendorPrivileged": {
protectionLevel |= PermissionInfo.PROTECTION_FLAG_VENDOR_PRIVILEGED;
} break;
@@ -315,6 +318,9 @@
case "wellbeing": {
protectionLevel |= PermissionInfo.PROTECTION_FLAG_WELLBEING;
} break;
+ case "configurator": {
+ protectionLevel |= PermissionInfo.PROTECTION_FLAG_CONFIGURATOR;
+ } break;
case "documenter": {
protectionLevel |= PermissionInfo.PROTECTION_FLAG_DOCUMENTER;
} break;
diff --git a/tests/tests/provider/Android.bp b/tests/tests/provider/Android.bp
new file mode 100644
index 0000000..1079cf8
--- /dev/null
+++ b/tests/tests/provider/Android.bp
@@ -0,0 +1,37 @@
+
+android_test {
+ name: "CtsProviderTestCases",
+ defaults: ["cts_defaults"],
+
+ compile_multilib: "both",
+
+ test_suites: [
+ "cts",
+ "vts",
+ "general-tests",
+ ],
+
+ libs: [
+ "android.test.mock",
+ "android.test.base.stubs",
+ "android.test.runner.stubs",
+ "telephony-common",
+ ],
+
+ static_libs: [
+ "compatibility-device-util",
+ "ctstestrunner",
+ "junit",
+ "truth-prebuilt",
+ ],
+
+ jni_libs: [
+ "libcts_jni",
+ "libnativehelper_compat_libc++",
+ ],
+
+ srcs: ["src/**/*.java"],
+
+ sdk_version: "test_current",
+ min_sdk_version: "21",
+}
diff --git a/tests/tests/provider/Android.mk b/tests/tests/provider/Android.mk
index e7def77..6361f9b 100644
--- a/tests/tests/provider/Android.mk
+++ b/tests/tests/provider/Android.mk
@@ -1,50 +1,2 @@
-# 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.
-
-LOCAL_PATH:= $(call my-dir)
-
-include $(CLEAR_VARS)
-
-# don't include this package in any target
-LOCAL_MODULE_TAGS := optional
-
-# Include both the 32 and 64 bit versions of libs
-LOCAL_MULTILIB := both
-
-# and when built explicitly put it in the data partition
-LOCAL_MODULE_PATH := $(TARGET_OUT_DATA_APPS)
-
-# Tag this module as a cts test artifact
-LOCAL_COMPATIBILITY_SUITE := cts vts general-tests
-
-LOCAL_JAVA_LIBRARIES := android.test.mock android.test.base.stubs android.test.runner.stubs telephony-common
-
-LOCAL_USE_AAPT2 := true
-
-LOCAL_STATIC_JAVA_LIBRARIES := \
- compatibility-device-util \
- ctstestrunner \
- junit \
- truth-prebuilt
-
-LOCAL_JNI_SHARED_LIBRARIES := libcts_jni libnativehelper_compat_libc++
-
-LOCAL_SRC_FILES := $(call all-java-files-under, src)
-
-LOCAL_PACKAGE_NAME := CtsProviderTestCases
-LOCAL_PRIVATE_PLATFORM_APIS := true
-
-LOCAL_MIN_SDK_VERSION := 21
-
-include $(BUILD_CTS_PACKAGE)
+LOCAL_PATH := $(call my-dir)
+include $(call all-makefiles-under,$(LOCAL_PATH))
diff --git a/tests/tests/provider/AndroidTest.xml b/tests/tests/provider/AndroidTest.xml
index bca4189..cafbdaa 100644
--- a/tests/tests/provider/AndroidTest.xml
+++ b/tests/tests/provider/AndroidTest.xml
@@ -17,6 +17,7 @@
<option name="test-suite-tag" value="cts" />
<option name="config-descriptor:metadata" key="component" value="framework" />
<option name="config-descriptor:metadata" key="parameter" value="instant_app" />
+ <target_preparer class="android.provider.cts.preconditions.ExternalStoragePreparer" />
<target_preparer class="com.android.tradefed.targetprep.suite.SuiteApkInstaller">
<option name="cleanup-apks" value="true" />
<option name="test-file-name" value="CtsProviderTestCases.apk" />
diff --git a/tests/tests/provider/preconditions/Android.mk b/tests/tests/provider/preconditions/Android.mk
new file mode 100644
index 0000000..f4063c4
--- /dev/null
+++ b/tests/tests/provider/preconditions/Android.mk
@@ -0,0 +1,20 @@
+LOCAL_PATH := $(call my-dir)
+
+include $(CLEAR_VARS)
+
+LOCAL_SRC_FILES := $(call all-java-files-under, src)
+
+LOCAL_JAVA_LIBRARIES := compatibility-host-util cts-tradefed tradefed
+
+LOCAL_MODULE_TAGS := optional
+
+LOCAL_MODULE := compatibility-host-provider-preconditions
+
+# Tag this module as a cts test artifact
+LOCAL_COMPATIBILITY_SUITE := cts vts general-tests
+
+LOCAL_SDK_VERSION := current
+
+include $(BUILD_HOST_JAVA_LIBRARY)
+
+include $(call all-makefiles-under,$(LOCAL_PATH))
diff --git a/tests/tests/provider/preconditions/src/android/provider/cts/preconditions/ExternalStoragePreparer.java b/tests/tests/provider/preconditions/src/android/provider/cts/preconditions/ExternalStoragePreparer.java
new file mode 100644
index 0000000..5007cea
--- /dev/null
+++ b/tests/tests/provider/preconditions/src/android/provider/cts/preconditions/ExternalStoragePreparer.java
@@ -0,0 +1,73 @@
+/*
+ * Copyright (C) 2019 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.provider.cts.preconditions;
+
+import com.android.tradefed.build.IBuildInfo;
+import com.android.tradefed.device.DeviceNotAvailableException;
+import com.android.tradefed.device.ITestDevice;
+import com.android.tradefed.targetprep.BuildError;
+import com.android.tradefed.targetprep.ITargetCleaner;
+import com.android.tradefed.targetprep.ITargetPreparer;
+import com.android.tradefed.targetprep.TargetSetupError;
+
+/**
+ * Creates secondary external storage for use during a test suite.
+ */
+public class ExternalStoragePreparer implements ITargetPreparer, ITargetCleaner {
+ @Override
+ public void setUp(ITestDevice device, IBuildInfo buildInfo)
+ throws TargetSetupError, BuildError, DeviceNotAvailableException {
+ if (!hasIsolatedStorage(device)) return;
+
+ device.executeShellCommand("sm set-virtual-disk false");
+ device.executeShellCommand("sm set-virtual-disk true");
+
+ // Partition disks to make sure they're usable by tests
+ final String diskId = getVirtualDisk(device);
+ device.executeShellCommand("sm partition " + diskId + " public");
+ }
+
+ @Override
+ public void tearDown(ITestDevice device, IBuildInfo buildInfo, Throwable throwable)
+ throws DeviceNotAvailableException {
+ if (!hasIsolatedStorage(device)) return;
+
+ device.executeShellCommand("sm set-virtual-disk false");
+ }
+
+ private boolean hasIsolatedStorage(ITestDevice device) throws DeviceNotAvailableException {
+ return device.executeShellCommand("getprop sys.isolated_storage_snapshot")
+ .contains("true");
+ }
+
+ private String getVirtualDisk(ITestDevice device) throws DeviceNotAvailableException {
+ int attempt = 0;
+ String disks = device.executeShellCommand("sm list-disks");
+ while ((disks == null || disks.isEmpty()) && attempt++ < 15) {
+ try {
+ Thread.sleep(1000);
+ } catch (InterruptedException ignored) {
+ }
+ disks = device.executeShellCommand("sm list-disks");
+ }
+
+ if (disks == null || disks.isEmpty()) {
+ throw new AssertionError("Device must support virtual disk to verify behavior");
+ }
+ return disks.split("\n")[0].trim();
+ }
+}
diff --git a/tests/tests/provider/src/android/provider/cts/BlockedNumberBackupRestoreTest.java b/tests/tests/provider/src/android/provider/cts/BlockedNumberBackupRestoreTest.java
index 1fabb4e..cb8eeda 100644
--- a/tests/tests/provider/src/android/provider/cts/BlockedNumberBackupRestoreTest.java
+++ b/tests/tests/provider/src/android/provider/cts/BlockedNumberBackupRestoreTest.java
@@ -22,7 +22,7 @@
import android.content.Context;
import android.content.pm.PackageManager;
import android.provider.BlockedNumberContract;
-import android.telecom.Log;
+import android.util.Log;
/**
* CTS tests for backup and restore of blocked numbers using local transport.
diff --git a/tests/tests/provider/src/android/provider/cts/BlockedNumberContractTest.java b/tests/tests/provider/src/android/provider/cts/BlockedNumberContractTest.java
index 30fdf24..39aa0bb 100644
--- a/tests/tests/provider/src/android/provider/cts/BlockedNumberContractTest.java
+++ b/tests/tests/provider/src/android/provider/cts/BlockedNumberContractTest.java
@@ -16,7 +16,6 @@
package android.provider.cts;
-import android.annotation.Nullable;
import android.content.ContentResolver;
import android.content.ContentUris;
import android.content.ContentValues;
@@ -323,7 +322,7 @@
}
private Uri assertInsertBlockedNumberSucceeds(
- String originalNumber, @Nullable String e164Number) {
+ String originalNumber, String e164Number) {
ContentValues cv = new ContentValues();
cv.put(BlockedNumbers.COLUMN_ORIGINAL_NUMBER, originalNumber);
if (e164Number != null) {
diff --git a/tests/tests/provider/src/android/provider/cts/FontsContractTest.java b/tests/tests/provider/src/android/provider/cts/FontsContractTest.java
index ea88369..631401a 100644
--- a/tests/tests/provider/src/android/provider/cts/FontsContractTest.java
+++ b/tests/tests/provider/src/android/provider/cts/FontsContractTest.java
@@ -40,8 +40,6 @@
import android.support.test.filters.SmallTest;
import android.support.test.runner.AndroidJUnit4;
-import com.android.internal.annotations.GuardedBy;
-
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
@@ -99,13 +97,13 @@
private static class TestCallback extends FontsContract.FontRequestCallback {
private final Object mLock = new Object();
- @GuardedBy("mLock")
+ // @GuardedBy("mLock")
private Typeface mTypeface;
- @GuardedBy("mLock")
+ // @GuardedBy("mLock")
private int mFailedReason;
- @GuardedBy("mLock")
+ // @GuardedBy("mLock")
private int mSuccessCallCount;
- @GuardedBy("mLock")
+ // @GuardedBy("mLock")
private int mFailedCallCount;
public void onTypefaceRetrieved(Typeface typeface) {
diff --git a/tests/tests/provider/src/android/provider/cts/MediaStoreAudioTestHelper.java b/tests/tests/provider/src/android/provider/cts/MediaStoreAudioTestHelper.java
index 32ea9cf..a2b62f0 100644
--- a/tests/tests/provider/src/android/provider/cts/MediaStoreAudioTestHelper.java
+++ b/tests/tests/provider/src/android/provider/cts/MediaStoreAudioTestHelper.java
@@ -19,7 +19,6 @@
import android.content.ContentResolver;
import android.content.ContentValues;
import android.net.Uri;
-import android.os.Environment;
import android.provider.MediaStore;
import android.provider.MediaStore.Audio.Media;
import android.support.test.runner.AndroidJUnit4;
@@ -29,6 +28,9 @@
import org.junit.Test;
import org.junit.runner.RunWith;
+import java.io.File;
+import java.io.IOException;
+
/**
* This class contains fake data and convenient methods for testing:
* {@link MediaStore.Audio.Media}
@@ -52,18 +54,18 @@
@RunWith(AndroidJUnit4.class)
public class MediaStoreAudioTestHelper {
public static abstract class MockAudioMediaInfo {
- public abstract ContentValues getContentValues(boolean isInternal);
+ public abstract ContentValues getContentValues(String volumeName);
- public Uri insertToInternal(ContentResolver contentResolver) {
- Uri uri = contentResolver.insert(Media.INTERNAL_CONTENT_URI, getContentValues(true));
- Assert.assertNotNull(uri);
- return uri;
- }
+ public Uri insert(ContentResolver contentResolver, String volumeName) {
+ final Uri dirUri = MediaStore.Audio.Media.getContentUri(volumeName);
+ final ContentValues values = getContentValues(volumeName);
+ contentResolver.delete(dirUri, MediaStore.Audio.Media.DATA + "=?", new String[] {
+ values.getAsString(MediaStore.Audio.Media.DATA)
+ });
- public Uri insertToExternal(ContentResolver contentResolver) {
- Uri uri = contentResolver.insert(Media.EXTERNAL_CONTENT_URI, getContentValues(false));
- Assert.assertNotNull(uri);
- return uri;
+ final Uri itemUri = contentResolver.insert(dirUri, values);
+ Assert.assertNotNull(itemUri);
+ return itemUri;
}
public int delete(ContentResolver contentResolver, Uri uri) {
@@ -82,50 +84,37 @@
}
public static final int IS_RINGTONE = 0;
-
public static final int IS_NOTIFICATION = 0;
-
public static final int IS_ALARM = 0;
-
public static final int IS_MUSIC = 1;
-
- public static final int IS_DRM = 0;
-
public static final int YEAR = 1992;
-
public static final int TRACK = 1;
-
public static final int DURATION = 340000;
-
public static final String COMPOSER = "Bruce Swedien";
-
public static final String ARTIST = "Michael Jackson";
-
public static final String ALBUM = "Dangerous";
-
public static final String TITLE = "Jam";
-
public static final int SIZE = 2737870;
-
public static final String MIME_TYPE = "audio/x-mpeg";
-
public static final String DISPLAY_NAME = "Jam -Michael Jackson";
-
- public static final String INTERNAL_DATA =
- "/data/data/android.provider.cts/files/Jam.mp3";
-
public static final String FILE_NAME = "Jam.mp3";
-
- public static final String EXTERNAL_DATA = Environment.getExternalStorageDirectory() +
- "/" + FILE_NAME;
-
public static final long DATE_MODIFIED = System.currentTimeMillis() / 1000;
-
public static final String GENRE = "POP";
+
@Override
- public ContentValues getContentValues(boolean isInternal) {
+ public ContentValues getContentValues(String volumeName) {
ContentValues values = new ContentValues();
- values.put(Media.DATA, isInternal ? INTERNAL_DATA : EXTERNAL_DATA);
+ try {
+ final File data;
+ if (MediaStore.VOLUME_INTERNAL.equals(volumeName)) {
+ data = new File("/data/data/android.provider.cts/files/", FILE_NAME);
+ } else {
+ data = new File(ProviderTestUtils.stageDir(volumeName), FILE_NAME);
+ }
+ values.put(Media.DATA, data.getAbsolutePath());
+ } catch (IOException e) {
+ throw new RuntimeException(e);
+ }
values.put(Media.DATE_MODIFIED, DATE_MODIFIED);
values.put(Media.DISPLAY_NAME, DISPLAY_NAME);
values.put(Media.MIME_TYPE, MIME_TYPE);
@@ -141,8 +130,6 @@
values.put(Media.IS_ALARM, IS_ALARM);
values.put(Media.IS_NOTIFICATION, IS_NOTIFICATION);
values.put(Media.IS_RINGTONE, IS_RINGTONE);
- values.put(Media.IS_DRM, IS_DRM);
-
return values;
}
}
@@ -158,53 +145,38 @@
}
public static final int IS_RINGTONE = 1;
-
public static final int IS_NOTIFICATION = 0;
-
public static final int IS_ALARM = 0;
-
public static final int IS_MUSIC = 0;
-
- public static final int IS_DRM = 0;
-
public static final int YEAR = 1992;
-
public static final int TRACK = 1001;
-
public static final int DURATION = 338000;
-
public static final String COMPOSER = "Bruce Swedien";
-
public static final String ARTIST =
"Michael Jackson - Live And Dangerous - National Stadium Bucharest";
-
public static final String ALBUM =
"Michael Jackson - Live And Dangerous - National Stadium Bucharest";
-
public static final String TITLE = "Jam";
-
public static final int SIZE = 2737321;
-
public static final String MIME_TYPE = "audio/x-mpeg";
-
public static final String DISPLAY_NAME = "Jam(Live)-Michael Jackson";
-
public static final String FILE_NAME = "Jam_live.mp3";
-
- public static final String EXTERNAL_DATA =
- Environment.getExternalStorageDirectory().getPath() + "/" + FILE_NAME;
-
- public static final String INTERNAL_DATA =
- "/data/data/android.provider.cts/files/Jam_live.mp3";
-
-
-
public static final long DATE_MODIFIED = System.currentTimeMillis() / 1000;
@Override
- public ContentValues getContentValues(boolean isInternal) {
+ public ContentValues getContentValues(String volumeName) {
ContentValues values = new ContentValues();
- values.put(Media.DATA, isInternal ? INTERNAL_DATA : EXTERNAL_DATA);
+ try {
+ final File data;
+ if (MediaStore.VOLUME_INTERNAL.equals(volumeName)) {
+ data = new File("/data/data/android.provider.cts/files/", FILE_NAME);
+ } else {
+ data = new File(ProviderTestUtils.stageDir(volumeName), FILE_NAME);
+ }
+ values.put(Media.DATA, data.getAbsolutePath());
+ } catch (IOException e) {
+ throw new RuntimeException(e);
+ }
values.put(Media.DATE_MODIFIED, DATE_MODIFIED);
values.put(Media.DISPLAY_NAME, DISPLAY_NAME);
values.put(Media.MIME_TYPE, MIME_TYPE);
@@ -220,8 +192,6 @@
values.put(Media.IS_ALARM, IS_ALARM);
values.put(Media.IS_NOTIFICATION, IS_NOTIFICATION);
values.put(Media.IS_RINGTONE, IS_RINGTONE);
- values.put(Media.IS_DRM, IS_DRM);
-
return values;
}
}
@@ -237,8 +207,8 @@
}
@Override
- public ContentValues getContentValues(boolean isInternal) {
- ContentValues values = super.getContentValues(isInternal);
+ public ContentValues getContentValues(String volumeName) {
+ ContentValues values = super.getContentValues(volumeName);
values.put(Media.DATA, values.getAsString(Media.DATA) + "_3");
return values;
}
@@ -255,8 +225,8 @@
}
@Override
- public ContentValues getContentValues(boolean isInternal) {
- ContentValues values = super.getContentValues(isInternal);
+ public ContentValues getContentValues(String volumeName) {
+ ContentValues values = super.getContentValues(volumeName);
values.put(Media.DATA, values.getAsString(Media.DATA) + "_4");
return values;
}
@@ -273,8 +243,8 @@
}
@Override
- public ContentValues getContentValues(boolean isInternal) {
- ContentValues values = super.getContentValues(isInternal);
+ public ContentValues getContentValues(String volumeName) {
+ ContentValues values = super.getContentValues(volumeName);
values.put(Media.DATA, values.getAsString(Media.DATA) + "_5");
return values;
}
diff --git a/tests/tests/provider/src/android/provider/cts/MediaStoreIntentsTest.java b/tests/tests/provider/src/android/provider/cts/MediaStoreIntentsTest.java
index 0b1dad8..c027004 100644
--- a/tests/tests/provider/src/android/provider/cts/MediaStoreIntentsTest.java
+++ b/tests/tests/provider/src/android/provider/cts/MediaStoreIntentsTest.java
@@ -16,6 +16,8 @@
package android.provider.cts;
+import static android.provider.cts.MediaStoreTest.TAG;
+
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertTrue;
@@ -24,10 +26,14 @@
import android.net.Uri;
import android.provider.MediaStore;
import android.support.test.InstrumentationRegistry;
-import android.support.test.runner.AndroidJUnit4;
+import android.util.Log;
+import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
+import org.junit.runners.Parameterized;
+import org.junit.runners.Parameterized.Parameter;
+import org.junit.runners.Parameterized.Parameters;
import java.util.List;
@@ -35,8 +41,28 @@
* Tests to verify that common actions on {@link MediaStore} content are
* available.
*/
-@RunWith(AndroidJUnit4.class)
+@RunWith(Parameterized.class)
public class MediaStoreIntentsTest {
+ private Uri mExternalAudio;
+ private Uri mExternalVideo;
+ private Uri mExternalImages;
+
+ @Parameter(0)
+ public String mVolumeName;
+
+ @Parameters
+ public static Iterable<? extends Object> data() {
+ return ProviderTestUtils.getSharedVolumeNames();
+ }
+
+ @Before
+ public void setUp() throws Exception {
+ Log.d(TAG, "Using volume " + mVolumeName);
+ mExternalAudio = MediaStore.Audio.Media.getContentUri(mVolumeName);
+ mExternalVideo = MediaStore.Video.Media.getContentUri(mVolumeName);
+ mExternalImages = MediaStore.Images.Media.getContentUri(mVolumeName);
+ }
+
public void assertCanBeHandled(Intent intent) {
List<ResolveInfo> resolveInfoList = InstrumentationRegistry.getTargetContext()
.getPackageManager().queryIntentActivities(intent, 0);
@@ -48,35 +74,35 @@
@Test
public void testPickImageDir() {
Intent intent = new Intent(Intent.ACTION_PICK);
- intent.setData(MediaStore.Images.Media.EXTERNAL_CONTENT_URI);
+ intent.setData(mExternalImages);
assertCanBeHandled(intent);
}
@Test
public void testPickVideoDir() {
Intent intent = new Intent(Intent.ACTION_PICK);
- intent.setData(MediaStore.Video.Media.EXTERNAL_CONTENT_URI);
+ intent.setData(mExternalVideo);
assertCanBeHandled(intent);
}
@Test
public void testPickAudioDir() {
Intent intent = new Intent(Intent.ACTION_PICK);
- intent.setData(MediaStore.Audio.Media.EXTERNAL_CONTENT_URI);
+ intent.setData(mExternalAudio);
assertCanBeHandled(intent);
}
@Test
public void testViewImageDir() {
Intent intent = new Intent(Intent.ACTION_VIEW);
- intent.setData(MediaStore.Images.Media.EXTERNAL_CONTENT_URI);
+ intent.setData(mExternalImages);
assertCanBeHandled(intent);
}
@Test
public void testViewVideoDir() {
Intent intent = new Intent(Intent.ACTION_VIEW);
- intent.setData(MediaStore.Video.Media.EXTERNAL_CONTENT_URI);
+ intent.setData(mExternalVideo);
assertCanBeHandled(intent);
}
diff --git a/tests/tests/provider/src/android/provider/cts/MediaStorePendingTest.java b/tests/tests/provider/src/android/provider/cts/MediaStorePendingTest.java
index 40ce7a8..2d15765 100644
--- a/tests/tests/provider/src/android/provider/cts/MediaStorePendingTest.java
+++ b/tests/tests/provider/src/android/provider/cts/MediaStorePendingTest.java
@@ -16,6 +16,10 @@
package android.provider.cts;
+import static android.provider.cts.MediaStoreTest.TAG;
+import static android.provider.cts.ProviderTestUtils.containsId;
+import static android.provider.cts.ProviderTestUtils.hash;
+
import static org.junit.Assert.assertArrayEquals;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
@@ -33,47 +37,54 @@
import android.provider.MediaStore.MediaColumns;
import android.provider.MediaStore.PendingParams;
import android.support.test.InstrumentationRegistry;
-import android.support.test.runner.AndroidJUnit4;
-
-import libcore.io.IoUtils;
+import android.util.Log;
import com.google.common.base.Objects;
-import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
+import org.junit.runners.Parameterized;
+import org.junit.runners.Parameterized.Parameter;
+import org.junit.runners.Parameterized.Parameters;
import java.io.File;
import java.io.FileNotFoundException;
-import java.io.FileOutputStream;
import java.io.InputStream;
import java.io.OutputStream;
-import java.security.DigestInputStream;
-import java.security.MessageDigest;
import java.util.Arrays;
import java.util.HashSet;
import java.util.Set;
import java.util.regex.Pattern;
-@RunWith(AndroidJUnit4.class)
+@RunWith(Parameterized.class)
public class MediaStorePendingTest {
private Context mContext;
private ContentResolver mResolver;
- private Uri mExternalAudio = MediaStore.Audio.Media.EXTERNAL_CONTENT_URI;
- private Uri mExternalVideo = MediaStore.Video.Media.EXTERNAL_CONTENT_URI;
- private Uri mExternalImages = MediaStore.Images.Media.EXTERNAL_CONTENT_URI;
- private Uri mExternalDownloads = MediaStore.Downloads.EXTERNAL_CONTENT_URI;
+ private Uri mExternalAudio;
+ private Uri mExternalVideo;
+ private Uri mExternalImages;
+ private Uri mExternalDownloads;
+
+ @Parameter(0)
+ public String mVolumeName;
+
+ @Parameters
+ public static Iterable<? extends Object> data() {
+ return ProviderTestUtils.getSharedVolumeNames();
+ }
@Before
public void setUp() throws Exception {
mContext = InstrumentationRegistry.getTargetContext();
mResolver = mContext.getContentResolver();
- }
- @After
- public void tearDown() throws Exception {
+ Log.d(TAG, "Using volume " + mVolumeName);
+ mExternalAudio = MediaStore.Audio.Media.getContentUri(mVolumeName);
+ mExternalVideo = MediaStore.Video.Media.getContentUri(mVolumeName);
+ mExternalImages = MediaStore.Images.Media.getContentUri(mVolumeName);
+ mExternalDownloads = MediaStore.Downloads.getContentUri(mVolumeName);
}
@Test
@@ -107,15 +118,12 @@
// Write an image into place
final Uri publishUri;
- final MediaStore.PendingSession session = MediaStore.openPending(mContext, pendingUri);
- try {
+ try (MediaStore.PendingSession session = MediaStore.openPending(mContext, pendingUri)) {
try (InputStream in = mContext.getResources().openRawResource(R.raw.scenery);
OutputStream out = session.openOutputStream()) {
FileUtils.copy(in, out);
}
publishUri = session.publish();
- } finally {
- IoUtils.closeQuietly(session);
}
// Verify pending status across various queries
@@ -149,8 +157,7 @@
final Uri pendingUri = MediaStore.createPending(mContext, params);
final File pendingFile;
- final MediaStore.PendingSession session = MediaStore.openPending(mContext, pendingUri);
- try {
+ try (MediaStore.PendingSession session = MediaStore.openPending(mContext, pendingUri)) {
try (InputStream in = mContext.getResources().openRawResource(R.raw.scenery);
OutputStream out = session.openOutputStream()) {
FileUtils.copy(in, out);
@@ -161,8 +168,6 @@
getRawFileHash(pendingFile);
session.abandon();
- } finally {
- IoUtils.closeQuietly(session);
}
// Should have no record of abandoned item
@@ -412,28 +417,15 @@
private Uri execPending(PendingParams params, int resId) throws Exception {
final Uri pendingUri = MediaStore.createPending(mContext, params);
- final MediaStore.PendingSession session = MediaStore.openPending(mContext, pendingUri);
- try {
+ try (MediaStore.PendingSession session = MediaStore.openPending(mContext, pendingUri)) {
try (InputStream in = mContext.getResources().openRawResource(resId);
OutputStream out = session.openOutputStream()) {
FileUtils.copy(in, out);
}
return session.publish();
- } finally {
- IoUtils.closeQuietly(session);
}
}
- private boolean containsId(Uri uri, long id) {
- try (Cursor c = mResolver.query(uri,
- new String[] { MediaColumns._ID }, null, null)) {
- while (c.moveToNext()) {
- if (c.getLong(0) == id) return true;
- }
- }
- return false;
- }
-
private static File getRawFile(Uri uri) throws Exception {
final String res = ProviderTestUtils.executeShellCommand(
"content query --uri " + uri + " --projection _data",
@@ -456,15 +448,4 @@
throw new FileNotFoundException("Failed to find hash for " + file + "; found " + res);
}
}
-
- private static byte[] hash(InputStream in) throws Exception {
- try (DigestInputStream digestIn = new DigestInputStream(in,
- MessageDigest.getInstance("SHA-1"));
- OutputStream out = new FileOutputStream(new File("/dev/null"))) {
- FileUtils.copy(digestIn, out);
- return digestIn.getMessageDigest().digest();
- } finally {
- IoUtils.closeQuietly(in);
- }
- }
}
diff --git a/tests/tests/provider/src/android/provider/cts/MediaStoreTest.java b/tests/tests/provider/src/android/provider/cts/MediaStoreTest.java
index ffb3afb..6104f61 100644
--- a/tests/tests/provider/src/android/provider/cts/MediaStoreTest.java
+++ b/tests/tests/provider/src/android/provider/cts/MediaStoreTest.java
@@ -19,26 +19,22 @@
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotEquals;
-import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;
import android.app.usage.StorageStatsManager;
import android.content.ContentResolver;
import android.content.ContentUris;
-import android.content.ContentValues;
import android.content.Context;
import android.content.res.AssetFileDescriptor;
import android.database.Cursor;
-import android.media.MediaScanner;
import android.net.Uri;
-import android.os.Environment;
import android.os.SystemClock;
import android.os.storage.StorageManager;
import android.provider.MediaStore;
import android.provider.MediaStore.MediaColumns;
import android.support.test.InstrumentationRegistry;
-import android.support.test.runner.AndroidJUnit4;
+import android.util.Log;
import libcore.util.HexEncoding;
@@ -47,6 +43,9 @@
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
+import org.junit.runners.Parameterized;
+import org.junit.runners.Parameterized.Parameter;
+import org.junit.runners.Parameterized.Parameters;
import java.io.File;
import java.io.OutputStream;
@@ -55,76 +54,51 @@
import java.util.Set;
import java.util.UUID;
-@RunWith(AndroidJUnit4.class)
+@RunWith(Parameterized.class)
public class MediaStoreTest {
- private static final String TEST_VOLUME_NAME = "volume_for_cts";
+ static final String TAG = "MediaStoreTest";
private static final long SIZE_DELTA = 32_000;
- private static final String[] PROJECTION = new String[] { MediaStore.MEDIA_SCANNER_VOLUME };
-
- private Uri mScannerUri;
-
- private String mVolumnBackup;
-
+ private Context mContext;
private ContentResolver mContentResolver;
+ private Uri mExternalImages;
+
+ @Parameter(0)
+ public String mVolumeName;
+
+ @Parameters
+ public static Iterable<? extends Object> data() {
+ return ProviderTestUtils.getSharedVolumeNames();
+ }
+
private Context getContext() {
return InstrumentationRegistry.getTargetContext();
}
@Before
public void setUp() throws Exception {
- mScannerUri = MediaStore.getMediaScannerUri();
- mContentResolver = getContext().getContentResolver();
+ mContext = InstrumentationRegistry.getTargetContext();
+ mContentResolver = mContext.getContentResolver();
- Cursor c = mContentResolver.query(mScannerUri, PROJECTION, null, null, null);
- if (c != null) {
- c.moveToFirst();
- mVolumnBackup = c.getString(0);
- c.close();
- }
+ Log.d(TAG, "Using volume " + mVolumeName);
+ mExternalImages = MediaStore.Images.Media.getContentUri(mVolumeName);
}
@After
public void tearDown() throws Exception {
InstrumentationRegistry.getInstrumentation().getUiAutomation()
.dropShellPermissionIdentity();
-
- // restore initial values
- if (mVolumnBackup != null) {
- ContentValues values = new ContentValues();
- values.put(MediaStore.MEDIA_SCANNER_VOLUME, mVolumnBackup);
- mContentResolver.insert(mScannerUri, values);
- }
}
@Test
public void testGetMediaScannerUri() {
- ContentValues values = new ContentValues();
- String selection = MediaStore.MEDIA_SCANNER_VOLUME + "=?";
- String[] selectionArgs = new String[] { TEST_VOLUME_NAME };
-
- // assert there is no item with name TEST_VOLUME_NAME
- assertNull(mContentResolver.query(mScannerUri, PROJECTION,
- selection, selectionArgs, null));
-
- // insert
- values.put(MediaStore.MEDIA_SCANNER_VOLUME, TEST_VOLUME_NAME);
- assertEquals(MediaStore.getMediaScannerUri(),
- mContentResolver.insert(mScannerUri, values));
-
// query
- Cursor c = mContentResolver.query(mScannerUri, PROJECTION,
- selection, selectionArgs, null);
+ Cursor c = mContentResolver.query(MediaStore.getMediaScannerUri(), null,
+ null, null, null);
assertEquals(1, c.getCount());
- c.moveToFirst();
- assertEquals(TEST_VOLUME_NAME, c.getString(0));
c.close();
-
- // delete
- assertEquals(1, mContentResolver.delete(mScannerUri, null, null));
- assertNull(mContentResolver.query(mScannerUri, PROJECTION, null, null, null));
}
@Test
@@ -138,19 +112,28 @@
Set<String> volumeNames = MediaStore.getAllVolumeNames(getContext());
// At very least should contain these two volumes
- assertTrue(volumeNames.contains("internal"));
- assertTrue(volumeNames.contains("external"));
+ assertTrue(volumeNames.contains(MediaStore.VOLUME_INTERNAL));
+ assertTrue(volumeNames.contains(MediaStore.VOLUME_EXTERNAL));
}
@Test
public void testContributedMedia() throws Exception {
// STOPSHIP: remove this once isolated storage is always enabled
Assume.assumeTrue(StorageManager.hasIsolatedStorage());
+ Assume.assumeTrue(MediaStore.VOLUME_EXTERNAL.equals(mVolumeName));
InstrumentationRegistry.getInstrumentation().getUiAutomation().adoptShellPermissionIdentity(
android.Manifest.permission.CLEAR_APP_USER_DATA,
android.Manifest.permission.PACKAGE_USAGE_STATS);
+ // Start by cleaning up contributed items
+ MediaStore.deleteContributedMedia(getContext(), getContext().getPackageName(),
+ android.os.Process.myUserHandle());
+
+ // Force sync to try updating other views
+ ProviderTestUtils.executeShellCommand("sync");
+ SystemClock.sleep(500);
+
// Measure usage before
final long beforePackage = getExternalPackageSize();
final long beforeTotal = getExternalTotalSize();
@@ -166,22 +149,21 @@
// Create media both inside and outside sandbox
final Uri inside;
final Uri outside;
- final File file = new File(getContext().getExternalMediaDirs()[0],
- "cts" + System.nanoTime());
+ final File file = new File(ProviderTestUtils.stageDir(mVolumeName),
+ "cts" + System.nanoTime() + ".jpg");
ProviderTestUtils.stageFile(R.raw.volantis, file);
- try (MediaScanner scanner = new MediaScanner(getContext(), "external")) {
- inside = scanner.scanSingleFile(file.getAbsolutePath(), "image/jpeg");
- }
- outside = ProviderTestUtils.stageMedia(R.raw.volantis,
- MediaStore.Images.Media.EXTERNAL_CONTENT_URI);
- SystemClock.sleep(500);
+ inside = ProviderTestUtils.scanFile(file);
+ outside = ProviderTestUtils.stageMedia(R.raw.volantis, mExternalImages);
{
- final HashSet<Long> visible = getVisibleIds(
- MediaStore.Images.Media.EXTERNAL_CONTENT_URI);
+ final HashSet<Long> visible = getVisibleIds(mExternalImages);
assertTrue(visible.contains(ContentUris.parseId(inside)));
assertTrue(visible.contains(ContentUris.parseId(outside)));
+ // Force sync to try updating other views
+ ProviderTestUtils.executeShellCommand("sync");
+ SystemClock.sleep(500);
+
final long afterPackage = getExternalPackageSize();
final long afterTotal = getExternalTotalSize();
final long afterContributed = MediaStore.getContributedMediaSize(getContext(),
@@ -195,13 +177,15 @@
// Delete only contributed items
MediaStore.deleteContributedMedia(getContext(), getContext().getPackageName(),
android.os.Process.myUserHandle());
- SystemClock.sleep(500);
{
- final HashSet<Long> visible = getVisibleIds(
- MediaStore.Images.Media.EXTERNAL_CONTENT_URI);
+ final HashSet<Long> visible = getVisibleIds(mExternalImages);
assertTrue(visible.contains(ContentUris.parseId(inside)));
assertFalse(visible.contains(ContentUris.parseId(outside)));
+ // Force sync to try updating other views
+ ProviderTestUtils.executeShellCommand("sync");
+ SystemClock.sleep(500);
+
final long afterPackage = getExternalPackageSize();
final long afterTotal = getExternalTotalSize();
final long afterContributed = MediaStore.getContributedMediaSize(getContext(),
@@ -217,8 +201,7 @@
public void testHash() throws Exception {
final ContentResolver resolver = getContext().getContentResolver();
- final Uri uri = ProviderTestUtils.stageMedia(R.raw.volantis,
- MediaStore.Images.Media.EXTERNAL_CONTENT_URI);
+ final Uri uri = ProviderTestUtils.stageMedia(R.raw.volantis, mExternalImages);
SystemClock.sleep(500);
final String expected = Arrays
@@ -246,7 +229,7 @@
final StorageManager storage = getContext().getSystemService(StorageManager.class);
final StorageStatsManager stats = getContext().getSystemService(StorageStatsManager.class);
- final UUID externalUuid = storage.getUuidForPath(Environment.getExternalStorageDirectory());
+ final UUID externalUuid = storage.getUuidForPath(MediaStore.getVolumePath(mVolumeName));
return stats.queryStatsForPackage(externalUuid, getContext().getPackageName(),
android.os.Process.myUserHandle()).getDataBytes();
}
@@ -255,7 +238,7 @@
final StorageManager storage = getContext().getSystemService(StorageManager.class);
final StorageStatsManager stats = getContext().getSystemService(StorageStatsManager.class);
- final UUID externalUuid = storage.getUuidForPath(Environment.getExternalStorageDirectory());
+ final UUID externalUuid = storage.getUuidForPath(MediaStore.getVolumePath(mVolumeName));
return stats.queryExternalStatsForUser(externalUuid, android.os.Process.myUserHandle())
.getTotalBytes();
}
diff --git a/tests/tests/provider/src/android/provider/cts/MediaStoreTrashTest.java b/tests/tests/provider/src/android/provider/cts/MediaStoreTrashTest.java
index 24a0c53..97cd1ff 100644
--- a/tests/tests/provider/src/android/provider/cts/MediaStoreTrashTest.java
+++ b/tests/tests/provider/src/android/provider/cts/MediaStoreTrashTest.java
@@ -16,6 +16,8 @@
package android.provider.cts;
+import static android.provider.cts.MediaStoreTest.TAG;
+
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;
@@ -30,30 +32,43 @@
import android.provider.MediaStore;
import android.provider.MediaStore.MediaColumns;
import android.support.test.InstrumentationRegistry;
-import android.support.test.runner.AndroidJUnit4;
import android.text.format.DateUtils;
import android.util.Log;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
+import org.junit.runners.Parameterized;
+import org.junit.runners.Parameterized.Parameter;
+import org.junit.runners.Parameterized.Parameters;
-@RunWith(AndroidJUnit4.class)
+@RunWith(Parameterized.class)
public class MediaStoreTrashTest {
- private static final String TAG = "MediaStoreTrashTest";
-
private Context mContext;
private ContentResolver mResolver;
+ private Uri mExternalImages;
+
+ @Parameter(0)
+ public String mVolumeName;
+
+ @Parameters
+ public static Iterable<? extends Object> data() {
+ return ProviderTestUtils.getSharedVolumeNames();
+ }
+
@Before
public void setUp() throws Exception {
mContext = InstrumentationRegistry.getTargetContext();
mResolver = mContext.getContentResolver();
+
+ Log.d(TAG, "Using volume " + mVolumeName);
+ mExternalImages = MediaStore.Images.Media.getContentUri(mVolumeName);
}
@Test
public void testTrashUntrash() throws Exception {
- final Uri insertUri = MediaStore.Images.Media.EXTERNAL_CONTENT_URI;
+ final Uri insertUri = mExternalImages;
final Uri uri = ProviderTestUtils.stageMedia(R.raw.volantis, insertUri);
final long id = ContentUris.parseId(uri);
@@ -93,7 +108,7 @@
@Test
public void testTrashExecutes() throws Exception {
- final Uri insertUri = MediaStore.Images.Media.EXTERNAL_CONTENT_URI;
+ final Uri insertUri = mExternalImages;
final Uri uri = ProviderTestUtils.stageMedia(R.raw.volantis, insertUri);
MediaStore.trash(mContext, uri, 1);
diff --git a/tests/tests/provider/src/android/provider/cts/MediaStore_Audio_AlbumsTest.java b/tests/tests/provider/src/android/provider/cts/MediaStore_Audio_AlbumsTest.java
index 609604f..079fec4 100644
--- a/tests/tests/provider/src/android/provider/cts/MediaStore_Audio_AlbumsTest.java
+++ b/tests/tests/provider/src/android/provider/cts/MediaStore_Audio_AlbumsTest.java
@@ -16,6 +16,8 @@
package android.provider.cts;
+import static android.provider.cts.MediaStoreTest.TAG;
+
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNull;
@@ -23,68 +25,65 @@
import static org.junit.Assert.fail;
import android.content.ContentResolver;
+import android.content.ContentUris;
import android.content.ContentValues;
import android.content.Context;
-import android.content.res.AssetFileDescriptor;
import android.database.Cursor;
+import android.graphics.BitmapFactory;
import android.net.Uri;
-import android.os.Environment;
import android.provider.MediaStore;
import android.provider.MediaStore.Audio.Albums;
import android.provider.MediaStore.Audio.Media;
import android.provider.cts.MediaStoreAudioTestHelper.Audio1;
import android.provider.cts.MediaStoreAudioTestHelper.Audio2;
import android.support.test.InstrumentationRegistry;
-import android.support.test.runner.AndroidJUnit4;
+import android.util.Log;
+import android.util.Size;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
+import org.junit.runners.Parameterized;
+import org.junit.runners.Parameterized.Parameter;
+import org.junit.runners.Parameterized.Parameters;
import java.io.File;
-import java.io.FileNotFoundException;
+import java.io.IOException;
-@RunWith(AndroidJUnit4.class)
+@RunWith(Parameterized.class)
public class MediaStore_Audio_AlbumsTest {
private Context mContext;
private ContentResolver mContentResolver;
+ @Parameter(0)
+ public String mVolumeName;
+
+ @Parameters
+ public static Iterable<? extends Object> data() {
+ return ProviderTestUtils.getSharedVolumeNames();
+ }
+
@Before
public void setUp() throws Exception {
mContext = InstrumentationRegistry.getTargetContext();
mContentResolver = mContext.getContentResolver();
+
+ Log.d(TAG, "Using volume " + mVolumeName);
}
@Test
public void testGetContentUri() {
Cursor c = null;
assertNotNull(c = mContentResolver.query(
- Albums.getContentUri(MediaStoreAudioTestHelper.INTERNAL_VOLUME_NAME), null, null,
+ Albums.getContentUri(mVolumeName), null, null,
null, null));
c.close();
- assertNotNull(c = mContentResolver.query(
- Albums.getContentUri(MediaStoreAudioTestHelper.EXTERNAL_VOLUME_NAME), null, null,
- null, null));
- c.close();
-
- // can not accept any other volume names
- String volume = "fakeVolume";
- assertNull(mContentResolver.query(Albums.getContentUri(volume), null, null, null, null));
}
@Test
- public void testStoreAudioAlbumsInternal() {
- doStoreAudioAlbums(true);
- }
-
- @Test
- public void testStoreAudioAlbumsExternal() {
- doStoreAudioAlbums(false);
- }
-
- private void doStoreAudioAlbums(boolean isInternal) {
+ public void testStoreAudioAlbums() {
// do not support direct insert operation of the albums
- Uri audioAlbumsUri = isInternal? Albums.INTERNAL_CONTENT_URI : Albums.EXTERNAL_CONTENT_URI;
+ Uri audioAlbumsUri = Albums.getContentUri(mVolumeName);
try {
mContentResolver.insert(audioAlbumsUri, new ContentValues());
fail("Should throw UnsupportedOperationException!");
@@ -94,8 +93,7 @@
// the album item is inserted when inserting audio media
Audio1 audio1 = Audio1.getInstance();
- Uri audioMediaUri = isInternal ? audio1.insertToInternal(mContentResolver)
- : audio1.insertToExternal(mContentResolver);
+ Uri audioMediaUri = audio1.insert(mContentResolver, mVolumeName);
String selection = Albums.ALBUM +"=?";
String[] selectionArgs = new String[] { Audio1.ALBUM };
@@ -174,57 +172,61 @@
}
@Test
- public void testAlbumArt() {
- File path = new File(Environment.getExternalStorageDirectory()
- + "/test" + System.currentTimeMillis() + ".mp3");
- Uri uri = null;
+ public void testAlbumArt() throws Exception {
+ final File dir = ProviderTestUtils.stageDir(mVolumeName);
+ final File path = new File(dir, "test" + System.currentTimeMillis() + ".mp3");
try {
- File dir = path.getParentFile();
- dir.mkdirs();
ProviderTestUtils.stageFile(R.raw.testmp3, path);
ContentValues v = new ContentValues();
v.put(Media.DATA, path.getAbsolutePath());
v.put(Media.TITLE, "testing");
v.put(Albums.ALBUM, "test" + System.currentTimeMillis());
- uri = mContentResolver.insert(MediaStore.Audio.Media.EXTERNAL_CONTENT_URI, v);
- AssetFileDescriptor afd = mContentResolver.openAssetFileDescriptor(
- uri.buildUpon().appendPath("albumart").build(), "r");
- assertNotNull(afd);
- afd.close();
- Cursor c = mContentResolver.query(uri, null, null, null, null);
- c.moveToFirst();
- long aid = c.getLong(c.getColumnIndex(Albums.ALBUM_ID));
- c.close();
+ final Uri mediaUri = mContentResolver
+ .insert(MediaStore.Audio.Media.getContentUri(mVolumeName), v);
+ final long mediaId = ContentUris.parseId(mediaUri);
- Uri albumart = Uri.parse("content://media/external/audio/albumart/" + aid);
- try {
- mContentResolver.delete(albumart, null, null);
- afd = mContentResolver.openAssetFileDescriptor(albumart, "r");
- } catch (FileNotFoundException e) {
- fail("no album art");
+ final long albumId;
+ try (Cursor c = mContentResolver.query(mediaUri, null, null, null, null)) {
+ assertTrue(c.moveToFirst());
+ albumId = c.getLong(c.getColumnIndex(Albums.ALBUM_ID));
}
- c = mContentResolver.query(albumart, null, null, null, null);
- c.moveToFirst();
- String albumartfile = c.getString(c.getColumnIndex("_data"));
- c.close();
- new File(albumartfile).delete();
+ // Verify that normal thumbnails work
+ assertNotNull(mContentResolver.loadThumbnail(mediaUri, new Size(32, 32), null));
+
+ // Verify that hidden APIs still work to obtain album art
+ final Uri byMedia = MediaStore.AUTHORITY_URI.buildUpon().appendPath(mVolumeName)
+ .appendPath("audio").appendPath("media")
+ .appendPath(Long.toString(mediaId)).appendPath("albumart").build();
+ final Uri byAlbum = MediaStore.AUTHORITY_URI.buildUpon().appendPath(mVolumeName)
+ .appendPath("audio").appendPath("albumart")
+ .appendPath(Long.toString(albumId)).build();
+ assertNotNull(BitmapFactory.decodeStream(mContentResolver.openInputStream(byMedia)));
+ assertNotNull(BitmapFactory.decodeStream(mContentResolver.openInputStream(byAlbum)));
+
+ // Delete item and confirm art is cleaned up
+ mContentResolver.delete(mediaUri, null, null);
+
try {
- afd = mContentResolver.openAssetFileDescriptor(albumart, "r");
- } catch (FileNotFoundException e) {
- fail("no album art");
+ mContentResolver.loadThumbnail(mediaUri, new Size(32, 32), null);
+ fail();
+ } catch (IOException expected) {
+ }
+ try {
+ BitmapFactory.decodeStream(mContentResolver.openInputStream(byMedia));
+ fail();
+ } catch (IOException expected) {
+ }
+ try {
+ BitmapFactory.decodeStream(mContentResolver.openInputStream(byAlbum));
+ fail();
+ } catch (IOException expected) {
}
- } catch (Exception e) {
- fail("album art failed " + e);
} finally {
path.delete();
- if (uri != null) {
- mContentResolver.delete(uri, null, null);
- }
}
}
-
}
diff --git a/tests/tests/provider/src/android/provider/cts/MediaStore_Audio_ArtistsTest.java b/tests/tests/provider/src/android/provider/cts/MediaStore_Audio_ArtistsTest.java
index 9f923e5..60950d1 100644
--- a/tests/tests/provider/src/android/provider/cts/MediaStore_Audio_ArtistsTest.java
+++ b/tests/tests/provider/src/android/provider/cts/MediaStore_Audio_ArtistsTest.java
@@ -16,6 +16,8 @@
package android.provider.cts;
+import static android.provider.cts.MediaStoreTest.TAG;
+
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNull;
@@ -31,52 +33,48 @@
import android.provider.cts.MediaStoreAudioTestHelper.Audio1;
import android.provider.cts.MediaStoreAudioTestHelper.Audio2;
import android.support.test.InstrumentationRegistry;
-import android.support.test.runner.AndroidJUnit4;
+import android.util.Log;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
+import org.junit.runners.Parameterized;
+import org.junit.runners.Parameterized.Parameter;
+import org.junit.runners.Parameterized.Parameters;
-@RunWith(AndroidJUnit4.class)
+@RunWith(Parameterized.class)
public class MediaStore_Audio_ArtistsTest {
private Context mContext;
private ContentResolver mContentResolver;
+ @Parameter(0)
+ public String mVolumeName;
+
+ @Parameters
+ public static Iterable<? extends Object> data() {
+ return ProviderTestUtils.getSharedVolumeNames();
+ }
+
@Before
public void setUp() throws Exception {
mContext = InstrumentationRegistry.getTargetContext();
mContentResolver = mContext.getContentResolver();
+
+ Log.d(TAG, "Using volume " + mVolumeName);
}
@Test
public void testGetContentUri() {
Cursor c = null;
assertNotNull(c = mContentResolver.query(
- Artists.getContentUri(MediaStoreAudioTestHelper.INTERNAL_VOLUME_NAME), null, null,
- null, null));
- c.close();
- assertNotNull(c = mContentResolver.query(
- Artists.getContentUri(MediaStoreAudioTestHelper.INTERNAL_VOLUME_NAME), null, null,
+ Artists.getContentUri(mVolumeName), null, null,
null, null));
c.close();
-
- // can not accept any other volume names
- String volume = "fakeVolume";
- assertNull(mContentResolver.query(Artists.getContentUri(volume), null, null, null, null));
}
@Test
- public void testStoreAudioArtistsInternal() {
- doStoreAudioArtists(true);
- }
-
- @Test
- public void testStoreAudioArtistsExternal() {
- doStoreAudioArtists(false);
- }
-
- private void doStoreAudioArtists(boolean isInternal) {
- Uri artistsUri = isInternal ? Artists.INTERNAL_CONTENT_URI : Artists.EXTERNAL_CONTENT_URI;
+ public void testStoreAudioArtists() {
+ Uri artistsUri = Artists.getContentUri(mVolumeName);
// do not support insert operation of the artists
try {
mContentResolver.insert(artistsUri, new ContentValues());
@@ -85,8 +83,7 @@
// expected
}
// the artist items are inserted when inserting audio media
- Uri uri = isInternal ? Audio1.getInstance().insertToInternal(mContentResolver)
- : Audio1.getInstance().insertToExternal(mContentResolver);
+ Uri uri = Audio1.getInstance().insert(mContentResolver, mVolumeName);
String selection = Artists.ARTIST + "=?";
String[] selectionArgs = new String[] { Audio1.ARTIST };
diff --git a/tests/tests/provider/src/android/provider/cts/MediaStore_Audio_Artists_AlbumsTest.java b/tests/tests/provider/src/android/provider/cts/MediaStore_Audio_Artists_AlbumsTest.java
index 3b5282d..bba1e1a 100644
--- a/tests/tests/provider/src/android/provider/cts/MediaStore_Audio_Artists_AlbumsTest.java
+++ b/tests/tests/provider/src/android/provider/cts/MediaStore_Audio_Artists_AlbumsTest.java
@@ -16,6 +16,8 @@
package android.provider.cts;
+import static android.provider.cts.MediaStoreTest.TAG;
+
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNull;
@@ -32,65 +34,55 @@
import android.provider.cts.MediaStoreAudioTestHelper.Audio1;
import android.provider.cts.MediaStoreAudioTestHelper.Audio2;
import android.support.test.InstrumentationRegistry;
-import android.support.test.runner.AndroidJUnit4;
+import android.util.Log;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
+import org.junit.runners.Parameterized;
+import org.junit.runners.Parameterized.Parameter;
+import org.junit.runners.Parameterized.Parameters;
-@RunWith(AndroidJUnit4.class)
+@RunWith(Parameterized.class)
public class MediaStore_Audio_Artists_AlbumsTest {
private Context mContext;
private ContentResolver mContentResolver;
+ @Parameter(0)
+ public String mVolumeName;
+
+ @Parameters
+ public static Iterable<? extends Object> data() {
+ return ProviderTestUtils.getSharedVolumeNames();
+ }
+
@Before
public void setUp() throws Exception {
mContext = InstrumentationRegistry.getTargetContext();
mContentResolver = mContext.getContentResolver();
+
+ Log.d(TAG, "Using volume " + mVolumeName);
}
@Test
public void testGetContentUri() {
Cursor c = null;
- Uri contentUri = MediaStore.Audio.Artists.Albums.getContentUri(
- MediaStoreAudioTestHelper.INTERNAL_VOLUME_NAME, 1);
+ Uri contentUri = MediaStore.Audio.Artists.Albums.getContentUri(mVolumeName, 1);
assertNotNull(c = mContentResolver.query(contentUri, null, null, null, null));
c.close();
-
- contentUri = MediaStore.Audio.Artists.Albums.getContentUri(
- MediaStoreAudioTestHelper.EXTERNAL_VOLUME_NAME, 1);
- assertNotNull(c = mContentResolver.query(contentUri, null, null, null, null));
- c.close();
-
- // can not accept any other volume names
- String volume = "fakeVolume";
- assertNull(mContentResolver.query(MediaStore.Audio.Artists.Albums.getContentUri(volume, 1),
- null, null, null, null));
}
@Test
- public void testStoreAudioArtistsAlbumsInternal() {
- doStoreAudioArtistsAlbums(true);
- }
-
- @Test
- public void testStoreAudioArtistsAlbumsExternal() {
- doStoreAudioArtistsAlbums(false);
- }
-
- private void doStoreAudioArtistsAlbums(boolean isInternal) {
+ public void testStoreAudioArtistsAlbums() {
// the album item is inserted when inserting audio media
- Uri audioMediaUri = isInternal ? Audio1.getInstance().insertToInternal(mContentResolver)
- : Audio1.getInstance().insertToExternal(mContentResolver);
+ Uri audioMediaUri = Audio1.getInstance().insert(mContentResolver, mVolumeName);
// get artist id
Cursor c = mContentResolver.query(audioMediaUri, new String[] { Media.ARTIST_ID }, null,
null, null);
c.moveToFirst();
Long artistId = c.getLong(c.getColumnIndex(Media.ARTIST_ID));
c.close();
- Uri artistsAlbumsUri = MediaStore.Audio.Artists.Albums.getContentUri(isInternal ?
- MediaStoreAudioTestHelper.INTERNAL_VOLUME_NAME :
- MediaStoreAudioTestHelper.EXTERNAL_VOLUME_NAME, artistId);
+ Uri artistsAlbumsUri = MediaStore.Audio.Artists.Albums.getContentUri(mVolumeName, artistId);
// do not support insert operation of the albums
try {
mContentResolver.insert(artistsAlbumsUri, new ContentValues());
diff --git a/tests/tests/provider/src/android/provider/cts/MediaStore_Audio_GenresTest.java b/tests/tests/provider/src/android/provider/cts/MediaStore_Audio_GenresTest.java
index 07d4912..c675059 100644
--- a/tests/tests/provider/src/android/provider/cts/MediaStore_Audio_GenresTest.java
+++ b/tests/tests/provider/src/android/provider/cts/MediaStore_Audio_GenresTest.java
@@ -16,6 +16,8 @@
package android.provider.cts;
+import static android.provider.cts.MediaStoreTest.TAG;
+
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotNull;
@@ -32,31 +34,43 @@
import android.net.Uri;
import android.provider.MediaStore.Audio.Genres;
import android.provider.MediaStore.Audio.Genres.Members;
-import android.provider.MediaStore.Audio.Media;
import android.provider.cts.MediaStoreAudioTestHelper.Audio1;
import android.support.test.InstrumentationRegistry;
-import android.support.test.runner.AndroidJUnit4;
+import android.util.Log;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
+import org.junit.runners.Parameterized;
+import org.junit.runners.Parameterized.Parameter;
+import org.junit.runners.Parameterized.Parameters;
-@RunWith(AndroidJUnit4.class)
+@RunWith(Parameterized.class)
public class MediaStore_Audio_GenresTest {
private Context mContext;
private ContentResolver mContentResolver;
+ @Parameter(0)
+ public String mVolumeName;
+
+ @Parameters
+ public static Iterable<? extends Object> data() {
+ return ProviderTestUtils.getSharedVolumeNames();
+ }
+
@Before
public void setUp() throws Exception {
mContext = InstrumentationRegistry.getTargetContext();
mContentResolver = mContext.getContentResolver();
+
+ Log.d(TAG, "Using volume " + mVolumeName);
}
@Test
public void testGetContentUri() {
Cursor c = null;
assertNotNull(c = mContentResolver.query(
- Genres.getContentUri(MediaStoreAudioTestHelper.EXTERNAL_VOLUME_NAME), null, null,
+ Genres.getContentUri(mVolumeName), null, null,
null, null));
c.close();
try {
@@ -68,10 +82,6 @@
} catch (SQLException e) {
// expected
}
-
- // can not accept any other volume names
- String volume = "fakeVolume";
- assertNull(mContentResolver.query(Genres.getContentUri(volume), null, null, null, null));
}
@Test
@@ -79,7 +89,7 @@
// insert
ContentValues values = new ContentValues();
values.put(Genres.NAME, "POP");
- Uri uri = mContentResolver.insert(Genres.EXTERNAL_CONTENT_URI, values);
+ Uri uri = mContentResolver.insert(Genres.getContentUri(mVolumeName), values);
assertNotNull(uri);
try {
@@ -107,33 +117,30 @@
@Test
public void testGetContentUriForAudioId() {
// Insert an audio file into the content provider.
- ContentValues values = Audio1.getInstance().getContentValues(true);
- Uri audioUri = mContentResolver.insert(Media.EXTERNAL_CONTENT_URI, values);
+ Uri audioUri = Audio1.getInstance().insert(mContentResolver, mVolumeName);
assertNotNull(audioUri);
long audioId = ContentUris.parseId(audioUri);
assertTrue(audioId != -1);
// Insert a genre into the content provider.
- values.clear();
+ ContentValues values = new ContentValues();
values.put(Genres.NAME, "Soda Pop");
- Uri genreUri = mContentResolver.insert(Genres.EXTERNAL_CONTENT_URI, values);
+ Uri genreUri = mContentResolver.insert(Genres.getContentUri(mVolumeName), values);
assertNotNull(genreUri);
long genreId = ContentUris.parseId(genreUri);
assertTrue(genreId != -1);
Cursor cursor = null;
try {
- String volumeName = MediaStoreAudioTestHelper.EXTERNAL_VOLUME_NAME;
-
// Check that the audio file has no genres yet.
- Uri audioGenresUri = Genres.getContentUriForAudioId(volumeName, (int) audioId);
+ Uri audioGenresUri = Genres.getContentUriForAudioId(mVolumeName, (int) audioId);
cursor = mContentResolver.query(audioGenresUri, null, null, null, null);
assertFalse(cursor.moveToNext());
// Link the audio file to the genre.
values.clear();
values.put(Members.AUDIO_ID, audioId);
- Uri membersUri = Members.getContentUri(volumeName, genreId);
+ Uri membersUri = Members.getContentUri(mVolumeName, genreId);
assertNotNull(mContentResolver.insert(membersUri, values));
// Check that the audio file has the genre it was linked to.
diff --git a/tests/tests/provider/src/android/provider/cts/MediaStore_Audio_Genres_MembersTest.java b/tests/tests/provider/src/android/provider/cts/MediaStore_Audio_Genres_MembersTest.java
index 1b2c73d..9d704cb 100644
--- a/tests/tests/provider/src/android/provider/cts/MediaStore_Audio_Genres_MembersTest.java
+++ b/tests/tests/provider/src/android/provider/cts/MediaStore_Audio_Genres_MembersTest.java
@@ -16,6 +16,8 @@
package android.provider.cts;
+import static android.provider.cts.MediaStoreTest.TAG;
+
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNull;
@@ -23,26 +25,42 @@
import static org.junit.Assert.fail;
import android.content.ContentResolver;
+import android.content.ContentUris;
import android.content.ContentValues;
import android.content.Context;
import android.database.Cursor;
import android.database.SQLException;
import android.net.Uri;
+import android.provider.MediaStore;
import android.provider.MediaStore.Audio.Genres;
import android.provider.MediaStore.Audio.Genres.Members;
import android.provider.MediaStore.Audio.Media;
import android.provider.cts.MediaStoreAudioTestHelper.Audio1;
import android.provider.cts.MediaStoreAudioTestHelper.Audio2;
import android.support.test.InstrumentationRegistry;
+import android.util.Log;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.Parameterized;
+import org.junit.runners.Parameterized.Parameter;
+import org.junit.runners.Parameterized.Parameters;
+@RunWith(Parameterized.class)
public class MediaStore_Audio_Genres_MembersTest {
private Context mContext;
private ContentResolver mContentResolver;
+ @Parameter(0)
+ public String mVolumeName;
+
+ @Parameters
+ public static Iterable<? extends Object> data() {
+ return ProviderTestUtils.getSharedVolumeNames();
+ }
+
private long mAudioIdOfJam;
private long mAudioIdOfJamLive;
@@ -52,13 +70,15 @@
mContext = InstrumentationRegistry.getTargetContext();
mContentResolver = mContext.getContentResolver();
- Uri uri = Audio1.getInstance().insertToExternal(mContentResolver);
+ Log.d(TAG, "Using volume " + mVolumeName);
+
+ Uri uri = Audio1.getInstance().insert(mContentResolver, mVolumeName);
Cursor c = mContentResolver.query(uri, null, null, null, null);
c.moveToFirst();
mAudioIdOfJam = c.getLong(c.getColumnIndex(Media._ID));
c.close();
- uri = Audio2.getInstance().insertToExternal(mContentResolver);
+ uri = Audio2.getInstance().insert(mContentResolver, mVolumeName);
c = mContentResolver.query(uri, null, null, null, null);
c.moveToFirst();
mAudioIdOfJamLive = c.getLong(c.getColumnIndex(Media._ID));
@@ -69,16 +89,17 @@
public void tearDown() throws Exception {
// "jam" should already have been deleted as part of the test, but delete it again just
// in case the test failed and aborted before that.
- mContentResolver.delete(Media.EXTERNAL_CONTENT_URI, Media._ID + "=" + mAudioIdOfJam, null);
- mContentResolver.delete(Media.EXTERNAL_CONTENT_URI, Media._ID + "=" + mAudioIdOfJamLive,
- null);
+ mContentResolver.delete(Media.getContentUri(mVolumeName),
+ Media._ID + "=" + mAudioIdOfJam, null);
+ mContentResolver.delete(Media.getContentUri(mVolumeName),
+ Media._ID + "=" + mAudioIdOfJamLive, null);
}
@Test
public void testGetContentUri() {
Cursor c = null;
assertNotNull(c = mContentResolver.query(
- Members.getContentUri(MediaStoreAudioTestHelper.EXTERNAL_VOLUME_NAME, 1), null,
+ Members.getContentUri(mVolumeName, 1), null,
null, null, null));
c.close();
@@ -91,18 +112,13 @@
} catch (SQLException e) {
// expected
}
-
- // can not accept any other volume names
- String volume = "fakeVolume";
- assertNull(mContentResolver.query(Members.getContentUri(volume, 1), null, null, null,
- null));
}
@Test
public void testStoreAudioGenresMembersExternal() {
ContentValues values = new ContentValues();
values.put(Genres.NAME, Audio1.GENRE);
- Uri uri = mContentResolver.insert(Genres.EXTERNAL_CONTENT_URI, values);
+ Uri uri = mContentResolver.insert(Genres.getContentUri(mVolumeName), values);
Cursor c = mContentResolver.query(uri, null, null, null, null);
c.moveToFirst();
@@ -111,13 +127,13 @@
c.close();
// verify that the Uri has the correct format and genre value
- assertEquals(uri.toString(), "content://media/external/audio/genres/" + genreId);
+ assertEquals(ContentUris.withAppendedId(Genres.getContentUri(mVolumeName), genreId),
+ uri);
// insert audio as the member of the genre
values.clear();
values.put(Members.AUDIO_ID, mAudioIdOfJam);
- Uri membersUri = Members.getContentUri(MediaStoreAudioTestHelper.EXTERNAL_VOLUME_NAME,
- genreId);
+ Uri membersUri = Members.getContentUri(mVolumeName, genreId);
assertNotNull(mContentResolver.insert(membersUri, values));
try {
@@ -130,7 +146,9 @@
assertEquals(mAudioIdOfJam, c.getLong(c.getColumnIndex(Members.AUDIO_ID)));
assertEquals(genreId, c.getLong(c.getColumnIndex(Members.GENRE_ID)));
assertEquals(mAudioIdOfJam, c.getLong(c.getColumnIndex(Members._ID)));
- assertEquals(Audio1.EXTERNAL_DATA, c.getString(c.getColumnIndex(Members.DATA)));
+ final String expected1 = Audio1.getInstance().getContentValues(mVolumeName)
+ .getAsString(Members.DATA);
+ assertEquals(expected1, c.getString(c.getColumnIndex(Members.DATA)));
assertTrue(c.getLong(c.getColumnIndex(Members.DATE_ADDED)) > 0);
assertEquals(Audio1.DATE_MODIFIED, c.getLong(c.getColumnIndex(Members.DATE_MODIFIED)));
assertEquals(Audio1.DISPLAY_NAME, c.getString(c.getColumnIndex(Members.DISPLAY_NAME)));
@@ -138,7 +156,6 @@
assertEquals(Audio1.SIZE, c.getInt(c.getColumnIndex(Members.SIZE)));
assertEquals(Audio1.TITLE, c.getString(c.getColumnIndex(Members.TITLE)));
assertEquals(Audio1.ALBUM, c.getString(c.getColumnIndex(Members.ALBUM)));
- assertEquals(Audio1.IS_DRM, c.getInt(c.getColumnIndex(Members.IS_DRM)));
String albumKey = c.getString(c.getColumnIndex(Members.ALBUM_KEY));
assertNotNull(albumKey);
long albumId = c.getLong(c.getColumnIndex(Members.ALBUM_ID));
@@ -182,7 +199,9 @@
c.close();
// Query members across all genres
- Uri allMembersUri = Uri.parse("content://media/external/audio/genres/all/members");
+ // TODO: migrate this to using public API
+ Uri allMembersUri = MediaStore.Audio.Genres.getContentUri(mVolumeName).buildUpon()
+ .appendPath("all").appendPath("members").build();
c = mContentResolver.query(allMembersUri, null, null, null, null);
int colidx = c.getColumnIndex(Members.AUDIO_ID);
int jamcnt = 0;
@@ -208,7 +227,7 @@
// create another genre
values.clear();
values.put(Genres.NAME, Audio1.GENRE + "-2");
- uri = mContentResolver.insert(Genres.EXTERNAL_CONTENT_URI, values);
+ uri = mContentResolver.insert(Genres.getContentUri(mVolumeName), values);
c = mContentResolver.query(uri, null, null, null, null);
c.moveToFirst();
genre2Id = c.getLong(c.getColumnIndex(Genres._ID));
@@ -217,8 +236,7 @@
// insert the song into the second genre
values.clear();
values.put(Members.AUDIO_ID, mAudioIdOfJam);
- Uri members2Uri = Members.getContentUri(MediaStoreAudioTestHelper.EXTERNAL_VOLUME_NAME,
- genre2Id);
+ Uri members2Uri = Members.getContentUri(mVolumeName, genre2Id);
assertNotNull(mContentResolver.insert(members2Uri, values));
// Query members across all genres again
@@ -260,8 +278,7 @@
// insert again, then verify that deleting the audio entry cleans up its genre member
// entry as well
values.put(Members.AUDIO_ID, mAudioIdOfJam);
- membersUri = Members.getContentUri(MediaStoreAudioTestHelper.EXTERNAL_VOLUME_NAME,
- genreId);
+ membersUri = Members.getContentUri(mVolumeName, genreId);
assertNotNull(mContentResolver.insert(membersUri, values));
// Query members across all genres
c = mContentResolver.query(allMembersUri,
@@ -277,7 +294,7 @@
}
assertEquals(1, jamcnt);
c.close();
- mContentResolver.delete(Media.EXTERNAL_CONTENT_URI,
+ mContentResolver.delete(Media.getContentUri(mVolumeName),
Media._ID + "=" + mAudioIdOfJam, null);
// Query members across all genres
c = mContentResolver.query(allMembersUri,
@@ -294,9 +311,11 @@
c.close();
} finally {
// the members are deleted when deleting the genre which they belong to
- mContentResolver.delete(Genres.EXTERNAL_CONTENT_URI, Genres._ID + "=" + genreId, null);
+ mContentResolver.delete(Genres.getContentUri(mVolumeName),
+ Genres._ID + "=" + genreId, null);
if (genre2Id >= 0) {
- mContentResolver.delete(Genres.EXTERNAL_CONTENT_URI, Genres._ID + "=" + genre2Id, null);
+ mContentResolver.delete(Genres.getContentUri(mVolumeName),
+ Genres._ID + "=" + genre2Id, null);
}
c = mContentResolver.query(membersUri, null, null, null, null);
assertEquals(0, c.getCount());
diff --git a/tests/tests/provider/src/android/provider/cts/MediaStore_Audio_MediaTest.java b/tests/tests/provider/src/android/provider/cts/MediaStore_Audio_MediaTest.java
index a2b760b..22f91f3 100644
--- a/tests/tests/provider/src/android/provider/cts/MediaStore_Audio_MediaTest.java
+++ b/tests/tests/provider/src/android/provider/cts/MediaStore_Audio_MediaTest.java
@@ -16,8 +16,9 @@
package android.provider.cts;
+import static android.provider.cts.MediaStoreTest.TAG;
+
import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertTrue;
@@ -30,40 +31,44 @@
import android.os.Environment;
import android.provider.MediaStore.Audio.Media;
import android.provider.cts.MediaStoreAudioTestHelper.Audio1;
-import android.provider.cts.MediaStoreAudioTestHelper.Audio2;
import android.support.test.InstrumentationRegistry;
-import android.support.test.runner.AndroidJUnit4;
+import android.util.Log;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
+import org.junit.runners.Parameterized;
+import org.junit.runners.Parameterized.Parameter;
+import org.junit.runners.Parameterized.Parameters;
-@RunWith(AndroidJUnit4.class)
+@RunWith(Parameterized.class)
public class MediaStore_Audio_MediaTest {
private Context mContext;
private ContentResolver mContentResolver;
+ @Parameter(0)
+ public String mVolumeName;
+
+ @Parameters
+ public static Iterable<? extends Object> data() {
+ return ProviderTestUtils.getSharedVolumeNames();
+ }
+
@Before
public void setUp() throws Exception {
mContext = InstrumentationRegistry.getTargetContext();
mContentResolver = mContext.getContentResolver();
+
+ Log.d(TAG, "Using volume " + mVolumeName);
}
@Test
public void testGetContentUri() {
Cursor c = null;
assertNotNull(c = mContentResolver.query(
- Media.getContentUri(MediaStoreAudioTestHelper.INTERNAL_VOLUME_NAME), null, null,
+ Media.getContentUri(mVolumeName), null, null,
null, null));
c.close();
- assertNotNull(c = mContentResolver.query(
- Media.getContentUri(MediaStoreAudioTestHelper.EXTERNAL_VOLUME_NAME), null, null,
- null, null));
- c.close();
-
- // can not accept any other volume names
- String volume = "faveVolume";
- assertNull(mContentResolver.query(Media.getContentUri(volume), null, null, null, null));
}
@Test
@@ -81,20 +86,11 @@
}
@Test
- public void testStoreAudioMediaInternal() {
- doStoreAudioMedia(true);
- }
-
- @Test
- public void testStoreAudioMediaExternal() {
- doStoreAudioMedia(false);
- }
-
- private void doStoreAudioMedia(boolean isInternal) {
+ public void testStoreAudioMedia() {
Audio1 audio1 = Audio1.getInstance();
- ContentValues values = audio1.getContentValues(isInternal);
+ ContentValues values = audio1.getContentValues(mVolumeName);
//insert
- Uri mediaUri = isInternal ? Media.INTERNAL_CONTENT_URI : Media.EXTERNAL_CONTENT_URI;
+ Uri mediaUri = Media.getContentUri(mVolumeName);
Uri uri = mContentResolver.insert(mediaUri, values);
assertNotNull(uri);
@@ -108,11 +104,10 @@
c.moveToFirst();
long id = c.getLong(c.getColumnIndex(Media._ID));
assertTrue(id > 0);
- String expected = isInternal ? Audio1.INTERNAL_DATA : Audio1.EXTERNAL_DATA;
+ String expected = audio1.getContentValues(mVolumeName).getAsString(Media.DATA);
assertEquals(expected, c.getString(c.getColumnIndex(Media.DATA)));
assertTrue(c.getLong(c.getColumnIndex(Media.DATE_ADDED)) > 0);
assertEquals(Audio1.DATE_MODIFIED, c.getLong(c.getColumnIndex(Media.DATE_MODIFIED)));
- assertEquals(Audio1.IS_DRM, c.getInt(c.getColumnIndex(Media.IS_DRM)));
assertEquals(Audio1.DISPLAY_NAME, c.getString(c.getColumnIndex(Media.DISPLAY_NAME)));
assertEquals(Audio1.MIME_TYPE, c.getString(c.getColumnIndex(Media.MIME_TYPE)));
assertEquals(Audio1.SIZE, c.getInt(c.getColumnIndex(Media.SIZE)));
@@ -140,7 +135,7 @@
c.close();
// test filtering
- Uri baseUri = isInternal ? Media.INTERNAL_CONTENT_URI : Media.EXTERNAL_CONTENT_URI;
+ Uri baseUri = Media.getContentUri(mVolumeName);
Uri filterUri = baseUri.buildUpon()
.appendQueryParameter("filter", Audio1.ARTIST).build();
c = mContentResolver.query(filterUri, null, null, null, null);
diff --git a/tests/tests/provider/src/android/provider/cts/MediaStore_Audio_PlaylistsTest.java b/tests/tests/provider/src/android/provider/cts/MediaStore_Audio_PlaylistsTest.java
index 846cfca..a06e93c 100644
--- a/tests/tests/provider/src/android/provider/cts/MediaStore_Audio_PlaylistsTest.java
+++ b/tests/tests/provider/src/android/provider/cts/MediaStore_Audio_PlaylistsTest.java
@@ -16,6 +16,8 @@
package android.provider.cts;
+import static android.provider.cts.MediaStoreTest.TAG;
+
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNull;
@@ -28,33 +30,45 @@
import android.database.Cursor;
import android.database.SQLException;
import android.net.Uri;
-import android.os.Environment;
import android.provider.MediaStore.Audio.Playlists;
import android.support.test.InstrumentationRegistry;
-import android.support.test.runner.AndroidJUnit4;
+import android.util.Log;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
+import org.junit.runners.Parameterized;
+import org.junit.runners.Parameterized.Parameter;
+import org.junit.runners.Parameterized.Parameters;
-import java.util.regex.Pattern;
+import java.io.File;
-@RunWith(AndroidJUnit4.class)
+@RunWith(Parameterized.class)
public class MediaStore_Audio_PlaylistsTest {
private Context mContext;
private ContentResolver mContentResolver;
+ @Parameter(0)
+ public String mVolumeName;
+
+ @Parameters
+ public static Iterable<? extends Object> data() {
+ return ProviderTestUtils.getSharedVolumeNames();
+ }
+
@Before
public void setUp() throws Exception {
mContext = InstrumentationRegistry.getTargetContext();
mContentResolver = mContext.getContentResolver();
+
+ Log.d(TAG, "Using volume " + mVolumeName);
}
@Test
public void testGetContentUri() {
Cursor c = null;
assertNotNull(c = mContentResolver.query(
- Playlists.getContentUri(MediaStoreAudioTestHelper.EXTERNAL_VOLUME_NAME), null, null,
+ Playlists.getContentUri(mVolumeName), null, null,
null, null));
c.close();
@@ -68,16 +82,12 @@
} catch (SQLException e) {
// expected
}
-
- String volume = "fakeVolume";
- assertNull(mContentResolver.query(Playlists.getContentUri(volume), null, null, null,
- null));
}
@Test
- public void testStoreAudioPlaylistsExternal() {
- final String externalPlaylistPath = Environment.getExternalStorageDirectory().getPath() +
- "/my_favorites.pl";
+ public void testStoreAudioPlaylistsExternal() throws Exception {
+ final String externalPlaylistPath = new File(ProviderTestUtils.stageDir(mVolumeName),
+ "my_favorites.pl").getAbsolutePath();
ContentValues values = new ContentValues();
values.put(Playlists.NAME, "My favourites");
values.put(Playlists.DATA, externalPlaylistPath);
@@ -85,7 +95,7 @@
long dateModified = System.currentTimeMillis() / 1000;
values.put(Playlists.DATE_MODIFIED, dateModified);
// insert
- Uri uri = mContentResolver.insert(Playlists.EXTERNAL_CONTENT_URI, values);
+ Uri uri = mContentResolver.insert(Playlists.getContentUri(mVolumeName), values);
assertNotNull(uri);
try {
@@ -106,26 +116,4 @@
assertEquals(1, mContentResolver.delete(uri, null, null));
}
}
-
- @Test
- public void testStoreAudioPlaylistsInternal() {
- ContentValues values = new ContentValues();
- values.put(Playlists.NAME, "My favourites");
- values.put(Playlists.DATA, "/data/data/android.provider.cts/files/my_favorites.pl");
- long dateAdded = System.currentTimeMillis();
- values.put(Playlists.DATE_ADDED, dateAdded);
- long dateModified = System.currentTimeMillis();
- values.put(Playlists.DATE_MODIFIED, dateModified);
- // insert
- Uri uri = mContentResolver.insert(Playlists.INTERNAL_CONTENT_URI, values);
- assertNotNull(uri);
-
- try {
- assertTrue(Pattern.matches("content://media/internal/audio/playlists/\\d+",
- uri.toString()));
- } finally {
- // delete the playlists
- assertEquals(1, mContentResolver.delete(uri, null, null));
- }
- }
}
diff --git a/tests/tests/provider/src/android/provider/cts/MediaStore_Audio_Playlists_MembersTest.java b/tests/tests/provider/src/android/provider/cts/MediaStore_Audio_Playlists_MembersTest.java
index e87e10a..89b7bc5 100644
--- a/tests/tests/provider/src/android/provider/cts/MediaStore_Audio_Playlists_MembersTest.java
+++ b/tests/tests/provider/src/android/provider/cts/MediaStore_Audio_Playlists_MembersTest.java
@@ -16,12 +16,15 @@
package android.provider.cts;
+import static android.provider.cts.MediaStoreTest.TAG;
+
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertTrue;
import android.content.ContentResolver;
+import android.content.ContentUris;
import android.content.ContentValues;
import android.content.Context;
import android.database.Cursor;
@@ -37,16 +40,17 @@
import android.provider.cts.MediaStoreAudioTestHelper.Audio5;
import android.provider.cts.MediaStoreAudioTestHelper.MockAudioMediaInfo;
import android.support.test.InstrumentationRegistry;
-import android.support.test.runner.AndroidJUnit4;
+import android.util.Log;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
+import org.junit.runners.Parameterized;
+import org.junit.runners.Parameterized.Parameter;
+import org.junit.runners.Parameterized.Parameters;
-import java.util.regex.Pattern;
-
-@RunWith(AndroidJUnit4.class)
+@RunWith(Parameterized.class)
public class MediaStore_Audio_Playlists_MembersTest {
private String[] mAudioProjection = {
Members._ID,
@@ -63,7 +67,6 @@
Members.DISPLAY_NAME,
Members.DURATION,
Members.IS_ALARM,
- Members.IS_DRM,
Members.IS_MUSIC,
Members.IS_NOTIFICATION,
Members.IS_RINGTONE,
@@ -93,7 +96,6 @@
Members.DISPLAY_NAME,
Members.DURATION,
Members.IS_ALARM,
- Members.IS_DRM,
Members.IS_MUSIC,
Members.IS_NOTIFICATION,
Members.IS_RINGTONE,
@@ -114,8 +116,16 @@
private long mIdOfAudio4;
private long mIdOfAudio5;
+ @Parameter(0)
+ public String mVolumeName;
+
+ @Parameters
+ public static Iterable<? extends Object> data() {
+ return ProviderTestUtils.getSharedVolumeNames();
+ }
+
private long insertAudioItem(MockAudioMediaInfo which) {
- Uri uri = which.insertToExternal(mContentResolver);
+ Uri uri = which.insert(mContentResolver, mVolumeName);
Cursor c = mContentResolver.query(uri, null, null, null, null);
c.moveToFirst();
long id = c.getLong(c.getColumnIndex(Media._ID));
@@ -128,6 +138,8 @@
mContext = InstrumentationRegistry.getTargetContext();
mContentResolver = mContext.getContentResolver();
+ Log.d(TAG, "Using volume " + mVolumeName);
+
mIdOfAudio1 = insertAudioItem(Audio1.getInstance());
mIdOfAudio2 = insertAudioItem(Audio2.getInstance());
mIdOfAudio3 = insertAudioItem(Audio3.getInstance());
@@ -137,11 +149,12 @@
@After
public void tearDown() throws Exception {
- mContentResolver.delete(Media.EXTERNAL_CONTENT_URI, Media._ID + "=" + mIdOfAudio1, null);
- mContentResolver.delete(Media.EXTERNAL_CONTENT_URI, Media._ID + "=" + mIdOfAudio2, null);
- mContentResolver.delete(Media.EXTERNAL_CONTENT_URI, Media._ID + "=" + mIdOfAudio3, null);
- mContentResolver.delete(Media.EXTERNAL_CONTENT_URI, Media._ID + "=" + mIdOfAudio4, null);
- mContentResolver.delete(Media.EXTERNAL_CONTENT_URI, Media._ID + "=" + mIdOfAudio5, null);
+ final Uri uri = Media.getContentUri(mVolumeName);
+ mContentResolver.delete(uri, Media._ID + "=" + mIdOfAudio1, null);
+ mContentResolver.delete(uri, Media._ID + "=" + mIdOfAudio2, null);
+ mContentResolver.delete(uri, Media._ID + "=" + mIdOfAudio3, null);
+ mContentResolver.delete(uri, Media._ID + "=" + mIdOfAudio4, null);
+ mContentResolver.delete(uri, Media._ID + "=" + mIdOfAudio5, null);
}
@Test
@@ -197,6 +210,9 @@
@Test
public void testStoreAudioPlaylistsMembersExternal() {
+ // TODO: expand test to verify paths from secondary storage devices
+ if (!MediaStore.VOLUME_EXTERNAL.equals(mVolumeName)) return;
+
ContentValues values = new ContentValues();
values.put(Playlists.NAME, "My favourites");
values.put(Playlists.DATA, "");
@@ -205,7 +221,7 @@
long dateModified = System.currentTimeMillis();
values.put(Playlists.DATE_MODIFIED, dateModified);
// insert
- Uri uri = mContentResolver.insert(Playlists.EXTERNAL_CONTENT_URI, values);
+ Uri uri = mContentResolver.insert(Playlists.getContentUri(mVolumeName), values);
assertNotNull(uri);
Cursor c = mContentResolver.query(uri, null, null, null, null);
c.moveToFirst();
@@ -213,11 +229,11 @@
long playlist2Id = -1; // used later
// verify that the Uri has the correct format and playlist value
- assertEquals(uri.toString(), "content://media/external/audio/playlists/" + playlistId);
+ assertEquals(ContentUris.withAppendedId(Playlists.getContentUri(mVolumeName), playlistId),
+ uri);
// insert audio as the member of the playlist
- Uri membersUri = Members.getContentUri(MediaStoreAudioTestHelper.EXTERNAL_VOLUME_NAME,
- playlistId);
+ Uri membersUri = Members.getContentUri(mVolumeName, playlistId);
Uri audioUri = insertPlaylistItem(membersUri, mIdOfAudio1, 1);
assertNotNull(audioUri);
@@ -230,10 +246,11 @@
c.moveToFirst();
long memberId = c.getLong(c.getColumnIndex(Members._ID));
assertEquals(memberId, Long.parseLong(audioUri.getPathSegments().get(5)));
- assertEquals(Audio1.EXTERNAL_DATA, c.getString(c.getColumnIndex(Members.DATA)));
+ final String expected1 = Audio1.getInstance().getContentValues(mVolumeName)
+ .getAsString(Members.DATA);
+ assertEquals(expected1, c.getString(c.getColumnIndex(Members.DATA)));
assertTrue(c.getLong(c.getColumnIndex(Members.DATE_ADDED)) > 0);
assertEquals(Audio1.DATE_MODIFIED, c.getLong(c.getColumnIndex(Members.DATE_MODIFIED)));
- assertEquals(Audio1.IS_DRM, c.getInt(c.getColumnIndex(Members.IS_DRM)));
assertEquals(Audio1.DISPLAY_NAME, c.getString(c.getColumnIndex(Members.DISPLAY_NAME)));
assertEquals(Audio1.MIME_TYPE, c.getString(c.getColumnIndex(Members.MIME_TYPE)));
assertEquals(Audio1.SIZE, c.getInt(c.getColumnIndex(Members.SIZE)));
@@ -274,10 +291,11 @@
c.moveToFirst();
assertEquals(2, c.getInt(c.getColumnIndex(Members.PLAY_ORDER)));
assertEquals(memberId, c.getLong(c.getColumnIndex(Members._ID)));
- assertEquals(Audio2.EXTERNAL_DATA, c.getString(c.getColumnIndex(Members.DATA)));
+ final String expected2 = Audio2.getInstance().getContentValues(mVolumeName)
+ .getAsString(Members.DATA);
+ assertEquals(expected2, c.getString(c.getColumnIndex(Members.DATA)));
assertTrue(c.getLong(c.getColumnIndex(Members.DATE_ADDED)) > 0);
assertEquals(Audio2.DATE_MODIFIED, c.getLong(c.getColumnIndex(Members.DATE_MODIFIED)));
- assertEquals(Audio2.IS_DRM, c.getInt(c.getColumnIndex(Members.IS_DRM)));
assertEquals(Audio2.DISPLAY_NAME, c.getString(c.getColumnIndex(Members.DISPLAY_NAME)));
assertEquals(Audio2.MIME_TYPE, c.getString(c.getColumnIndex(Members.MIME_TYPE)));
assertEquals(Audio2.SIZE, c.getInt(c.getColumnIndex(Members.SIZE)));
@@ -333,7 +351,8 @@
new long [] {mIdOfAudio1, mIdOfAudio2, mIdOfAudio3}, new int [] {1,2,3});
// delete the middle item
- mContentResolver.delete(Media.EXTERNAL_CONTENT_URI, Media._ID + "=" + mIdOfAudio2, null);
+ mContentResolver.delete(Media.getContentUri(mVolumeName),
+ Media._ID + "=" + mIdOfAudio2, null);
// check the remaining items are still in the right order, and the play_order of the
// last item has been adjusted
@@ -367,7 +386,7 @@
values.put(Playlists.DATE_ADDED, dateAdded);
values.put(Playlists.DATE_MODIFIED, dateModified);
// insert
- uri = mContentResolver.insert(Playlists.EXTERNAL_CONTENT_URI, values);
+ uri = mContentResolver.insert(Playlists.getContentUri(mVolumeName), values);
assertNotNull(uri);
c = mContentResolver.query(uri, null, null, null, null);
c.moveToFirst();
@@ -375,8 +394,7 @@
c.close();
// insert audio into 2nd playlist
- Uri members2Uri = Members.getContentUri(MediaStoreAudioTestHelper.EXTERNAL_VOLUME_NAME,
- playlist2Id);
+ Uri members2Uri = Members.getContentUri(mVolumeName, playlist2Id);
Uri audio2Uri = insertPlaylistItem(members2Uri, mIdOfAudio1, 1);
c = mContentResolver.query(membersUri, null, null, null, null);
@@ -420,8 +438,7 @@
// insert again, then verify that deleting the audio entry cleans up its playlist member
// entry as well
- membersUri = Members.getContentUri(MediaStoreAudioTestHelper.EXTERNAL_VOLUME_NAME,
- playlistId);
+ membersUri = Members.getContentUri(mVolumeName, playlistId);
audioUri = insertPlaylistItem(membersUri, mIdOfAudio1, 1);
assertNotNull(audioUri);
// Query members of the playlist
@@ -438,7 +455,7 @@
}
assertEquals(1, cnt);
c.close();
- mContentResolver.delete(Media.EXTERNAL_CONTENT_URI,
+ mContentResolver.delete(Media.getContentUri(mVolumeName),
Media._ID + "=" + mIdOfAudio1, null);
// Query members of the playlist
c = mContentResolver.query(membersUri,
@@ -456,34 +473,12 @@
} finally {
// delete the playlists
- mContentResolver.delete(Playlists.EXTERNAL_CONTENT_URI,
+ mContentResolver.delete(Playlists.getContentUri(mVolumeName),
Playlists._ID + "=" + playlistId, null);
if (playlist2Id >= 0) {
- mContentResolver.delete(Playlists.EXTERNAL_CONTENT_URI,
+ mContentResolver.delete(Playlists.getContentUri(mVolumeName),
Playlists._ID + "=" + playlist2Id, null);
}
}
}
-
- @Test
- public void testStoreAudioPlaylistsMembersInternal() {
- ContentValues values = new ContentValues();
- values.put(Playlists.NAME, "My favourites");
- values.put(Playlists.DATA, "/data/data/android.provider.cts/files/my_favorites.pl");
- long dateAdded = System.currentTimeMillis();
- values.put(Playlists.DATE_ADDED, dateAdded);
- long dateModified = System.currentTimeMillis();
- values.put(Playlists.DATE_MODIFIED, dateModified);
- // insert
- Uri uri = mContentResolver.insert(Playlists.INTERNAL_CONTENT_URI, values);
- assertNotNull(uri);
-
- try {
- assertTrue(Pattern.matches("content://media/internal/audio/playlists/\\d+",
- uri.toString()));
- } finally {
- // delete the playlists
- assertEquals(1, mContentResolver.delete(uri, null, null));
- }
- }
}
diff --git a/tests/tests/provider/src/android/provider/cts/MediaStore_DownloadsTest.java b/tests/tests/provider/src/android/provider/cts/MediaStore_DownloadsTest.java
index 56e392c..f9a3372 100644
--- a/tests/tests/provider/src/android/provider/cts/MediaStore_DownloadsTest.java
+++ b/tests/tests/provider/src/android/provider/cts/MediaStore_DownloadsTest.java
@@ -16,10 +16,11 @@
package android.provider.cts;
+import static android.provider.cts.ProviderTestUtils.hash;
+
import static org.junit.Assert.assertArrayEquals;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
-import static org.junit.Assert.assertNull;
import static org.junit.Assert.fail;
import android.content.ContentResolver;
@@ -40,8 +41,6 @@
import android.support.test.runner.AndroidJUnit4;
import android.util.Log;
-import libcore.io.IoUtils;
-
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
@@ -53,8 +52,6 @@
import java.io.InputStream;
import java.io.OutputStream;
import java.io.PrintWriter;
-import java.security.DigestInputStream;
-import java.security.MessageDigest;
import java.util.ArrayList;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.TimeUnit;
@@ -126,11 +123,6 @@
assertNotNull(c = mContentResolver.query(Downloads.EXTERNAL_CONTENT_URI,
null, null, null, null));
c.close();
-
- // can not accept any other volume names
- final String volume = "faveVolume";
- assertNull(mContentResolver.query(Downloads.getContentUri(volume),
- null, null, null, null));
}
@Test
@@ -170,15 +162,12 @@
assertNotNull(pendingUri);
mAddedUris.add(pendingUri);
final Uri publishUri;
- final MediaStore.PendingSession session = MediaStore.openPending(mContext, pendingUri);
- try {
+ try (MediaStore.PendingSession session = MediaStore.openPending(mContext, pendingUri)) {
try (InputStream in = mContext.getResources().openRawResource(R.raw.testvideo);
OutputStream out = session.openOutputStream()) {
android.os.FileUtils.copy(in, out);
}
publishUri = session.publish();
- } finally {
- IoUtils.closeQuietly(session);
}
final ContentValues updateValues = new ContentValues();
@@ -210,15 +199,12 @@
assertNotNull(pendingUri);
mAddedUris.add(pendingUri);
final Uri publishUri;
- final MediaStore.PendingSession session = MediaStore.openPending(mContext, pendingUri);
- try {
+ try (MediaStore.PendingSession session = MediaStore.openPending(mContext, pendingUri)) {
try (InputStream in = mContext.getResources().openRawResource(R.raw.testvideo);
OutputStream out = session.openOutputStream()) {
android.os.FileUtils.copy(in, out);
}
publishUri = session.publish();
- } finally {
- IoUtils.closeQuietly(session);
}
assertEquals(1, mContentResolver.delete(publishUri, null, null));
@@ -254,15 +240,12 @@
assertNotNull(pendingUri);
mAddedUris.add(pendingUri);
final Uri publishUri;
- final MediaStore.PendingSession session = MediaStore.openPending(mContext, pendingUri);
- try {
+ try (MediaStore.PendingSession session = MediaStore.openPending(mContext, pendingUri)) {
try (InputStream in = mContext.getResources().openRawResource(R.raw.testvideo);
OutputStream out = session.openOutputStream()) {
android.os.FileUtils.copy(in, out);
}
publishUri = session.publish();
- } finally {
- IoUtils.closeQuietly(session);
}
mCountDownLatch.await(NOTIFY_TIMEOUT_MILLIS, TimeUnit.MILLISECONDS);
@@ -341,15 +324,4 @@
assertNotNull("Failed to scan " + file.getAbsolutePath(), mediaStoreUris[0]);
return mediaStoreUris[0];
}
-
- private static byte[] hash(InputStream in) throws Exception {
- try (DigestInputStream digestIn = new DigestInputStream(in,
- MessageDigest.getInstance("SHA-1"));
- OutputStream out = new FileOutputStream(new File("/dev/null"))) {
- FileUtils.copy(digestIn, out);
- return digestIn.getMessageDigest().digest();
- } finally {
- IoUtils.closeQuietly(in);
- }
- }
}
diff --git a/tests/tests/provider/src/android/provider/cts/MediaStore_FilesTest.java b/tests/tests/provider/src/android/provider/cts/MediaStore_FilesTest.java
index 380ba82..ffc6b49 100644
--- a/tests/tests/provider/src/android/provider/cts/MediaStore_FilesTest.java
+++ b/tests/tests/provider/src/android/provider/cts/MediaStore_FilesTest.java
@@ -16,8 +16,8 @@
package android.provider.cts;
-import static android.provider.cts.ProviderTestUtils.assertExists;
-import static android.provider.cts.ProviderTestUtils.assertNotExists;
+import static android.provider.cts.MediaStoreTest.TAG;
+import static android.provider.cts.ProviderTestUtils.containsId;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
@@ -34,108 +34,76 @@
import android.net.Uri;
import android.os.Environment;
import android.os.ParcelFileDescriptor;
-import android.os.SystemClock;
import android.provider.MediaStore;
import android.provider.MediaStore.Files.FileColumns;
import android.provider.MediaStore.MediaColumns;
import android.support.test.InstrumentationRegistry;
-import android.support.test.runner.AndroidJUnit4;
+import android.util.Log;
-import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
+import org.junit.runners.Parameterized;
+import org.junit.runners.Parameterized.Parameter;
+import org.junit.runners.Parameterized.Parameters;
import java.io.File;
-import java.io.FileNotFoundException;
-import java.io.FileOutputStream;
-import java.io.FilenameFilter;
import java.io.IOException;
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.List;
-@RunWith(AndroidJUnit4.class)
+@RunWith(Parameterized.class)
public class MediaStore_FilesTest {
private Context mContext;
private ContentResolver mResolver;
+ private Uri mExternalImages;
+ private Uri mExternalFiles;
+
+ @Parameter(0)
+ public String mVolumeName;
+
+ @Parameters
+ public static Iterable<? extends Object> data() {
+ return ProviderTestUtils.getSharedVolumeNames();
+ }
+
@Before
public void setUp() throws Exception {
mContext = InstrumentationRegistry.getTargetContext();
mResolver = mContext.getContentResolver();
- cleanup();
- }
-
- @After
- public void tearDown() throws Exception {
- cleanup();
- }
-
- void cleanup() {
- final String testName = getClass().getCanonicalName();
- mResolver.delete(MediaStore.Audio.Media.EXTERNAL_CONTENT_URI,
- "_data LIKE ?1", new String[] {"%" + testName + "%"});
-
- mResolver.delete(MediaStore.Files.getContentUri("external"),
- "_data LIKE ?1", new String[] {"%" + testName + "%"});
-
- File ext = Environment.getExternalStorageDirectory();
- File[] junk = ext.listFiles(new FilenameFilter() {
-
- @Override
- public boolean accept(File dir, String filename) {
- return filename.contains(testName);
- }
- });
- for (File f: junk) {
- deleteAll(f);
- }
- }
-
- void deleteAll(File f) {
- if (f.isDirectory()) {
- File [] sub = f.listFiles();
- for (File s: sub) {
- deleteAll(s);
- }
- }
- f.delete();
+ Log.d(TAG, "Using volume " + mVolumeName);
+ mExternalImages = MediaStore.Images.Media.getContentUri(mVolumeName);
+ mExternalFiles = MediaStore.Files.getContentUri(mVolumeName);
}
@Test
- public void testGetContentUri() {
- String volumeName = MediaStoreAudioTestHelper.EXTERNAL_VOLUME_NAME;
- Uri allFilesUri = MediaStore.Files.getContentUri(volumeName);
-
- // Get the current file count. We will check if this increases after
- // adding a file to the provider.
- int fileCount = getFileCount(allFilesUri);
+ public void testGetContentUri() throws Exception {
+ Uri allFilesUri = mExternalFiles;
ContentValues values = new ContentValues();
// Add a path for a file and check that the returned uri appends a
// path properly.
- String dataPath = "does_not_really_exist.txt";
+ String dataPath = new File(ProviderTestUtils.stageDir(mVolumeName),
+ "does_not_really_exist.txt").getAbsolutePath();
values.put(MediaColumns.DATA, dataPath);
Uri fileUri = mResolver.insert(allFilesUri, values);
long fileId = ContentUris.parseId(fileUri);
assertEquals(fileUri, ContentUris.withAppendedId(allFilesUri, fileId));
// Check that getContentUri with the file id produces the same url
- Uri rowUri = MediaStore.Files.getContentUri(volumeName, fileId);
+ Uri rowUri = ContentUris.withAppendedId(mExternalFiles, fileId);
assertEquals(fileUri, rowUri);
// Check that the file count has increased.
- int newFileCount = getFileCount(allFilesUri);
- assertEquals(fileCount + 1, newFileCount);
+ assertTrue(containsId(allFilesUri, fileId));
// Check that the path we inserted was stored properly.
assertStringColumn(fileUri, MediaColumns.DATA, dataPath);
// Update the path and check that the database changed.
- String updatedPath = "still_does_not_exist.txt";
+ String updatedPath = new File(ProviderTestUtils.stageDir(mVolumeName),
+ "still_does_not_exist.txt").getAbsolutePath();
values.put(MediaColumns.DATA, updatedPath);
assertEquals(1, mResolver.update(fileUri, values, null, null));
assertStringColumn(fileUri, MediaColumns.DATA, updatedPath);
@@ -146,7 +114,7 @@
// Delete the file and observe that the file count decreased.
assertEquals(1, mResolver.delete(fileUri, null, null));
- assertEquals(fileCount, getFileCount(allFilesUri));
+ assertFalse(containsId(allFilesUri, fileId));
// Make sure the deleted file is not returned by the cursor.
Cursor cursor = mResolver.query(fileUri, null, null, null, null);
@@ -159,7 +127,10 @@
// insert file and check its parent
values.clear();
try {
- String b = mContext.getExternalFilesDir(Environment.DIRECTORY_MUSIC).getCanonicalPath();
+ File stageDir = new File(ProviderTestUtils.stageDir(mVolumeName),
+ Environment.DIRECTORY_MUSIC);
+ stageDir.mkdirs();
+ String b = stageDir.getAbsolutePath();
values.put(MediaColumns.DATA, b + "/testing");
fileUri = mResolver.insert(allFilesUri, values);
cursor = mResolver.query(fileUri, new String[] { MediaStore.Files.FileColumns.PARENT },
@@ -187,328 +158,113 @@
@Test
public void testCaseSensitivity() throws IOException {
- String fileDir = Environment.getExternalStorageDirectory() +
- "/" + getClass().getCanonicalName();
- String fileName = fileDir + "/Test.Mp3";
- writeFile(R.raw.testmp3, fileName);
+ final String name = "Test-" + System.nanoTime() + ".Mp3";
+ final File dir = ProviderTestUtils.stageDir(mVolumeName);
+ final File file = new File(dir, name);
+ final File fileLower = new File(dir, name.toLowerCase());
+ ProviderTestUtils.stageFile(R.raw.testmp3, file);
- String volumeName = MediaStoreAudioTestHelper.EXTERNAL_VOLUME_NAME;
- Uri allFilesUri = MediaStore.Files.getContentUri(volumeName);
+ Uri allFilesUri = mExternalFiles;
ContentValues values = new ContentValues();
- values.put(MediaColumns.DATA, fileDir + "/test.mp3");
+ values.put(MediaColumns.DATA, fileLower.getAbsolutePath());
Uri fileUri = mResolver.insert(allFilesUri, values);
try {
ParcelFileDescriptor pfd = mResolver.openFileDescriptor(fileUri, "r");
pfd.close();
} finally {
mResolver.delete(fileUri, null, null);
- new File(fileName).delete();
- new File(fileDir).delete();
}
}
- String realPathFor(ParcelFileDescriptor pfd) {
- File real = new File("/proc/self/fd/" + pfd.getFd());
- try {
- return real.getCanonicalPath();
- } catch (IOException e) {
- return null;
+ @Test
+ public void testAccessInternal() throws Exception {
+ final Uri internalFiles = MediaStore.Files.getContentUri(MediaStore.VOLUME_INTERNAL);
+
+ for (String valid : new String[] {
+ "/system/media/" + System.nanoTime() + ".ogg",
+ }) {
+ final ContentValues values = new ContentValues();
+ values.put(MediaColumns.DATA, valid);
+
+ final Uri uri = mResolver.insert(internalFiles, values);
+ assertNotNull("Failed to insert " + valid, uri);
+ mResolver.delete(uri, null, null);
+ }
+
+ for (String invalid : new String[] {
+ "/data/media/" + System.nanoTime() + ".jpg",
+ "/data/system/appops.xml",
+ "/data/data/com.android.providers.media/databases/internal.db",
+ new File(Environment.getExternalStorageDirectory(), System.nanoTime() + ".jpg")
+ .getAbsolutePath(),
+ }) {
+ final ContentValues values = new ContentValues();
+ values.put(MediaColumns.DATA, invalid);
+
+ try {
+ mResolver.insert(internalFiles, values);
+ fail("Able to insert " + invalid);
+ } catch (SecurityException | IllegalArgumentException expected) {
+ }
}
}
@Test
public void testAccess() throws Exception {
- // clean up from previous run
- mResolver.delete(MediaStore.Images.Media.INTERNAL_CONTENT_URI,
- "_data NOT LIKE ?", new String[] { "/system/%" } );
+ final String path = MediaStore.getVolumePath(mVolumeName).getAbsolutePath();
+ final Uri updateUri = ContentUris.withAppendedId(mExternalFiles,
+ ContentUris.parseId(ProviderTestUtils.stageMedia(R.raw.volantis, mExternalImages)));
- // insert some dummy starter data into the provider
- ContentValues values = new ContentValues();
- values.put(MediaStore.Images.Media.DISPLAY_NAME, "My Bitmap");
- values.put(MediaStore.Images.Media.MIME_TYPE, "image/jpeg");
- values.put(MediaStore.Images.Media.DATA, "/foo/bar/dummy.jpg");
- Uri uri = mResolver.insert(MediaStore.Images.Media.INTERNAL_CONTENT_URI, values);
+ for (String valid : new String[] {
+ path + "/" + System.nanoTime() + ".jpg",
+ path + "/DCIM/" + System.nanoTime() + ".jpg",
+ }) {
+ final ContentValues values = new ContentValues();
+ values.put(MediaColumns.DATA, valid);
- // point _data at directory and try to get an fd for it
- values = new ContentValues();
- values.put("_data", "/data/media");
- mResolver.update(uri, values, null, null);
- ParcelFileDescriptor pfd = null;
- try {
- pfd = mResolver.openFileDescriptor(uri, "r");
- pfd.close();
- fail("shouldn't be here");
- } catch (FileNotFoundException e) {
- // expected
+ final Uri uri = mResolver.insert(mExternalFiles, values);
+ assertNotNull("Failed to insert " + valid, uri);
+ mResolver.delete(uri, null, null);
+
+ final int count = mResolver.update(updateUri, values, null, null);
+ assertEquals("Failed to update", 1, count);
}
- // try to create a file in a place we don't have access to
- values = new ContentValues();
- values.put("_data", "/data/media/test.dat");
- mResolver.update(uri, values, null, null);
- try {
- pfd = mResolver.openFileDescriptor(uri, "w");
- pfd.close();
- fail("shouldn't be here");
- } catch (FileNotFoundException e) {
- // expected
- }
- // read file back
- try {
- pfd = mResolver.openFileDescriptor(uri, "r");
- pfd.close();
- fail("shouldn't be here");
- } catch (FileNotFoundException e) {
- // expected
- }
+ for (String invalid : new String[] {
+ "/data/media/" + System.nanoTime() + ".jpg",
+ "/data/system/appops.xml",
+ "/data/data/com.android.providers.media/databases/internal.db",
+ path + "/../../../../../data/system/appops.xml",
+ }) {
+ final ContentValues values = new ContentValues();
+ values.put(MediaColumns.DATA, invalid);
- // point _data at media database and read it
- values = new ContentValues();
- values.put("_data", "/data/data/com.android.providers.media/databases/internal.db");
- mResolver.update(uri, values, null, null);
- try {
- pfd = mResolver.openFileDescriptor(uri, "r");
- pfd.close();
- fail("shouldn't be here");
- } catch (FileNotFoundException e) {
- // expected
- }
-
- // Insert a private file into the database. Since it's private, the media provider won't
- // be able to open it
- FileOutputStream fos = mContext.openFileOutput("dummy.dat", Context.MODE_PRIVATE);
- fos.write(0);
- fos.close();
- File path = mContext.getFileStreamPath("dummy.dat");
- values = new ContentValues();
- values.put("_data", path.getAbsolutePath());
-
- mResolver.update(uri, values, null, null);
- try {
- pfd = mResolver.openFileDescriptor(uri, "r");
- pfd.close();
- fail("shouldn't be here");
- } catch (FileNotFoundException e) {
- // expected
- }
- path.delete();
-
- File sdfile = null;
- if (Environment.isExternalStorageEmulated()) {
- // create file on sdcard and check access via real path
- String fileDir = Environment.getExternalStorageDirectory() +
- "/" + getClass().getCanonicalName() + "/test.mp3";
- sdfile = new File(fileDir);
- writeFile(R.raw.testmp3, sdfile.getCanonicalPath());
- assertExists(sdfile);
- values = new ContentValues();
- values.put("_data", sdfile.getCanonicalPath());
- mResolver.update(uri, values, null, null);
try {
- pfd = mResolver.openFileDescriptor(uri, "r");
-
- // get the real path from the file descriptor (this relies on the media provider
- // having opened the path via the real path instead of the emulated path).
- String realPath = realPathFor(pfd);
- pfd.close();
- if (realPath.equals(sdfile.getCanonicalPath())) {
- // provider did not use real/translated path
- sdfile = null;
- } else {
- values = new ContentValues();
- values.put("_data", realPath);
- mResolver.update(uri, values, null, null);
-
- // we shouldn't be able to access this
- try {
- pfd = mResolver.openFileDescriptor(uri, "r");
- fail("shouldn't have fd for " + realPath);
- } catch (FileNotFoundException e) {
- // expected
- } finally {
- pfd.close();
- }
- }
- } catch (FileNotFoundException e) {
- fail("couldn't open file");
+ mResolver.insert(mExternalFiles, values);
+ fail("Able to insert " + invalid);
+ } catch (SecurityException | IllegalArgumentException expected) {
}
- }
- // clean up
- assertEquals(1, mResolver.delete(uri, null, null));
- if (sdfile != null) {
- assertEquals("couldn't delete " + sdfile.getCanonicalPath(), true, sdfile.delete());
- }
-
- // test secondary storage if present
- List<File> allpaths = getSecondaryPackageSpecificPaths(mContext);
- List<String> trimmedPaths = new ArrayList<String>();
-
- for (File extpath: allpaths) {
- assertNotNull("Valid media must be inserted during CTS", extpath);
- assertEquals("Valid media must be inserted for " + extpath
- + " during CTS", Environment.MEDIA_MOUNTED,
- Environment.getStorageState(extpath));
-
- File child = extpath;
- while (true) {
- File parent = child.getParentFile();
- if (parent == null) {
- fail("didn't expect to be here");
- }
- if (!Environment.MEDIA_MOUNTED.equals(Environment.getStorageState(parent))) {
- // we went past the root
- String abspath = child.getAbsolutePath();
- if (!trimmedPaths.contains(abspath)) {
- trimmedPaths.add(abspath);
- }
- break;
- }
- child = parent;
- }
- }
-
- String fileDir = Environment.getExternalStorageDirectory() +
- "/" + getClass().getCanonicalName() + "-" + SystemClock.elapsedRealtime();
- String fileName = fileDir + "/TestSecondary.Mp3";
- writeFile(R.raw.testmp3_2, fileName); // file without album art
-
-
- // insert temp file
- values = new ContentValues();
- values.put(MediaStore.Audio.Media.DATA, fileName);
- values.put(MediaStore.Audio.Media.ARTIST, "Artist-" + SystemClock.elapsedRealtime());
- values.put(MediaStore.Audio.Media.ALBUM, "Album-" + SystemClock.elapsedRealtime());
- values.put(MediaStore.Audio.Media.MIME_TYPE, "audio/mp3");
- Uri fileUri = mResolver.insert(MediaStore.Audio.Media.EXTERNAL_CONTENT_URI, values);
- // give media provider some time to realize there's no album art
- SystemClock.sleep(1000);
- // get its album id
- Cursor c = mResolver.query(fileUri, new String[] { MediaStore.Audio.Media.ALBUM_ID},
- null, null, null);
- assertTrue(c.moveToFirst());
- int albumid = c.getInt(0);
- Uri albumArtUriBase = Uri.parse("content://media/external/audio/albumart");
- Uri albumArtUri = ContentUris.withAppendedId(albumArtUriBase, albumid);
- try {
- pfd = mResolver.openFileDescriptor(albumArtUri, "r");
- fail("no album art, shouldn't be here. Got: " + realPathFor(pfd));
- } catch (Exception e) {
- // expected
- }
-
- // replace file with one that has album art
- writeFile(R.raw.testmp3, fileName); // file with album art
-
- for (String s: trimmedPaths) {
- File dir = new File(s + "/foobardir-" + SystemClock.elapsedRealtime());
- assertNotExists("please remove " + dir.getAbsolutePath()
- + " before running", dir.getAbsolutePath());
- File file = new File(dir, "foobar");
- values = new ContentValues();
- values.put(MediaStore.Audio.Media.ALBUM_ID, albumid);
- values.put(MediaStore.Audio.Media.DATA, file.getAbsolutePath());
- mResolver.insert(albumArtUriBase, values);
try {
- pfd = mResolver.openFileDescriptor(albumArtUri, "r");
- fail("shouldn't have fd for album " + albumid + ", got " + realPathFor(pfd));
- } catch (Exception e) {
- // expected
- } finally {
- pfd.close();
+ mResolver.update(updateUri, values, null, null);
+ fail("Able to update " + invalid);
+ } catch (SecurityException | IllegalArgumentException expected) {
}
- assertNotExists(dir.getAbsolutePath() + " was created", dir.getAbsolutePath());
}
- mResolver.delete(fileUri, null, null);
- new File(fileName).delete();
-
- // try creating files in root
- for (String s: trimmedPaths) {
- File dir = new File(s);
- File file = new File(dir, "foobar.jpg");
-
- values = new ContentValues();
- values.put(MediaStore.Files.FileColumns.DATA, file.getAbsolutePath());
- fileUri = mResolver.insert(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, values);
- assertNotNull(fileUri);
-
- // check that adding the file doesn't cause it to be created
- assertNotExists(file);
-
- // check if opening the file for write works
- try {
- mResolver.openOutputStream(fileUri).close();
- fail("shouldn't have been able to create output stream");
- } catch (SecurityException e) {
- // expected
- }
- // check that deleting the file doesn't cause it to be created
- mResolver.delete(fileUri, null, null);
- assertNotExists(file);
- }
-
- // try creating files in new subdir
- for (String s: trimmedPaths) {
- File dir = new File(s + "/foobardir");
- File file = new File(dir, "foobar.jpg");
-
- values = new ContentValues();
- values.put(MediaStore.Files.FileColumns.DATA, dir.getAbsolutePath());
-
- Uri dirUri = mResolver.insert(MediaStore.Files.getContentUri("external"), values);
- assertNotNull(dirUri);
-
- values = new ContentValues();
- values.put(MediaStore.Files.FileColumns.DATA, file.getAbsolutePath());
- fileUri = mResolver.insert(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, values);
- assertNotNull(fileUri);
-
- // check that adding the file or its folder didn't cause either one to be created
- assertNotExists(dir);
- assertNotExists(file);
-
- // check if opening the file for write works
- try {
- mResolver.openOutputStream(fileUri).close();
- fail("shouldn't have been able to create output stream");
- } catch (SecurityException e) {
- // expected
- }
- // check that deleting the file or its folder doesn't cause either one to be created
- mResolver.delete(fileUri, null, null);
- assertNotExists(dir);
- assertNotExists(file);
- mResolver.delete(dirUri, null, null);
- assertNotExists(dir);
- assertNotExists(file);
- }
- }
-
- public static List<File> getSecondaryPackageSpecificPaths(Context context) {
- final List<File> paths = new ArrayList<File>();
- Collections.addAll(paths, dropFirst(context.getExternalCacheDirs()));
- Collections.addAll(paths, dropFirst(context.getExternalFilesDirs(null)));
- Collections.addAll(
- paths, dropFirst(context.getExternalFilesDirs(Environment.DIRECTORY_PICTURES)));
- Collections.addAll(paths, dropFirst(context.getObbDirs()));
- return paths;
}
@Test
public void testUpdateMediaType() throws Exception {
- String fileDir = Environment.getExternalStorageDirectory() +
- "/" + getClass().getCanonicalName();
- String fileName = fileDir + "/test.mp3";
- writeFile(R.raw.testmp3, fileName);
+ final File file = new File(ProviderTestUtils.stageDir(mVolumeName),
+ "test" + System.nanoTime() + ".mp3");
+ ProviderTestUtils.stageFile(R.raw.testmp3, file);
- String volumeName = MediaStoreAudioTestHelper.EXTERNAL_VOLUME_NAME;
- Uri allFilesUri = MediaStore.Files.getContentUri(volumeName);
+ Uri allFilesUri = mExternalFiles;
ContentValues values = new ContentValues();
- values.put(MediaColumns.DATA, fileName);
+ values.put(MediaColumns.DATA, file.getAbsolutePath());
values.put(FileColumns.MEDIA_TYPE, FileColumns.MEDIA_TYPE_AUDIO);
Uri fileUri = mResolver.insert(allFilesUri, values);
-
// There is special logic in MediaProvider#update() to update paths when a folder was moved
// or renamed. It only checks whether newValues only has one column but assumes the provided
// column is _data. We need to guard the case where there is only one column in newValues
@@ -525,28 +281,6 @@
}
}
- private static File[] dropFirst(File[] before) {
- final File[] after = new File[before.length - 1];
- System.arraycopy(before, 1, after, 0, after.length);
- return after;
- }
-
- private void writeFile(int resid, String path) throws IOException {
- File out = new File(path);
- File dir = out.getParentFile();
- dir.mkdirs();
- ProviderTestUtils.stageFile(resid, out);
- }
-
- private int getFileCount(Uri uri) {
- Cursor cursor = mResolver.query(uri, null, null, null, null);
- try {
- return cursor.getCount();
- } finally {
- cursor.close();
- }
- }
-
private void assertStringColumn(Uri fileUri, String columnName, String expectedValue) {
Cursor cursor = mResolver.query(fileUri, null, null, null, null);
try {
diff --git a/tests/tests/provider/src/android/provider/cts/MediaStore_Images_MediaTest.java b/tests/tests/provider/src/android/provider/cts/MediaStore_Images_MediaTest.java
index b467538..d930560 100644
--- a/tests/tests/provider/src/android/provider/cts/MediaStore_Images_MediaTest.java
+++ b/tests/tests/provider/src/android/provider/cts/MediaStore_Images_MediaTest.java
@@ -16,9 +16,10 @@
package android.provider.cts;
+import static android.provider.cts.MediaStoreTest.TAG;
+
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
-import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;
@@ -30,63 +31,47 @@
import android.graphics.BitmapFactory;
import android.media.ExifInterface;
import android.net.Uri;
-import android.os.Environment;
import android.os.ParcelFileDescriptor;
import android.os.storage.StorageManager;
import android.platform.test.annotations.Presubmit;
import android.provider.MediaStore;
import android.provider.MediaStore.Images.ImageColumns;
import android.provider.MediaStore.Images.Media;
-import android.provider.MediaStore.Images.Thumbnails;
import android.support.test.InstrumentationRegistry;
-import android.support.test.runner.AndroidJUnit4;
import android.util.Log;
+import android.util.Size;
import com.android.compatibility.common.util.FileUtils;
-import libcore.io.IoUtils;
-
-import org.junit.After;
import org.junit.Assume;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
+import org.junit.runners.Parameterized;
+import org.junit.runners.Parameterized.Parameter;
+import org.junit.runners.Parameterized.Parameters;
import java.io.File;
import java.io.FileNotFoundException;
+import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
-import java.util.ArrayList;
-@RunWith(AndroidJUnit4.class)
+@RunWith(Parameterized.class)
public class MediaStore_Images_MediaTest {
private static final String MIME_TYPE_JPEG = "image/jpeg";
- private static final String TEST_TITLE1 = "test title1";
-
- private static final String TEST_DESCRIPTION1 = "test description1";
-
- private static final String TEST_TITLE2 = "test title2";
-
- private static final String TEST_DESCRIPTION2 = "test description2";
-
- private static final String TEST_TITLE3 = "test title3";
-
- private static final String TEST_DESCRIPTION3 = "test description3";
-
- private static final String LOG_TAG = "MediaStore_Images_MediaTest";
-
- private ArrayList<Uri> mRowsAdded;
-
private Context mContext;
-
private ContentResolver mContentResolver;
- @After
- public void tearDown() throws Exception {
- for (Uri row : mRowsAdded) {
- mContentResolver.delete(row, null, null);
- }
+ private Uri mExternalImages;
+
+ @Parameter(0)
+ public String mVolumeName;
+
+ @Parameters
+ public static Iterable<? extends Object> data() {
+ return ProviderTestUtils.getSharedVolumeNames();
}
@Before
@@ -94,28 +79,31 @@
mContext = InstrumentationRegistry.getTargetContext();
mContentResolver = mContext.getContentResolver();
- mRowsAdded = new ArrayList<Uri>();
-
- File pics = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES);
- if (!pics.exists()) {
- Log.i(LOG_TAG, "Nonstandard test-environment: Pictures directory does not exist!");
- pics.mkdirs();
- if (!pics.exists()) {
- Log.i(LOG_TAG, "Couldn't create Pictures directory, some tests may fail!");
- }
- }
-
+ Log.d(TAG, "Using volume " + mVolumeName);
+ mExternalImages = MediaStore.Images.Media.getContentUri(mVolumeName);
}
@Test
public void testInsertImageWithImagePath() throws Exception {
- Cursor c = Media.query(mContentResolver, Media.EXTERNAL_CONTENT_URI, null, null,
+ // TODO: expand test to verify paths from secondary storage devices
+ if (!MediaStore.VOLUME_EXTERNAL.equals(mVolumeName)) return;
+
+ final long unique1 = System.nanoTime();
+ final String TEST_TITLE1 = "Title " + unique1;
+ final String TEST_DESCRIPTION1 = "Description " + unique1;
+
+ final long unique2 = System.nanoTime();
+ final String TEST_TITLE2 = "Title " + unique2;
+ final String TEST_DESCRIPTION2 = "Description " + unique2;
+
+ Cursor c = Media.query(mContentResolver, mExternalImages, null, null,
"_id ASC");
int previousCount = c.getCount();
c.close();
// insert an image by path
- File file = mContext.getFileStreamPath("mediaStoreTest1.jpg");
+ File file = new File(ProviderTestUtils.stageDir(MediaStore.VOLUME_EXTERNAL),
+ "mediaStoreTest1.jpg");
String path = file.getAbsolutePath();
ProviderTestUtils.stageFile(R.raw.scenery, file);
String stringUrl = null;
@@ -128,10 +116,10 @@
fail("There is no sdcard attached! " + e.getMessage());
}
assertInsertionSuccess(stringUrl);
- mRowsAdded.add(Uri.parse(stringUrl));
// insert another image by path
- file = mContext.getFileStreamPath("mediaStoreTest2.jpg");
+ file = new File(ProviderTestUtils.stageDir(MediaStore.VOLUME_EXTERNAL),
+ "mediaStoreTest2.jpg");
path = file.getAbsolutePath();
ProviderTestUtils.stageFile(R.raw.scenery, file);
stringUrl = null;
@@ -144,7 +132,6 @@
fail("There is no sdcard attached! " + e.getMessage());
}
assertInsertionSuccess(stringUrl);
- mRowsAdded.add(Uri.parse(stringUrl));
// query the newly added image
c = Media.query(mContentResolver, Uri.parse(stringUrl),
@@ -158,7 +145,7 @@
// query all the images in external db and order them by descending id
// (make the images added in test case in the first positions)
- c = Media.query(mContentResolver, Media.EXTERNAL_CONTENT_URI,
+ c = Media.query(mContentResolver, mExternalImages,
new String[] { Media.TITLE, Media.DESCRIPTION, Media.MIME_TYPE }, null,
"_id DESC");
assertEquals(previousCount + 2, c.getCount());
@@ -185,6 +172,10 @@
@Test
public void testInsertImageWithBitmap() throws Exception {
+ final long unique3 = System.nanoTime();
+ final String TEST_TITLE3 = "Title " + unique3;
+ final String TEST_DESCRIPTION3 = "Description " + unique3;
+
// insert the image by bitmap
Bitmap src = BitmapFactory.decodeResource(mContext.getResources(), R.raw.scenery);
String stringUrl = null;
@@ -195,7 +186,6 @@
fail("There is no sdcard attached! " + e.getMessage());
}
assertInsertionSuccess(stringUrl);
- mRowsAdded.add(Uri.parse(stringUrl));
Cursor c = Media.query(mContentResolver, Uri.parse(stringUrl), new String[] { Media.DATA },
null, "_id ASC");
@@ -217,26 +207,22 @@
assertNotNull(c = mContentResolver.query(Media.getContentUri("internal"), null, null, null,
null));
c.close();
- assertNotNull(c = mContentResolver.query(Media.getContentUri("external"), null, null, null,
+ assertNotNull(c = mContentResolver.query(Media.getContentUri(mVolumeName), null, null, null,
null));
c.close();
-
- // can not accept any other volume names
- String volume = "fakeVolume";
- assertNull(mContentResolver.query(Media.getContentUri(volume), null, null, null, null));
}
private void cleanExternalMediaFile(String path) {
- mContentResolver.delete(Media.EXTERNAL_CONTENT_URI, "_data=?", new String[] { path });
+ mContentResolver.delete(mExternalImages, "_data=?", new String[] { path });
new File(path).delete();
}
@Test
public void testStoreImagesMediaExternal() throws Exception {
- final String externalPath = Environment.getExternalStorageDirectory().getPath() +
- "/testimage.jpg";
- final String externalPath2 = Environment.getExternalStorageDirectory().getPath() +
- "/testimage1.jpg";
+ final String externalPath = new File(ProviderTestUtils.stageDir(mVolumeName),
+ "testimage.jpg").getAbsolutePath();
+ final String externalPath2 = new File(ProviderTestUtils.stageDir(mVolumeName),
+ "testimage1.jpg").getAbsolutePath();
// clean up any potential left over entries from a previous aborted run
cleanExternalMediaFile(externalPath);
@@ -264,7 +250,7 @@
values.put(Media.DATE_MODIFIED, dateModified);
// insert
- Uri uri = mContentResolver.insert(Media.EXTERNAL_CONTENT_URI, values);
+ Uri uri = mContentResolver.insert(mExternalImages, values);
assertNotNull(uri);
try {
@@ -310,22 +296,16 @@
}
}
- private void assertInsertionSuccess(String stringUrl) {
- assertNotNull(stringUrl);
+ private void assertInsertionSuccess(String stringUrl) throws IOException {
+ final Uri uri = Uri.parse(stringUrl);
+
// check whether the thumbnails are generated
- Cursor c = mContentResolver.query(Uri.parse(stringUrl), new String[]{ Media._ID }, null,
- null, null);
- assertTrue(c.moveToFirst());
- long imageId = c.getLong(c.getColumnIndex(Media._ID));
- c.close();
- assertNotNull(Thumbnails.getThumbnail(mContentResolver, imageId,
- Thumbnails.MINI_KIND, null));
- assertNotNull(Thumbnails.getThumbnail(mContentResolver, imageId,
- Thumbnails.MICRO_KIND, null));
- c = mContentResolver.query(Thumbnails.EXTERNAL_CONTENT_URI, null,
- Thumbnails.IMAGE_ID + "=" + imageId, null, null);
- assertEquals(2, c.getCount());
- c.close();
+ try (Cursor c = mContentResolver.query(uri, null, null, null)) {
+ assertEquals(1, c.getCount());
+ }
+
+ assertNotNull(mContentResolver.loadThumbnail(uri, new Size(512, 384), null));
+ assertNotNull(mContentResolver.loadThumbnail(uri, new Size(96, 96), null));
}
/**
@@ -340,19 +320,16 @@
final String displayName = "cts" + System.nanoTime();
final MediaStore.PendingParams params = new MediaStore.PendingParams(
- MediaStore.Images.Media.EXTERNAL_CONTENT_URI, displayName, "image/jpeg");
+ mExternalImages, displayName, "image/jpeg");
final Uri pendingUri = MediaStore.createPending(mContext, params);
final Uri publishUri;
- final MediaStore.PendingSession session = MediaStore.openPending(mContext, pendingUri);
- try {
+ try (MediaStore.PendingSession session = MediaStore.openPending(mContext, pendingUri)) {
try (InputStream in = mContext.getResources().openRawResource(R.raw.volantis);
OutputStream out = session.openOutputStream()) {
android.os.FileUtils.copy(in, out);
}
publishUri = session.publish();
- } finally {
- IoUtils.closeQuietly(session);
}
final Uri originalUri = MediaStore.setRequireOriginal(publishUri);
@@ -392,19 +369,16 @@
public void testLocationDeprecated() throws Exception {
final String displayName = "cts" + System.nanoTime();
final MediaStore.PendingParams params = new MediaStore.PendingParams(
- MediaStore.Images.Media.EXTERNAL_CONTENT_URI, displayName, "image/jpeg");
+ mExternalImages, displayName, "image/jpeg");
final Uri pendingUri = MediaStore.createPending(mContext, params);
final Uri publishUri;
- final MediaStore.PendingSession session = MediaStore.openPending(mContext, pendingUri);
- try {
+ try (MediaStore.PendingSession session = MediaStore.openPending(mContext, pendingUri)) {
try (InputStream in = mContext.getResources().openRawResource(R.raw.volantis);
OutputStream out = session.openOutputStream()) {
android.os.FileUtils.copy(in, out);
}
publishUri = session.publish();
- } finally {
- IoUtils.closeQuietly(session);
}
// Verify that location wasn't indexed
diff --git a/tests/tests/provider/src/android/provider/cts/MediaStore_Images_ThumbnailsTest.java b/tests/tests/provider/src/android/provider/cts/MediaStore_Images_ThumbnailsTest.java
index ee6fbe5..19cba84 100644
--- a/tests/tests/provider/src/android/provider/cts/MediaStore_Images_ThumbnailsTest.java
+++ b/tests/tests/provider/src/android/provider/cts/MediaStore_Images_ThumbnailsTest.java
@@ -16,6 +16,7 @@
package android.provider.cts;
+import static android.provider.cts.MediaStoreTest.TAG;
import static android.provider.cts.ProviderTestUtils.assertExists;
import static android.provider.cts.ProviderTestUtils.assertNotExists;
@@ -30,19 +31,25 @@
import android.content.ContentUris;
import android.content.ContentValues;
import android.content.Context;
+import android.content.res.Configuration;
+import android.content.res.Resources;
import android.database.Cursor;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
-import android.media.MediaScanner;
+import android.graphics.Canvas;
+import android.graphics.Color;
+import android.graphics.ImageDecoder;
import android.net.Uri;
import android.os.Environment;
+import android.os.SystemClock;
import android.provider.MediaStore;
import android.provider.MediaStore.Images.Media;
import android.provider.MediaStore.Images.Thumbnails;
import android.provider.MediaStore.MediaColumns;
import android.support.test.InstrumentationRegistry;
-import android.support.test.runner.AndroidJUnit4;
import android.util.DisplayMetrics;
+import android.util.Log;
+import android.util.Size;
import junit.framework.AssertionFailedError;
@@ -50,18 +57,34 @@
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
+import org.junit.runners.Parameterized;
+import org.junit.runners.Parameterized.Parameter;
+import org.junit.runners.Parameterized.Parameters;
import java.io.File;
+import java.io.FileNotFoundException;
+import java.io.OutputStream;
import java.util.ArrayList;
-@RunWith(AndroidJUnit4.class)
+@RunWith(Parameterized.class)
public class MediaStore_Images_ThumbnailsTest {
private ArrayList<Uri> mRowsAdded;
private Context mContext;
-
private ContentResolver mContentResolver;
+ private Uri mExternalImages;
+
+ @Parameter(0)
+ public String mVolumeName;
+
+ private int mLargestDimension;
+
+ @Parameters
+ public static Iterable<? extends Object> data() {
+ return ProviderTestUtils.getSharedVolumeNames();
+ }
+
private Uri mRed;
private Uri mBlue;
@@ -83,17 +106,19 @@
mContentResolver = mContext.getContentResolver();
mRowsAdded = new ArrayList<Uri>();
+
+ Log.d(TAG, "Using volume " + mVolumeName);
+ mExternalImages = MediaStore.Images.Media.getContentUri(mVolumeName);
+
+ final Resources res = mContext.getResources();
+ final Configuration config = res.getConfiguration();
+ mLargestDimension = (int) (Math.max(config.screenWidthDp, config.screenHeightDp)
+ * res.getDisplayMetrics().density);
}
private void prepareImages() throws Exception {
- final File red = new File(Environment.getExternalStorageDirectory(), "red.jpg");
- final File blue = new File(Environment.getExternalStorageDirectory(), "blue.jpg");
- ProviderTestUtils.stageFile(R.raw.scenery, red);
- ProviderTestUtils.stageFile(R.raw.scenery, blue);
- try (MediaScanner scanner = new MediaScanner(mContext, "external")) {
- mRed = scanner.scanSingleFile(red.getAbsolutePath(), "image/jpeg");
- mBlue = scanner.scanSingleFile(blue.getAbsolutePath(), "image/jpeg");
- }
+ mRed = ProviderTestUtils.stageMedia(R.raw.scenery, mExternalImages);
+ mBlue = ProviderTestUtils.stageMedia(R.raw.scenery, mExternalImages);
mRowsAdded.add(mRed);
mRowsAdded.add(mBlue);
}
@@ -106,6 +131,7 @@
@Test
public void testQueryExternalThumbnails() throws Exception {
+ if (!MediaStore.VOLUME_EXTERNAL.equals(mVolumeName)) return;
prepareImages();
Cursor c = Thumbnails.queryMiniThumbnails(mContentResolver,
@@ -114,7 +140,8 @@
c.close();
// add a thumbnail
- final File file = mContext.getFileStreamPath("testThumbnails.jpg");
+ final File file = new File(ProviderTestUtils.stageDir(MediaStore.VOLUME_EXTERNAL),
+ "testThumbnails.jpg");
final String path = file.getAbsolutePath();
ProviderTestUtils.stageFile(R.raw.scenery, file);
ContentValues values = new ContentValues();
@@ -150,6 +177,9 @@
@Test
public void testQueryExternalMiniThumbnails() throws Exception {
+ if (!MediaStore.VOLUME_EXTERNAL.equals(mVolumeName)) return;
+ final ContentResolver resolver = mContentResolver;
+
// insert the image by bitmap
BitmapFactory.Options opts = new BitmapFactory.Options();
opts.inTargetDensity = DisplayMetrics.DENSITY_XHIGH;
@@ -174,31 +204,8 @@
c.close();
assertExists("image file does not exist", imagePath);
-
- String[] sizeProjection = new String[] { Thumbnails.WIDTH, Thumbnails.HEIGHT };
- c = Thumbnails.queryMiniThumbnail(mContentResolver, imageId, Thumbnails.MINI_KIND,
- sizeProjection);
- assertEquals(1, c.getCount());
- assertTrue(c.moveToFirst());
- assertMostlyEquals(320, c.getInt(c.getColumnIndex(Thumbnails.WIDTH)), 128);
- assertMostlyEquals(320, c.getInt(c.getColumnIndex(Thumbnails.HEIGHT)), 128);
- c.close();
- c = Thumbnails.queryMiniThumbnail(mContentResolver, imageId, Thumbnails.MICRO_KIND,
- sizeProjection);
- assertEquals(1, c.getCount());
- assertTrue(c.moveToFirst());
- assertMostlyEquals(96, c.getInt(c.getColumnIndex(Thumbnails.WIDTH)), 64);
- assertMostlyEquals(96, c.getInt(c.getColumnIndex(Thumbnails.HEIGHT)), 64);
- c.close();
-
- c = Thumbnails.queryMiniThumbnail(mContentResolver, imageId, Thumbnails.MINI_KIND,
- new String[] { Thumbnails._ID, Thumbnails.DATA, Thumbnails.IMAGE_ID});
-
- c.moveToNext();
- long img = c.getLong(c.getColumnIndex(Thumbnails.IMAGE_ID));
- assertEquals(imageId, img);
- String thumbPath = c.getString(c.getColumnIndex(Thumbnails.DATA));
- assertExists("thumbnail file does not exist", thumbPath);
+ assertNotNull(Thumbnails.getThumbnail(resolver, imageId, Thumbnails.MINI_KIND, null));
+ assertNotNull(Thumbnails.getThumbnail(resolver, imageId, Thumbnails.MICRO_KIND, null));
// deleting the image from the database also deletes the image file, and the
// corresponding entry in the thumbnail table, which in turn triggers deletion
@@ -207,14 +214,8 @@
mRowsAdded.remove(stringUri);
assertNotExists("image file should no longer exist", imagePath);
-
- Cursor c2 = Thumbnails.queryMiniThumbnail(mContentResolver, imageId, Thumbnails.MINI_KIND,
- new String[] { Thumbnails._ID, Thumbnails.DATA, Thumbnails.IMAGE_ID});
- assertEquals(0, c2.getCount());
- c2.close();
-
- assertNotExists("thumbnail file should no longer exist", thumbPath);
- c.close();
+ assertNull(Thumbnails.getThumbnail(resolver, imageId, Thumbnails.MINI_KIND, null));
+ assertNull(Thumbnails.getThumbnail(resolver, imageId, Thumbnails.MICRO_KIND, null));
// insert image, then delete it via the files table
stringUrl = Media.insertImage(mContentResolver, src, null, null);
@@ -228,30 +229,6 @@
Uri fileuri = MediaStore.Files.getContentUri("external", imageId);
mContentResolver.delete(fileuri, null, null);
assertNotExists("image file should no longer exist", imagePath);
-
-
- // insert image, then delete its thumbnail
- stringUrl = Media.insertImage(mContentResolver, src, null, null);
- c = mContentResolver.query(Uri.parse(stringUrl),
- new String[]{ Media._ID, Media.DATA}, null, null, null);
- c.moveToFirst();
- imageId = c.getLong(c.getColumnIndex(Media._ID));
- imagePath = c.getString(c.getColumnIndex(Media.DATA));
- c.close();
- c2 = Thumbnails.queryMiniThumbnail(mContentResolver, imageId, Thumbnails.MINI_KIND,
- new String[] { Thumbnails._ID, Thumbnails.DATA, Thumbnails.IMAGE_ID});
- c2.moveToFirst();
- thumbPath = c2.getString(c2.getColumnIndex(Thumbnails.DATA));
- assertExists("thumbnail file does not exist", thumbPath);
-
- Uri imguri = Uri.parse(stringUrl);
- long imgid = ContentUris.parseId(imguri);
- assertEquals(imgid, imageId);
- mRowsAdded.add(imguri);
- mContentResolver.delete(MediaStore.Images.Thumbnails.EXTERNAL_CONTENT_URI,
- MediaStore.Images.Thumbnails.IMAGE_ID + "=?", new String[]{ "" + imgid});
- assertNotExists("thumbnail file should no longer exist", thumbPath);
- assertExists("image file should still exist", imagePath);
}
@Test
@@ -260,18 +237,14 @@
assertNotNull(c = mContentResolver.query(Thumbnails.getContentUri("internal"), null, null,
null, null));
c.close();
- assertNotNull(c = mContentResolver.query(Thumbnails.getContentUri("external"), null, null,
+ assertNotNull(c = mContentResolver.query(Thumbnails.getContentUri(mVolumeName), null, null,
null, null));
c.close();
-
- // can not accept any other volume names
- String volume = "fakeVolume";
- assertNull(mContentResolver.query(Thumbnails.getContentUri(volume), null, null, null,
- null));
}
@Test
public void testStoreImagesMediaExternal() throws Exception {
+ if (!MediaStore.VOLUME_EXTERNAL.equals(mVolumeName)) return;
prepareImages();
final String externalImgPath = Environment.getExternalStorageDirectory() +
@@ -317,42 +290,30 @@
@Test
public void testThumbnailGenerationAndCleanup() throws Exception {
+ if (!MediaStore.VOLUME_EXTERNAL.equals(mVolumeName)) return;
+ final ContentResolver resolver = mContentResolver;
+
// insert an image
Bitmap src = BitmapFactory.decodeResource(mContext.getResources(), R.raw.scenery);
Uri uri = Uri.parse(Media.insertImage(mContentResolver, src, "test", "test description"));
+ long imageId = ContentUris.parseId(uri);
- // query its thumbnail
- Cursor c = mContentResolver.query(
- Thumbnails.EXTERNAL_CONTENT_URI,
- new String [] {Thumbnails.DATA},
- "image_id=?",
- new String[] {uri.getLastPathSegment()},
- null /* sort */
- );
- assertTrue("couldn't find thumbnail", c.moveToNext());
- String path = c.getString(0);
- c.close();
- assertExists("thumbnail does not exist", path);
+ assertNotNull(Thumbnails.getThumbnail(resolver, imageId, Thumbnails.MINI_KIND, null));
+ assertNotNull(Thumbnails.getThumbnail(resolver, imageId, Thumbnails.MICRO_KIND, null));
// delete the source image and check that the thumbnail is gone too
mContentResolver.delete(uri, null /* where clause */, null /* where args */);
- assertNotExists("thumbnail still exists after source file delete", path);
+
+ assertNull(Thumbnails.getThumbnail(resolver, imageId, Thumbnails.MINI_KIND, null));
+ assertNull(Thumbnails.getThumbnail(resolver, imageId, Thumbnails.MICRO_KIND, null));
// insert again
uri = Uri.parse(Media.insertImage(mContentResolver, src, "test", "test description"));
+ imageId = ContentUris.parseId(uri);
// query its thumbnail again
- c = mContentResolver.query(
- Thumbnails.EXTERNAL_CONTENT_URI,
- new String [] {Thumbnails.DATA},
- "image_id=?",
- new String[] {uri.getLastPathSegment()},
- null /* sortOrder */
- );
- assertTrue("couldn't find thumbnail", c.moveToNext());
- path = c.getString(0);
- c.close();
- assertExists("thumbnail does not exist", path);
+ assertNotNull(Thumbnails.getThumbnail(resolver, imageId, Thumbnails.MINI_KIND, null));
+ assertNotNull(Thumbnails.getThumbnail(resolver, imageId, Thumbnails.MICRO_KIND, null));
// update the media type
ContentValues values = new ContentValues();
@@ -361,23 +322,11 @@
1, mContentResolver.update(uri, values, null /* where */, null /* where args */));
// image was marked as regular file in the database, which should have deleted its thumbnail
-
- // query its thumbnail again
- c = mContentResolver.query(
- Thumbnails.EXTERNAL_CONTENT_URI,
- new String [] {Thumbnails.DATA},
- "image_id=?",
- new String[] {uri.getLastPathSegment()},
- null /* sort */
- );
- if (c != null) {
- assertFalse("thumbnail entry exists for non-thumbnail file", c.moveToNext());
- c.close();
- }
- assertNotExists("thumbnail remains after source file type change", path);
+ assertNull(Thumbnails.getThumbnail(resolver, imageId, Thumbnails.MINI_KIND, null));
+ assertNull(Thumbnails.getThumbnail(resolver, imageId, Thumbnails.MICRO_KIND, null));
// check source no longer exists as image
- c = mContentResolver.query(uri,
+ Cursor c = mContentResolver.query(uri,
null /* projection */, null /* where */, null /* where args */, null /* sort */);
assertFalse("source entry should be gone", c.moveToNext());
c.close();
@@ -411,6 +360,8 @@
@Test
public void testThumbnailOrderedQuery() throws Exception {
+ if (!MediaStore.VOLUME_EXTERNAL.equals(mVolumeName)) return;
+
Bitmap src = BitmapFactory.decodeResource(mContext.getResources(), R.raw.scenery);
Uri url[] = new Uri[3];
try{
@@ -456,4 +407,93 @@
fail("There is no sdcard attached! " + e.getMessage());
}
}
+
+ @Test
+ public void testInsertUpdateDelete() throws Exception {
+ final String displayName = "cts" + System.nanoTime();
+ final MediaStore.PendingParams params = new MediaStore.PendingParams(
+ mExternalImages, displayName, "image/png");
+ final Uri pendingUri = MediaStore.createPending(mContext, params);
+ final Uri finalUri;
+ try (MediaStore.PendingSession session = MediaStore.openPending(mContext, pendingUri)) {
+ try (OutputStream out = session.openOutputStream()) {
+ writeImage(mLargestDimension, mLargestDimension, Color.RED, out);
+ }
+ finalUri = session.publish();
+ }
+
+ // Directly reading should be larger
+ final Bitmap full = ImageDecoder
+ .decodeBitmap(ImageDecoder.createSource(mContentResolver, finalUri));
+ assertEquals(mLargestDimension, full.getWidth());
+ assertEquals(mLargestDimension, full.getHeight());
+
+ {
+ // Thumbnail should be smaller
+ final Bitmap thumb = mContentResolver.loadThumbnail(finalUri, new Size(32, 32), null);
+ assertTrue(thumb.getWidth() < full.getWidth());
+ assertTrue(thumb.getHeight() < full.getHeight());
+
+ // Thumbnail should match contents
+ assertColorMostlyEquals(Color.RED, thumb.getPixel(16, 16));
+ }
+
+ // Verify legacy APIs still work
+ if (MediaStore.VOLUME_EXTERNAL.equals(mVolumeName)) {
+ for (int kind : new int[] {
+ MediaStore.Images.Thumbnails.MINI_KIND,
+ MediaStore.Images.Thumbnails.FULL_SCREEN_KIND,
+ MediaStore.Images.Thumbnails.MICRO_KIND
+ }) {
+ // Thumbnail should be smaller
+ final Bitmap thumb = MediaStore.Images.Thumbnails.getThumbnail(mContentResolver,
+ ContentUris.parseId(finalUri), kind, null);
+ assertTrue(thumb.getWidth() < full.getWidth());
+ assertTrue(thumb.getHeight() < full.getHeight());
+
+ // Thumbnail should match contents
+ assertColorMostlyEquals(Color.RED, thumb.getPixel(16, 16));
+ }
+ }
+
+ // Edit image contents
+ try (OutputStream out = mContentResolver.openOutputStream(finalUri)) {
+ writeImage(mLargestDimension, mLargestDimension, Color.BLUE, out);
+ }
+
+ // Wait a few moments for events to settle
+ SystemClock.sleep(1000);
+
+ {
+ // Thumbnail should match updated contents
+ final Bitmap thumb = mContentResolver.loadThumbnail(finalUri, new Size(32, 32), null);
+ assertColorMostlyEquals(Color.BLUE, thumb.getPixel(16, 16));
+ }
+
+ // Delete image contents
+ mContentResolver.delete(finalUri, null, null);
+
+ // Thumbnail should no longer exist
+ try {
+ mContentResolver.loadThumbnail(finalUri, new Size(32, 32), null);
+ fail("Funky; we somehow made a thumbnail out of nothing?");
+ } catch (FileNotFoundException expected) {
+ }
+ }
+
+ private static void writeImage(int width, int height, int color, OutputStream out) {
+ final Bitmap bitmap = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);
+ final Canvas canvas = new Canvas(bitmap);
+ canvas.drawColor(color);
+ bitmap.compress(Bitmap.CompressFormat.PNG, 90, out);
+ }
+
+ /**
+ * Since thumbnails might be bounced through a compression pass, we're okay
+ * if they're mostly equal.
+ */
+ private static void assertColorMostlyEquals(int expected, int actual) {
+ assertEquals(Integer.toHexString(expected & 0xF0F0F0F0),
+ Integer.toHexString(actual & 0xF0F0F0F0));
+ }
}
diff --git a/tests/tests/provider/src/android/provider/cts/MediaStore_VideoTest.java b/tests/tests/provider/src/android/provider/cts/MediaStore_VideoTest.java
index 1a82b216..612e2b4 100644
--- a/tests/tests/provider/src/android/provider/cts/MediaStore_VideoTest.java
+++ b/tests/tests/provider/src/android/provider/cts/MediaStore_VideoTest.java
@@ -16,66 +16,70 @@
package android.provider.cts;
+import static android.provider.cts.MediaStoreTest.TAG;
+
import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
import android.content.ContentResolver;
import android.content.ContentValues;
import android.content.Context;
import android.database.Cursor;
import android.net.Uri;
+import android.provider.MediaStore;
import android.provider.MediaStore.Video;
import android.provider.MediaStore.Video.VideoColumns;
import android.support.test.InstrumentationRegistry;
-import android.support.test.runner.AndroidJUnit4;
+import android.util.Log;
-import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
+import org.junit.runners.Parameterized;
+import org.junit.runners.Parameterized.Parameter;
+import org.junit.runners.Parameterized.Parameters;
import java.io.File;
-import java.util.ArrayList;
-@RunWith(AndroidJUnit4.class)
+@RunWith(Parameterized.class)
public class MediaStore_VideoTest {
- private static final String TEST_VIDEO_3GP = "testVideo.3gp";
-
- private ArrayList<Uri> mRowsAdded;
-
private Context mContext;
+ private ContentResolver mResolver;
- private ContentResolver mContentResolver;
+ private Uri mExternalVideo;
- @After
- public void tearDown() throws Exception {
- for (Uri row : mRowsAdded) {
- mContentResolver.delete(row, null, null);
- }
+ @Parameter(0)
+ public String mVolumeName;
+
+ @Parameters
+ public static Iterable<? extends Object> data() {
+ return ProviderTestUtils.getSharedVolumeNames();
}
@Before
public void setUp() throws Exception {
mContext = InstrumentationRegistry.getTargetContext();
- mContentResolver = mContext.getContentResolver();
- mRowsAdded = new ArrayList<Uri>();
+ mResolver = mContext.getContentResolver();
+
+ Log.d(TAG, "Using volume " + mVolumeName);
+ mExternalVideo = MediaStore.Video.Media.getContentUri(mVolumeName);
}
@Test
public void testQuery() throws Exception {
ContentValues values = new ContentValues();
- final File file = mContext.getFileStreamPath(TEST_VIDEO_3GP);
+ final File file = new File(ProviderTestUtils.stageDir(mVolumeName),
+ "testVideo" + System.nanoTime() + ".3gp");
final String valueOfData = file.getAbsolutePath();
ProviderTestUtils.stageFile(R.raw.testvideo, file);
values.put(VideoColumns.DATA, valueOfData);
- Uri newUri = mContentResolver.insert(Video.Media.INTERNAL_CONTENT_URI, values);
- if (!Video.Media.INTERNAL_CONTENT_URI.equals(newUri)) {
- mRowsAdded.add(newUri);
- }
+ Uri newUri = mResolver.insert(mExternalVideo, values);
+ assertNotNull(newUri);
- Cursor c = Video.query(mContentResolver, newUri, new String[] { VideoColumns.DATA });
+ Cursor c = Video.query(mResolver, newUri, new String[] { VideoColumns.DATA });
assertEquals(1, c.getCount());
c.moveToFirst();
assertEquals(valueOfData, c.getString(c.getColumnIndex(VideoColumns.DATA)));
diff --git a/tests/tests/provider/src/android/provider/cts/MediaStore_Video_MediaTest.java b/tests/tests/provider/src/android/provider/cts/MediaStore_Video_MediaTest.java
index c1aae48..c4577b6 100644
--- a/tests/tests/provider/src/android/provider/cts/MediaStore_Video_MediaTest.java
+++ b/tests/tests/provider/src/android/provider/cts/MediaStore_Video_MediaTest.java
@@ -16,12 +16,12 @@
package android.provider.cts;
+import static android.provider.cts.MediaStoreTest.TAG;
import static android.provider.cts.ProviderTestUtils.assertExists;
import static android.provider.cts.ProviderTestUtils.assertNotExists;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
-import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;
@@ -30,31 +30,46 @@
import android.content.Context;
import android.database.Cursor;
import android.net.Uri;
-import android.os.Environment;
import android.provider.MediaStore;
import android.provider.MediaStore.Video.Media;
import android.provider.MediaStore.Video.VideoColumns;
import android.support.test.InstrumentationRegistry;
-import android.support.test.runner.AndroidJUnit4;
+import android.util.Log;
import com.android.compatibility.common.util.FileUtils;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
+import org.junit.runners.Parameterized;
+import org.junit.runners.Parameterized.Parameter;
+import org.junit.runners.Parameterized.Parameters;
import java.io.File;
import java.io.IOException;
-@RunWith(AndroidJUnit4.class)
+@RunWith(Parameterized.class)
public class MediaStore_Video_MediaTest {
private Context mContext;
private ContentResolver mContentResolver;
+ private Uri mExternalVideo;
+
+ @Parameter(0)
+ public String mVolumeName;
+
+ @Parameters
+ public static Iterable<? extends Object> data() {
+ return ProviderTestUtils.getSharedVolumeNames();
+ }
+
@Before
public void setUp() throws Exception {
mContext = InstrumentationRegistry.getTargetContext();
mContentResolver = mContext.getContentResolver();
+
+ Log.d(TAG, "Using volume " + mVolumeName);
+ mExternalVideo = MediaStore.Video.Media.getContentUri(mVolumeName);
}
@Test
@@ -63,26 +78,22 @@
assertNotNull(c = mContentResolver.query(Media.getContentUri("internal"), null, null, null,
null));
c.close();
- assertNotNull(c = mContentResolver.query(Media.getContentUri("external"), null, null, null,
+ assertNotNull(c = mContentResolver.query(Media.getContentUri(mVolumeName), null, null, null,
null));
c.close();
-
- // can not accept any other volume names
- String volume = "fakeVolume";
- assertNull(mContentResolver.query(Media.getContentUri(volume), null, null, null, null));
}
private void cleanExternalMediaFile(String path) {
- mContentResolver.delete(Media.EXTERNAL_CONTENT_URI, "_data=?", new String[] { path });
+ mContentResolver.delete(mExternalVideo, "_data=?", new String[] { path });
new File(path).delete();
}
@Test
public void testStoreVideoMediaExternal() throws Exception {
- final String externalVideoPath = Environment.getExternalStorageDirectory().getPath() +
- "/video/testvideo.3gp";
- final String externalVideoPath2 = Environment.getExternalStorageDirectory().getPath() +
- "/video/testvideo1.3gp";
+ final String externalVideoPath = new File(ProviderTestUtils.stageDir(mVolumeName),
+ "testvideo.3gp").getAbsolutePath();
+ final String externalVideoPath2 = new File(ProviderTestUtils.stageDir(mVolumeName),
+ "testvideo1.3gp").getAbsolutePath();
// clean up any potential left over entries from a previous aborted run
cleanExternalMediaFile(externalVideoPath);
@@ -116,7 +127,7 @@
values.put(Media.DATE_MODIFIED, dateModified);
// insert
- Uri uri = mContentResolver.insert(Media.EXTERNAL_CONTENT_URI, values);
+ Uri uri = mContentResolver.insert(mExternalVideo, values);
assertNotNull(uri);
try {
@@ -156,20 +167,10 @@
// check that the video file is removed when deleting the database entry
Context context = mContext;
Uri videoUri = insertVideo(context);
- File videofile = new File(Environment.getExternalStorageDirectory(), "testVideo.3gp");
+ File videofile = new File(ProviderTestUtils.stageDir(mVolumeName), "testVideo.3gp");
assertExists(videofile);
mContentResolver.delete(videoUri, null, null);
assertNotExists(videofile);
-
- // insert again, then delete with the "delete data" parameter set to false
- videoUri = insertVideo(context);
- assertExists(videofile);
- Uri.Builder builder = videoUri.buildUpon();
- builder.appendQueryParameter(MediaStore.PARAM_DELETE_DATA, "false");
- mContentResolver.delete(builder.build(), null, null);
- assertExists(videofile);
- videofile.delete();
-
}
@Test
@@ -185,7 +186,8 @@
}
private Uri insertVideo(Context context) throws IOException {
- File file = new File(Environment.getExternalStorageDirectory(), "testVideo.3gp");
+ final File dir = ProviderTestUtils.stageDir(mVolumeName);
+ final File file = new File(dir, "testVideo.3gp");
// clean up any potential left over entries from a previous aborted run
cleanExternalMediaFile(file.getAbsolutePath());
@@ -193,6 +195,6 @@
ContentValues values = new ContentValues();
values.put(VideoColumns.DATA, file.getAbsolutePath());
- return context.getContentResolver().insert(Media.EXTERNAL_CONTENT_URI, values);
+ return context.getContentResolver().insert(mExternalVideo, values);
}
}
diff --git a/tests/tests/provider/src/android/provider/cts/MediaStore_Video_ThumbnailsTest.java b/tests/tests/provider/src/android/provider/cts/MediaStore_Video_ThumbnailsTest.java
index fbc546f..e265206 100644
--- a/tests/tests/provider/src/android/provider/cts/MediaStore_Video_ThumbnailsTest.java
+++ b/tests/tests/provider/src/android/provider/cts/MediaStore_Video_ThumbnailsTest.java
@@ -16,11 +16,12 @@
package android.provider.cts;
-import static android.provider.cts.ProviderTestUtils.assertExists;
-import static android.provider.cts.ProviderTestUtils.assertNotExists;
+import static android.media.MediaMetadataRetriever.METADATA_KEY_VIDEO_HEIGHT;
+import static android.media.MediaMetadataRetriever.METADATA_KEY_VIDEO_WIDTH;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNotEquals;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertTrue;
@@ -31,26 +32,36 @@
import android.content.ContentValues;
import android.content.Context;
import android.database.Cursor;
+import android.graphics.Bitmap;
+import android.media.MediaMetadataRetriever;
import android.net.Uri;
-import android.os.Environment;
+import android.os.FileUtils;
+import android.os.SystemClock;
+import android.provider.MediaStore;
import android.provider.MediaStore.Files;
import android.provider.MediaStore.Video.Media;
import android.provider.MediaStore.Video.Thumbnails;
import android.provider.MediaStore.Video.VideoColumns;
import android.support.test.InstrumentationRegistry;
-import android.support.test.runner.AndroidJUnit4;
import android.util.Log;
+import android.util.Size;
import com.android.compatibility.common.util.MediaUtils;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
+import org.junit.runners.Parameterized;
+import org.junit.runners.Parameterized.Parameter;
+import org.junit.runners.Parameterized.Parameters;
import java.io.File;
+import java.io.FileNotFoundException;
import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
-@RunWith(AndroidJUnit4.class)
+@RunWith(Parameterized.class)
public class MediaStore_Video_ThumbnailsTest {
private static final String TAG = "MediaStore_Video_ThumbnailsTest";
@@ -62,10 +73,23 @@
mContext, R.raw.testthumbvideo, "video/");
}
+ private Uri mExternalVideo;
+
+ @Parameter(0)
+ public String mVolumeName;
+
+ @Parameters
+ public static Iterable<? extends Object> data() {
+ return ProviderTestUtils.getSharedVolumeNames();
+ }
+
@Before
public void setUp() throws Exception {
mContext = InstrumentationRegistry.getTargetContext();
mResolver = mContext.getContentResolver();
+
+ Log.d(TAG, "Using volume " + mVolumeName);
+ mExternalVideo = MediaStore.Video.Media.getContentUri(mVolumeName);
}
@Test
@@ -78,6 +102,8 @@
@Test
public void testGetThumbnail() throws Exception {
+ if (!MediaStore.VOLUME_EXTERNAL.equals(mVolumeName)) return;
+
// Insert a video into the provider.
Uri videoUri = insertVideo();
long videoId = ContentUris.parseId(videoUri);
@@ -85,9 +111,6 @@
assertEquals(ContentUris.withAppendedId(Media.EXTERNAL_CONTENT_URI, videoId),
videoUri);
- // Get the current thumbnail count for future comparison.
- int count = getThumbnailCount(Thumbnails.EXTERNAL_CONTENT_URI);
-
// Don't run the test if the codec isn't supported.
if (!hasCodec()) {
// Calling getThumbnail should not generate a new thumbnail.
@@ -100,31 +123,12 @@
assertNotNull(Thumbnails.getThumbnail(mResolver, videoId, Thumbnails.MINI_KIND, null));
assertNotNull(Thumbnails.getThumbnail(mResolver, videoId, Thumbnails.MICRO_KIND, null));
- // Check that an additional thumbnails have been registered.
- int count2 = getThumbnailCount(Thumbnails.EXTERNAL_CONTENT_URI);
- assertTrue(count2 > count);
-
- Cursor c = mResolver.query(Thumbnails.EXTERNAL_CONTENT_URI,
- new String[] { Thumbnails._ID, Thumbnails.DATA, Thumbnails.VIDEO_ID },
- null, null, null);
-
- if (c.moveToLast()) {
- long vid = c.getLong(2);
- assertEquals(videoId, vid);
- String path = c.getString(1);
- assertExists("thumbnail file does not exist", path);
- long id = c.getLong(0);
- mResolver.delete(ContentUris.withAppendedId(Thumbnails.EXTERNAL_CONTENT_URI, id),
- null, null);
- assertNotExists("thumbnail file should no longer exist", path);
- }
- c.close();
-
assertEquals(1, mResolver.delete(videoUri, null, null));
}
@Test
public void testThumbnailGenerationAndCleanup() throws Exception {
+ if (!MediaStore.VOLUME_EXTERNAL.equals(mVolumeName)) return;
if (!hasCodec()) {
// we don't support video, so no need to run the test
@@ -136,45 +140,20 @@
Uri uri = insertVideo();
// request thumbnail creation
- Thumbnails.getThumbnail(mResolver, Long.valueOf(uri.getLastPathSegment()),
- Thumbnails.MINI_KIND, null /* options */);
-
- // query the thumbnail
- Cursor c = mResolver.query(
- Thumbnails.EXTERNAL_CONTENT_URI,
- new String [] {Thumbnails.DATA},
- "video_id=?",
- new String[] {uri.getLastPathSegment()},
- null /* sort */
- );
- assertTrue("couldn't find thumbnail", c.moveToNext());
- String path = c.getString(0);
- c.close();
- assertExists("thumbnail does not exist", path);
+ assertNotNull(Thumbnails.getThumbnail(mResolver, Long.valueOf(uri.getLastPathSegment()),
+ Thumbnails.MINI_KIND, null /* options */));
// delete the source video and check that the thumbnail is gone too
mResolver.delete(uri, null /* where clause */, null /* where args */);
- assertNotExists("thumbnail still exists after source file delete", path);
+ assertNull(Thumbnails.getThumbnail(mResolver, Long.valueOf(uri.getLastPathSegment()),
+ Thumbnails.MINI_KIND, null /* options */));
// insert again
uri = insertVideo();
// request thumbnail creation
- Thumbnails.getThumbnail(mResolver, Long.valueOf(uri.getLastPathSegment()),
- Thumbnails.MINI_KIND, null);
-
- // query its thumbnail again
- c = mResolver.query(
- Thumbnails.EXTERNAL_CONTENT_URI,
- new String [] {Thumbnails.DATA},
- "video_id=?",
- new String[] {uri.getLastPathSegment()},
- null /* sort */
- );
- assertTrue("couldn't find thumbnail", c.moveToNext());
- path = c.getString(0);
- c.close();
- assertExists("thumbnail does not exist", path);
+ assertNotNull(Thumbnails.getThumbnail(mResolver, Long.valueOf(uri.getLastPathSegment()),
+ Thumbnails.MINI_KIND, null));
// update the media type
ContentValues values = new ContentValues();
@@ -183,23 +162,11 @@
1, mResolver.update(uri, values, null /* where */, null /* where args */));
// video was marked as regular file in the database, which should have deleted its thumbnail
-
- // query its thumbnail again
- c = mResolver.query(
- Thumbnails.EXTERNAL_CONTENT_URI,
- new String [] {Thumbnails.DATA},
- "video_id=?",
- new String[] {uri.getLastPathSegment()},
- null /* sort */
- );
- if (c != null) {
- assertFalse("thumbnail entry exists for non-thumbnail file", c.moveToNext());
- c.close();
- }
- assertNotExists("thumbnail remains after source file type change", path);
+ assertNull(Thumbnails.getThumbnail(mResolver, Long.valueOf(uri.getLastPathSegment()),
+ Thumbnails.MINI_KIND, null /* options */));
// check source no longer exists as video
- c = mResolver.query(uri,
+ Cursor c = mResolver.query(uri,
null /* projection */, null /* where */, null /* where args */, null /* sort */);
assertFalse("source entry should be gone", c.moveToNext());
c.close();
@@ -220,7 +187,8 @@
}
private Uri insertVideo() throws IOException {
- File file = new File(Environment.getExternalStorageDirectory(), "testVideo.3gp");
+ File file = new File(ProviderTestUtils.stageDir(MediaStore.VOLUME_EXTERNAL),
+ "testVideo" + System.nanoTime() + ".3gp");
// clean up any potential left over entries from a previous aborted run
mResolver.delete(Media.EXTERNAL_CONTENT_URI,
"_data=?", new String[] { file.getAbsolutePath() });
@@ -233,12 +201,69 @@
return mResolver.insert(Media.EXTERNAL_CONTENT_URI, values);
}
- private int getThumbnailCount(Uri uri) {
- Cursor cursor = mResolver.query(uri, null, null, null, null);
- try {
- return cursor.getCount();
- } finally {
- cursor.close();
+ @Test
+ public void testInsertUpdateDelete() throws Exception {
+ final Uri finalUri = ProviderTestUtils.stageMedia(R.raw.testvideo,
+ mExternalVideo, "video/mp4");
+
+ // Directly reading should be larger
+ final Size full;
+ try (MediaMetadataRetriever mmr = new MediaMetadataRetriever()) {
+ mmr.setDataSource(mContext, finalUri);
+ full = new Size(
+ Integer.parseInt(mmr.extractMetadata(METADATA_KEY_VIDEO_WIDTH)),
+ Integer.parseInt(mmr.extractMetadata(METADATA_KEY_VIDEO_HEIGHT)));
}
+
+ // Thumbnail should be smaller
+ final Bitmap beforeThumb = mResolver.loadThumbnail(finalUri, new Size(32, 32), null);
+ assertTrue(beforeThumb.getWidth() < full.getWidth());
+ assertTrue(beforeThumb.getHeight() < full.getHeight());
+ final int beforeColor = beforeThumb.getPixel(16, 16);
+
+ // Verify legacy APIs still work
+ if (MediaStore.VOLUME_EXTERNAL.equals(mVolumeName)) {
+ for (int kind : new int[] {
+ MediaStore.Video.Thumbnails.MINI_KIND,
+ MediaStore.Video.Thumbnails.FULL_SCREEN_KIND,
+ MediaStore.Video.Thumbnails.MICRO_KIND
+ }) {
+ assertNotNull(MediaStore.Video.Thumbnails.getThumbnail(mResolver,
+ ContentUris.parseId(finalUri), kind, null));
+ }
+ }
+
+ // Edit video contents
+ try (InputStream from = mContext.getResources().openRawResource(R.raw.testthumbvideo);
+ OutputStream to = mResolver.openOutputStream(finalUri)) {
+ FileUtils.copy(from, to);
+ }
+
+ // Wait a few moments for events to settle
+ SystemClock.sleep(1000);
+
+ // Thumbnail should match updated contents
+ final Bitmap afterThumb = mResolver.loadThumbnail(finalUri, new Size(32, 32), null);
+ final int afterColor = afterThumb.getPixel(16, 16);
+ assertNotColorMostlyEquals(beforeColor, afterColor);
+
+ // Delete video contents
+ mResolver.delete(finalUri, null, null);
+
+ // Thumbnail should no longer exist
+ try {
+ mResolver.loadThumbnail(finalUri, new Size(32, 32), null);
+ fail("Funky; we somehow made a thumbnail out of nothing?");
+ } catch (FileNotFoundException expected) {
+ }
+ }
+
+ /**
+ * Since thumbnails might be bounced through a compression pass, we're okay
+ * if they're mostly equal.
+ */
+ private static void assertNotColorMostlyEquals(int expected, int actual) {
+ assertNotEquals(Integer.toHexString(expected & 0xF0F0F0F0),
+ Integer.toHexString(actual & 0xF0F0F0F0));
}
}
diff --git a/tests/tests/provider/src/android/provider/cts/ProviderTestUtils.java b/tests/tests/provider/src/android/provider/cts/ProviderTestUtils.java
index d3e0af1..038291a 100644
--- a/tests/tests/provider/src/android/provider/cts/ProviderTestUtils.java
+++ b/tests/tests/provider/src/android/provider/cts/ProviderTestUtils.java
@@ -16,28 +16,46 @@
package android.provider.cts;
+import static android.provider.cts.MediaStoreTest.TAG;
+
import static org.junit.Assert.fail;
import android.app.UiAutomation;
+import android.content.ContentProviderClient;
+import android.content.ContentResolver;
import android.content.Context;
+import android.content.Intent;
+import android.content.res.AssetFileDescriptor;
+import android.database.Cursor;
import android.net.Uri;
+import android.os.Bundle;
+import android.os.Environment;
+import android.os.FileUtils;
import android.os.ParcelFileDescriptor;
+import android.os.storage.StorageManager;
import android.provider.MediaStore;
+import android.provider.MediaStore.MediaColumns;
import android.support.test.InstrumentationRegistry;
import android.system.ErrnoException;
import android.system.Os;
import android.system.OsConstants;
+import android.util.Log;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
+import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.nio.charset.StandardCharsets;
+import java.security.DigestInputStream;
+import java.security.MessageDigest;
+import java.util.Arrays;
import java.util.Objects;
+import java.util.Set;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
@@ -50,6 +68,17 @@
private static final Pattern BMGR_ENABLED_PATTERN = Pattern.compile(
"^Backup Manager currently (enabled|disabled)$");
+ static Iterable<String> getSharedVolumeNames() {
+ if (StorageManager.hasIsolatedStorage()) {
+ final Set<String> volumeNames = MediaStore
+ .getAllVolumeNames(InstrumentationRegistry.getTargetContext());
+ volumeNames.remove(MediaStore.VOLUME_INTERNAL);
+ return volumeNames;
+ } else {
+ return Arrays.asList(MediaStore.VOLUME_EXTERNAL);
+ }
+ }
+
static void setDefaultSmsApp(boolean setToSmsApp, String packageName, UiAutomation uiAutomation)
throws Exception {
String mode = setToSmsApp ? "allow" : "default";
@@ -58,8 +87,14 @@
executeShellCommand(String.format(cmd, packageName, "READ_SMS", mode), uiAutomation);
}
+ static String executeShellCommand(String command) throws IOException {
+ return executeShellCommand(command,
+ InstrumentationRegistry.getInstrumentation().getUiAutomation());
+ }
+
static String executeShellCommand(String command, UiAutomation uiAutomation)
throws IOException {
+ Log.v(TAG, "$ " + command);
ParcelFileDescriptor pfd = uiAutomation.executeShellCommand(command.toString());
BufferedReader br = null;
try (InputStream in = new FileInputStream(pfd.getFileDescriptor());) {
@@ -67,6 +102,7 @@
String str = null;
StringBuilder out = new StringBuilder();
while ((str = br.readLine()) != null) {
+ Log.v(TAG, "> " + str);
out.append(str);
}
return out.toString();
@@ -133,76 +169,150 @@
executeShellCommand("bmgr wipe " + backupTransport + " " + packageName, uiAutomation);
}
- static String stageInternalFile(int resId, String fileName) throws IOException {
- final Context context = InstrumentationRegistry.getTargetContext();
- try (InputStream source = context.getResources().openRawResource(resId);
- OutputStream target = context.openFileOutput(fileName, Context.MODE_PRIVATE)) {
- android.os.FileUtils.copy(source, target);
- }
- return context.getFileStreamPath(fileName).getAbsolutePath();
+ static File stageDir(String volumeName) throws IOException {
+ return Environment.buildPath(MediaStore.getVolumePath(volumeName), "Android", "media",
+ "android.provider.cts");
}
static void stageFile(int resId, File file) throws IOException {
- final Context context = InstrumentationRegistry.getTargetContext();
- try (InputStream source = context.getResources().openRawResource(resId);
- OutputStream target = new FileOutputStream(file)) {
- android.os.FileUtils.copy(source, target);
+ // The caller may be trying to stage into a location only available to
+ // the shell user, so we need to perform the entire copy as the shell
+ if (FileUtils.contains(Environment.getStorageDirectory(), file)) {
+ executeShellCommand("mkdir -p " + file.getParent());
+
+ final Context context = InstrumentationRegistry.getTargetContext();
+ try (AssetFileDescriptor afd = context.getResources().openRawResourceFd(resId)) {
+ final File source = ParcelFileDescriptor.getFile(afd.getFileDescriptor());
+ final long skip = afd.getStartOffset();
+ final long count = afd.getLength();
+
+ executeShellCommand(String.format("dd bs=1 if=%s skip=%d count=%d of=%s",
+ source.getAbsolutePath(), skip, count, file.getAbsolutePath()));
+
+ // Force sync to try updating other views
+ executeShellCommand("sync");
+ }
+ } else {
+ final File dir = file.getParentFile();
+ dir.mkdirs();
+ if (!dir.exists()) {
+ throw new FileNotFoundException("Failed to create parent for " + file);
+ }
+ final Context context = InstrumentationRegistry.getTargetContext();
+ try (InputStream source = context.getResources().openRawResource(resId);
+ OutputStream target = new FileOutputStream(file)) {
+ FileUtils.copy(source, target);
+ }
}
}
static Uri stageMedia(int resId, Uri collectionUri) throws IOException {
+ return stageMedia(resId, collectionUri, "image/png");
+ }
+
+ static Uri stageMedia(int resId, Uri collectionUri, String mimeType) throws IOException {
final Context context = InstrumentationRegistry.getTargetContext();
final String displayName = "cts" + System.nanoTime();
final MediaStore.PendingParams params = new MediaStore.PendingParams(
- collectionUri, displayName, "image/png");
+ collectionUri, displayName, mimeType);
final Uri pendingUri = MediaStore.createPending(context, params);
try (MediaStore.PendingSession session = MediaStore.openPending(context, pendingUri)) {
try (InputStream source = context.getResources().openRawResource(resId);
OutputStream target = session.openOutputStream()) {
- android.os.FileUtils.copy(source, target);
+ FileUtils.copy(source, target);
}
return session.publish();
}
}
- public static void assertExists(String path) throws ErrnoException {
+ static Uri scanFile(File file) throws Exception {
+ final ContentResolver resolver = InstrumentationRegistry.getTargetContext()
+ .getContentResolver();
+ try (ContentProviderClient cpc = resolver
+ .acquireContentProviderClient(MediaStore.AUTHORITY)) {
+ final Bundle in = new Bundle();
+ in.putParcelable(Intent.EXTRA_STREAM, Uri.fromFile(file));
+ in.putBoolean(Intent.EXTRA_LOCAL_ONLY, true);
+ final Bundle out = cpc.call(MediaStore.AUTHORITY, MediaStore.SCAN_FILE_CALL, null, in);
+ return out.getParcelable(Intent.EXTRA_STREAM);
+ }
+ }
+
+ static void scanVolume(File file) throws Exception {
+ final ContentResolver resolver = InstrumentationRegistry.getTargetContext()
+ .getContentResolver();
+ try (ContentProviderClient cpc = resolver
+ .acquireContentProviderClient(MediaStore.AUTHORITY)) {
+ final Bundle in = new Bundle();
+ in.putParcelable(Intent.EXTRA_STREAM, Uri.fromFile(file));
+ in.putBoolean(Intent.EXTRA_LOCAL_ONLY, true);
+ cpc.call(MediaStore.AUTHORITY, MediaStore.SCAN_VOLUME_CALL, null, in);
+ }
+ }
+
+ public static byte[] hash(InputStream in) throws Exception {
+ try (DigestInputStream digestIn = new DigestInputStream(in,
+ MessageDigest.getInstance("SHA-1"));
+ OutputStream out = new FileOutputStream(new File("/dev/null"))) {
+ FileUtils.copy(digestIn, out);
+ return digestIn.getMessageDigest().digest();
+ }
+ }
+
+ public static void assertExists(String path) throws IOException {
assertExists(null, path);
}
- public static void assertExists(File file) throws ErrnoException {
+ public static void assertExists(File file) throws IOException {
assertExists(null, file.getAbsolutePath());
}
- public static void assertExists(String msg, String path) throws ErrnoException {
- try {
- Os.access(path, OsConstants.F_OK);
- } catch (ErrnoException e) {
- if (e.errno == OsConstants.ENOENT) {
- fail(msg);
- } else {
- throw e;
- }
+ public static void assertExists(String msg, String path) throws IOException {
+ if (!access(path)) {
+ fail(msg);
}
}
- public static void assertNotExists(String path) throws ErrnoException {
+ public static void assertNotExists(String path) throws IOException {
assertNotExists(null, path);
}
- public static void assertNotExists(File file) throws ErrnoException {
+ public static void assertNotExists(File file) throws IOException {
assertNotExists(null, file.getAbsolutePath());
}
- public static void assertNotExists(String msg, String path) throws ErrnoException {
- try {
- Os.access(path, OsConstants.F_OK);
+ public static void assertNotExists(String msg, String path) throws IOException {
+ if (access(path)) {
fail(msg);
- } catch (ErrnoException e) {
- if (e.errno == OsConstants.ENOENT) {
- return;
- } else {
- throw e;
+ }
+ }
+
+ private static boolean access(String path) throws IOException {
+ // The caller may be trying to stage into a location only available to
+ // the shell user, so we need to perform the entire copy as the shell
+ if (FileUtils.contains(Environment.getStorageDirectory(), new File(path))) {
+ return executeShellCommand("ls -la " + path).contains(path);
+ } else {
+ try {
+ Os.access(path, OsConstants.F_OK);
+ return true;
+ } catch (ErrnoException e) {
+ if (e.errno == OsConstants.ENOENT) {
+ return false;
+ } else {
+ throw new IOException(e.getMessage());
+ }
}
}
}
+
+ public static boolean containsId(Uri uri, long id) {
+ try (Cursor c = InstrumentationRegistry.getTargetContext().getContentResolver().query(uri,
+ new String[] { MediaColumns._ID }, null, null)) {
+ while (c.moveToNext()) {
+ if (c.getLong(0) == id) return true;
+ }
+ }
+ return false;
+ }
}
diff --git a/tests/tests/provider/src/android/provider/cts/SettingsPanelTest.java b/tests/tests/provider/src/android/provider/cts/SettingsPanelTest.java
index 01be317..917b1bc 100644
--- a/tests/tests/provider/src/android/provider/cts/SettingsPanelTest.java
+++ b/tests/tests/provider/src/android/provider/cts/SettingsPanelTest.java
@@ -98,6 +98,15 @@
}
@Test
+ public void nfcPanel_correctPackage() {
+ launchNfcPanel();
+
+ String currentPackage = mDevice.getCurrentPackageName();
+
+ assertThat(currentPackage).isEqualTo(SETTINGS_PACKAGE);
+ }
+
+ @Test
public void internetPanel_correctTitle() {
launchInternetPanel();
@@ -116,6 +125,15 @@
}
@Test
+ public void nfcPanel_correctTitle() {
+ launchNfcPanel();
+
+ final UiObject2 titleView = mDevice.findObject(By.res(SETTINGS_PACKAGE, RESOURCE_TITLE));
+
+ assertThat(titleView.getText()).isEqualTo("NFC");
+ }
+
+ @Test
public void internetPanel_doneClosesPanel() {
// Launch panel
launchInternetPanel();
@@ -148,6 +166,22 @@
}
@Test
+ public void nfcPanel_doneClosesPanel() {
+ // Launch panel
+ launchNfcPanel();
+ String currentPackage = mDevice.getCurrentPackageName();
+ assertThat(currentPackage).isEqualTo(SETTINGS_PACKAGE);
+
+ // Click the done button
+ mDevice.findObject(By.res(SETTINGS_PACKAGE, RESOURCE_DONE)).click();
+ mDevice.wait(Until.hasObject(By.pkg(mLauncherPackage).depth(0)), TIMEOUT);
+
+ // Assert that we have left the panel
+ currentPackage = mDevice.getCurrentPackageName();
+ assertThat(currentPackage).isNotEqualTo(SETTINGS_PACKAGE);
+ }
+
+ @Test
public void internetPanel_seeMoreButton_launchesIntoSettings() {
// Launch panel
launchInternetPanel();
@@ -183,6 +217,24 @@
assertThat(titleView).isNull();
}
+ @Test
+ public void nfcPanel_seeMoreButton_launchesIntoSettings() {
+ // Launch panel
+ launchNfcPanel();
+ String currentPackage = mDevice.getCurrentPackageName();
+ assertThat(currentPackage).isEqualTo(SETTINGS_PACKAGE);
+
+ // Click the see more button
+ mDevice.findObject(By.res(SETTINGS_PACKAGE, RESOURCE_SEE_MORE)).click();
+ mDevice.wait(Until.hasObject(By.pkg(SETTINGS_PACKAGE).depth(0)), TIMEOUT);
+
+ // Assert that we're still in Settings, on a different page.
+ currentPackage = mDevice.getCurrentPackageName();
+ assertThat(currentPackage).isEqualTo(SETTINGS_PACKAGE);
+ UiObject2 titleView = mDevice.findObject(By.res(SETTINGS_PACKAGE, RESOURCE_TITLE));
+ assertThat(titleView).isNull();
+ }
+
private void launchVolumePanel() {
launchPanel(Settings.Panel.ACTION_VOLUME);
}
@@ -191,6 +243,10 @@
launchPanel(Settings.Panel.ACTION_INTERNET_CONNECTIVITY);
}
+ private void launchNfcPanel() {
+ launchPanel(Settings.Panel.ACTION_NFC);
+ }
+
private void launchPanel(String action) {
// Start from the home screen
mDevice.pressHome();
diff --git a/tests/tests/provider/src/android/provider/cts/contacts/ContactsContractIntentsTest.java b/tests/tests/provider/src/android/provider/cts/contacts/ContactsContractIntentsTest.java
index c0ff4c0..be9d1d2 100644
--- a/tests/tests/provider/src/android/provider/cts/contacts/ContactsContractIntentsTest.java
+++ b/tests/tests/provider/src/android/provider/cts/contacts/ContactsContractIntentsTest.java
@@ -32,7 +32,7 @@
List<ResolveInfo> resolveInfoList = getContext()
.getPackageManager().queryIntentActivities(intent, 0);
assertNotNull("Missing ResolveInfo", resolveInfoList);
- assertTrue("No ResolveInfo found for " + intent.toInsecureString(),
+ assertTrue("No ResolveInfo found for " + intent.toString(),
resolveInfoList.size() > 0);
}
diff --git a/tests/tests/provider/src/android/provider/cts/contacts/ContactsContract_AggregationSuggestionsTest.java b/tests/tests/provider/src/android/provider/cts/contacts/ContactsContract_AggregationSuggestionsTest.java
index c19e571..7b3a93a 100644
--- a/tests/tests/provider/src/android/provider/cts/contacts/ContactsContract_AggregationSuggestionsTest.java
+++ b/tests/tests/provider/src/android/provider/cts/contacts/ContactsContract_AggregationSuggestionsTest.java
@@ -59,7 +59,7 @@
long [] contactIds = setupThreeContacts();
// Setup: create query with first and last name reversed.
- Uri uri = AggregationSuggestions.builder()
+ Uri uri = new AggregationSuggestions.Builder()
.addNameParameter("last1 first1")
.build();
@@ -81,7 +81,7 @@
long [] contactIds = setupThreeContacts();
// Setup: create query with first and last name in same order as display name.
- Uri uri = AggregationSuggestions.builder()
+ Uri uri = new AggregationSuggestions.Builder()
.addNameParameter("first1 last1")
.build();
@@ -102,7 +102,7 @@
setupThreeContacts();
// Setup: query with name that is completely different than all the contacts.
- Uri uri = AggregationSuggestions.builder()
+ Uri uri = new AggregationSuggestions.Builder()
.addNameParameter("unmatched name")
.build();
@@ -118,7 +118,7 @@
long [] contactIds = setupThreeContacts();
// Setup: query with two names. The first name is completely unlike all the contacts.
- Uri uri = AggregationSuggestions.builder()
+ Uri uri = new AggregationSuggestions.Builder()
.addNameParameter("unmatched name")
.addNameParameter("first2 last2")
.build();
@@ -139,7 +139,7 @@
long [] contactIds = setupThreeContacts();
// Setup: query with two names. The second name is completely unlike all the contacts.
- Uri uri = AggregationSuggestions.builder()
+ Uri uri = new AggregationSuggestions.Builder()
.addNameParameter("first2 last2")
.addNameParameter("unmatched name")
.build();
diff --git a/tests/tests/provider/src/android/provider/cts/contacts/ContactsContract_QuickContactsTest.java b/tests/tests/provider/src/android/provider/cts/contacts/ContactsContract_QuickContactsTest.java
index 5e27e21..89960cc 100644
--- a/tests/tests/provider/src/android/provider/cts/contacts/ContactsContract_QuickContactsTest.java
+++ b/tests/tests/provider/src/android/provider/cts/contacts/ContactsContract_QuickContactsTest.java
@@ -50,12 +50,10 @@
testCallback(intent);
}
- @Override
public void startActivityAsUser(Intent intent, UserHandle user) {
testCallback(intent);
}
- @Override
public void startActivityAsUser(Intent intent, Bundle options, UserHandle user) {
testCallback(intent);
}
diff --git a/tests/tests/provider/src/android/provider/cts/contacts/ContactsContract_StreamItemPhotosTest.java b/tests/tests/provider/src/android/provider/cts/contacts/ContactsContract_StreamItemPhotosTest.java
deleted file mode 100644
index 24cc122..0000000
--- a/tests/tests/provider/src/android/provider/cts/contacts/ContactsContract_StreamItemPhotosTest.java
+++ /dev/null
@@ -1,76 +0,0 @@
-/*
- * Copyright (C) 2012 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.provider.cts.contacts;
-
-import android.content.ContentResolver;
-import android.content.ContentUris;
-import android.content.ContentValues;
-import android.net.Uri;
-import android.provider.ContactsContract.StreamItemPhotos;
-import android.provider.ContactsContract.StreamItems;
-import android.provider.cts.PhotoUtil;
-import android.test.AndroidTestCase;
-
-public class ContactsContract_StreamItemPhotosTest extends AndroidTestCase {
-
- private ContentResolver mResolver;
-
- private Uri mStreamItemUri;
-
- private long mStreamItemId;
-
- @Override
- protected void setUp() throws Exception {
- super.setUp();
- mResolver = mContext.getContentResolver();
-
- long rawContactId = ContactsContract_StreamItemsTest.insertRawContact(mResolver);
- mStreamItemUri = ContactsContract_StreamItemsTest.insertViaContentDirectoryUri(mResolver,
- rawContactId);
- mStreamItemId = ContentUris.parseId(mStreamItemUri);
- assertTrue(mStreamItemId != -1);
- }
-
- public void testContentDirectoryUri() {
- byte[] photoData = PhotoUtil.getTestPhotoData(mContext);
- ContentValues values = new ContentValues();
- values.put(StreamItemPhotos.SORT_INDEX, 1);
- values.put(StreamItemPhotos.PHOTO, photoData);
-
- Uri insertUri = Uri.withAppendedPath(
- ContentUris.withAppendedId(StreamItems.CONTENT_URI, mStreamItemId),
- StreamItems.StreamItemPhotos.CONTENT_DIRECTORY);
- Uri uri = mResolver.insert(insertUri, values);
- long photoId = ContentUris.parseId(uri);
- assertTrue(photoId != -1);
- assertEquals(Uri.withAppendedPath(insertUri, Long.toString(photoId)), uri);
- }
-
- public void testContentPhotoUri() {
- byte[] photoData = PhotoUtil.getTestPhotoData(mContext);
- ContentValues values = new ContentValues();
- values.put(StreamItemPhotos.STREAM_ITEM_ID, mStreamItemId);
- values.put(StreamItemPhotos.SORT_INDEX, 1);
- values.put(StreamItemPhotos.PHOTO, photoData);
-
- Uri uri = mResolver.insert(StreamItems.CONTENT_PHOTO_URI, values);
- long photoId = ContentUris.parseId(uri);
- assertTrue(photoId != -1);
- assertEquals(Uri.withAppendedPath(StreamItems.CONTENT_PHOTO_URI,
- Long.toString(photoId)), uri);
- }
-}
diff --git a/tests/tests/provider/src/android/provider/cts/contacts/ContactsContract_StreamItemsTest.java b/tests/tests/provider/src/android/provider/cts/contacts/ContactsContract_StreamItemsTest.java
deleted file mode 100644
index a69b97c..0000000
--- a/tests/tests/provider/src/android/provider/cts/contacts/ContactsContract_StreamItemsTest.java
+++ /dev/null
@@ -1,182 +0,0 @@
-/*
- * Copyright (C) 2012 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.provider.cts.contacts;
-
-import android.content.ContentProviderOperation;
-import android.content.ContentProviderResult;
-import android.content.ContentResolver;
-import android.content.ContentUris;
-import android.content.ContentValues;
-import android.database.Cursor;
-import android.net.Uri;
-import android.provider.ContactsContract;
-import android.provider.ContactsContract.Data;
-import android.provider.ContactsContract.RawContacts;
-import android.provider.ContactsContract.StreamItems;
-import android.test.AndroidTestCase;
-
-import java.util.ArrayList;
-
-public class ContactsContract_StreamItemsTest extends AndroidTestCase {
-
- private static final String ACCOUNT_TYPE = "com.android.cts";
- private static final String ACCOUNT_NAME = "ContactsContract_StreamItemsTest";
-
- private static final String INSERT_TEXT = "Wrote a test for the StreamItems class";
- private static final long INSERT_TIMESTAMP = 3007;
- private static final String INSERT_COMMENTS = "1337 people reshared this";
-
- private static final String UPDATE_TEXT = "Wrote more tests for the StreamItems class";
- private static final long UPDATE_TIMESTAMP = 8008;
- private static final String UPDATE_COMMENTS = "3007 people reshared this";
-
- private ContentResolver mResolver;
-
- @Override
- protected void setUp() throws Exception {
- super.setUp();
- mResolver = mContext.getContentResolver();
- }
-
- public void testContentDirectoryUri() throws Exception {
- long rawContactId = insertRawContact(mResolver);
- Uri streamItemUri = insertViaContentDirectoryUri(mResolver, rawContactId);
- long streamItemId = ContentUris.parseId(streamItemUri);
- assertTrue(streamItemId != -1);
-
- // Check that the provider returns the stream id in it's URI.
- assertEquals(streamItemUri,
- ContentUris.withAppendedId(RawContacts.CONTENT_URI, rawContactId).buildUpon()
- .appendPath(RawContacts.StreamItems.CONTENT_DIRECTORY)
- .appendPath(Long.toString(streamItemId))
- .build());
-
- // Check that the provider stored what we put into it.
- assertInsertedItem(streamItemUri);
-
- // Update the stream item.
- ContentValues values = new ContentValues();
- values.put(Data.RAW_CONTACT_ID, rawContactId);
- values.put(RawContacts.ACCOUNT_TYPE, ACCOUNT_TYPE);
- values.put(RawContacts.ACCOUNT_NAME, ACCOUNT_NAME);
- values.put(StreamItems.TEXT, UPDATE_TEXT);
- values.put(StreamItems.TIMESTAMP, UPDATE_TIMESTAMP);
- values.put(StreamItems.COMMENTS, UPDATE_COMMENTS);
-
- assertEquals(1, mResolver.update(streamItemUri, values, null, null));
- assertUpdatedItem(streamItemUri);
- }
-
- static long insertRawContact(ContentResolver resolver) {
- // Create a contact to attach the stream item to it.
- ContentValues values = new ContentValues();
- values.put(RawContacts.ACCOUNT_TYPE, ACCOUNT_TYPE);
- values.put(RawContacts.ACCOUNT_NAME, ACCOUNT_NAME);
-
- Uri contactUri = resolver.insert(RawContacts.CONTENT_URI, values);
- long rawContactId = ContentUris.parseId(contactUri);
- assertTrue(rawContactId != -1);
- return rawContactId;
- }
-
- static Uri insertViaContentDirectoryUri(ContentResolver resolver, long rawContactId) {
- // Attach a stream item to the contact.
- ContentValues values = new ContentValues();
- values.put(RawContacts.ACCOUNT_TYPE, ACCOUNT_TYPE);
- values.put(RawContacts.ACCOUNT_NAME, ACCOUNT_NAME);
- values.put(StreamItems.TEXT, INSERT_TEXT);
- values.put(StreamItems.TIMESTAMP, INSERT_TIMESTAMP);
- values.put(StreamItems.COMMENTS, INSERT_COMMENTS);
-
- Uri contactStreamUri = Uri.withAppendedPath(
- ContentUris.withAppendedId(RawContacts.CONTENT_URI, rawContactId),
- RawContacts.StreamItems.CONTENT_DIRECTORY);
- return resolver.insert(contactStreamUri, values);
- }
-
- public void testContentUri() throws Exception {
- // Create a contact with one stream item in it.
- ArrayList<ContentProviderOperation> ops = new ArrayList<ContentProviderOperation>();
-
- ops.add(ContentProviderOperation.newInsert(RawContacts.CONTENT_URI)
- .withValue(RawContacts.ACCOUNT_TYPE, ACCOUNT_TYPE)
- .withValue(RawContacts.ACCOUNT_NAME, ACCOUNT_NAME)
- .build());
-
- ops.add(ContentProviderOperation.newInsert(StreamItems.CONTENT_URI)
- .withValueBackReference(Data.RAW_CONTACT_ID, 0)
- .withValue(RawContacts.ACCOUNT_TYPE, ACCOUNT_TYPE)
- .withValue(RawContacts.ACCOUNT_NAME, ACCOUNT_NAME)
- .withValue(StreamItems.TEXT, INSERT_TEXT)
- .withValue(StreamItems.TIMESTAMP, INSERT_TIMESTAMP)
- .withValue(StreamItems.COMMENTS, INSERT_COMMENTS)
- .build());
-
- ContentProviderResult[] results = mResolver.applyBatch(ContactsContract.AUTHORITY, ops);
- long rawContactId = ContentUris.parseId(results[0].uri);
- assertTrue(rawContactId != -1);
-
- Uri streamItemUri = results[1].uri;
- long streamItemId = ContentUris.parseId(streamItemUri);
- assertTrue(streamItemId != -1);
-
- // Check that the provider returns the stream id in it's URI.
- assertEquals(streamItemUri,
- ContentUris.withAppendedId(StreamItems.CONTENT_URI, streamItemId));
-
- // Check that the provider stored what we put into it.
- assertInsertedItem(streamItemUri);
-
- // Update the stream item.
- ops.clear();
- ops.add(ContentProviderOperation.newUpdate(streamItemUri)
- .withValue(Data.RAW_CONTACT_ID, rawContactId)
- .withValue(RawContacts.ACCOUNT_TYPE, ACCOUNT_TYPE)
- .withValue(RawContacts.ACCOUNT_NAME, ACCOUNT_NAME)
- .withValue(StreamItems.TEXT, UPDATE_TEXT)
- .withValue(StreamItems.TIMESTAMP, UPDATE_TIMESTAMP)
- .withValue(StreamItems.COMMENTS, UPDATE_COMMENTS)
- .build());
-
- results = mResolver.applyBatch(ContactsContract.AUTHORITY, ops);
- assertEquals(Integer.valueOf(1), results[0].count);
- assertUpdatedItem(streamItemUri);
- }
-
- private void assertInsertedItem(Uri itemUri) {
- assertStreamItem(itemUri, INSERT_TEXT, INSERT_TIMESTAMP, INSERT_COMMENTS);
- }
-
- private void assertUpdatedItem(Uri itemUri) {
- assertStreamItem(itemUri, UPDATE_TEXT, UPDATE_TIMESTAMP, UPDATE_COMMENTS);
- }
-
- private void assertStreamItem(Uri uri, String text, long timestamp, String comments) {
- Cursor cursor = mResolver.query(uri, null, null, null, null);
- try {
- assertTrue(cursor.moveToFirst());
- assertEquals(text, cursor.getString(
- cursor.getColumnIndexOrThrow(StreamItems.TEXT)));
- assertEquals(timestamp, cursor.getLong(
- cursor.getColumnIndexOrThrow(StreamItems.TIMESTAMP)));
- assertEquals(comments, cursor.getString(
- cursor.getColumnIndexOrThrow(StreamItems.COMMENTS)));
- } finally {
- cursor.close();
- }
- }
-}
diff --git a/tests/tests/provider/src/android/provider/cts/contacts/ContactsContract_TestDataBuilder.java b/tests/tests/provider/src/android/provider/cts/contacts/ContactsContract_TestDataBuilder.java
index a923584..15b228c 100644
--- a/tests/tests/provider/src/android/provider/cts/contacts/ContactsContract_TestDataBuilder.java
+++ b/tests/tests/provider/src/android/provider/cts/contacts/ContactsContract_TestDataBuilder.java
@@ -16,9 +16,6 @@
package android.provider.cts.contacts;
-import com.google.android.collect.Lists;
-import com.google.android.collect.Sets;
-
import android.content.ContentProviderClient;
import android.content.ContentUris;
import android.content.ContentValues;
@@ -32,22 +29,22 @@
import android.provider.ContactsContract.RawContacts;
import android.text.TextUtils;
+import junit.framework.Assert;
+import junit.framework.ComparisonFailure;
+
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
-import junit.framework.Assert;
-import junit.framework.ComparisonFailure;
-
/**
* A test data builder for ContactsContract tests.
*/
public class ContactsContract_TestDataBuilder {
private ContentProviderClient mProvider;
- private ArrayList<Builder<?>> mCreatedRows = Lists.newArrayList();
- private HashSet<Builder<?>> mLoadedRows = Sets.newHashSet();
+ private ArrayList<Builder<?>> mCreatedRows = new ArrayList<>();
+ private HashSet<Builder<?>> mLoadedRows = new HashSet<>();
private interface IdQuery {
String[] COLUMNS = new String[] {
@@ -170,7 +167,7 @@
mLoadedRows.add(this);
StringBuilder selection = new StringBuilder();
- ArrayList<String> selectionArgs = Lists.newArrayList();
+ ArrayList<String> selectionArgs = new ArrayList<>();
Set<Map.Entry<String, Object>> entries = mValues.valueSet();
for (Map.Entry<String, Object> entry : entries) {
String column = entry.getKey();
diff --git a/tests/tests/provider/src/android/provider/cts/contacts/ContactsProvider2_AccountRemovalTest.java b/tests/tests/provider/src/android/provider/cts/contacts/ContactsProvider2_AccountRemovalTest.java
index ced09d6..4f82a49 100755
--- a/tests/tests/provider/src/android/provider/cts/contacts/ContactsProvider2_AccountRemovalTest.java
+++ b/tests/tests/provider/src/android/provider/cts/contacts/ContactsProvider2_AccountRemovalTest.java
@@ -16,26 +16,18 @@
package android.provider.cts.contacts;
-import static android.provider.cts.contacts.DatabaseAsserts.ContactIdPair;
-
import android.accounts.Account;
import android.accounts.AccountManager;
import android.content.ContentResolver;
import android.os.SystemClock;
-import android.provider.cts.contacts.CommonDatabaseUtils;
-import android.provider.cts.contacts.ContactUtil;
-import android.provider.cts.contacts.DataUtil;
-import android.provider.cts.contacts.DatabaseAsserts;
-import android.provider.cts.contacts.DeletedContactUtil;
-import android.provider.cts.contacts.RawContactUtil;
+import android.provider.cts.contacts.DatabaseAsserts.ContactIdPair;
import android.provider.cts.contacts.account.StaticAccountAuthenticator;
import android.test.AndroidTestCase;
import android.test.suitebuilder.annotation.MediumTest;
-import com.google.android.collect.Lists;
-
import java.util.ArrayList;
import java.util.Arrays;
+import java.util.List;
@MediumTest
public class ContactsProvider2_AccountRemovalTest extends AndroidTestCase {
@@ -102,7 +94,7 @@
*/
public void testAccountRemovalWithMergedContact_deletesContacts() {
mAccountManager.addAccountExplicitly(ACCT_1, null, null);
- ArrayList<ContactIdPair> idList = createAndAssertMergedContact(ACCT_1, ACCT_1);
+ List<ContactIdPair> idList = createAndAssertMergedContact(ACCT_1, ACCT_1);
mAccountManager.removeAccount(ACCT_1, null, null);
assertContactsDeletedEventually(System.currentTimeMillis(), idList);
}
@@ -114,7 +106,7 @@
public void testAccountRemovalWithMergedContact_doesNotDeleteContactAndTimestampUpdated() {
mAccountManager.addAccountExplicitly(ACCT_1, null, null);
mAccountManager.addAccountExplicitly(ACCT_2, null, null);
- ArrayList<ContactIdPair> idList = createAndAssertMergedContact(ACCT_1, ACCT_2);
+ List<ContactIdPair> idList = createAndAssertMergedContact(ACCT_1, ACCT_2);
long contactId = idList.get(0).mContactId;
long baseTime = ContactUtil.queryContactLastUpdatedTimestamp(mResolver, contactId);
@@ -131,13 +123,13 @@
public void testAccountRemovalWithMergedContact_hasDeleteLogsForContacts() {
mAccountManager.addAccountExplicitly(ACCT_1, null, null);
- ArrayList<ContactIdPair> idList = createAndAssertMergedContact(ACCT_1, ACCT_1);
+ List<ContactIdPair> idList = createAndAssertMergedContact(ACCT_1, ACCT_1);
long start = System.currentTimeMillis();
mAccountManager.removeAccount(ACCT_1, null, null);
assertContactsInDeleteLogEventually(start, idList);
}
- private ArrayList<ContactIdPair> createAndAssertMergedContact(Account acct, Account acct2) {
+ private List<ContactIdPair> createAndAssertMergedContact(Account acct, Account acct2) {
ContactIdPair ids1 = DatabaseAsserts.assertAndCreateContactWithName(mResolver, acct,
"merge me");
DataUtil.insertPhoneNumber(mResolver, ids1.mRawContactId, "555-5555");
@@ -154,7 +146,7 @@
ids1.mContactId = mergedContactId;
ids2.mContactId = mergedContactId;
- return Lists.newArrayList(ids1, ids2);
+ return Arrays.asList(ids1, ids2);
}
private long assertMerged(long start, long rawContactId, long rawContactId2) {
@@ -178,7 +170,7 @@
return NOT_MERGED;
}
- private void assertContactsInDeleteLogEventually(long start, ArrayList<ContactIdPair> idList) {
+ private void assertContactsInDeleteLogEventually(long start, List<ContactIdPair> idList) {
// Can not use newArrayList() because the version that accepts size is missing.
ArrayList<ContactIdPair> remaining = new ArrayList<ContactIdPair>(idList.size());
remaining.addAll(idList);
@@ -189,7 +181,7 @@
" are not in delete log after account removal.");
// Need a second list to remove since we can't remove from the list while iterating.
- ArrayList<ContactIdPair> toBeRemoved = Lists.newArrayList();
+ ArrayList<ContactIdPair> toBeRemoved = new ArrayList<>();
for (ContactIdPair ids : remaining) {
long deletedTime = DeletedContactUtil.queryDeletedTimestampForContactId(mResolver,
ids.mContactId);
@@ -209,7 +201,7 @@
* Polls every so often to see if all contacts have been deleted. If not deleted in the
* pre-defined threshold, fails.
*/
- private void assertContactsDeletedEventually(long start, ArrayList<ContactIdPair> idList) {
+ private void assertContactsDeletedEventually(long start, List<ContactIdPair> idList) {
// Can not use newArrayList() because the version that accepts size is missing.
ArrayList<ContactIdPair> remaining = new ArrayList<ContactIdPair>(idList.size());
remaining.addAll(idList);
@@ -219,7 +211,7 @@
assertWithinTimeoutLimit(start, "Contacts have not been deleted after account"
+ " removal.");
- ArrayList<ContactIdPair> toBeRemoved = Lists.newArrayList();
+ ArrayList<ContactIdPair> toBeRemoved = new ArrayList<>();
for (ContactIdPair ids : remaining) {
if (!RawContactUtil.rawContactExistsById(mResolver, ids.mRawContactId)) {
toBeRemoved.add(ids);
@@ -244,7 +236,7 @@
* Creates a given number of contacts for an account.
*/
private ArrayList<ContactIdPair> createContacts(Account account, int numContacts) {
- ArrayList<ContactIdPair> accountIds = Lists.newArrayList();
+ ArrayList<ContactIdPair> accountIds = new ArrayList<>();
for (int i = 0; i < numContacts; i++) {
accountIds.add(DatabaseAsserts.assertAndCreateContact(mResolver, account));
}
diff --git a/tests/tests/provider/src/android/provider/cts/contacts/Contacts_ContactMethodsTest.java b/tests/tests/provider/src/android/provider/cts/contacts/Contacts_ContactMethodsTest.java
index 91f53d4..3b4854b 100644
--- a/tests/tests/provider/src/android/provider/cts/contacts/Contacts_ContactMethodsTest.java
+++ b/tests/tests/provider/src/android/provider/cts/contacts/Contacts_ContactMethodsTest.java
@@ -16,14 +16,10 @@
package android.provider.cts.contacts;
-import android.content.Context;
import android.provider.Contacts;
import android.provider.Contacts.ContactMethods;
import android.test.AndroidTestCase;
-import com.android.internal.R;
-
-
public class Contacts_ContactMethodsTest extends AndroidTestCase {
public void testAddPostalLocation() {
}
@@ -57,49 +53,8 @@
ContactMethods.TYPE_CUSTOM, label).toString();
assertEquals(label, display);
- CharSequence[] labels = getContext().getResources().getTextArray(
- com.android.internal.R.array.emailAddressTypes);
- display = ContactMethods.getDisplayLabel(getContext(), Contacts.KIND_EMAIL,
- ContactMethods.TYPE_HOME, label).toString();
- assertEquals(labels[ContactMethods.TYPE_HOME - 1], display);
-
- display = ContactMethods.getDisplayLabel(getContext(), Contacts.KIND_EMAIL,
- ContactMethods.TYPE_OTHER, label).toString();
- assertEquals(labels[ContactMethods.TYPE_OTHER - 1], display);
-
- display = ContactMethods.getDisplayLabel(getContext(), Contacts.KIND_EMAIL,
- ContactMethods.TYPE_WORK, label).toString();
- assertEquals(labels[ContactMethods.TYPE_WORK - 1], display);
-
- String untitled = getContext().getString(R.string.untitled);
- display = ContactMethods.getDisplayLabel(getContext(), Contacts.KIND_IM,
- ContactMethods.TYPE_CUSTOM, label).toString();
- assertEquals(untitled, display);
-
- display = ContactMethods.getDisplayLabel(getContext(), Contacts.KIND_ORGANIZATION,
- ContactMethods.TYPE_CUSTOM, label).toString();
- assertEquals(untitled, display);
-
- display = ContactMethods.getDisplayLabel(getContext(), Contacts.KIND_PHONE,
- ContactMethods.TYPE_CUSTOM, label).toString();
- assertEquals(untitled, display);
-
display = ContactMethods.getDisplayLabel(getContext(), Contacts.KIND_POSTAL,
ContactMethods.TYPE_CUSTOM, label).toString();
assertEquals(label, display);
-
- labels = getContext().getResources().getTextArray(
- com.android.internal.R.array.postalAddressTypes);
- display = ContactMethods.getDisplayLabel(getContext(), Contacts.KIND_POSTAL,
- ContactMethods.TYPE_HOME, label).toString();
- assertEquals(labels[ContactMethods.TYPE_HOME - 1], display);
-
- display = ContactMethods.getDisplayLabel(getContext(), Contacts.KIND_POSTAL,
- ContactMethods.TYPE_OTHER, label).toString();
- assertEquals(labels[ContactMethods.TYPE_OTHER - 1], display);
-
- display = ContactMethods.getDisplayLabel(getContext(), Contacts.KIND_POSTAL,
- ContactMethods.TYPE_WORK, label).toString();
- assertEquals(labels[ContactMethods.TYPE_WORK - 1], display);
}
}
diff --git a/tests/tests/provider/src/android/provider/cts/contacts/Contacts_OrganizationsTest.java b/tests/tests/provider/src/android/provider/cts/contacts/Contacts_OrganizationsTest.java
index 814c845..37e3266 100644
--- a/tests/tests/provider/src/android/provider/cts/contacts/Contacts_OrganizationsTest.java
+++ b/tests/tests/provider/src/android/provider/cts/contacts/Contacts_OrganizationsTest.java
@@ -16,7 +16,6 @@
package android.provider.cts.contacts;
-import android.content.Context;
import android.provider.Contacts.Organizations;
import android.test.AndroidTestCase;
@@ -26,15 +25,5 @@
String display = Organizations.getDisplayLabel(getContext(),
Organizations.TYPE_CUSTOM, label).toString();
assertEquals(label, display);
-
- CharSequence[] labels = getContext().getResources().getTextArray(
- com.android.internal.R.array.organizationTypes);
- display = Organizations.getDisplayLabel(getContext(),
- Organizations.TYPE_OTHER, label).toString();
- assertEquals(labels[Organizations.TYPE_OTHER - 1], display);
-
- display = Organizations.getDisplayLabel(getContext(),
- Organizations.TYPE_WORK, label).toString();
- assertEquals(labels[Organizations.TYPE_WORK - 1], display);
}
}
diff --git a/tests/tests/provider/src/android/provider/cts/contacts/Contacts_PhonesTest.java b/tests/tests/provider/src/android/provider/cts/contacts/Contacts_PhonesTest.java
index 363ba61..ab296a3 100644
--- a/tests/tests/provider/src/android/provider/cts/contacts/Contacts_PhonesTest.java
+++ b/tests/tests/provider/src/android/provider/cts/contacts/Contacts_PhonesTest.java
@@ -26,36 +26,6 @@
String display = Phones.getDisplayLabel(getContext(),
Phones.TYPE_CUSTOM, label).toString();
assertEquals(label, display);
-
- CharSequence[] labels = getContext().getResources().getTextArray(
- com.android.internal.R.array.phoneTypes);
- display = Phones.getDisplayLabel(getContext(),
- Phones.TYPE_HOME, label).toString();
- assertEquals(labels[Phones.TYPE_HOME - 1], display);
-
- display = Phones.getDisplayLabel(getContext(),
- Phones.TYPE_MOBILE, label).toString();
- assertEquals(labels[Phones.TYPE_MOBILE - 1], display);
-
- display = Phones.getDisplayLabel(getContext(),
- Phones.TYPE_WORK, label).toString();
- assertEquals(labels[Phones.TYPE_WORK - 1], display);
-
- display = Phones.getDisplayLabel(getContext(),
- Phones.TYPE_FAX_WORK, label).toString();
- assertEquals(labels[Phones.TYPE_FAX_WORK - 1], display);
-
- display = Phones.getDisplayLabel(getContext(),
- Phones.TYPE_FAX_HOME, label).toString();
- assertEquals(labels[Phones.TYPE_FAX_HOME - 1], display);
-
- display = Phones.getDisplayLabel(getContext(),
- Phones.TYPE_PAGER, label).toString();
- assertEquals(labels[Phones.TYPE_PAGER - 1], display);
-
- display = Phones.getDisplayLabel(getContext(),
- Phones.TYPE_OTHER, label).toString();
- assertEquals(labels[Phones.TYPE_OTHER - 1], display);
}
public void testGetDisplayLabelCharSequenceArray() {
diff --git a/tests/tests/provider/src/libcore/util/HexEncoding.java b/tests/tests/provider/src/libcore/util/HexEncoding.java
new file mode 100644
index 0000000..992acbd
--- /dev/null
+++ b/tests/tests/provider/src/libcore/util/HexEncoding.java
@@ -0,0 +1,138 @@
+/*
+ * 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 libcore.util;
+
+/**
+ * Hexadecimal encoding where each byte is represented by two hexadecimal digits.
+ * @hide
+ */
+public class HexEncoding {
+
+ /** Hidden constructor to prevent instantiation. */
+ private HexEncoding() {}
+
+ private static final char[] HEX_DIGITS = "0123456789ABCDEF".toCharArray();
+
+ /**
+ * Encodes the provided data as a sequence of hexadecimal characters.
+ */
+ public static char[] encode(byte[] data) {
+ return encode(data, 0, data.length);
+ }
+
+ /**
+ * Encodes the provided data as a sequence of hexadecimal characters.
+ */
+ public static char[] encode(byte[] data, int offset, int len) {
+ char[] result = new char[len * 2];
+ for (int i = 0; i < len; i++) {
+ byte b = data[offset + i];
+ int resultIndex = 2 * i;
+ result[resultIndex] = (HEX_DIGITS[(b >>> 4) & 0x0f]);
+ result[resultIndex + 1] = (HEX_DIGITS[b & 0x0f]);
+ }
+
+ return result;
+ }
+
+ /**
+ * Encodes the provided data as a sequence of hexadecimal characters.
+ */
+ public static String encodeToString(byte[] data) {
+ return new String(encode(data));
+ }
+
+ /**
+ * Decodes the provided hexadecimal string into a byte array. Odd-length inputs
+ * are not allowed.
+ *
+ * Throws an {@code IllegalArgumentException} if the input is malformed.
+ */
+ public static byte[] decode(String encoded) throws IllegalArgumentException {
+ return decode(encoded.toCharArray());
+ }
+
+ /**
+ * Decodes the provided hexadecimal string into a byte array. If {@code allowSingleChar}
+ * is {@code true} odd-length inputs are allowed and the first character is interpreted
+ * as the lower bits of the first result byte.
+ *
+ * Throws an {@code IllegalArgumentException} if the input is malformed.
+ */
+ public static byte[] decode(String encoded, boolean allowSingleChar) throws IllegalArgumentException {
+ return decode(encoded.toCharArray(), allowSingleChar);
+ }
+
+ /**
+ * Decodes the provided hexadecimal string into a byte array. Odd-length inputs
+ * are not allowed.
+ *
+ * Throws an {@code IllegalArgumentException} if the input is malformed.
+ */
+ public static byte[] decode(char[] encoded) throws IllegalArgumentException {
+ return decode(encoded, false);
+ }
+
+ /**
+ * Decodes the provided hexadecimal string into a byte array. If {@code allowSingleChar}
+ * is {@code true} odd-length inputs are allowed and the first character is interpreted
+ * as the lower bits of the first result byte.
+ *
+ * Throws an {@code IllegalArgumentException} if the input is malformed.
+ */
+ public static byte[] decode(char[] encoded, boolean allowSingleChar) throws IllegalArgumentException {
+ int resultLengthBytes = (encoded.length + 1) / 2;
+ byte[] result = new byte[resultLengthBytes];
+
+ int resultOffset = 0;
+ int i = 0;
+ if (allowSingleChar) {
+ if ((encoded.length % 2) != 0) {
+ // Odd number of digits -- the first digit is the lower 4 bits of the first result byte.
+ result[resultOffset++] = (byte) toDigit(encoded, i);
+ i++;
+ }
+ } else {
+ if ((encoded.length % 2) != 0) {
+ throw new IllegalArgumentException("Invalid input length: " + encoded.length);
+ }
+ }
+
+ for (int len = encoded.length; i < len; i += 2) {
+ result[resultOffset++] = (byte) ((toDigit(encoded, i) << 4) | toDigit(encoded, i + 1));
+ }
+
+ return result;
+ }
+
+ private static int toDigit(char[] str, int offset) throws IllegalArgumentException {
+ // NOTE: that this isn't really a code point in the traditional sense, since we're
+ // just rejecting surrogate pairs outright.
+ int pseudoCodePoint = str[offset];
+
+ if ('0' <= pseudoCodePoint && pseudoCodePoint <= '9') {
+ return pseudoCodePoint - '0';
+ } else if ('a' <= pseudoCodePoint && pseudoCodePoint <= 'f') {
+ return 10 + (pseudoCodePoint - 'a');
+ } else if ('A' <= pseudoCodePoint && pseudoCodePoint <= 'F') {
+ return 10 + (pseudoCodePoint - 'A');
+ }
+
+ throw new IllegalArgumentException("Illegal char: " + str[offset] +
+ " at offset " + offset);
+ }
+}
diff --git a/tests/tests/security/jni/android_security_cts_NativeCodeTest.cpp b/tests/tests/security/jni/android_security_cts_NativeCodeTest.cpp
index e903ab7..f142975 100644
--- a/tests/tests/security/jni/android_security_cts_NativeCodeTest.cpp
+++ b/tests/tests/security/jni/android_security_cts_NativeCodeTest.cpp
@@ -36,6 +36,7 @@
#include <arpa/inet.h>
#include <linux/ipc.h>
#include <pthread.h>
+#include <sys/uio.h>
/*
* Returns true iff this device is vulnerable to CVE-2013-2094.
diff --git a/tests/tests/security/src/android/security/cts/CertificateData.java b/tests/tests/security/src/android/security/cts/CertificateData.java
index 76f86d5..ef27222 100644
--- a/tests/tests/security/src/android/security/cts/CertificateData.java
+++ b/tests/tests/security/src/android/security/cts/CertificateData.java
@@ -28,9 +28,7 @@
class CertificateData {
static final String[] CERTIFICATE_DATA = {
"91:C6:D6:EE:3E:8A:C8:63:84:E5:48:C2:99:29:5C:75:6C:81:7B:81",
- "22:FD:D0:B7:FD:A2:4E:0D:AC:49:2C:A0:AC:A6:7B:6A:1F:E3:F7:66",
"D1:CB:CA:5D:B2:D5:2A:7F:69:3B:67:4D:E5:F0:5A:1D:0C:95:7D:F0",
- "C4:18:F6:4D:46:D1:DF:00:3D:27:30:13:72:43:A9:12:11:C6:75:FB",
"69:69:56:2E:40:80:F4:24:A1:E7:19:9F:14:BA:F3:EE:58:AB:6A:BB",
"92:5A:8F:8D:2C:6D:04:E0:66:5F:59:6A:FF:22:D8:63:E8:25:6F:3F",
"75:E0:AB:B6:13:85:12:27:1C:04:F8:5F:DD:DE:38:E4:B7:24:2E:FE",
@@ -49,17 +47,19 @@
"1F:24:C6:30:CD:A4:18:EF:20:69:FF:AD:4F:DD:5F:46:3A:1B:69:AA",
"DA:FA:F7:FA:66:84:EC:06:8F:14:50:BD:C7:C2:81:A5:BC:A9:64:57",
"74:F8:A3:C3:EF:E7:B3:90:06:4B:83:90:3C:21:64:60:20:E5:DF:CE",
+ "2D:0D:52:14:FF:9E:AD:99:24:01:74:20:47:6E:6C:85:27:27:F5:43",
+ "28:F9:78:16:19:7A:FF:18:25:18:AA:44:FE:C1:A0:CE:5C:B6:4C:8A",
"31:43:64:9B:EC:CE:27:EC:ED:3A:3F:0B:8F:0D:E4:E8:91:DD:EE:CA",
"B7:AB:33:08:D1:EA:44:77:BA:14:80:12:5A:6F:BD:A9:36:49:0C:BB",
"5F:43:E5:B1:BF:F8:78:8C:AC:1C:C7:CA:4A:9A:C6:22:2B:CC:34:C6",
"2B:8F:1B:57:33:0D:BB:A2:D0:7A:6C:51:F7:0E:E9:0D:DA:B9:AD:8E",
- "79:5F:88:60:C5:AB:7C:3D:92:E6:CB:F4:8D:E1:45:CD:11:EF:60:0B",
"A8:98:5D:3A:65:E5:E5:C4:B2:D7:D6:6D:40:C6:DD:2F:B1:9C:54:36",
"59:22:A1:E1:5A:EA:16:35:21:F8:98:39:6A:46:46:B0:44:1B:0F:A9",
"D4:DE:20:D0:5E:66:FC:53:FE:1A:50:88:2C:78:DB:28:52:CA:E4:74",
"02:FA:F3:E2:91:43:54:68:60:78:57:69:4D:F5:E4:5B:68:85:18:68",
"76:E2:7E:C1:4F:DB:82:C1:C0:A6:75:B5:05:BE:3D:29:B4:ED:DB:BB",
"D8:C5:38:8A:B7:30:1B:1B:6E:D4:7A:E6:45:25:3A:6F:9F:1A:27:61",
+ "E0:11:84:5E:34:DE:BE:88:81:B9:9C:F6:16:26:D1:96:1F:C3:B9:31",
"93:05:7A:88:15:C6:4F:CE:88:2F:FA:91:16:52:28:78:BC:53:64:17",
"59:AF:82:79:91:86:C7:B4:75:07:CB:CF:03:57:46:EB:04:DD:B7:16",
"50:30:06:09:1D:97:D4:F5:AE:39:F7:CB:E7:92:7D:7D:65:2D:34:31",
@@ -75,6 +75,7 @@
"74:3A:F0:52:9B:D0:32:A0:F4:4A:83:CD:D4:BA:A9:7B:7C:2E:C4:9A",
"D8:EB:6B:41:51:92:59:E0:F3:E7:85:00:C0:3D:B6:88:97:C9:EE:FC",
"66:31:BF:9E:F7:4F:9E:B6:C9:D5:A6:0C:BA:6A:BE:D1:F7:BD:EF:7B",
+ "2A:1D:60:27:D9:4A:B1:0A:1C:4D:91:5C:CD:33:A0:CB:3E:2D:54:CB",
"DE:3F:40:BD:50:93:D3:9B:6C:60:F6:DA:BC:07:62:01:00:89:76:C9",
"22:D5:D8:DF:8F:02:31:D1:8D:F7:9D:B7:CF:8A:2D:64:C9:3F:6C:3A",
"F3:73:B3:87:06:5A:28:84:8A:F2:F3:4A:CE:19:2B:DD:C7:8E:9C:AC",
@@ -83,7 +84,7 @@
"43:13:BB:96:F1:D5:86:9B:C1:4E:6A:92:F6:CF:F6:34:69:87:82:37",
"F1:8B:53:8D:1B:E9:03:B6:A6:F0:56:43:5B:17:15:89:CA:F3:6B:F2",
"05:63:B8:63:0D:62:D7:5A:BB:C8:AB:1E:4B:DF:B5:A8:99:B2:4D:43",
- "70:17:9B:86:8C:00:A4:FA:60:91:52:22:3F:9F:3E:32:BD:E0:05:62",
+ "30:D4:24:6F:07:FF:DB:91:89:8A:0B:E9:49:66:11:EB:8C:5E:46:E5",
"D1:EB:23:A4:6D:17:D6:8F:D9:25:64:C2:F1:F1:60:17:64:D8:E3:49",
"B8:01:86:D1:EB:9C:86:A5:41:04:CF:30:54:F3:4C:52:B7:E5:58:C6",
"4C:DD:51:A3:D1:F5:20:32:14:B0:C6:C5:32:23:03:91:C7:46:42:6D",
@@ -109,11 +110,9 @@
"07:E0:32:E0:20:B7:2C:3F:19:2F:06:28:A2:59:3A:19:A7:0F:06:9E",
"D6:DA:A8:20:8D:09:D2:15:4D:24:B5:2F:CB:34:6E:B2:58:B2:8A:58",
"32:3C:11:8E:1B:F7:B8:B6:52:54:E2:E2:10:0D:D6:02:90:37:F0:96",
- "79:91:E8:34:F7:E2:EE:DD:08:95:01:52:E9:55:2D:14:E9:58:D5:7E",
+ "80:94:64:0E:B5:A7:A1:CA:11:9C:1F:DD:D5:9F:81:02:63:A7:FB:D1",
"67:65:0D:F1:7E:8E:7E:5B:82:40:A4:F4:56:4B:CF:E2:3D:69:C6:F0",
- "FE:B8:C4:32:DC:F9:76:9A:CE:AE:3D:D8:90:8F:FD:28:86:65:64:7D",
"4A:BD:EE:EC:95:0D:35:9C:89:AE:C7:52:A1:2C:5B:29:F6:D6:AA:0C",
- "33:9B:6B:14:50:24:9B:55:7A:01:87:72:84:D9:E0:2F:C3:D2:D8:E9",
"DD:FB:16:CD:49:31:C9:73:A2:03:7D:3F:C8:3A:4D:7D:77:5D:05:E4",
"36:B1:2B:49:F9:81:9E:D7:4C:9E:BC:38:0F:C6:56:8F:5D:AC:B2:F7",
"37:F7:6D:E6:07:7C:90:C5:B1:3E:93:1A:B7:41:10:B4:F2:E4:9A:27",
@@ -134,6 +133,7 @@
"58:D1:DF:95:95:67:6B:63:C0:F0:5B:1C:17:4D:8B:84:0B:C8:78:BD",
"F5:17:A2:4F:9A:48:C6:C9:F8:A2:00:26:9F:DC:0F:48:2C:AB:30:89",
"3B:C0:38:0B:33:C3:F6:A6:0C:86:15:22:93:D9:DF:F5:4B:81:C0:04",
+ "D2:73:96:2A:2A:5E:39:9F:73:3F:E1:C7:1E:64:3F:03:38:34:FC:4D",
"03:9E:ED:B8:0B:E7:A0:3C:69:53:89:3B:20:D2:D9:32:3A:4C:2A:FD",
"1E:0E:56:19:0A:D1:8B:25:98:B2:04:44:FF:66:8A:04:17:99:5F:3F",
"DF:3C:24:F9:BF:D6:66:76:1B:26:80:73:FE:06:D1:CC:8D:4F:82:A4",
@@ -151,6 +151,7 @@
"9D:70:BB:01:A5:A4:A0:18:11:2E:F7:1C:01:B9:32:C5:34:E7:88:A8",
"96:C9:1B:0B:95:B4:10:98:42:FA:D0:D8:22:79:FE:60:FA:B9:16:83",
"4F:65:8E:1F:E9:06:D8:28:02:E9:54:47:41:C9:54:25:5D:69:CC:1A",
+ "A3:A1:B0:6F:24:61:23:4A:E3:36:A5:C2:37:FC:A6:FF:DD:F0:D7:3A",
"D8:A6:33:2C:E0:03:6F:B1:85:F6:63:4F:7D:6A:06:65:26:32:28:27",
"01:0C:06:95:A6:98:19:14:FF:BF:5F:C6:B0:B6:95:EA:29:E9:12:A6",
"0F:F9:40:76:18:D3:D7:6A:4B:98:F0:A8:35:9E:0C:FD:27:AC:CC:ED",
@@ -159,7 +160,7 @@
"E6:21:F3:35:43:79:05:9A:4B:68:30:9D:8A:2F:74:22:15:87:EC:79",
"89:DF:74:FE:5C:F4:0F:4A:80:F9:E3:37:7D:54:DA:91:E1:01:31:8E",
"7E:04:DE:89:6A:3E:66:6D:00:E6:87:D3:3F:FA:D9:3B:E8:3D:34:9E",
- "6E:3A:55:A4:19:0C:19:5C:93:84:3C:C0:DB:72:2E:31:30:61:F0:B1",
+ "E1:C9:50:E6:EF:22:F8:4C:56:45:72:8B:92:20:60:D7:D5:A7:A3:E8",
"4E:B6:D5:78:49:9B:1C:CF:5F:58:1E:AD:56:BE:3D:9B:67:44:A5:E5",
"5A:8C:EF:45:D7:A6:98:59:76:7A:8C:8B:44:96:B5:78:CF:47:4B:1A",
"8D:A7:F9:65:EC:5E:FC:37:91:0F:1C:6E:59:FD:C1:CC:6A:6E:DE:16",
diff --git a/tests/tests/selinux/common/src/android/security/SELinuxTargetSdkTestBase.java b/tests/tests/selinux/common/src/android/security/SELinuxTargetSdkTestBase.java
index 349e2c9..69a4a4a 100644
--- a/tests/tests/selinux/common/src/android/security/SELinuxTargetSdkTestBase.java
+++ b/tests/tests/selinux/common/src/android/security/SELinuxTargetSdkTestBase.java
@@ -61,9 +61,20 @@
* Check expectations of being able to read/execute dex2oat.
*/
protected static void checkDex2oatAccess(boolean expectedAllowed) throws Exception {
- File dex2oatBinary = new File("/system/bin/dex2oat");
- assertTrue(dex2oatBinary.exists());
+ // First check whether there is an Android Runtime APEX dex2oat binary.
+ File dex2oatRuntimeApexBinary = new File("/apex/com.android.runtime/bin/dex2oat");
+ if (dex2oatRuntimeApexBinary.exists()) {
+ checkDex2oatBinaryAccess(dex2oatRuntimeApexBinary, expectedAllowed);
+ }
+ // Also check whether there is a "legacy" system binary.
+ File dex2oatSystemBinary = new File("/system/bin/dex2oat");
+ if (dex2oatSystemBinary.exists()) {
+ checkDex2oatBinaryAccess(dex2oatSystemBinary, expectedAllowed);
+ }
+ }
+ private static void checkDex2oatBinaryAccess(File dex2oatBinary, boolean expectedAllowed)
+ throws Exception {
// Check permissions.
assertEquals(expectedAllowed, dex2oatBinary.canRead());
assertEquals(expectedAllowed, dex2oatBinary.canExecute());
diff --git a/tests/tests/selinux/selinuxTargetSdk28/src/android/security/SELinuxTargetSdkTest.java b/tests/tests/selinux/selinuxTargetSdk28/src/android/security/SELinuxTargetSdkTest.java
index 4ccc725..92e1070 100644
--- a/tests/tests/selinux/selinuxTargetSdk28/src/android/security/SELinuxTargetSdkTest.java
+++ b/tests/tests/selinux/selinuxTargetSdk28/src/android/security/SELinuxTargetSdkTest.java
@@ -60,4 +60,8 @@
"Actual value: ";
appDataContext(context, msg);
}
+
+ public void testDex2oat() throws Exception {
+ checkDex2oatAccess(true);
+ }
}
diff --git a/tests/tests/telecom/src/android/telecom/cts/BaseTelecomTestWithMockServices.java b/tests/tests/telecom/src/android/telecom/cts/BaseTelecomTestWithMockServices.java
index 436150b..a6d9fc1 100644
--- a/tests/tests/telecom/src/android/telecom/cts/BaseTelecomTestWithMockServices.java
+++ b/tests/tests/telecom/src/android/telecom/cts/BaseTelecomTestWithMockServices.java
@@ -64,6 +64,7 @@
public static final int FLAG_REGISTER = 0x1;
public static final int FLAG_ENABLE = 0x2;
+ public static final int FLAG_SET_DEFAULT = 0x4;
private static int sCounter = 5549999;
@@ -90,6 +91,8 @@
InCallServiceCallbacks mInCallCallbacks;
String mPreviousDefaultDialer = null;
+ PhoneAccountHandle mPreviousDefaultOutgoingAccount = null;
+ boolean mShouldRestoreDefaultOutgoingAccount = false;
MockConnectionService connectionService = null;
HandlerThread mPhoneStateListenerThread;
@@ -194,6 +197,15 @@
assertPhoneAccountEnabled(TestUtils.TEST_PHONE_ACCOUNT_HANDLE);
}
+ if ((flags & FLAG_SET_DEFAULT) != 0) {
+ mPreviousDefaultOutgoingAccount = mTelecomManager.getUserSelectedOutgoingPhoneAccount();
+ mShouldRestoreDefaultOutgoingAccount = true;
+ TestUtils.setDefaultOutgoingPhoneAccount(getInstrumentation(),
+ TestUtils.TEST_PHONE_ACCOUNT_HANDLE);
+ // Wait till the adb commands have executed and the default has changed.
+ assertPhoneAccountIsDefault(TestUtils.TEST_PHONE_ACCOUNT_HANDLE);
+ }
+
return TestUtils.TEST_PHONE_ACCOUNT;
}
@@ -204,7 +216,13 @@
mTelecomManager.unregisterPhoneAccount(accountHandle);
CtsConnectionService.tearDown();
assertCtsConnectionServiceUnbound();
+ if (mShouldRestoreDefaultOutgoingAccount) {
+ TestUtils.setDefaultOutgoingPhoneAccount(getInstrumentation(),
+ mPreviousDefaultOutgoingAccount);
+ }
this.connectionService = null;
+ mPreviousDefaultOutgoingAccount = null;
+ mShouldRestoreDefaultOutgoingAccount = false;
}
protected void startCallTo(Uri address, PhoneAccountHandle accountHandle) {
@@ -1065,6 +1083,26 @@
);
}
+ void assertPhoneAccountIsDefault(final PhoneAccountHandle handle) {
+ waitUntilConditionIsTrueOrTimeout(
+ new Condition() {
+ @Override
+ public Object expected() {
+ return true;
+ }
+
+ @Override
+ public Object actual() {
+ PhoneAccountHandle phoneAccountHandle =
+ mTelecomManager.getUserSelectedOutgoingPhoneAccount();
+ return (phoneAccountHandle != null && phoneAccountHandle.equals(handle));
+ }
+ },
+ WAIT_FOR_STATE_CHANGE_TIMEOUT_MS,
+ "Failed to set default phone account to " + handle
+ );
+ }
+
void assertCtsConnectionServiceUnbound() {
if (CtsConnectionService.isBound()) {
assertTrue("CtsConnectionService not yet unbound!",
diff --git a/tests/tests/telecom/src/android/telecom/cts/DefaultPhoneAccountTest.java b/tests/tests/telecom/src/android/telecom/cts/DefaultPhoneAccountTest.java
new file mode 100755
index 0000000..9d73e43
--- /dev/null
+++ b/tests/tests/telecom/src/android/telecom/cts/DefaultPhoneAccountTest.java
@@ -0,0 +1,180 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License
+ */
+
+package android.telecom.cts;
+
+import android.telecom.PhoneAccount;
+import android.telecom.PhoneAccountHandle;
+import android.telecom.TelecomManager;
+
+/**
+ * Tests use of APIs related to changing the default outgoing phone account.
+ */
+public class DefaultPhoneAccountTest extends BaseTelecomTestWithMockServices {
+
+ @Override
+ protected void setUp() throws Exception {
+ super.setUp();
+ mContext = getInstrumentation().getContext();
+ }
+
+ /**
+ * Verifies that {@link TelecomManager#getUserSelectedOutgoingPhoneAccount()} is able to
+ * retrieve the user-selected outgoing phone account.
+ * Given that there is a user-selected default, also verifies that
+ * {@link TelecomManager#getDefaultOutgoingPhoneAccount(String)} reports this value as well.
+ * Note: This test depends on
+ * {@code TelecomManager#setUserSelectedOutgoingPhoneAccount(PhoneAccountHandle)} being run
+ * through the telecom shell command in order to change the user-selected default outgoing
+ * account.
+ * @throws Exception
+ */
+ public void testDefaultIsSet() throws Exception {
+ if (!mShouldTestTelecom) {
+ return;
+ }
+ // Make sure to set the default outgoing phone account to the new connection service
+ setupConnectionService(null, FLAG_REGISTER | FLAG_ENABLE | FLAG_SET_DEFAULT);
+
+ PhoneAccountHandle handle = mTelecomManager.getUserSelectedOutgoingPhoneAccount();
+ assertEquals(TestUtils.TEST_PHONE_ACCOUNT_HANDLE, handle);
+
+ PhoneAccountHandle defaultOutgoing = mTelecomManager.getDefaultOutgoingPhoneAccount(
+ PhoneAccount.SCHEME_TEL);
+ assertEquals(TestUtils.TEST_PHONE_ACCOUNT_HANDLE, defaultOutgoing);
+ }
+
+ /**
+ * Verifies operation of the {@link TelecomManager#getDefaultOutgoingPhoneAccount(String)} API
+ * where there is NO user selected default outgoing phone account.
+ * In AOSP, this mimics the user having changed the
+ * Phone --> Settings --> Call Settings --> Calling accounts --> Make Calls With
+ * option to "Ask first".
+ *
+ * The test assumes that a device either has a single sim, or has multiple sims.
+ * In either case, it registers another TEL outgoing calling account.
+ *
+ * We can expect two things:
+ * 1. {@link TelecomManager#getUserSelectedOutgoingPhoneAccount()} returns null, since the
+ * "ask first" option was chosen.
+ * 2. {@link TelecomManager#getUserSelectedOutgoingPhoneAccount()} returns null, since there is
+ * now 2 or more potential outgoing phone accounts with the TEL scheme.
+ * @throws Exception
+ */
+ public void testGetDefaultOutgoingNoUserSelected() throws Exception {
+ if (!mShouldTestTelecom) {
+ return;
+ }
+
+ PhoneAccountHandle previousOutgoingPhoneAccount =
+ mTelecomManager.getUserSelectedOutgoingPhoneAccount();
+
+ // Clear the default outgoing phone account; this is the same as saying "ask every time" in
+ // the user settings.
+ TestUtils.setDefaultOutgoingPhoneAccount(getInstrumentation(),
+ null /* clear default */);
+ try {
+ // Register another TEL URI phone account; since we expect devices to have at minimum
+ // 1 sim, this ensures that we have a scenario where there are multiple potential
+ // outgoing phone accounts with the TEL scheme.
+ setupConnectionService(null, FLAG_REGISTER | FLAG_ENABLE);
+
+ // There should be NO user selected default outgoing account (we cleared it).
+ PhoneAccountHandle handle = mTelecomManager.getUserSelectedOutgoingPhoneAccount();
+ assertEquals(null, handle);
+
+ // There should be multiple potential TEL phone accounts now, so we expect null here.
+ PhoneAccountHandle defaultOutgoing = mTelecomManager.getDefaultOutgoingPhoneAccount(
+ PhoneAccount.SCHEME_TEL);
+ assertEquals(null, defaultOutgoing);
+ } finally {
+ // Restore the default outgoing phone account.
+ TestUtils.setDefaultOutgoingPhoneAccount(getInstrumentation(),
+ previousOutgoingPhoneAccount);
+ }
+ }
+
+ /**
+ * Verifies correct operation of the
+ * {@link TelecomManager#getDefaultOutgoingPhoneAccount(String)} API.
+ * The purpose of this CTS test is to verify the following scenarios:
+ * 1. Where there is NO user selected default outgoing phone account and there is a single
+ * potential phone account, that phone account should be returned.
+ * 2. Where there is NO user selected default outgoing phone account and there are multiple
+ * potential phone accounts, null should be returned.
+ * This test performs this operation using a test URI scheme to remove dependencies on the
+ * number of potential sims in a device, however the test cases above should pass even if the
+ * TEL uri scheme was being tested.
+ * @throws Exception
+ */
+ public void testGetDefaultOutgoingPhoneAccountOneOrMany() throws Exception {
+ if (!mShouldTestTelecom) {
+ return;
+ }
+
+ PhoneAccountHandle previousOutgoingPhoneAccount =
+ mTelecomManager.getUserSelectedOutgoingPhoneAccount();
+
+ // Clear the default outgoing phone account; this is the same as saying "ask every time" in
+ // the user settings.
+ TestUtils.setDefaultOutgoingPhoneAccount(getInstrumentation(),
+ null /* clear default */);
+
+ try {
+ // Lets register a new phone account using a test URI scheme 'foobuzz' (this avoids
+ // conflicts with any sims on the device).
+ registerAndEnablePhoneAccount(TestUtils.TEST_DEFAULT_PHONE_ACCOUNT_1);
+
+ // There should be NO user selected default outgoing account (we cleared it above).
+ PhoneAccountHandle handle = mTelecomManager.getUserSelectedOutgoingPhoneAccount();
+ assertEquals(null, handle);
+
+ // There should be a single potential phone account in the 'foobuzz' scheme, so it
+ // should be reported as the default outgoing phone account.
+ PhoneAccountHandle defaultOutgoing = mTelecomManager.getDefaultOutgoingPhoneAccount(
+ TestUtils.TEST_URI_SCHEME);
+ assertEquals(TestUtils.TEST_DEFAULT_PHONE_ACCOUNT_HANDLE_1, defaultOutgoing);
+
+ // Next, lets register another new phone account using the test URI scheme 'foobuzz'.
+ registerAndEnablePhoneAccount(TestUtils.TEST_DEFAULT_PHONE_ACCOUNT_2);
+
+ // There should still be NO user selected default outgoing account (we cleared it
+ // above).
+ handle = mTelecomManager.getUserSelectedOutgoingPhoneAccount();
+ assertEquals(null, handle);
+
+ // Now that there are two potential outgoing accounts in the same scheme and nothing is
+ // chosen as the default, the default outgoing phone account should be "null".
+ defaultOutgoing = mTelecomManager.getDefaultOutgoingPhoneAccount(
+ TestUtils.TEST_URI_SCHEME);
+ assertEquals(null, defaultOutgoing);
+ } finally {
+ mTelecomManager.unregisterPhoneAccount(TestUtils.TEST_DEFAULT_PHONE_ACCOUNT_HANDLE_1);
+ mTelecomManager.unregisterPhoneAccount(TestUtils.TEST_DEFAULT_PHONE_ACCOUNT_HANDLE_2);
+
+ // Restore the default outgoing phone account.
+ TestUtils.setDefaultOutgoingPhoneAccount(getInstrumentation(),
+ previousOutgoingPhoneAccount);
+ }
+ }
+
+ private void registerAndEnablePhoneAccount(PhoneAccount phoneAccount) throws Exception {
+ mTelecomManager.registerPhoneAccount(phoneAccount);
+ TestUtils.enablePhoneAccount(getInstrumentation(), phoneAccount.getAccountHandle());
+ // Wait till the adb commands have executed and account is enabled in Telecom database.
+ assertPhoneAccountEnabled(phoneAccount.getAccountHandle());
+ }
+}
diff --git a/tests/tests/telecom/src/android/telecom/cts/TestUtils.java b/tests/tests/telecom/src/android/telecom/cts/TestUtils.java
index d955efc..38e1a25 100644
--- a/tests/tests/telecom/src/android/telecom/cts/TestUtils.java
+++ b/tests/tests/telecom/src/android/telecom/cts/TestUtils.java
@@ -64,6 +64,7 @@
// Non-final to allow modification by tests not in this package (e.g. permission-related
// tests in the Telecom2 test package.
public static String PACKAGE = "android.telecom.cts";
+ public static final String TEST_URI_SCHEME = "foobuzz";
public static final String COMPONENT = "android.telecom.cts.CtsConnectionService";
public static final String SELF_MANAGED_COMPONENT =
"android.telecom.cts.CtsSelfManagedConnectionService";
@@ -75,6 +76,14 @@
new PhoneAccountHandle(new ComponentName(PACKAGE, COMPONENT), ACCOUNT_ID_1);
public static final PhoneAccountHandle TEST_PHONE_ACCOUNT_HANDLE_2 =
new PhoneAccountHandle(new ComponentName(PACKAGE, COMPONENT), ACCOUNT_ID_2);
+ public static final String DEFAULT_TEST_ACCOUNT_1_ID = "ctstest_DEFAULT_TEST_ID_1";
+ public static final String DEFAULT_TEST_ACCOUNT_2_ID = "ctstest_DEFAULT_TEST_ID_2";
+ public static final PhoneAccountHandle TEST_DEFAULT_PHONE_ACCOUNT_HANDLE_1 =
+ new PhoneAccountHandle(new ComponentName(PACKAGE, COMPONENT),
+ DEFAULT_TEST_ACCOUNT_1_ID);
+ public static final PhoneAccountHandle TEST_DEFAULT_PHONE_ACCOUNT_HANDLE_2 =
+ new PhoneAccountHandle(new ComponentName(PACKAGE, COMPONENT),
+ DEFAULT_TEST_ACCOUNT_2_ID);
public static final PhoneAccountHandle TEST_HANDOVER_SRC_PHONE_ACCOUNT_HANDLE =
new PhoneAccountHandle(new ComponentName(PACKAGE, COMPONENT), "handoverFrom");
public static final PhoneAccountHandle TEST_HANDOVER_DEST_PHONE_ACCOUNT_HANDLE =
@@ -123,6 +132,22 @@
.addSupportedUriScheme(PhoneAccount.SCHEME_VOICEMAIL)
.build();
+ public static final PhoneAccount TEST_DEFAULT_PHONE_ACCOUNT_1 = PhoneAccount.builder(
+ TEST_DEFAULT_PHONE_ACCOUNT_HANDLE_1, "Default Test 1")
+ .setAddress(Uri.parse("foobuzz:testuri1"))
+ .setCapabilities(PhoneAccount.CAPABILITY_CALL_PROVIDER)
+ .setHighlightColor(Color.RED)
+ .setShortDescription("Default Test 1")
+ .addSupportedUriScheme(TEST_URI_SCHEME)
+ .build();
+ public static final PhoneAccount TEST_DEFAULT_PHONE_ACCOUNT_2 = PhoneAccount.builder(
+ TEST_DEFAULT_PHONE_ACCOUNT_HANDLE_2, "Default Test 2")
+ .setAddress(Uri.parse("foobuzz:testuri2"))
+ .setCapabilities(PhoneAccount.CAPABILITY_CALL_PROVIDER)
+ .setHighlightColor(Color.RED)
+ .setShortDescription("Default Test 2")
+ .addSupportedUriScheme(TEST_URI_SCHEME)
+ .build();
private static final Bundle SUPPORTS_HANDOVER_FROM_EXTRAS = new Bundle();
private static final Bundle SUPPORTS_HANDOVER_TO_EXTRAS = new Bundle();
static {
@@ -153,7 +178,6 @@
.build();
public static final String REMOTE_ACCOUNT_LABEL = "CTSRemoteConnectionService";
public static final String SELF_MANAGED_ACCOUNT_LABEL = "android.telecom.cts";
- public static final String TEST_URI_SCHEME = "foobuzz";
public static final PhoneAccount TEST_SELF_MANAGED_PHONE_ACCOUNT_3 = PhoneAccount.builder(
TEST_SELF_MANAGED_HANDLE_3, SELF_MANAGED_ACCOUNT_LABEL)
.setAddress(Uri.fromParts(TEST_URI_SCHEME, "test@test.com", null))
@@ -203,6 +227,9 @@
private static final String COMMAND_REGISTER_SIM = "telecom register-sim-phone-account ";
+ private static final String COMMAND_SET_DEFAULT_PHONE_ACCOUNT =
+ "telecom set-user-selected-outgoing-phone-account ";
+
private static final String COMMAND_WAIT_ON_HANDLERS = "telecom wait-on-handlers";
public static final String MERGE_CALLER_NAME = "calls-merged";
@@ -255,6 +282,19 @@
+ handle.getId() + " " + currentUserSerial + " " + label + " " + address);
}
+ public static void setDefaultOutgoingPhoneAccount(Instrumentation instrumentation,
+ PhoneAccountHandle handle) throws Exception {
+ if (handle != null) {
+ final ComponentName component = handle.getComponentName();
+ final long currentUserSerial = getCurrentUserSerialNumber(instrumentation);
+ executeShellCommand(instrumentation, COMMAND_SET_DEFAULT_PHONE_ACCOUNT
+ + component.getPackageName() + "/" + component.getClassName() + " "
+ + handle.getId() + " " + currentUserSerial);
+ } else {
+ executeShellCommand(instrumentation, COMMAND_SET_DEFAULT_PHONE_ACCOUNT);
+ }
+ }
+
public static void waitOnAllHandlers(Instrumentation instrumentation) throws Exception {
executeShellCommand(instrumentation, COMMAND_WAIT_ON_HANDLERS);
}
diff --git a/tests/tests/telephony/Android.mk b/tests/tests/telephony/Android.mk
index 6f3d71a..85e22f1 100644
--- a/tests/tests/telephony/Android.mk
+++ b/tests/tests/telephony/Android.mk
@@ -1,4 +1,5 @@
-# Copyright (C) 2008 The Android Open Source Project
+#
+# Copyright (C) 2019 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.
@@ -11,42 +12,6 @@
# 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 := optional
-# and when built explicitly put it in the data partition
-LOCAL_MODULE_PATH := $(TARGET_OUT_DATA_APPS)
-
-LOCAL_JAVA_LIBRARIES := telephony-common
-
-LOCAL_STATIC_JAVA_LIBRARIES := \
- ctstestrunner \
- compatibility-device-util \
- truth-prebuilt
-
-LOCAL_HOST_SHARED_LIBRARIES := compatibility-device-telephony-preconditions
-
-LOCAL_SRC_FILES := $(call all-java-files-under, src) \
- $(call all-java-files-under, EmbmsMiddlewareTestApp) \
- $(call all-Iaidl-files-under, EmbmsMiddlewareTestApp)
-
-LOCAL_AIDL_INCLUDES := EmbmsMiddlewareTestApp/aidl/
-
-LOCAL_PACKAGE_NAME := CtsTelephonyTestCases
-
-# Tag this module as a cts test artifact
-LOCAL_COMPATIBILITY_SUITE := cts vts general-tests
-
-# uncomment when b/13250611 is fixed
-#LOCAL_SDK_VERSION := current
-LOCAL_PRIVATE_PLATFORM_APIS := true
-LOCAL_JAVA_LIBRARIES += android.test.runner.stubs
-LOCAL_JAVA_LIBRARIES += android.test.base.stubs
-
-include $(BUILD_CTS_PACKAGE)
-include $(call all-makefiles-under,$(LOCAL_PATH))
+include $(call all-subdir-makefiles)
diff --git a/tests/tests/telephony/TestSmsRetrieverApp/Android.bp b/tests/tests/telephony/TestSmsRetrieverApp/Android.bp
new file mode 100644
index 0000000..d0c1a74
--- /dev/null
+++ b/tests/tests/telephony/TestSmsRetrieverApp/Android.bp
@@ -0,0 +1,27 @@
+// Copyright (C) 2019 Google Inc.
+//
+// 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.
+
+android_test {
+ name: "TestSmsRetrieverApp",
+
+ srcs: ["src/**/*.kt", "src/**/*.java"],
+
+ static_libs: [
+ "compatibility-device-util",
+ ],
+
+ test_suites: [
+ "cts",
+ ],
+}
\ No newline at end of file
diff --git a/tests/tests/telephony/TestSmsRetrieverApp/AndroidManifest.xml b/tests/tests/telephony/TestSmsRetrieverApp/AndroidManifest.xml
new file mode 100644
index 0000000..2ac0079f
--- /dev/null
+++ b/tests/tests/telephony/TestSmsRetrieverApp/AndroidManifest.xml
@@ -0,0 +1,29 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2019 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.telephony.cts.smsretriever">
+
+ <application android:label="TestSmsRetrieverApp">
+ <activity
+ android:name="android.telephony.cts.smsretriever.MainActivity"
+ android:exported="true"/>
+ <receiver android:name="android.telephony.cts.smsretriever.SmsRetrieverBroadcastReceiver">
+ <intent-filter>
+ <action android:name="android.telephony.cts.action.SMS_RETRIEVED"></action>
+ </intent-filter>
+ </receiver>
+ </application>
+</manifest>
diff --git a/tests/tests/telephony/TestSmsRetrieverApp/res/layout/main_activity.xml b/tests/tests/telephony/TestSmsRetrieverApp/res/layout/main_activity.xml
new file mode 100644
index 0000000..8758e66
--- /dev/null
+++ b/tests/tests/telephony/TestSmsRetrieverApp/res/layout/main_activity.xml
@@ -0,0 +1,20 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2019 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+
+<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent">
+</RelativeLayout>
diff --git a/tests/tests/telephony/TestSmsRetrieverApp/src/android/telephony/cts/smsretriever/MainActivity.java b/tests/tests/telephony/TestSmsRetrieverApp/src/android/telephony/cts/smsretriever/MainActivity.java
new file mode 100644
index 0000000..1f89db5
--- /dev/null
+++ b/tests/tests/telephony/TestSmsRetrieverApp/src/android/telephony/cts/smsretriever/MainActivity.java
@@ -0,0 +1,78 @@
+/*
+ * Copyright (C) 2019 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.telephony.cts.smsretriever;
+
+import static org.hamcrest.Matchers.equalTo;
+import static org.junit.Assert.assertThat;
+
+import android.app.Activity;
+import android.app.PendingIntent;
+import android.content.BroadcastReceiver;
+import android.content.ComponentName;
+import android.content.Context;
+import android.content.Intent;
+import android.content.IntentFilter;
+import android.os.Bundle;
+import android.os.RemoteCallback;
+import android.telephony.SmsManager;
+import android.util.Log;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.TimeUnit;
+
+public class MainActivity extends Activity {
+ private static final String SMS_RETRIEVER_ACTION = "CTS_SMS_RETRIEVER_ACTION";
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ Intent intent = new Intent("android.telephony.cts.action.SMS_RETRIEVED")
+ .setComponent(new ComponentName(
+ "android.telephony.cts.smsretriever",
+ "android.telephony.cts.smsretriever.SmsRetrieverBroadcastReceiver"));
+ PendingIntent pIntent = PendingIntent.getBroadcast(
+ getApplicationContext(), 0, intent, PendingIntent.FLAG_CANCEL_CURRENT);
+ String token = null;
+ try {
+ token = SmsManager.getDefault().createAppSpecificSmsTokenWithPackageInfo(
+ "testprefix1,testprefix2", pIntent);
+ } catch (Exception e) {
+ Log.w("MainActivity", "received Exception e:" + e);
+ }
+
+ if (getIntent().getAction() == null) {
+ Bundle result = new Bundle();
+ result.putString("class", getClass().getName());
+ result.putString("token", token);
+ sendResult(result);
+ } else {
+ // Launched by broadcast receiver
+ assertThat(getIntent().getStringExtra("message"),
+ equalTo("testprefix1This is a test message" + token));
+ Intent bIntent = new Intent(SMS_RETRIEVER_ACTION);
+ sendBroadcast(bIntent);
+ finish();
+ }
+ }
+
+ public void sendResult(Bundle result) {
+ getIntent().<RemoteCallback>getParcelableExtra("callback").sendResult(result);
+ }
+
+
+}
diff --git a/tests/tests/telephony/TestSmsRetrieverApp/src/android/telephony/cts/smsretriever/SmsRetrieverBroadcastReceiver.java b/tests/tests/telephony/TestSmsRetrieverApp/src/android/telephony/cts/smsretriever/SmsRetrieverBroadcastReceiver.java
new file mode 100644
index 0000000..ebb17b9
--- /dev/null
+++ b/tests/tests/telephony/TestSmsRetrieverApp/src/android/telephony/cts/smsretriever/SmsRetrieverBroadcastReceiver.java
@@ -0,0 +1,47 @@
+/*
+ * Copyright (C) 2019 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.telephony.cts.smsretriever;
+
+import android.app.Activity;
+import android.content.BroadcastReceiver;
+import android.content.ComponentName;
+import android.content.Context;
+import android.content.Intent;
+import android.content.IntentFilter;
+import android.os.Bundle;
+import android.os.RemoteCallback;
+import android.telephony.SmsManager;
+import android.util.Log;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.TimeUnit;
+
+public class SmsRetrieverBroadcastReceiver extends BroadcastReceiver {
+
+ @Override
+ public void onReceive(Context context, Intent intent) {
+ if (intent.getAction().equals("android.telephony.cts.action.SMS_RETRIEVED")) {
+ context.startActivity(new Intent("any.action")
+ .setFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
+ .setComponent(new ComponentName("android.telephony.cts.smsretriever",
+ "android.telephony.cts.smsretriever.MainActivity"))
+ .putExtra("message", intent.getStringExtra(SmsManager.EXTRA_SMS_MESSAGE)));
+ }
+ }
+}
diff --git a/tests/tests/telephony/current/Android.mk b/tests/tests/telephony/current/Android.mk
new file mode 100644
index 0000000..6f3d71a
--- /dev/null
+++ b/tests/tests/telephony/current/Android.mk
@@ -0,0 +1,52 @@
+# 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 := optional
+# and when built explicitly put it in the data partition
+LOCAL_MODULE_PATH := $(TARGET_OUT_DATA_APPS)
+
+LOCAL_JAVA_LIBRARIES := telephony-common
+
+LOCAL_STATIC_JAVA_LIBRARIES := \
+ ctstestrunner \
+ compatibility-device-util \
+ truth-prebuilt
+
+LOCAL_HOST_SHARED_LIBRARIES := compatibility-device-telephony-preconditions
+
+LOCAL_SRC_FILES := $(call all-java-files-under, src) \
+ $(call all-java-files-under, EmbmsMiddlewareTestApp) \
+ $(call all-Iaidl-files-under, EmbmsMiddlewareTestApp)
+
+LOCAL_AIDL_INCLUDES := EmbmsMiddlewareTestApp/aidl/
+
+LOCAL_PACKAGE_NAME := CtsTelephonyTestCases
+
+# Tag this module as a cts test artifact
+LOCAL_COMPATIBILITY_SUITE := cts vts general-tests
+
+# uncomment when b/13250611 is fixed
+#LOCAL_SDK_VERSION := current
+LOCAL_PRIVATE_PLATFORM_APIS := true
+LOCAL_JAVA_LIBRARIES += android.test.runner.stubs
+LOCAL_JAVA_LIBRARIES += android.test.base.stubs
+
+include $(BUILD_CTS_PACKAGE)
+include $(call all-makefiles-under,$(LOCAL_PATH))
diff --git a/tests/tests/telephony/AndroidManifest.xml b/tests/tests/telephony/current/AndroidManifest.xml
similarity index 100%
rename from tests/tests/telephony/AndroidManifest.xml
rename to tests/tests/telephony/current/AndroidManifest.xml
diff --git a/tests/tests/telephony/AndroidTest.xml b/tests/tests/telephony/current/AndroidTest.xml
similarity index 97%
rename from tests/tests/telephony/AndroidTest.xml
rename to tests/tests/telephony/current/AndroidTest.xml
index 4fabab8..44a4c68 100644
--- a/tests/tests/telephony/AndroidTest.xml
+++ b/tests/tests/telephony/current/AndroidTest.xml
@@ -28,6 +28,7 @@
<option name="test-file-name" value="EmbmsMiddlewareCtsTestApp.apk"/>
<option name="test-file-name" value="TestSmsApp22.apk"/>
<option name="test-file-name" value="TestSmsApp.apk"/>
+ <option name="test-file-name" value="TestSmsRetrieverApp.apk"/>
</target_preparer>
<test class="com.android.tradefed.testtype.AndroidJUnitTest" >
<option name="package" value="android.telephony.cts" />
diff --git a/tests/tests/telephony/EmbmsMiddlewareTestApp/Android.mk b/tests/tests/telephony/current/EmbmsMiddlewareTestApp/Android.mk
similarity index 100%
rename from tests/tests/telephony/EmbmsMiddlewareTestApp/Android.mk
rename to tests/tests/telephony/current/EmbmsMiddlewareTestApp/Android.mk
diff --git a/tests/tests/telephony/EmbmsMiddlewareTestApp/AndroidManifest.xml b/tests/tests/telephony/current/EmbmsMiddlewareTestApp/AndroidManifest.xml
similarity index 100%
rename from tests/tests/telephony/EmbmsMiddlewareTestApp/AndroidManifest.xml
rename to tests/tests/telephony/current/EmbmsMiddlewareTestApp/AndroidManifest.xml
diff --git a/tests/tests/telephony/EmbmsMiddlewareTestApp/aidl/android/telephony/cts/embmstestapp/ICtsDownloadMiddlewareControl.aidl b/tests/tests/telephony/current/EmbmsMiddlewareTestApp/aidl/android/telephony/cts/embmstestapp/ICtsDownloadMiddlewareControl.aidl
similarity index 100%
rename from tests/tests/telephony/EmbmsMiddlewareTestApp/aidl/android/telephony/cts/embmstestapp/ICtsDownloadMiddlewareControl.aidl
rename to tests/tests/telephony/current/EmbmsMiddlewareTestApp/aidl/android/telephony/cts/embmstestapp/ICtsDownloadMiddlewareControl.aidl
diff --git a/tests/tests/telephony/EmbmsMiddlewareTestApp/aidl/android/telephony/cts/embmstestapp/ICtsGroupCallMiddlewareControl.aidl b/tests/tests/telephony/current/EmbmsMiddlewareTestApp/aidl/android/telephony/cts/embmstestapp/ICtsGroupCallMiddlewareControl.aidl
similarity index 100%
rename from tests/tests/telephony/EmbmsMiddlewareTestApp/aidl/android/telephony/cts/embmstestapp/ICtsGroupCallMiddlewareControl.aidl
rename to tests/tests/telephony/current/EmbmsMiddlewareTestApp/aidl/android/telephony/cts/embmstestapp/ICtsGroupCallMiddlewareControl.aidl
diff --git a/tests/tests/telephony/EmbmsMiddlewareTestApp/aidl/android/telephony/cts/embmstestapp/ICtsStreamingMiddlewareControl.aidl b/tests/tests/telephony/current/EmbmsMiddlewareTestApp/aidl/android/telephony/cts/embmstestapp/ICtsStreamingMiddlewareControl.aidl
similarity index 100%
rename from tests/tests/telephony/EmbmsMiddlewareTestApp/aidl/android/telephony/cts/embmstestapp/ICtsStreamingMiddlewareControl.aidl
rename to tests/tests/telephony/current/EmbmsMiddlewareTestApp/aidl/android/telephony/cts/embmstestapp/ICtsStreamingMiddlewareControl.aidl
diff --git a/tests/tests/telephony/EmbmsMiddlewareTestApp/src/android/telephony/cts/embmstestapp/CtsDownloadService.java b/tests/tests/telephony/current/EmbmsMiddlewareTestApp/src/android/telephony/cts/embmstestapp/CtsDownloadService.java
similarity index 100%
rename from tests/tests/telephony/EmbmsMiddlewareTestApp/src/android/telephony/cts/embmstestapp/CtsDownloadService.java
rename to tests/tests/telephony/current/EmbmsMiddlewareTestApp/src/android/telephony/cts/embmstestapp/CtsDownloadService.java
diff --git a/tests/tests/telephony/EmbmsMiddlewareTestApp/src/android/telephony/cts/embmstestapp/CtsGroupCallService.java b/tests/tests/telephony/current/EmbmsMiddlewareTestApp/src/android/telephony/cts/embmstestapp/CtsGroupCallService.java
similarity index 100%
rename from tests/tests/telephony/EmbmsMiddlewareTestApp/src/android/telephony/cts/embmstestapp/CtsGroupCallService.java
rename to tests/tests/telephony/current/EmbmsMiddlewareTestApp/src/android/telephony/cts/embmstestapp/CtsGroupCallService.java
diff --git a/tests/tests/telephony/EmbmsMiddlewareTestApp/src/android/telephony/cts/embmstestapp/CtsStreamingService.java b/tests/tests/telephony/current/EmbmsMiddlewareTestApp/src/android/telephony/cts/embmstestapp/CtsStreamingService.java
similarity index 100%
rename from tests/tests/telephony/EmbmsMiddlewareTestApp/src/android/telephony/cts/embmstestapp/CtsStreamingService.java
rename to tests/tests/telephony/current/EmbmsMiddlewareTestApp/src/android/telephony/cts/embmstestapp/CtsStreamingService.java
diff --git a/tests/tests/telephony/preconditions/Android.mk b/tests/tests/telephony/current/preconditions/Android.mk
similarity index 100%
rename from tests/tests/telephony/preconditions/Android.mk
rename to tests/tests/telephony/current/preconditions/Android.mk
diff --git a/tests/tests/telephony/preconditions/app/Android.mk b/tests/tests/telephony/current/preconditions/app/Android.mk
similarity index 100%
rename from tests/tests/telephony/preconditions/app/Android.mk
rename to tests/tests/telephony/current/preconditions/app/Android.mk
diff --git a/tests/tests/telephony/preconditions/app/AndroidManifest.xml b/tests/tests/telephony/current/preconditions/app/AndroidManifest.xml
similarity index 100%
rename from tests/tests/telephony/preconditions/app/AndroidManifest.xml
rename to tests/tests/telephony/current/preconditions/app/AndroidManifest.xml
diff --git a/tests/tests/telephony/preconditions/app/src/android/telephony/cts/preconditions/app/TelephonyPreparerAppTest.java b/tests/tests/telephony/current/preconditions/app/src/android/telephony/cts/preconditions/app/TelephonyPreparerAppTest.java
similarity index 100%
rename from tests/tests/telephony/preconditions/app/src/android/telephony/cts/preconditions/app/TelephonyPreparerAppTest.java
rename to tests/tests/telephony/current/preconditions/app/src/android/telephony/cts/preconditions/app/TelephonyPreparerAppTest.java
diff --git a/tests/tests/telephony/preconditions/src/android/telephony/cts/preconditions/TelephonyPreparer.java b/tests/tests/telephony/current/preconditions/src/android/telephony/cts/preconditions/TelephonyPreparer.java
similarity index 100%
rename from tests/tests/telephony/preconditions/src/android/telephony/cts/preconditions/TelephonyPreparer.java
rename to tests/tests/telephony/current/preconditions/src/android/telephony/cts/preconditions/TelephonyPreparer.java
diff --git a/tests/tests/telephony/src/android/telephony/cts/CarrierCapability.java b/tests/tests/telephony/current/src/android/telephony/cts/CarrierCapability.java
similarity index 100%
rename from tests/tests/telephony/src/android/telephony/cts/CarrierCapability.java
rename to tests/tests/telephony/current/src/android/telephony/cts/CarrierCapability.java
diff --git a/tests/tests/telephony/src/android/telephony/cts/CarrierConfigManagerTest.java b/tests/tests/telephony/current/src/android/telephony/cts/CarrierConfigManagerTest.java
similarity index 100%
rename from tests/tests/telephony/src/android/telephony/cts/CarrierConfigManagerTest.java
rename to tests/tests/telephony/current/src/android/telephony/cts/CarrierConfigManagerTest.java
diff --git a/tests/tests/telephony/src/android/telephony/cts/CarrierServiceTest.java b/tests/tests/telephony/current/src/android/telephony/cts/CarrierServiceTest.java
similarity index 100%
rename from tests/tests/telephony/src/android/telephony/cts/CarrierServiceTest.java
rename to tests/tests/telephony/current/src/android/telephony/cts/CarrierServiceTest.java
diff --git a/tests/tests/telephony/src/android/telephony/cts/CellInfoTest.java b/tests/tests/telephony/current/src/android/telephony/cts/CellInfoTest.java
similarity index 100%
rename from tests/tests/telephony/src/android/telephony/cts/CellInfoTest.java
rename to tests/tests/telephony/current/src/android/telephony/cts/CellInfoTest.java
diff --git a/tests/tests/telephony/src/android/telephony/cts/CellLocationTest.java b/tests/tests/telephony/current/src/android/telephony/cts/CellLocationTest.java
similarity index 100%
rename from tests/tests/telephony/src/android/telephony/cts/CellLocationTest.java
rename to tests/tests/telephony/current/src/android/telephony/cts/CellLocationTest.java
diff --git a/tests/tests/telephony/src/android/telephony/cts/ComposeSmsActivity.java b/tests/tests/telephony/current/src/android/telephony/cts/ComposeSmsActivity.java
similarity index 100%
rename from tests/tests/telephony/src/android/telephony/cts/ComposeSmsActivity.java
rename to tests/tests/telephony/current/src/android/telephony/cts/ComposeSmsActivity.java
diff --git a/tests/tests/telephony/src/android/telephony/cts/HeadlessSmsSendService.java b/tests/tests/telephony/current/src/android/telephony/cts/HeadlessSmsSendService.java
similarity index 100%
rename from tests/tests/telephony/src/android/telephony/cts/HeadlessSmsSendService.java
rename to tests/tests/telephony/current/src/android/telephony/cts/HeadlessSmsSendService.java
diff --git a/tests/tests/telephony/src/android/telephony/cts/MmsPduProvider.java b/tests/tests/telephony/current/src/android/telephony/cts/MmsPduProvider.java
similarity index 100%
rename from tests/tests/telephony/src/android/telephony/cts/MmsPduProvider.java
rename to tests/tests/telephony/current/src/android/telephony/cts/MmsPduProvider.java
diff --git a/tests/tests/telephony/src/android/telephony/cts/MmsReceiver.java b/tests/tests/telephony/current/src/android/telephony/cts/MmsReceiver.java
similarity index 100%
rename from tests/tests/telephony/src/android/telephony/cts/MmsReceiver.java
rename to tests/tests/telephony/current/src/android/telephony/cts/MmsReceiver.java
diff --git a/tests/tests/telephony/src/android/telephony/cts/MmsTest.java b/tests/tests/telephony/current/src/android/telephony/cts/MmsTest.java
similarity index 100%
rename from tests/tests/telephony/src/android/telephony/cts/MmsTest.java
rename to tests/tests/telephony/current/src/android/telephony/cts/MmsTest.java
diff --git a/tests/tests/telephony/src/android/telephony/cts/MockVisualVoicemailService.java b/tests/tests/telephony/current/src/android/telephony/cts/MockVisualVoicemailService.java
similarity index 100%
rename from tests/tests/telephony/src/android/telephony/cts/MockVisualVoicemailService.java
rename to tests/tests/telephony/current/src/android/telephony/cts/MockVisualVoicemailService.java
diff --git a/tests/tests/telephony/src/android/telephony/cts/NeighboringCellInfoTest.java b/tests/tests/telephony/current/src/android/telephony/cts/NeighboringCellInfoTest.java
similarity index 100%
rename from tests/tests/telephony/src/android/telephony/cts/NeighboringCellInfoTest.java
rename to tests/tests/telephony/current/src/android/telephony/cts/NeighboringCellInfoTest.java
diff --git a/tests/tests/telephony/src/android/telephony/cts/PermissionlessVisualVoicemailService.java b/tests/tests/telephony/current/src/android/telephony/cts/PermissionlessVisualVoicemailService.java
similarity index 100%
rename from tests/tests/telephony/src/android/telephony/cts/PermissionlessVisualVoicemailService.java
rename to tests/tests/telephony/current/src/android/telephony/cts/PermissionlessVisualVoicemailService.java
diff --git a/tests/tests/telephony/src/android/telephony/cts/PhoneNumberUtilsTest.java b/tests/tests/telephony/current/src/android/telephony/cts/PhoneNumberUtilsTest.java
similarity index 100%
rename from tests/tests/telephony/src/android/telephony/cts/PhoneNumberUtilsTest.java
rename to tests/tests/telephony/current/src/android/telephony/cts/PhoneNumberUtilsTest.java
diff --git a/tests/tests/telephony/current/src/android/telephony/cts/PhoneStateListenerTest.java b/tests/tests/telephony/current/src/android/telephony/cts/PhoneStateListenerTest.java
new file mode 100644
index 0000000..b0d8f18
--- /dev/null
+++ b/tests/tests/telephony/current/src/android/telephony/cts/PhoneStateListenerTest.java
@@ -0,0 +1,824 @@
+/*
+ * 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.telephony.cts;
+
+import android.content.Context;
+import android.os.Looper;
+import android.telephony.CellInfo;
+import android.telephony.CellLocation;
+import android.telephony.PhoneStateListener;
+import android.telephony.PreciseCallState;
+import android.telephony.PreciseDataConnectionState;
+import android.telephony.ServiceState;
+import android.telephony.SignalStrength;
+import android.telephony.TelephonyManager;
+import android.net.ConnectivityManager;
+import android.test.AndroidTestCase;
+import android.util.Log;
+
+import com.android.compatibility.common.util.ShellIdentityUtils;
+import com.android.compatibility.common.util.TestThread;
+import static com.google.common.truth.Truth.assertThat;
+
+import java.util.Arrays;
+import java.util.List;
+import java.util.concurrent.Executor;
+
+public class PhoneStateListenerTest extends AndroidTestCase{
+
+ public static final long WAIT_TIME = 1000;
+
+ private boolean mOnCallForwardingIndicatorChangedCalled;
+ private boolean mOnCallStateChangedCalled;
+ private boolean mOnCellLocationChangedCalled;
+ private boolean mOnUserMobileDataStateChanged;
+ private boolean mOnDataActivityCalled;
+ private boolean mOnDataConnectionStateChangedCalled;
+ private boolean mOnDataConnectionStateChangedWithNetworkTypeCalled;
+ private boolean mOnMessageWaitingIndicatorChangedCalled;
+ private boolean mOnCellInfoChangedCalled;
+ private boolean mOnServiceStateChangedCalled;
+ private boolean mOnSignalStrengthChangedCalled;
+ private boolean mOnPreciseCallStateChangedCalled;
+ private boolean mOnCallDisconnectCauseChangedCalled;
+ private boolean mOnPreciseDataConnectionStateChanged;
+ private boolean mOnRadioPowerStateChangedCalled;
+ private boolean mVoiceActivationStateChangedCalled;
+ private boolean mSrvccStateChangedCalled;
+ @TelephonyManager.RadioPowerState private int mRadioPowerState;
+ @TelephonyManager.SimActivationState private int mVoiceActivationState;
+ private PreciseDataConnectionState mPreciseDataConnectionState;
+ private PreciseCallState mPreciseCallState;
+ private SignalStrength mSignalStrength;
+ private TelephonyManager mTelephonyManager;
+ private PhoneStateListener mListener;
+ private final Object mLock = new Object();
+ private static final String TAG = "android.telephony.cts.PhoneStateListenerTest";
+ private static ConnectivityManager mCm;
+ private static final List<Integer> DATA_CONNECTION_STATE = Arrays.asList(
+ TelephonyManager.DATA_CONNECTED,
+ TelephonyManager.DATA_DISCONNECTED,
+ TelephonyManager.DATA_CONNECTING,
+ TelephonyManager.DATA_UNKNOWN,
+ TelephonyManager.DATA_SUSPENDED
+ );
+ private static final List<Integer> PRECISE_CALL_STATE = Arrays.asList(
+ PreciseCallState.PRECISE_CALL_STATE_ACTIVE,
+ PreciseCallState.PRECISE_CALL_STATE_ALERTING,
+ PreciseCallState.PRECISE_CALL_STATE_DIALING,
+ PreciseCallState.PRECISE_CALL_STATE_DISCONNECTED,
+ PreciseCallState.PRECISE_CALL_STATE_DISCONNECTING,
+ PreciseCallState.PRECISE_CALL_STATE_HOLDING,
+ PreciseCallState.PRECISE_CALL_STATE_IDLE,
+ PreciseCallState.PRECISE_CALL_STATE_INCOMING,
+ PreciseCallState.PRECISE_CALL_STATE_NOT_VALID,
+ PreciseCallState.PRECISE_CALL_STATE_WAITING
+ );
+ private Executor mSimpleExecutor = new Executor() {
+ @Override
+ public void execute(Runnable r) {
+ r.run();
+ }
+ };
+
+ @Override
+ protected void setUp() throws Exception {
+ super.setUp();
+ mTelephonyManager =
+ (TelephonyManager)getContext().getSystemService(Context.TELEPHONY_SERVICE);
+ mCm = (ConnectivityManager)getContext().getSystemService(Context.CONNECTIVITY_SERVICE);
+ }
+
+ @Override
+ protected void tearDown() throws Exception {
+ super.tearDown();
+ if (mListener != null) {
+ // unregister the listener
+ mTelephonyManager.listen(mListener, PhoneStateListener.LISTEN_NONE);
+ }
+ }
+
+ public void testPhoneStateListener() {
+ if (mCm.getNetworkInfo(ConnectivityManager.TYPE_MOBILE) == null) {
+ Log.d(TAG, "Skipping test that requires ConnectivityManager.TYPE_MOBILE");
+ return;
+ }
+
+ Looper.prepare();
+ new PhoneStateListener();
+ }
+
+ /*
+ * The tests below rely on the framework to immediately call the installed listener upon
+ * registration. There is no simple way to emulate state changes for testing the listeners.
+ */
+
+ public void testOnServiceStateChanged() throws Throwable {
+ if (mCm.getNetworkInfo(ConnectivityManager.TYPE_MOBILE) == null) {
+ Log.d(TAG, "Skipping test that requires ConnectivityManager.TYPE_MOBILE");
+ return;
+ }
+
+ TestThread t = new TestThread(new Runnable() {
+ public void run() {
+ Looper.prepare();
+
+ mListener = new PhoneStateListener() {
+ @Override
+ public void onServiceStateChanged(ServiceState serviceState) {
+ synchronized(mLock) {
+ mOnServiceStateChangedCalled = true;
+ mLock.notify();
+ }
+ }
+ };
+ mTelephonyManager.listen(mListener, PhoneStateListener.LISTEN_SERVICE_STATE);
+
+ Looper.loop();
+ }
+ });
+
+ assertFalse(mOnServiceStateChangedCalled);
+ t.start();
+
+ synchronized (mLock) {
+ if (!mOnServiceStateChangedCalled){
+ mLock.wait(WAIT_TIME);
+ }
+ }
+ t.checkException();
+ assertTrue(mOnServiceStateChangedCalled);
+ }
+
+ public void testOnSignalStrengthChanged() throws Throwable {
+ if (mCm.getNetworkInfo(ConnectivityManager.TYPE_MOBILE) == null) {
+ Log.d(TAG, "Skipping test that requires ConnectivityManager.TYPE_MOBILE");
+ return;
+ }
+
+ TestThread t = new TestThread(new Runnable() {
+ public void run() {
+ Looper.prepare();
+
+ mListener = new PhoneStateListener() {
+ @Override
+ public void onSignalStrengthChanged(int asu) {
+ synchronized(mLock) {
+ mOnSignalStrengthChangedCalled = true;
+ mLock.notify();
+ }
+ }
+ };
+ mTelephonyManager.listen(mListener, PhoneStateListener.LISTEN_SIGNAL_STRENGTH);
+
+ Looper.loop();
+ }
+ });
+
+ assertFalse(mOnSignalStrengthChangedCalled);
+ t.start();
+
+ synchronized (mLock) {
+ if (!mOnSignalStrengthChangedCalled){
+ mLock.wait(WAIT_TIME);
+ }
+ }
+ t.checkException();
+ assertTrue(mOnSignalStrengthChangedCalled);
+ }
+
+ public void testOnSignalStrengthsChanged() throws Throwable {
+ if (mCm.getNetworkInfo(ConnectivityManager.TYPE_MOBILE) == null) {
+ Log.d(TAG, "Skipping test that requires ConnectivityManager.TYPE_MOBILE");
+ return;
+ }
+
+ TestThread t = new TestThread(new Runnable() {
+ public void run() {
+ Looper.prepare();
+
+ mListener = new PhoneStateListener() {
+ @Override
+ public void onSignalStrengthsChanged(SignalStrength signalStrength) {
+ synchronized(mLock) {
+ mSignalStrength = signalStrength;
+ mLock.notify();
+ }
+ }
+ };
+ mTelephonyManager.listen(mListener, PhoneStateListener.LISTEN_SIGNAL_STRENGTHS);
+
+ Looper.loop();
+ }
+ });
+
+ assertTrue(mSignalStrength == null);
+ t.start();
+
+ synchronized (mLock) {
+ if (mSignalStrength == null) {
+ mLock.wait(WAIT_TIME);
+ }
+ }
+ t.checkException();
+ assertTrue(mSignalStrength != null);
+
+ // Call SignalStrength methods to make sure they do not throw any exceptions
+ mSignalStrength.getCdmaDbm();
+ mSignalStrength.getCdmaEcio();
+ mSignalStrength.getEvdoDbm();
+ mSignalStrength.getEvdoEcio();
+ mSignalStrength.getEvdoSnr();
+ mSignalStrength.getGsmBitErrorRate();
+ mSignalStrength.getGsmSignalStrength();
+ mSignalStrength.isGsm();
+ mSignalStrength.getLevel();
+ }
+
+ public void testOnMessageWaitingIndicatorChanged() throws Throwable {
+ if (mCm.getNetworkInfo(ConnectivityManager.TYPE_MOBILE) == null) {
+ Log.d(TAG, "Skipping test that requires ConnectivityManager.TYPE_MOBILE");
+ return;
+ }
+
+ TestThread t = new TestThread(new Runnable() {
+ public void run() {
+ Looper.prepare();
+
+ mListener = new PhoneStateListener() {
+ @Override
+ public void onMessageWaitingIndicatorChanged(boolean mwi) {
+ synchronized(mLock) {
+ mOnMessageWaitingIndicatorChangedCalled = true;
+ mLock.notify();
+ }
+ }
+ };
+ mTelephonyManager.listen(
+ mListener, PhoneStateListener.LISTEN_MESSAGE_WAITING_INDICATOR);
+
+ Looper.loop();
+ }
+ });
+
+ assertFalse(mOnMessageWaitingIndicatorChangedCalled);
+ t.start();
+
+ synchronized (mLock) {
+ if (!mOnMessageWaitingIndicatorChangedCalled){
+ mLock.wait(WAIT_TIME);
+ }
+ }
+ t.checkException();
+ assertTrue(mOnMessageWaitingIndicatorChangedCalled);
+ }
+
+ /*
+ * The tests below rely on the framework to immediately call the installed listener upon
+ * registration. There is no simple way to emulate state changes for testing the listeners.
+ */
+ public void testOnPreciseCallStateChanged() throws Throwable {
+ if (mCm.getNetworkInfo(ConnectivityManager.TYPE_MOBILE) == null) {
+ Log.d(TAG, "Skipping test that requires ConnectivityManager.TYPE_MOBILE");
+ return;
+ }
+
+ TestThread t = new TestThread(new Runnable() {
+ public void run() {
+ Looper.prepare();
+
+ mListener = new PhoneStateListener() {
+ @Override
+ public void onPreciseCallStateChanged(PreciseCallState preciseCallState) {
+ synchronized (mLock) {
+ mOnPreciseCallStateChangedCalled = true;
+ mPreciseCallState = preciseCallState;
+ mLock.notify();
+ }
+ }
+ };
+ ShellIdentityUtils.invokeMethodWithShellPermissionsNoReturn(mTelephonyManager,
+ (tm) -> tm.listen(mListener, PhoneStateListener.LISTEN_PRECISE_CALL_STATE));
+ Looper.loop();
+ }
+ });
+
+ assertThat(mOnPreciseCallStateChangedCalled).isFalse();
+ t.start();
+
+ synchronized (mLock) {
+ if (!mOnPreciseCallStateChangedCalled) {
+ mLock.wait(WAIT_TIME);
+ }
+ }
+ t.checkException();
+ Log.d(TAG, "testOnPreciseCallStateChanged: " + mOnPreciseCallStateChangedCalled);
+ assertThat(mOnPreciseCallStateChangedCalled).isTrue();
+ assertThat(mPreciseCallState.getForegroundCallState()).isIn(PRECISE_CALL_STATE);
+ assertThat(mPreciseCallState.getBackgroundCallState()).isIn(PRECISE_CALL_STATE);
+ assertThat(mPreciseCallState.getRingingCallState()).isIn(PRECISE_CALL_STATE);
+ }
+
+ /*
+ * The tests below rely on the framework to immediately call the installed listener upon
+ * registration. There is no simple way to emulate state changes for testing the listeners.
+ */
+ public void testOnCallDisconnectCauseChanged() throws Throwable {
+ if (mCm.getNetworkInfo(ConnectivityManager.TYPE_MOBILE) == null) {
+ Log.d(TAG, "Skipping test that requires ConnectivityManager.TYPE_MOBILE");
+ return;
+ }
+
+ TestThread t = new TestThread(new Runnable() {
+ public void run() {
+ Looper.prepare();
+
+ mListener = new PhoneStateListener() {
+ @Override
+ public void onCallDisconnectCauseChanged(int disconnectCause,
+ int preciseDisconnectCause) {
+ synchronized (mLock) {
+ mOnCallDisconnectCauseChangedCalled = true;
+ mLock.notify();
+ }
+ }
+ };
+ ShellIdentityUtils.invokeMethodWithShellPermissionsNoReturn(mTelephonyManager,
+ (tm) -> tm.listen(mListener,
+ PhoneStateListener.LISTEN_CALL_DISCONNECT_CAUSES));
+ Looper.loop();
+ }
+ });
+
+ assertThat(mOnCallDisconnectCauseChangedCalled).isFalse();
+ t.start();
+
+ synchronized (mLock) {
+ if (!mOnCallDisconnectCauseChangedCalled){
+ mLock.wait(WAIT_TIME);
+ }
+ }
+ t.checkException();
+ assertThat(mOnCallDisconnectCauseChangedCalled).isTrue();
+ }
+
+ public void testOnPhoneStateListenerExecutorWithSrvccChanged() throws Throwable {
+ if (mCm.getNetworkInfo(ConnectivityManager.TYPE_MOBILE) == null) {
+ Log.d(TAG, "Skipping test that requires ConnectivityManager.TYPE_MOBILE");
+ return;
+ }
+ TestThread t = new TestThread(new Runnable() {
+ public void run() {
+ Looper.prepare();
+
+ mListener = new PhoneStateListener(mSimpleExecutor) {
+ @Override
+ public void onSrvccStateChanged(int state) {
+ synchronized (mLock) {
+ mSrvccStateChangedCalled = true;
+ mLock.notify();
+ }
+ }
+ };
+ ShellIdentityUtils.invokeMethodWithShellPermissionsNoReturn(mTelephonyManager,
+ (tm) -> tm.listen(mListener,
+ PhoneStateListener.LISTEN_SRVCC_STATE_CHANGED));
+ Looper.loop();
+ }
+ });
+
+ assertThat(mSrvccStateChangedCalled).isFalse();
+ t.start();
+
+ synchronized (mLock) {
+ if (!mSrvccStateChangedCalled){
+ mLock.wait(WAIT_TIME);
+ }
+ }
+ assertThat(mSrvccStateChangedCalled).isTrue();
+ t.checkException();
+ Log.d(TAG, "testOnPhoneStateListenerExecutorWithSrvccChanged");
+ }
+
+ /*
+ * The tests below rely on the framework to immediately call the installed listener upon
+ * registration. There is no simple way to emulate state changes for testing the listeners.
+ */
+ public void testOnRadioPowerStateChanged() throws Throwable {
+ if (mCm.getNetworkInfo(ConnectivityManager.TYPE_MOBILE) == null) {
+ Log.d(TAG, "Skipping test that requires ConnectivityManager.TYPE_MOBILE");
+ return;
+ }
+ TestThread t = new TestThread(new Runnable() {
+ public void run() {
+ Looper.prepare();
+
+ mListener = new PhoneStateListener() {
+ @Override
+ public void onRadioPowerStateChanged(int state) {
+ synchronized(mLock) {
+ mRadioPowerState = state;
+ mOnRadioPowerStateChangedCalled = true;
+ mLock.notify();
+ }
+ }
+ };
+ ShellIdentityUtils.invokeMethodWithShellPermissionsNoReturn(mTelephonyManager,
+ (tm) -> tm.listen(mListener,
+ PhoneStateListener.LISTEN_RADIO_POWER_STATE_CHANGED));
+ Looper.loop();
+ }
+ });
+ assertThat(mOnRadioPowerStateChangedCalled).isFalse();
+ t.start();
+
+ synchronized (mLock) {
+ if (!mOnRadioPowerStateChangedCalled){
+ mLock.wait(WAIT_TIME);
+ }
+ }
+ t.checkException();
+ Log.d(TAG, "testOnRadioPowerStateChanged: " + mRadioPowerState);
+ assertThat(mTelephonyManager.getRadioPowerState()).isEqualTo(mRadioPowerState);
+ }
+
+ /*
+ * The tests below rely on the framework to immediately call the installed listener upon
+ * registration. There is no simple way to emulate state changes for testing the listeners.
+ */
+ public void testOnVoiceActivationStateChanged() throws Throwable {
+ if (mCm.getNetworkInfo(ConnectivityManager.TYPE_MOBILE) == null) {
+ Log.d(TAG, "Skipping test that requires ConnectivityManager.TYPE_MOBILE");
+ return;
+ }
+ TestThread t = new TestThread(new Runnable() {
+ public void run() {
+ Looper.prepare();
+
+ mListener = new PhoneStateListener() {
+ @Override
+ public void onVoiceActivationStateChanged(int state) {
+ synchronized(mLock) {
+ mVoiceActivationState = state;
+ mVoiceActivationStateChangedCalled = true;
+ mLock.notify();
+ }
+ }
+ };
+ ShellIdentityUtils.invokeMethodWithShellPermissionsNoReturn(mTelephonyManager,
+ (tm) -> tm.listen(mListener,
+ PhoneStateListener.LISTEN_VOICE_ACTIVATION_STATE));
+ Looper.loop();
+ }
+ });
+ assertThat(mVoiceActivationStateChangedCalled).isFalse();
+ t.start();
+
+ synchronized (mLock) {
+ if (!mVoiceActivationStateChangedCalled){
+ mLock.wait(WAIT_TIME);
+ }
+ }
+ t.checkException();
+ Log.d(TAG, "onVoiceActivationStateChanged: " + mVoiceActivationState);
+ int state = ShellIdentityUtils.invokeMethodWithShellPermissions(mTelephonyManager,
+ (tm) -> tm.getVoiceActivationState());
+ assertEquals(state, mVoiceActivationState);
+ }
+
+ /*
+ * The tests below rely on the framework to immediately call the installed listener upon
+ * registration. There is no simple way to emulate state changes for testing the listeners.
+ */
+ public void testOnPreciseDataConnectionStateChanged() throws Throwable {
+ if (mCm.getNetworkInfo(ConnectivityManager.TYPE_MOBILE) == null) {
+ Log.d(TAG, "Skipping test that requires ConnectivityManager.TYPE_MOBILE");
+ return;
+ }
+
+ TestThread t = new TestThread(new Runnable() {
+ public void run() {
+ Looper.prepare();
+
+ mListener = new PhoneStateListener() {
+ @Override
+ public void onPreciseDataConnectionStateChanged(
+ PreciseDataConnectionState state) {
+ synchronized(mLock) {
+ mOnPreciseDataConnectionStateChanged = true;
+ mPreciseDataConnectionState = state;
+ mLock.notify();
+ }
+ }
+ };
+ ShellIdentityUtils.invokeMethodWithShellPermissionsNoReturn(mTelephonyManager,
+ (tm) -> tm.listen(mListener,
+ PhoneStateListener.LISTEN_PRECISE_DATA_CONNECTION_STATE));
+ Looper.loop();
+ }
+ });
+
+ assertThat(mOnCallDisconnectCauseChangedCalled).isFalse();
+ t.start();
+
+ synchronized (mLock) {
+ if (!mOnPreciseDataConnectionStateChanged){
+ mLock.wait(WAIT_TIME);
+ }
+ }
+ t.checkException();
+ assertThat(mOnPreciseDataConnectionStateChanged).isTrue();
+ assertThat(mPreciseDataConnectionState.getDataConnectionState())
+ .isIn(DATA_CONNECTION_STATE);
+ // basic test to verify there is no exception thrown.
+ mPreciseDataConnectionState.getDataConnectionApnTypeBitMask();
+ mPreciseDataConnectionState.getDataConnectionApn();
+ mPreciseDataConnectionState.getDataConnectionFailCause();
+ }
+
+ public void testOnCallForwardingIndicatorChanged() throws Throwable {
+ if (mCm.getNetworkInfo(ConnectivityManager.TYPE_MOBILE) == null) {
+ Log.d(TAG, "Skipping test that requires ConnectivityManager.TYPE_MOBILE");
+ return;
+ }
+
+ TestThread t = new TestThread(new Runnable() {
+ @Override
+ public void run() {
+ Looper.prepare();
+
+ mListener = new PhoneStateListener() {
+ @Override
+ public void onCallForwardingIndicatorChanged(boolean cfi) {
+ synchronized(mLock) {
+ mOnCallForwardingIndicatorChangedCalled = true;
+ mLock.notify();
+ }
+ }
+ };
+ mTelephonyManager.listen(
+ mListener, PhoneStateListener.LISTEN_CALL_FORWARDING_INDICATOR);
+
+ Looper.loop();
+ }
+ });
+
+ assertFalse(mOnCallForwardingIndicatorChangedCalled);
+ t.start();
+
+ synchronized (mLock) {
+ if (!mOnCallForwardingIndicatorChangedCalled){
+ mLock.wait(WAIT_TIME);
+ }
+ }
+ t.checkException();
+ assertTrue(mOnCallForwardingIndicatorChangedCalled);
+ }
+
+ public void testOnCellLocationChanged() throws Throwable {
+ if (mCm.getNetworkInfo(ConnectivityManager.TYPE_MOBILE) == null) {
+ Log.d(TAG, "Skipping test that requires ConnectivityManager.TYPE_MOBILE");
+ return;
+ }
+
+ TestThread t = new TestThread(new Runnable() {
+ public void run() {
+ Looper.prepare();
+
+ mListener = new PhoneStateListener() {
+ @Override
+ public void onCellLocationChanged(CellLocation location) {
+ synchronized(mLock) {
+ mOnCellLocationChangedCalled = true;
+ mLock.notify();
+ }
+ }
+ };
+ mTelephonyManager.listen(mListener, PhoneStateListener.LISTEN_CELL_LOCATION);
+
+ Looper.loop();
+ }
+ });
+
+ assertFalse(mOnCellLocationChangedCalled);
+ t.start();
+
+ synchronized (mLock) {
+ if (!mOnCellLocationChangedCalled){
+ mLock.wait(WAIT_TIME);
+ }
+ }
+ t.checkException();
+ assertTrue(mOnCellLocationChangedCalled);
+ }
+
+ public void testOnCallStateChanged() throws Throwable {
+ if (mCm.getNetworkInfo(ConnectivityManager.TYPE_MOBILE) == null) {
+ Log.d(TAG, "Skipping test that requires ConnectivityManager.TYPE_MOBILE");
+ return;
+ }
+
+ TestThread t = new TestThread(new Runnable() {
+ public void run() {
+ Looper.prepare();
+
+ mListener = new PhoneStateListener() {
+ @Override
+ public void onCallStateChanged(int state, String incomingNumber) {
+ synchronized(mLock) {
+ mOnCallStateChangedCalled = true;
+ mLock.notify();
+ }
+ }
+ };
+ mTelephonyManager.listen(mListener, PhoneStateListener.LISTEN_CALL_STATE);
+
+ Looper.loop();
+ }
+ });
+
+ assertFalse(mOnCallStateChangedCalled);
+ t.start();
+
+ synchronized (mLock) {
+ if (!mOnCallStateChangedCalled){
+ mLock.wait(WAIT_TIME);
+ }
+ }
+ t.checkException();
+ assertTrue(mOnCallStateChangedCalled);
+ }
+
+ public void testOnDataConnectionStateChanged() throws Throwable {
+ if (mCm.getNetworkInfo(ConnectivityManager.TYPE_MOBILE) == null) {
+ Log.d(TAG, "Skipping test that requires ConnectivityManager.TYPE_MOBILE");
+ return;
+ }
+
+ TestThread t = new TestThread(new Runnable() {
+ public void run() {
+ Looper.prepare();
+
+ mListener = new PhoneStateListener() {
+ @Override
+ public void onDataConnectionStateChanged(int state) {
+ synchronized(mLock) {
+ mOnDataConnectionStateChangedCalled = true;
+ mLock.notify();
+ }
+ }
+ @Override
+ public void onDataConnectionStateChanged(int state, int networkType) {
+ synchronized(mLock) {
+ mOnDataConnectionStateChangedWithNetworkTypeCalled = true;
+ mLock.notify();
+ }
+ }
+ };
+ mTelephonyManager.listen(
+ mListener, PhoneStateListener.LISTEN_DATA_CONNECTION_STATE);
+
+ Looper.loop();
+ }
+ });
+
+ assertFalse(mOnDataConnectionStateChangedCalled);
+ assertFalse(mOnDataConnectionStateChangedWithNetworkTypeCalled);
+ t.start();
+
+ synchronized (mLock) {
+ if (!mOnDataConnectionStateChangedCalled ||
+ !mOnDataConnectionStateChangedWithNetworkTypeCalled){
+ mLock.wait(WAIT_TIME);
+ }
+ }
+ t.checkException();
+ assertTrue(mOnDataConnectionStateChangedCalled);
+ assertTrue(mOnDataConnectionStateChangedWithNetworkTypeCalled);
+ }
+
+ public void testOnDataActivity() throws Throwable {
+ if (mCm.getNetworkInfo(ConnectivityManager.TYPE_MOBILE) == null) {
+ Log.d(TAG, "Skipping test that requires ConnectivityManager.TYPE_MOBILE");
+ return;
+ }
+
+ TestThread t = new TestThread(new Runnable() {
+ public void run() {
+ Looper.prepare();
+
+ mListener = new PhoneStateListener() {
+ @Override
+ public void onDataActivity(int direction) {
+ synchronized(mLock) {
+ mOnDataActivityCalled = true;
+ mLock.notify();
+ }
+ }
+ };
+ mTelephonyManager.listen(mListener, PhoneStateListener.LISTEN_DATA_ACTIVITY);
+
+ Looper.loop();
+ }
+ });
+
+ assertFalse(mOnDataActivityCalled);
+ t.start();
+
+ synchronized (mLock) {
+ if (!mOnDataActivityCalled){
+ mLock.wait(WAIT_TIME);
+ }
+ }
+ t.checkException();
+ assertTrue(mOnDataActivityCalled);
+ }
+
+ public void testOnCellInfoChanged() throws Throwable {
+ if (mCm.getNetworkInfo(ConnectivityManager.TYPE_MOBILE) == null) {
+ Log.d(TAG, "Skipping test that requires ConnectivityManager.TYPE_MOBILE");
+ return;
+ }
+
+ TestThread t = new TestThread(new Runnable() {
+ public void run() {
+ Looper.prepare();
+
+ mListener = new PhoneStateListener() {
+ @Override
+ public void onCellInfoChanged(List<CellInfo> cellInfo) {
+ synchronized(mLock) {
+ mOnCellInfoChangedCalled = true;
+ mLock.notify();
+ }
+ }
+ };
+ mTelephonyManager.listen(mListener, PhoneStateListener.LISTEN_CELL_INFO);
+
+ Looper.loop();
+ }
+ });
+
+ assertFalse(mOnDataActivityCalled);
+ t.start();
+
+ synchronized (mLock) {
+ if (!mOnCellInfoChangedCalled){
+ mLock.wait(WAIT_TIME);
+ }
+ }
+ t.checkException();
+ assertTrue(mOnCellInfoChangedCalled);
+ }
+
+ public void testOnUserMobileDataStateChanged() throws Throwable {
+ if (mCm.getNetworkInfo(ConnectivityManager.TYPE_MOBILE) == null) {
+ Log.d(TAG, "Skipping test that requires ConnectivityManager.TYPE_MOBILE");
+ return;
+ }
+
+ TestThread t = new TestThread(new Runnable() {
+ public void run() {
+ Looper.prepare();
+
+ mListener = new PhoneStateListener() {
+ @Override
+ public void onUserMobileDataStateChanged(boolean state) {
+ synchronized(mLock) {
+ mOnUserMobileDataStateChanged = true;
+ mLock.notify();
+ }
+ }
+ };
+ mTelephonyManager.listen(
+ mListener, PhoneStateListener.LISTEN_USER_MOBILE_DATA_STATE);
+
+ Looper.loop();
+ }
+ });
+
+ assertFalse(mOnUserMobileDataStateChanged);
+ t.start();
+
+ synchronized (mLock) {
+ if (!mOnUserMobileDataStateChanged){
+ mLock.wait(WAIT_TIME);
+ }
+ }
+ t.checkException();
+ assertTrue(mOnUserMobileDataStateChanged);
+ }
+}
diff --git a/tests/tests/telephony/src/android/telephony/cts/RadioAccessSpecifierTest.java b/tests/tests/telephony/current/src/android/telephony/cts/RadioAccessSpecifierTest.java
similarity index 100%
rename from tests/tests/telephony/src/android/telephony/cts/RadioAccessSpecifierTest.java
rename to tests/tests/telephony/current/src/android/telephony/cts/RadioAccessSpecifierTest.java
diff --git a/tests/tests/telephony/src/android/telephony/cts/ServiceStateTest.java b/tests/tests/telephony/current/src/android/telephony/cts/ServiceStateTest.java
similarity index 100%
rename from tests/tests/telephony/src/android/telephony/cts/ServiceStateTest.java
rename to tests/tests/telephony/current/src/android/telephony/cts/ServiceStateTest.java
diff --git a/tests/tests/telephony/current/src/android/telephony/cts/SignalStrengthTest.java b/tests/tests/telephony/current/src/android/telephony/cts/SignalStrengthTest.java
new file mode 100644
index 0000000..cb87173
--- /dev/null
+++ b/tests/tests/telephony/current/src/android/telephony/cts/SignalStrengthTest.java
@@ -0,0 +1,145 @@
+/*
+ * 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.telephony.cts;
+
+import static android.telephony.NetworkRegistrationState.NR_STATUS_CONNECTED;
+import android.content.Context;
+import android.content.pm.PackageManager;
+import android.net.ConnectivityManager;
+import android.os.Parcel;
+import android.telephony.CellInfoCdma;
+import android.telephony.CellInfoGsm;
+import android.telephony.CellInfoLte;
+import android.telephony.CellInfoWcdma;
+import android.telephony.CellSignalStrengthCdma;
+import android.telephony.CellSignalStrengthGsm;
+import android.telephony.CellSignalStrengthLte;
+import android.telephony.CellSignalStrengthNr;
+import android.telephony.CellSignalStrengthTdscdma;
+import android.telephony.CellSignalStrengthWcdma;
+import android.telephony.CellSignalStrength;
+import android.telephony.ServiceState;
+import android.telephony.SignalStrength;
+import android.telephony.TelephonyManager;
+import android.test.AndroidTestCase;
+import android.util.Log;
+
+
+import java.util.HashSet;
+import java.util.List;
+import java.util.Objects;
+import java.util.Set;
+
+
+/**
+ * Test SignalStrength to ensure that valid data is being reported and that invalid data is
+ * not reported.
+ */
+public class SignalStrengthTest extends AndroidTestCase {
+ private static final String TAG = "SignalStrengthTest";
+
+ private TelephonyManager mTm;
+ private PackageManager mPm;
+
+ // Check that the device is camped on a cellular cell */
+ private boolean isCamped() {
+ ServiceState ss = mTm.getServiceState();
+ if (ss == null) return false;
+ return (ss.getState() == ServiceState.STATE_IN_SERVICE
+ || ss.getState() == ServiceState.STATE_EMERGENCY_ONLY);
+ }
+
+ @Override
+ protected void setUp() throws Exception {
+ super.setUp();
+ mTm = (TelephonyManager) getContext().getSystemService(Context.TELEPHONY_SERVICE);
+ mPm = getContext().getPackageManager();
+ }
+
+ public void testSignalStrength() throws Throwable {
+ if (!mPm.hasSystemFeature(PackageManager.FEATURE_TELEPHONY)) {
+ Log.d(TAG, "Skipping test that requires FEATURE_TELEPHONY");
+ return;
+ }
+
+ if (!isCamped()) fail("Device is not camped on cellular");
+
+ SignalStrength ss = mTm.getSignalStrength();
+ assertNotNull("TelephonyManager.getSignalStrength() returned NULL!", ss);
+
+ List<CellSignalStrength> signalStrengths = ss.getCellSignalStrengths();
+
+ assertTrue("No Signal Strength Information Reported!", !signalStrengths.isEmpty());
+
+ Set<Class<?>> types = new HashSet<Class<?>>();
+
+ Class<?> type = getSignalStrengthTypeForNetworkType(mTm.getDataNetworkType());
+ if (type != null) types.add(type);
+
+ type = getSignalStrengthTypeForNetworkType(mTm.getNetworkType());
+ if (type != null) types.add(type);
+
+ // Blocked by b/123096279
+ /*
+ for (CellSignalStrength css : signalStrengths) {
+ assertTrue("Invalid SignalStrength type detected" + css.getClass(),
+ types.contains(css.getClass())
+ || css instanceof CellSignalStrengthNr && isUsingEnDc());
+ }
+ */
+ }
+
+ /** Check whether the device is LTE + NR dual connected */
+ private boolean isUsingEnDc() {
+ ServiceState ss = mTm.getServiceState();
+ return false;
+ // blocked by b/123096279
+ // return ss != null && ss.getNrStatus() == NR_STATUS_CONNECTED;
+ }
+
+ /** Get the CellSignalStrength class type that should be returned when using a network type */
+ private static Class<?> getSignalStrengthTypeForNetworkType(int networkType) {
+ switch(networkType) {
+ case TelephonyManager.NETWORK_TYPE_GPRS: /* fall through */
+ case TelephonyManager.NETWORK_TYPE_EDGE: /* fall through */
+ case TelephonyManager.NETWORK_TYPE_GSM:
+ return CellSignalStrengthGsm.class;
+ case TelephonyManager.NETWORK_TYPE_UMTS: /* fall through */
+ case TelephonyManager.NETWORK_TYPE_HSDPA: /* fall through */
+ case TelephonyManager.NETWORK_TYPE_HSUPA: /* fall through */
+ case TelephonyManager.NETWORK_TYPE_HSPA: /* fall through */
+ case TelephonyManager.NETWORK_TYPE_HSPAP:
+ return CellSignalStrengthWcdma.class;
+ case TelephonyManager.NETWORK_TYPE_TD_SCDMA:
+ return CellSignalStrengthTdscdma.class;
+ case TelephonyManager.NETWORK_TYPE_CDMA: /* fall through */
+ case TelephonyManager.NETWORK_TYPE_1xRTT: /* fall through */
+ case TelephonyManager.NETWORK_TYPE_EVDO_0: /* fall through */
+ case TelephonyManager.NETWORK_TYPE_EVDO_A: /* fall through */
+ case TelephonyManager.NETWORK_TYPE_EVDO_B: /* fall through */
+ case TelephonyManager.NETWORK_TYPE_EHRPD:
+ return CellSignalStrengthCdma.class;
+ case TelephonyManager.NETWORK_TYPE_LTE: /* fall through */
+ case TelephonyManager.NETWORK_TYPE_LTE_CA:
+ return CellSignalStrengthLte.class;
+ case TelephonyManager.NETWORK_TYPE_IWLAN: /* fall through */
+ case TelephonyManager.NETWORK_TYPE_IDEN: /* fall through */
+ case TelephonyManager.NETWORK_TYPE_NR: /* fall through */
+ default:
+ return null;
+ }
+ }
+}
diff --git a/tests/tests/telephony/src/android/telephony/cts/SmsManagerTest.java b/tests/tests/telephony/current/src/android/telephony/cts/SmsManagerTest.java
similarity index 93%
rename from tests/tests/telephony/src/android/telephony/cts/SmsManagerTest.java
rename to tests/tests/telephony/current/src/android/telephony/cts/SmsManagerTest.java
index 6eaf46e..208afb0 100755
--- a/tests/tests/telephony/src/android/telephony/cts/SmsManagerTest.java
+++ b/tests/tests/telephony/current/src/android/telephony/cts/SmsManagerTest.java
@@ -57,12 +57,14 @@
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
+import java.lang.StringBuilder;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.concurrent.Callable;
import java.util.concurrent.CompletableFuture;
+import java.util.concurrent.CountDownLatch;
import java.util.concurrent.TimeUnit;
/**
@@ -90,6 +92,8 @@
public static final String SMS_DELIVER_DEFAULT_APP_ACTION = "CTS_SMS_DELIVERY_ACTION_DEFAULT_APP";
public static final String LEGACY_SMS_APP = "android.telephony.cts.sms23";
public static final String MODERN_SMS_APP = "android.telephony.cts.sms";
+ private static final String SMS_RETRIEVER_APP = "android.telephony.cts.smsretriever";
+ private static final String SMS_RETRIEVER_ACTION = "CTS_SMS_RETRIEVER_ACTION";
private TelephonyManager mTelephonyManager;
private PackageManager mPackageManager;
@@ -100,6 +104,7 @@
private SmsBroadcastReceiver mDataSmsReceiver;
private SmsBroadcastReceiver mSmsDeliverReceiver;
private SmsBroadcastReceiver mSmsReceivedReceiver;
+ private SmsBroadcastReceiver mSmsRetrieverReceiver;
private PendingIntent mSentIntent;
private PendingIntent mDeliveredIntent;
private Intent mSendIntent;
@@ -182,6 +187,39 @@
return longText.equals(actualMessage);
}
+ public void testSmsRetriever() throws Exception {
+ if (!mPackageManager.hasSystemFeature(PackageManager.FEATURE_TELEPHONY)) {
+ return;
+ }
+
+ assertFalse("[RERUN] SIM card does not provide phone number. Use a suitable SIM Card.",
+ TextUtils.isEmpty(mDestAddr));
+
+ String mccmnc = mTelephonyManager.getSimOperator();
+ setupBroadcastReceivers();
+ init();
+
+ CompletableFuture<Bundle> callbackResult = new CompletableFuture<>();
+
+ mContext.startActivity(new Intent()
+ .setFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
+ .setComponent(new ComponentName(
+ SMS_RETRIEVER_APP, SMS_RETRIEVER_APP + ".MainActivity"))
+ .putExtra("callback", new RemoteCallback(callbackResult::complete)));
+
+
+ Bundle bundle = callbackResult.get(200, TimeUnit.SECONDS);
+ String token = bundle.getString("token");
+ assertThat(bundle.getString("class"), startsWith(SMS_RETRIEVER_APP));
+ assertNotNull(token);
+
+ String composedText = "testprefix1" + mText + token;
+ sendTextMessage(mDestAddr, composedText, null, null);
+
+ assertTrue("[RERUN] SMS retriever message not received. Check signal.",
+ mSmsRetrieverReceiver.waitForCalls(1, TIME_OUT));
+ }
+
public void testSendAndReceiveMessages() throws Exception {
if (!mPackageManager.hasSystemFeature(PackageManager.FEATURE_TELEPHONY)) {
return;
@@ -488,6 +526,7 @@
mDataSmsReceiver.reset();
mSmsDeliverReceiver.reset();
mSmsReceivedReceiver.reset();
+ mSmsRetrieverReceiver.reset();
mReceivedDataSms = false;
mSentIntent = PendingIntent.getBroadcast(mContext, 0, mSendIntent,
PendingIntent.FLAG_ONE_SHOT);
@@ -505,6 +544,7 @@
IntentFilter smsDeliverIntentFilter = new IntentFilter(SMS_DELIVER_DEFAULT_APP_ACTION);
IntentFilter smsReceivedIntentFilter =
new IntentFilter(Telephony.Sms.Intents.SMS_RECEIVED_ACTION);
+ IntentFilter smsRetrieverIntentFilter = new IntentFilter(SMS_RETRIEVER_ACTION);
dataSmsReceivedIntentFilter.addDataScheme("sms");
dataSmsReceivedIntentFilter.addDataAuthority("localhost", "19989");
@@ -513,12 +553,14 @@
mDataSmsReceiver = new SmsBroadcastReceiver(DATA_SMS_RECEIVED_ACTION);
mSmsDeliverReceiver = new SmsBroadcastReceiver(SMS_DELIVER_DEFAULT_APP_ACTION);
mSmsReceivedReceiver = new SmsBroadcastReceiver(Telephony.Sms.Intents.SMS_RECEIVED_ACTION);
+ mSmsRetrieverReceiver = new SmsBroadcastReceiver(SMS_RETRIEVER_ACTION);
mContext.registerReceiver(mSendReceiver, sendIntentFilter);
mContext.registerReceiver(mDeliveryReceiver, deliveryIntentFilter);
mContext.registerReceiver(mDataSmsReceiver, dataSmsReceivedIntentFilter);
mContext.registerReceiver(mSmsDeliverReceiver, smsDeliverIntentFilter);
mContext.registerReceiver(mSmsReceivedReceiver, smsReceivedIntentFilter);
+ mContext.registerReceiver(mSmsRetrieverReceiver, smsRetrieverIntentFilter);
}
/**
diff --git a/tests/tests/telephony/src/android/telephony/cts/SmsMessageTest.java b/tests/tests/telephony/current/src/android/telephony/cts/SmsMessageTest.java
similarity index 100%
rename from tests/tests/telephony/src/android/telephony/cts/SmsMessageTest.java
rename to tests/tests/telephony/current/src/android/telephony/cts/SmsMessageTest.java
diff --git a/tests/tests/telephony/src/android/telephony/cts/SmsMessage_MessageClassTest.java b/tests/tests/telephony/current/src/android/telephony/cts/SmsMessage_MessageClassTest.java
similarity index 100%
rename from tests/tests/telephony/src/android/telephony/cts/SmsMessage_MessageClassTest.java
rename to tests/tests/telephony/current/src/android/telephony/cts/SmsMessage_MessageClassTest.java
diff --git a/tests/tests/telephony/src/android/telephony/cts/SmsMessage_SubmitPduTest.java b/tests/tests/telephony/current/src/android/telephony/cts/SmsMessage_SubmitPduTest.java
similarity index 100%
rename from tests/tests/telephony/src/android/telephony/cts/SmsMessage_SubmitPduTest.java
rename to tests/tests/telephony/current/src/android/telephony/cts/SmsMessage_SubmitPduTest.java
diff --git a/tests/tests/telephony/src/android/telephony/cts/SmsReceiver.java b/tests/tests/telephony/current/src/android/telephony/cts/SmsReceiver.java
similarity index 100%
rename from tests/tests/telephony/src/android/telephony/cts/SmsReceiver.java
rename to tests/tests/telephony/current/src/android/telephony/cts/SmsReceiver.java
diff --git a/tests/tests/telephony/src/android/telephony/cts/SmsUsageMonitorShortCodeTest.java b/tests/tests/telephony/current/src/android/telephony/cts/SmsUsageMonitorShortCodeTest.java
similarity index 98%
rename from tests/tests/telephony/src/android/telephony/cts/SmsUsageMonitorShortCodeTest.java
rename to tests/tests/telephony/current/src/android/telephony/cts/SmsUsageMonitorShortCodeTest.java
index 88475d1..58c33be 100644
--- a/tests/tests/telephony/src/android/telephony/cts/SmsUsageMonitorShortCodeTest.java
+++ b/tests/tests/telephony/current/src/android/telephony/cts/SmsUsageMonitorShortCodeTest.java
@@ -502,6 +502,13 @@
SmsUsageMonitor monitor = new SmsUsageMonitor(mContext);
for (ShortCodeTest test : sShortCodeTests) {
+ // It is intended that a short code number in country A may be an emergency number
+ // in country B. It is intended that the destination will be changed because of this
+ // reason. checkDestination() returns CATEGORY_NOT_SHORT_CODE for emergency numbers.
+ if (test.category != CATEGORY_NOT_SHORT_CODE
+ && PhoneNumberUtils.isEmergencyNumber(test.address, test.countryIso)) {
+ continue;
+ }
assertEquals("country: " + test.countryIso + " number: " + test.address,
test.category, monitor.checkDestination(test.address, test.countryIso));
}
diff --git a/tests/tests/telephony/src/android/telephony/cts/StubDialerActivity.java b/tests/tests/telephony/current/src/android/telephony/cts/StubDialerActivity.java
similarity index 100%
rename from tests/tests/telephony/src/android/telephony/cts/StubDialerActivity.java
rename to tests/tests/telephony/current/src/android/telephony/cts/StubDialerActivity.java
diff --git a/tests/tests/telephony/src/android/telephony/cts/StubInCallService.java b/tests/tests/telephony/current/src/android/telephony/cts/StubInCallService.java
similarity index 100%
rename from tests/tests/telephony/src/android/telephony/cts/StubInCallService.java
rename to tests/tests/telephony/current/src/android/telephony/cts/StubInCallService.java
diff --git a/tests/tests/telephony/src/android/telephony/cts/SubscriptionManagerTest.java b/tests/tests/telephony/current/src/android/telephony/cts/SubscriptionManagerTest.java
similarity index 95%
rename from tests/tests/telephony/src/android/telephony/cts/SubscriptionManagerTest.java
rename to tests/tests/telephony/current/src/android/telephony/cts/SubscriptionManagerTest.java
index 1fef678..f358d8c 100644
--- a/tests/tests/telephony/src/android/telephony/cts/SubscriptionManagerTest.java
+++ b/tests/tests/telephony/current/src/android/telephony/cts/SubscriptionManagerTest.java
@@ -43,6 +43,7 @@
import android.telephony.SubscriptionPlan;
import com.android.compatibility.common.util.SystemUtil;
+import com.android.internal.util.ArrayUtils;
import org.junit.AfterClass;
import org.junit.Before;
@@ -144,12 +145,32 @@
@Test
public void testGetActiveSubscriptionInfoCount() throws Exception {
if (!isSupported()) return;
-
assertTrue(mSm.getActiveSubscriptionInfoCount() <=
mSm.getActiveSubscriptionInfoCountMax());
}
@Test
+ public void testIsActiveSubscriptionId() throws Exception {
+ if (!isSupported()) return;
+ assertTrue(mSm.isActiveSubscriptionId(mSubId));
+ }
+
+ @Test
+ public void testGetSubscriptionIds() throws Exception {
+ if (!isSupported()) return;
+ int slotId = SubscriptionManager.getSlotIndex(mSubId);
+ int[] subIds = mSm.getSubscriptionIds(slotId);
+ assertNotNull(subIds);
+ assertTrue(ArrayUtils.contains(subIds, mSubId));
+ }
+
+ @Test
+ public void testIsUsableSubscriptionId() throws Exception {
+ if (!isSupported()) return;
+ assertTrue(SubscriptionManager.isUsableSubIdValue(mSubId));
+ }
+
+ @Test
public void testActiveSubscriptions() throws Exception {
if (!isSupported()) return;
diff --git a/tests/tests/telephony/src/android/telephony/cts/TelephonyManagerTest.java b/tests/tests/telephony/current/src/android/telephony/cts/TelephonyManagerTest.java
similarity index 71%
rename from tests/tests/telephony/src/android/telephony/cts/TelephonyManagerTest.java
rename to tests/tests/telephony/current/src/android/telephony/cts/TelephonyManagerTest.java
index 68765af..b964292 100644
--- a/tests/tests/telephony/src/android/telephony/cts/TelephonyManagerTest.java
+++ b/tests/tests/telephony/current/src/android/telephony/cts/TelephonyManagerTest.java
@@ -34,10 +34,13 @@
import android.os.Looper;
import android.support.test.InstrumentationRegistry;
import android.support.test.runner.AndroidJUnit4;
+import static com.google.common.truth.Truth.assertThat;
import android.telecom.PhoneAccount;
import android.telecom.PhoneAccountHandle;
import android.telecom.TelecomManager;
+import android.telephony.AccessNetworkConstants;
import android.telephony.CellLocation;
+import android.telephony.NetworkRegistrationState;
import android.telephony.PhoneStateListener;
import android.telephony.ServiceState;
import android.telephony.SubscriptionInfo;
@@ -55,6 +58,7 @@
import org.junit.Test;
import org.junit.runner.RunWith;
+import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.util.regex.Pattern;
@@ -67,20 +71,53 @@
@RunWith(AndroidJUnit4.class)
public class TelephonyManagerTest {
private TelephonyManager mTelephonyManager;
+ private SubscriptionManager mSubscriptionManager;
private PackageManager mPackageManager;
private boolean mOnCellLocationChangedCalled = false;
+ private boolean mServiceStateChangedCalled = false;
+ private boolean mRadioRebootTriggered = false;
+ private boolean mHasRadioPowerOff = false;
private ServiceState mServiceState;
private final Object mLock = new Object();
private static final int TOLERANCE = 1000;
private PhoneStateListener mListener;
private static ConnectivityManager mCm;
private static final String TAG = "TelephonyManagerTest";
+ private static final List<Integer> ROAMING_TYPES = Arrays.asList(
+ ServiceState.ROAMING_TYPE_DOMESTIC,
+ ServiceState.ROAMING_TYPE_INTERNATIONAL,
+ ServiceState.ROAMING_TYPE_NOT_ROAMING,
+ ServiceState.ROAMING_TYPE_UNKNOWN);
+ private static final List<Integer> NETWORK_TYPES = Arrays.asList(
+ TelephonyManager.NETWORK_TYPE_UNKNOWN,
+ TelephonyManager.NETWORK_TYPE_GPRS,
+ TelephonyManager.NETWORK_TYPE_EDGE,
+ TelephonyManager.NETWORK_TYPE_UMTS,
+ TelephonyManager.NETWORK_TYPE_CDMA,
+ TelephonyManager.NETWORK_TYPE_EVDO_0,
+ TelephonyManager.NETWORK_TYPE_EVDO_A,
+ TelephonyManager.NETWORK_TYPE_1xRTT,
+ TelephonyManager.NETWORK_TYPE_HSDPA,
+ TelephonyManager.NETWORK_TYPE_HSUPA,
+ TelephonyManager.NETWORK_TYPE_HSPA,
+ TelephonyManager.NETWORK_TYPE_IDEN,
+ TelephonyManager.NETWORK_TYPE_EVDO_B,
+ TelephonyManager.NETWORK_TYPE_LTE,
+ TelephonyManager.NETWORK_TYPE_EHRPD,
+ TelephonyManager.NETWORK_TYPE_HSPAP,
+ TelephonyManager.NETWORK_TYPE_GSM,
+ TelephonyManager.NETWORK_TYPE_TD_SCDMA,
+ TelephonyManager.NETWORK_TYPE_IWLAN,
+ TelephonyManager.NETWORK_TYPE_LTE_CA,
+ TelephonyManager.NETWORK_TYPE_NR);
@Before
public void setUp() throws Exception {
mTelephonyManager =
(TelephonyManager) getContext().getSystemService(Context.TELEPHONY_SERVICE);
mCm = (ConnectivityManager) getContext().getSystemService(Context.CONNECTIVITY_SERVICE);
+ mSubscriptionManager = (SubscriptionManager) getContext()
+ .getSystemService(Context.TELEPHONY_SUBSCRIPTION_SERVICE);
mPackageManager = getContext().getPackageManager();
}
@@ -524,6 +561,22 @@
assertEquals(mServiceState, mTelephonyManager.getServiceState());
}
+ @Test
+ public void testGetSimLocale() throws InterruptedException {
+ if (mPackageManager.hasSystemFeature(PackageManager.FEATURE_TELEPHONY)) {
+ Log.d(TAG,"skipping test that requires Telephony");
+ return;
+ }
+ if (SubscriptionManager.getDefaultSubscriptionId()
+ == SubscriptionManager.INVALID_SUBSCRIPTION_ID) {
+ fail("Expected SIM inserted");
+ }
+ String locale = ShellIdentityUtils.invokeMethodWithShellPermissions(mTelephonyManager,
+ (tm) -> tm.getSimLocale());
+ Log.d(TAG, "testGetSimLocale: " + locale);
+ assertNotNull(locale);
+ }
+
/**
* Tests that the device properly reports either a valid IMEI or null.
*/
@@ -567,6 +620,227 @@
}
/**
+ * Verifies that {@link TelephonyManager#getRadioPowerState()} does not throw any exception
+ * and returns radio on.
+ */
+ @Test
+ public void testGetRadioPowerState() {
+ if (!mPackageManager.hasSystemFeature(PackageManager.FEATURE_TELEPHONY)) {
+ return;
+ }
+
+ // Also verify that no exception is thrown.
+ assertThat(mTelephonyManager.getRadioPowerState()).isEqualTo(
+ TelephonyManager.RADIO_POWER_ON);
+ }
+
+ /**
+ * Verifies that {@link TelephonyManager#setCarrierDataEnabled(boolean)} does not throw any
+ * exception. TODO enhance later if we have an API to get data enabled state.
+ */
+ @Test
+ public void testSetCarrierDataEnabled() {
+ if (!mPackageManager.hasSystemFeature(PackageManager.FEATURE_TELEPHONY)) {
+ return;
+ }
+ // Also verify that no exception is thrown.
+ ShellIdentityUtils.invokeMethodWithShellPermissionsNoReturn(mTelephonyManager,
+ (tm) -> tm.setCarrierDataEnabled(false));
+ ShellIdentityUtils.invokeMethodWithShellPermissionsNoReturn(mTelephonyManager,
+ (tm) -> tm.setCarrierDataEnabled(true));
+ }
+
+ /**
+ * Verifies that {@link TelephonyManager#rebootRadio()} does not throw any exception
+ * and final radio state is radio power on.
+ */
+ @Test
+ public void testRebootRadio() throws Throwable {
+ if (!mPackageManager.hasSystemFeature(PackageManager.FEATURE_TELEPHONY)) {
+ return;
+ }
+ assertEquals(mTelephonyManager.getServiceState().getState(), ServiceState.STATE_IN_SERVICE);
+
+ TestThread t = new TestThread(new Runnable() {
+ public void run() {
+ Looper.prepare();
+
+ mListener = new PhoneStateListener() {
+ @Override
+ public void onRadioPowerStateChanged(
+ @TelephonyManager.RadioPowerState int state) {
+ synchronized (mLock) {
+ if (state == TelephonyManager.RADIO_POWER_ON && mHasRadioPowerOff) {
+ mRadioRebootTriggered = true;
+ mLock.notify();
+ } else if (state == TelephonyManager.RADIO_POWER_OFF) {
+ // reboot must go to power off
+ mHasRadioPowerOff = true;
+ }
+ }
+ }
+ };
+ ShellIdentityUtils.invokeMethodWithShellPermissionsNoReturn(mTelephonyManager,
+ (tm) -> tm.listen(mListener,
+ PhoneStateListener.LISTEN_RADIO_POWER_STATE_CHANGED));
+ Looper.loop();
+ }
+ });
+
+ assertThat(mTelephonyManager.getRadioPowerState()).isEqualTo(
+ TelephonyManager.RADIO_POWER_ON);
+ assertThat(mRadioRebootTriggered).isFalse();
+ assertThat(mHasRadioPowerOff).isFalse();
+ ShellIdentityUtils.invokeMethodWithShellPermissions(mTelephonyManager,
+ (tm) -> tm.rebootRadio());
+ t.start();
+ synchronized (mLock) {
+ // reboot takes longer time
+ if (!mRadioRebootTriggered) {
+ mLock.wait(10000);
+ }
+ }
+ assertThat(mTelephonyManager.getRadioPowerState()).isEqualTo(
+ TelephonyManager.RADIO_POWER_ON);
+ assertThat(mRadioRebootTriggered).isTrue();
+
+ // note, other telephony states might not resumes properly at this point. e.g, service state
+ // might still in the transition from OOS to In service. Thus we need to wait for in
+ // service state before running next tests.
+ t = new TestThread(new Runnable() {
+ public void run() {
+ Looper.prepare();
+
+ mListener = new PhoneStateListener() {
+ @Override
+ public void onServiceStateChanged(ServiceState serviceState) {
+ synchronized (mLock) {
+ if (serviceState.getState() == ServiceState.STATE_IN_SERVICE) {
+ mServiceStateChangedCalled = true;
+ mLock.notify();
+ }
+ }
+ }
+ };
+ ShellIdentityUtils.invokeMethodWithShellPermissionsNoReturn(mTelephonyManager,
+ (tm) -> tm.listen(mListener, PhoneStateListener.LISTEN_SERVICE_STATE));
+ Looper.loop();
+ }
+ });
+
+ synchronized (mLock) {
+ t.start();
+ if (!mServiceStateChangedCalled) {
+ mLock.wait(10000);
+ }
+ }
+ assertThat(mTelephonyManager.getServiceState().getState()).isEqualTo(
+ ServiceState.STATE_IN_SERVICE);
+ }
+
+ /**
+ * Verifies that {@link TelephonyManager#getAidForAppType(int)} does not throw any exception
+ * for all supported subscription app type.
+ */
+ @Test
+ public void testGetAidForAppType() {
+ if (!mPackageManager.hasSystemFeature(PackageManager.FEATURE_TELEPHONY)) {
+ return;
+ }
+ ShellIdentityUtils.invokeMethodWithShellPermissions(mTelephonyManager,
+ (tm) -> tm.getAidForAppType(TelephonyManager.APPTYPE_SIM));
+ ShellIdentityUtils.invokeMethodWithShellPermissions(mTelephonyManager,
+ (tm) -> tm.getAidForAppType(TelephonyManager.APPTYPE_CSIM));
+ ShellIdentityUtils.invokeMethodWithShellPermissions(mTelephonyManager,
+ (tm) -> tm.getAidForAppType(TelephonyManager.APPTYPE_RUIM));
+ ShellIdentityUtils.invokeMethodWithShellPermissions(mTelephonyManager,
+ (tm) -> tm.getAidForAppType(TelephonyManager.APPTYPE_ISIM));
+ ShellIdentityUtils.invokeMethodWithShellPermissions(mTelephonyManager,
+ (tm) -> tm.getAidForAppType(TelephonyManager.APPTYPE_USIM));
+ }
+
+ /**
+ * Verifies that {@link TelephonyManager#getIsimDomain()} does not throw any exception
+ */
+ @Test
+ public void testGetIsimDomain() {
+ if (!mPackageManager.hasSystemFeature(PackageManager.FEATURE_TELEPHONY)) {
+ return;
+ }
+ ShellIdentityUtils.invokeMethodWithShellPermissions(mTelephonyManager,
+ (tm) -> tm.getIsimDomain());
+ }
+
+ /**
+ * Basic test to ensure {@link NetworkRegistrationState#isRoaming()} does not throw any
+ * exception.
+ */
+ @Test
+ public void testNetworkRegistrationStateIsRoaming() {
+ if (!mPackageManager.hasSystemFeature(PackageManager.FEATURE_TELEPHONY)) {
+ return;
+ }
+ // get NetworkRegistration object
+ NetworkRegistrationState nwReg = mTelephonyManager.getServiceState()
+ .getNetworkRegistrationState(NetworkRegistrationState.DOMAIN_CS,
+ AccessNetworkConstants.TransportType.WWAN);
+ assertThat(nwReg).isNotNull();
+ nwReg.isRoaming();
+ }
+
+ /**
+ * Basic test to ensure {@link NetworkRegistrationState#getRoamingType()} ()} does not throw any
+ * exception and returns valid result
+ * @see ServiceState.RoamingType
+ */
+ @Test
+ public void testNetworkRegistrationStateGetRoamingType() {
+ if (!mPackageManager.hasSystemFeature(PackageManager.FEATURE_TELEPHONY)) {
+ return;
+ }
+ // get NetworkRegistration object for voice
+ NetworkRegistrationState nwReg = mTelephonyManager.getServiceState()
+ .getNetworkRegistrationState(NetworkRegistrationState.DOMAIN_CS,
+ AccessNetworkConstants.TransportType.WWAN);
+ assertNotNull(nwReg);
+ assertThat(nwReg.getRoamingType()).isIn(ROAMING_TYPES);
+
+ // getNetworkRegistration object for data
+ // get NetworkRegistration object for voice
+ nwReg = mTelephonyManager.getServiceState()
+ .getNetworkRegistrationState(NetworkRegistrationState.DOMAIN_PS,
+ AccessNetworkConstants.TransportType.WWAN);
+ assertThat(nwReg).isNotNull();
+ assertThat(nwReg.getRoamingType()).isIn(ROAMING_TYPES);
+ }
+
+ /**
+ * Basic test to ensure {@link NetworkRegistrationState#getAccessNetworkTechnology()} not
+ * throw any exception and returns valid result
+ * @see TelephonyManager.NetworkType
+ */
+ @Test
+ public void testNetworkRegistationStateGetAccessNetworkTechnology() {
+ if (!mPackageManager.hasSystemFeature(PackageManager.FEATURE_TELEPHONY)) {
+ return;
+ }
+ // get NetworkRegistration object for voice
+ NetworkRegistrationState nwReg = mTelephonyManager.getServiceState()
+ .getNetworkRegistrationState(NetworkRegistrationState.DOMAIN_CS,
+ AccessNetworkConstants.TransportType.WWAN);
+ assertThat(nwReg).isNotNull();
+ assertThat(nwReg.getAccessNetworkTechnology()).isIn(NETWORK_TYPES);
+
+ // get NetworkRegistation object for data
+ nwReg = mTelephonyManager.getServiceState()
+ .getNetworkRegistrationState(NetworkRegistrationState.DOMAIN_PS,
+ AccessNetworkConstants.TransportType.WWAN);
+ assertThat(nwReg).isNotNull();
+ assertThat(nwReg.getAccessNetworkTechnology()).isIn(NETWORK_TYPES);
+ }
+
+
+ /**
* Tests that the device properly reports either a valid MEID or null.
*/
@Test
@@ -744,4 +1018,12 @@
boolean isEmergencyNumber = mTelephonyManager.isCurrentPotentialEmergencyNumber("911");
// TODO enhance it later
}
+
+ public static void waitForMs(long ms) {
+ try {
+ Thread.sleep(ms);
+ } catch (InterruptedException e) {
+ Log.d(TAG, "InterruptedException while waiting: " + e);
+ }
+ }
}
diff --git a/tests/tests/telephony/src/android/telephony/cts/TelephonyUtils.java b/tests/tests/telephony/current/src/android/telephony/cts/TelephonyUtils.java
similarity index 100%
rename from tests/tests/telephony/src/android/telephony/cts/TelephonyUtils.java
rename to tests/tests/telephony/current/src/android/telephony/cts/TelephonyUtils.java
diff --git a/tests/tests/telephony/src/android/telephony/cts/VisualVoicemailServiceTest.java b/tests/tests/telephony/current/src/android/telephony/cts/VisualVoicemailServiceTest.java
similarity index 100%
rename from tests/tests/telephony/src/android/telephony/cts/VisualVoicemailServiceTest.java
rename to tests/tests/telephony/current/src/android/telephony/cts/VisualVoicemailServiceTest.java
diff --git a/tests/tests/telephony/src/android/telephony/embms/cts/DownloadRequestTest.java b/tests/tests/telephony/current/src/android/telephony/embms/cts/DownloadRequestTest.java
similarity index 100%
rename from tests/tests/telephony/src/android/telephony/embms/cts/DownloadRequestTest.java
rename to tests/tests/telephony/current/src/android/telephony/embms/cts/DownloadRequestTest.java
diff --git a/tests/tests/telephony/src/android/telephony/embms/cts/MbmsDownloadCallbackTest.java b/tests/tests/telephony/current/src/android/telephony/embms/cts/MbmsDownloadCallbackTest.java
similarity index 100%
rename from tests/tests/telephony/src/android/telephony/embms/cts/MbmsDownloadCallbackTest.java
rename to tests/tests/telephony/current/src/android/telephony/embms/cts/MbmsDownloadCallbackTest.java
diff --git a/tests/tests/telephony/src/android/telephony/embms/cts/MbmsDownloadFlowTest.java b/tests/tests/telephony/current/src/android/telephony/embms/cts/MbmsDownloadFlowTest.java
similarity index 100%
rename from tests/tests/telephony/src/android/telephony/embms/cts/MbmsDownloadFlowTest.java
rename to tests/tests/telephony/current/src/android/telephony/embms/cts/MbmsDownloadFlowTest.java
diff --git a/tests/tests/telephony/src/android/telephony/embms/cts/MbmsDownloadReceiverTest.java b/tests/tests/telephony/current/src/android/telephony/embms/cts/MbmsDownloadReceiverTest.java
similarity index 100%
rename from tests/tests/telephony/src/android/telephony/embms/cts/MbmsDownloadReceiverTest.java
rename to tests/tests/telephony/current/src/android/telephony/embms/cts/MbmsDownloadReceiverTest.java
diff --git a/tests/tests/telephony/src/android/telephony/embms/cts/MbmsDownloadSessionTest.java b/tests/tests/telephony/current/src/android/telephony/embms/cts/MbmsDownloadSessionTest.java
similarity index 100%
rename from tests/tests/telephony/src/android/telephony/embms/cts/MbmsDownloadSessionTest.java
rename to tests/tests/telephony/current/src/android/telephony/embms/cts/MbmsDownloadSessionTest.java
diff --git a/tests/tests/telephony/src/android/telephony/embms/cts/MbmsDownloadTestBase.java b/tests/tests/telephony/current/src/android/telephony/embms/cts/MbmsDownloadTestBase.java
similarity index 100%
rename from tests/tests/telephony/src/android/telephony/embms/cts/MbmsDownloadTestBase.java
rename to tests/tests/telephony/current/src/android/telephony/embms/cts/MbmsDownloadTestBase.java
diff --git a/tests/tests/telephony/src/android/telephony/embms/cts/MbmsGroupCallSessionTest.java b/tests/tests/telephony/current/src/android/telephony/embms/cts/MbmsGroupCallSessionTest.java
similarity index 100%
rename from tests/tests/telephony/src/android/telephony/embms/cts/MbmsGroupCallSessionTest.java
rename to tests/tests/telephony/current/src/android/telephony/embms/cts/MbmsGroupCallSessionTest.java
diff --git a/tests/tests/telephony/src/android/telephony/embms/cts/MbmsGroupCallTest.java b/tests/tests/telephony/current/src/android/telephony/embms/cts/MbmsGroupCallTest.java
similarity index 100%
rename from tests/tests/telephony/src/android/telephony/embms/cts/MbmsGroupCallTest.java
rename to tests/tests/telephony/current/src/android/telephony/embms/cts/MbmsGroupCallTest.java
diff --git a/tests/tests/telephony/src/android/telephony/embms/cts/MbmsGroupCallTestBase.java b/tests/tests/telephony/current/src/android/telephony/embms/cts/MbmsGroupCallTestBase.java
similarity index 100%
rename from tests/tests/telephony/src/android/telephony/embms/cts/MbmsGroupCallTestBase.java
rename to tests/tests/telephony/current/src/android/telephony/embms/cts/MbmsGroupCallTestBase.java
diff --git a/tests/tests/telephony/src/android/telephony/embms/cts/MbmsStreamingServiceTest.java b/tests/tests/telephony/current/src/android/telephony/embms/cts/MbmsStreamingServiceTest.java
similarity index 100%
rename from tests/tests/telephony/src/android/telephony/embms/cts/MbmsStreamingServiceTest.java
rename to tests/tests/telephony/current/src/android/telephony/embms/cts/MbmsStreamingServiceTest.java
diff --git a/tests/tests/telephony/src/android/telephony/embms/cts/MbmsStreamingSessionTest.java b/tests/tests/telephony/current/src/android/telephony/embms/cts/MbmsStreamingSessionTest.java
similarity index 100%
rename from tests/tests/telephony/src/android/telephony/embms/cts/MbmsStreamingSessionTest.java
rename to tests/tests/telephony/current/src/android/telephony/embms/cts/MbmsStreamingSessionTest.java
diff --git a/tests/tests/telephony/src/android/telephony/embms/cts/MbmsStreamingTestBase.java b/tests/tests/telephony/current/src/android/telephony/embms/cts/MbmsStreamingTestBase.java
similarity index 100%
rename from tests/tests/telephony/src/android/telephony/embms/cts/MbmsStreamingTestBase.java
rename to tests/tests/telephony/current/src/android/telephony/embms/cts/MbmsStreamingTestBase.java
diff --git a/tests/tests/telephony/src/android/telephony/embms/cts/ServiceInfoTest.java b/tests/tests/telephony/current/src/android/telephony/embms/cts/ServiceInfoTest.java
similarity index 100%
rename from tests/tests/telephony/src/android/telephony/embms/cts/ServiceInfoTest.java
rename to tests/tests/telephony/current/src/android/telephony/embms/cts/ServiceInfoTest.java
diff --git a/tests/tests/telephony/src/android/telephony/embms/cts/SomeArgs.java b/tests/tests/telephony/current/src/android/telephony/embms/cts/SomeArgs.java
similarity index 100%
rename from tests/tests/telephony/src/android/telephony/embms/cts/SomeArgs.java
rename to tests/tests/telephony/current/src/android/telephony/embms/cts/SomeArgs.java
diff --git a/tests/tests/telephony/src/android/telephony/euicc/cts/DownloadableSubscriptionTest.java b/tests/tests/telephony/current/src/android/telephony/euicc/cts/DownloadableSubscriptionTest.java
similarity index 100%
rename from tests/tests/telephony/src/android/telephony/euicc/cts/DownloadableSubscriptionTest.java
rename to tests/tests/telephony/current/src/android/telephony/euicc/cts/DownloadableSubscriptionTest.java
diff --git a/tests/tests/telephony/src/android/telephony/euicc/cts/EuiccInfoTest.java b/tests/tests/telephony/current/src/android/telephony/euicc/cts/EuiccInfoTest.java
similarity index 100%
rename from tests/tests/telephony/src/android/telephony/euicc/cts/EuiccInfoTest.java
rename to tests/tests/telephony/current/src/android/telephony/euicc/cts/EuiccInfoTest.java
diff --git a/tests/tests/telephony/src/android/telephony/euicc/cts/EuiccManagerTest.java b/tests/tests/telephony/current/src/android/telephony/euicc/cts/EuiccManagerTest.java
similarity index 100%
rename from tests/tests/telephony/src/android/telephony/euicc/cts/EuiccManagerTest.java
rename to tests/tests/telephony/current/src/android/telephony/euicc/cts/EuiccManagerTest.java
diff --git a/tests/tests/telephony/src/android/telephony/euicc/cts/EuiccResolutionActivity.java b/tests/tests/telephony/current/src/android/telephony/euicc/cts/EuiccResolutionActivity.java
similarity index 100%
rename from tests/tests/telephony/src/android/telephony/euicc/cts/EuiccResolutionActivity.java
rename to tests/tests/telephony/current/src/android/telephony/euicc/cts/EuiccResolutionActivity.java
diff --git a/tests/tests/telephony/src/android/telephony/euicc/cts/EuiccTestResolutionActivity.java b/tests/tests/telephony/current/src/android/telephony/euicc/cts/EuiccTestResolutionActivity.java
similarity index 100%
rename from tests/tests/telephony/src/android/telephony/euicc/cts/EuiccTestResolutionActivity.java
rename to tests/tests/telephony/current/src/android/telephony/euicc/cts/EuiccTestResolutionActivity.java
diff --git a/tests/tests/telephony/src/android/telephony/gsm/cts/GsmCellLocationTest.java b/tests/tests/telephony/current/src/android/telephony/gsm/cts/GsmCellLocationTest.java
similarity index 100%
rename from tests/tests/telephony/src/android/telephony/gsm/cts/GsmCellLocationTest.java
rename to tests/tests/telephony/current/src/android/telephony/gsm/cts/GsmCellLocationTest.java
diff --git a/tests/tests/telephony/src/android/telephony/gsm/cts/SmsManagerTest.java b/tests/tests/telephony/current/src/android/telephony/gsm/cts/SmsManagerTest.java
similarity index 100%
rename from tests/tests/telephony/src/android/telephony/gsm/cts/SmsManagerTest.java
rename to tests/tests/telephony/current/src/android/telephony/gsm/cts/SmsManagerTest.java
diff --git a/tests/tests/telephony/src/android/telephony/gsm/cts/SmsMessage_MessageClassTest.java b/tests/tests/telephony/current/src/android/telephony/gsm/cts/SmsMessage_MessageClassTest.java
similarity index 100%
rename from tests/tests/telephony/src/android/telephony/gsm/cts/SmsMessage_MessageClassTest.java
rename to tests/tests/telephony/current/src/android/telephony/gsm/cts/SmsMessage_MessageClassTest.java
diff --git a/tests/tests/telephony/src/android/telephony/gsm/cts/SmsMessage_SubmitPduTest.java b/tests/tests/telephony/current/src/android/telephony/gsm/cts/SmsMessage_SubmitPduTest.java
similarity index 100%
rename from tests/tests/telephony/src/android/telephony/gsm/cts/SmsMessage_SubmitPduTest.java
rename to tests/tests/telephony/current/src/android/telephony/gsm/cts/SmsMessage_SubmitPduTest.java
diff --git a/tests/tests/text/Android.mk b/tests/tests/telephony/sdk28/Android.mk
similarity index 66%
copy from tests/tests/text/Android.mk
copy to tests/tests/telephony/sdk28/Android.mk
index ffa5f9eb..36e30fd 100644
--- a/tests/tests/text/Android.mk
+++ b/tests/tests/telephony/sdk28/Android.mk
@@ -1,4 +1,4 @@
-# Copyright (C) 2008 The Android Open Source Project
+# 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.
@@ -12,6 +12,7 @@
# See the License for the specific language governing permissions and
# limitations under the License.
+
LOCAL_PATH:= $(call my-dir)
include $(CLEAR_VARS)
@@ -21,24 +22,19 @@
# and when built explicitly put it in the data partition
LOCAL_MODULE_PATH := $(TARGET_OUT_DATA_APPS)
-LOCAL_JAVA_LIBRARIES := android.test.runner.stubs android.test.base.stubs
-
-LOCAL_STATIC_JAVA_LIBRARIES += \
- compatibility-device-util \
- ctsdeviceutillegacy \
+LOCAL_STATIC_JAVA_LIBRARIES := \
ctstestrunner \
- android-support-test \
- mockito-target-minus-junit4 \
- ub-uiautomator
+ compatibility-device-util
LOCAL_SRC_FILES := $(call all-java-files-under, src)
-LOCAL_PACKAGE_NAME := CtsTextTestCases
+LOCAL_PACKAGE_NAME := CtsTelephonySdk28TestCases
+LOCAL_SDK_VERSION := 28
# Tag this module as a cts test artifact
-LOCAL_COMPATIBILITY_SUITE := cts vts general-tests cts_instant
+LOCAL_COMPATIBILITY_SUITE := cts vts general-tests
-# Enforce public / test api only
-LOCAL_SDK_VERSION := test_current
+LOCAL_JAVA_LIBRARIES += android.test.runner.stubs
+LOCAL_JAVA_LIBRARIES += android.test.base.stubs
include $(BUILD_CTS_PACKAGE)
diff --git a/tests/tests/telephony/sdk28/AndroidManifest.xml b/tests/tests/telephony/sdk28/AndroidManifest.xml
new file mode 100644
index 0000000..2f37696
--- /dev/null
+++ b/tests/tests/telephony/sdk28/AndroidManifest.xml
@@ -0,0 +1,37 @@
+<?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.
+-->
+
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+ package="android.telephony.sdk28.cts">
+ <uses-sdk android:targetSdkVersion="28"
+ android:minSdkVersion="28"
+ android:maxSdkVersion="28" />
+
+ <uses-permission android:name="android.permission.READ_PHONE_STATE" />
+ <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
+
+ <application>
+ <uses-library android:name="android.test.runner" />
+ </application>
+
+ <instrumentation android:name="android.support.test.runner.AndroidJUnitRunner"
+ android:targetPackage="android.telephony.sdk28.cts">
+ <meta-data android:name="listener"
+ android:value="com.android.cts.runner.CtsTestRunListener" />
+ </instrumentation>
+
+</manifest>
+
diff --git a/tests/libcore/coreplatformapi/AndroidTest.xml b/tests/tests/telephony/sdk28/AndroidTest.xml
similarity index 60%
copy from tests/libcore/coreplatformapi/AndroidTest.xml
copy to tests/tests/telephony/sdk28/AndroidTest.xml
index 907fb2d..ab37882 100644
--- a/tests/libcore/coreplatformapi/AndroidTest.xml
+++ b/tests/tests/telephony/sdk28/AndroidTest.xml
@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2018 The Android Open Source Project
+<!-- 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.
@@ -13,16 +13,21 @@
See the License for the specific language governing permissions and
limitations under the License.
-->
-<configuration description="Config for CTS Libcore core platform API test cases">
+<configuration description="Config for CTS Telephony test cases">
<option name="test-suite-tag" value="cts" />
- <option name="config-descriptor:metadata" key="component" value="libcore" />
+ <option name="config-descriptor:metadata" key="component" value="telecom" />
+ <option name="config-descriptor:metadata" key="token" value="SIM_CARD" />
+ <option name="not-shardable" value="true" />
+ <target_preparer class="android.telephony.cts.preconditions.TelephonyPreparer">
+ <option name="apk" value="CtsTelephonyPreparerApp.apk" />
+ <option name="package" value="android.telephony.cts.preconditions.app" />
+ </target_preparer>
<target_preparer class="com.android.tradefed.targetprep.suite.SuiteApkInstaller">
<option name="cleanup-apks" value="true" />
- <option name="test-file-name" value="CtsLibcoreCorePlatformApiTestCases.apk" />
+ <option name="test-file-name" value="CtsTelephonySdk28TestCases.apk" />
</target_preparer>
<test class="com.android.tradefed.testtype.AndroidJUnitTest" >
- <option name="package" value="android.libcore.cts.coreplatformapi" />
- <option name="runtime-hint" value="1m"/>
+ <option name="package" value="android.telephony.sdk28.cts" />
<option name="hidden-api-checks" value="false"/>
</test>
</configuration>
diff --git a/tests/tests/telephony/sdk28/src/android/telephony/sdk28/cts/CellInfoTest.java b/tests/tests/telephony/sdk28/src/android/telephony/sdk28/cts/CellInfoTest.java
new file mode 100644
index 0000000..aebeeda
--- /dev/null
+++ b/tests/tests/telephony/sdk28/src/android/telephony/sdk28/cts/CellInfoTest.java
@@ -0,0 +1,87 @@
+/*
+ * Copyright (C) 2019 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.telephony.sdk28.cts;
+
+import android.content.Context;
+import android.content.pm.PackageManager;
+import android.net.ConnectivityManager;
+import android.os.Parcel;
+import android.telephony.CellInfo;
+import android.telephony.ServiceState;
+import android.telephony.TelephonyManager;
+import android.test.AndroidTestCase;
+import android.util.Log;
+
+
+import java.util.List;
+import java.util.Objects;
+
+public class CellInfoTest extends AndroidTestCase {
+ private static final String TAG = "CellInfoTest";
+
+ private static final int MAX_WAIT_SECONDS = 15;
+ private static final int POLL_INTERVAL_MILLIS = 1000;
+
+ private TelephonyManager mTm;
+ private PackageManager mPm;
+
+ private boolean isCamped() {
+ ServiceState ss = mTm.getServiceState();
+ if (ss == null) return false;
+ return (ss.getState() == ServiceState.STATE_IN_SERVICE
+ || ss.getState() == ServiceState.STATE_EMERGENCY_ONLY);
+ }
+
+ @Override
+ protected void setUp() throws Exception {
+ super.setUp();
+ mTm = (TelephonyManager) getContext().getSystemService(Context.TELEPHONY_SERVICE);
+ mPm = getContext().getPackageManager();
+ }
+
+ public void testCellInfoSdk28() {
+ if (!mPm.hasSystemFeature(PackageManager.FEATURE_TELEPHONY)) {
+ Log.d(TAG, "Skipping test that requires FEATURE_TELEPHONY");
+ return;
+ }
+
+ if (!isCamped()) fail("Device is not camped to a cell");
+
+ List<CellInfo> cellInfo = mTm.getAllCellInfo();
+
+ // getAllCellInfo should never return null, and there should be at least one entry.
+ assertNotNull("TelephonyManager.getAllCellInfo() returned NULL CellInfo", cellInfo);
+ assertFalse("TelephonyManager.getAllCellInfo() returned an empty list", cellInfo.isEmpty());
+
+ final long initialTime = cellInfo.get(0).getTimeStamp();
+
+ for(int i = 0; i < MAX_WAIT_SECONDS; i++) {
+ try {
+ Thread.sleep(POLL_INTERVAL_MILLIS); // 1 second
+ } catch (InterruptedException ie) {
+ fail("Thread was interrupted");
+ }
+ List<CellInfo> newCellInfo = mTm.getAllCellInfo();
+ assertNotNull("TelephonyManager.getAllCellInfo() returned NULL CellInfo", newCellInfo);
+ assertFalse("TelephonyManager.getAllCellInfo() returned an empty list",
+ newCellInfo.isEmpty());
+ // Test that new CellInfo has been retrieved from the modem
+ if (newCellInfo.get(0).getTimeStamp() != initialTime) return;
+ }
+ fail("CellInfo failed to update after " + MAX_WAIT_SECONDS + " seconds.");
+ }
+}
diff --git a/tests/tests/telephony/src/android/telephony/cts/PhoneStateListenerTest.java b/tests/tests/telephony/src/android/telephony/cts/PhoneStateListenerTest.java
deleted file mode 100644
index 7745497..0000000
--- a/tests/tests/telephony/src/android/telephony/cts/PhoneStateListenerTest.java
+++ /dev/null
@@ -1,520 +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.telephony.cts;
-
-import android.content.Context;
-import android.os.Looper;
-import android.telephony.CellInfo;
-import android.telephony.CellLocation;
-import android.telephony.PhoneStateListener;
-import android.telephony.ServiceState;
-import android.telephony.SignalStrength;
-import android.telephony.TelephonyManager;
-import android.net.ConnectivityManager;
-import android.test.AndroidTestCase;
-import android.util.Log;
-
-import com.android.compatibility.common.util.TestThread;
-
-import java.util.List;
-
-public class PhoneStateListenerTest extends AndroidTestCase{
-
- public static final long WAIT_TIME = 1000;
-
- private boolean mOnCallForwardingIndicatorChangedCalled;
- private boolean mOnCallStateChangedCalled;
- private boolean mOnCellLocationChangedCalled;
- private boolean mOnUserMobileDataStateChanged;
- private boolean mOnDataActivityCalled;
- private boolean mOnDataConnectionStateChangedCalled;
- private boolean mOnDataConnectionStateChangedWithNetworkTypeCalled;
- private boolean mOnMessageWaitingIndicatorChangedCalled;
- private boolean mOnCellInfoChangedCalled;
- private boolean mOnServiceStateChangedCalled;
- private boolean mOnSignalStrengthChangedCalled;
- private SignalStrength mSignalStrength;
- private TelephonyManager mTelephonyManager;
- private PhoneStateListener mListener;
- private final Object mLock = new Object();
- private static final String TAG = "android.telephony.cts.PhoneStateListenerTest";
- private static ConnectivityManager mCm;
-
- @Override
- protected void setUp() throws Exception {
- super.setUp();
- mTelephonyManager =
- (TelephonyManager)getContext().getSystemService(Context.TELEPHONY_SERVICE);
- mCm = (ConnectivityManager)getContext().getSystemService(Context.CONNECTIVITY_SERVICE);
- }
-
- @Override
- protected void tearDown() throws Exception {
- super.tearDown();
- if (mListener != null) {
- // unregister the listener
- mTelephonyManager.listen(mListener, PhoneStateListener.LISTEN_NONE);
- }
- }
-
- public void testPhoneStateListener() {
- if (mCm.getNetworkInfo(ConnectivityManager.TYPE_MOBILE) == null) {
- Log.d(TAG, "Skipping test that requires ConnectivityManager.TYPE_MOBILE");
- return;
- }
-
- Looper.prepare();
- new PhoneStateListener();
- }
-
- /*
- * The tests below rely on the framework to immediately call the installed listener upon
- * registration. There is no simple way to emulate state changes for testing the listeners.
- */
-
- public void testOnServiceStateChanged() throws Throwable {
- if (mCm.getNetworkInfo(ConnectivityManager.TYPE_MOBILE) == null) {
- Log.d(TAG, "Skipping test that requires ConnectivityManager.TYPE_MOBILE");
- return;
- }
-
- TestThread t = new TestThread(new Runnable() {
- public void run() {
- Looper.prepare();
-
- mListener = new PhoneStateListener() {
- @Override
- public void onServiceStateChanged(ServiceState serviceState) {
- synchronized(mLock) {
- mOnServiceStateChangedCalled = true;
- mLock.notify();
- }
- }
- };
- mTelephonyManager.listen(mListener, PhoneStateListener.LISTEN_SERVICE_STATE);
-
- Looper.loop();
- }
- });
-
- assertFalse(mOnServiceStateChangedCalled);
- t.start();
-
- synchronized (mLock) {
- while(!mOnServiceStateChangedCalled){
- mLock.wait();
- }
- }
- t.checkException();
- assertTrue(mOnServiceStateChangedCalled);
- }
-
- public void testOnSignalStrengthChanged() throws Throwable {
- if (mCm.getNetworkInfo(ConnectivityManager.TYPE_MOBILE) == null) {
- Log.d(TAG, "Skipping test that requires ConnectivityManager.TYPE_MOBILE");
- return;
- }
-
- TestThread t = new TestThread(new Runnable() {
- public void run() {
- Looper.prepare();
-
- mListener = new PhoneStateListener() {
- @Override
- public void onSignalStrengthChanged(int asu) {
- synchronized(mLock) {
- mOnSignalStrengthChangedCalled = true;
- mLock.notify();
- }
- }
- };
- mTelephonyManager.listen(mListener, PhoneStateListener.LISTEN_SIGNAL_STRENGTH);
-
- Looper.loop();
- }
- });
-
- assertFalse(mOnSignalStrengthChangedCalled);
- t.start();
-
- synchronized (mLock) {
- while(!mOnSignalStrengthChangedCalled){
- mLock.wait();
- }
- }
- t.checkException();
- assertTrue(mOnSignalStrengthChangedCalled);
- }
-
- public void testOnSignalStrengthsChanged() throws Throwable {
- if (mCm.getNetworkInfo(ConnectivityManager.TYPE_MOBILE) == null) {
- Log.d(TAG, "Skipping test that requires ConnectivityManager.TYPE_MOBILE");
- return;
- }
-
- TestThread t = new TestThread(new Runnable() {
- public void run() {
- Looper.prepare();
-
- mListener = new PhoneStateListener() {
- @Override
- public void onSignalStrengthsChanged(SignalStrength signalStrength) {
- synchronized(mLock) {
- mSignalStrength = signalStrength;
- mLock.notify();
- }
- }
- };
- mTelephonyManager.listen(mListener, PhoneStateListener.LISTEN_SIGNAL_STRENGTHS);
-
- Looper.loop();
- }
- });
-
- assertTrue(mSignalStrength == null);
- t.start();
-
- synchronized (mLock) {
- while(mSignalStrength == null) {
- mLock.wait();
- }
- }
- t.checkException();
- assertTrue(mSignalStrength != null);
-
- // Call SignalStrength methods to make sure they do not throw any exceptions
- mSignalStrength.getCdmaDbm();
- mSignalStrength.getCdmaEcio();
- mSignalStrength.getEvdoDbm();
- mSignalStrength.getEvdoEcio();
- mSignalStrength.getEvdoSnr();
- mSignalStrength.getGsmBitErrorRate();
- mSignalStrength.getGsmSignalStrength();
- mSignalStrength.isGsm();
- mSignalStrength.getLevel();
- }
-
- public void testOnMessageWaitingIndicatorChanged() throws Throwable {
- if (mCm.getNetworkInfo(ConnectivityManager.TYPE_MOBILE) == null) {
- Log.d(TAG, "Skipping test that requires ConnectivityManager.TYPE_MOBILE");
- return;
- }
-
- TestThread t = new TestThread(new Runnable() {
- public void run() {
- Looper.prepare();
-
- mListener = new PhoneStateListener() {
- @Override
- public void onMessageWaitingIndicatorChanged(boolean mwi) {
- synchronized(mLock) {
- mOnMessageWaitingIndicatorChangedCalled = true;
- mLock.notify();
- }
- }
- };
- mTelephonyManager.listen(
- mListener, PhoneStateListener.LISTEN_MESSAGE_WAITING_INDICATOR);
-
- Looper.loop();
- }
- });
-
- assertFalse(mOnMessageWaitingIndicatorChangedCalled);
- t.start();
-
- synchronized (mLock) {
- while(!mOnMessageWaitingIndicatorChangedCalled){
- mLock.wait();
- }
- }
- t.checkException();
- assertTrue(mOnMessageWaitingIndicatorChangedCalled);
- }
-
- public void testOnCallForwardingIndicatorChanged() throws Throwable {
- if (mCm.getNetworkInfo(ConnectivityManager.TYPE_MOBILE) == null) {
- Log.d(TAG, "Skipping test that requires ConnectivityManager.TYPE_MOBILE");
- return;
- }
-
- TestThread t = new TestThread(new Runnable() {
- @Override
- public void run() {
- Looper.prepare();
-
- mListener = new PhoneStateListener() {
- @Override
- public void onCallForwardingIndicatorChanged(boolean cfi) {
- synchronized(mLock) {
- mOnCallForwardingIndicatorChangedCalled = true;
- mLock.notify();
- }
- }
- };
- mTelephonyManager.listen(
- mListener, PhoneStateListener.LISTEN_CALL_FORWARDING_INDICATOR);
-
- Looper.loop();
- }
- });
-
- assertFalse(mOnCallForwardingIndicatorChangedCalled);
- t.start();
-
- synchronized (mLock) {
- while(!mOnCallForwardingIndicatorChangedCalled){
- mLock.wait();
- }
- }
- t.checkException();
- assertTrue(mOnCallForwardingIndicatorChangedCalled);
- }
-
- public void testOnCellLocationChanged() throws Throwable {
- if (mCm.getNetworkInfo(ConnectivityManager.TYPE_MOBILE) == null) {
- Log.d(TAG, "Skipping test that requires ConnectivityManager.TYPE_MOBILE");
- return;
- }
-
- TestThread t = new TestThread(new Runnable() {
- public void run() {
- Looper.prepare();
-
- mListener = new PhoneStateListener() {
- @Override
- public void onCellLocationChanged(CellLocation location) {
- synchronized(mLock) {
- mOnCellLocationChangedCalled = true;
- mLock.notify();
- }
- }
- };
- mTelephonyManager.listen(mListener, PhoneStateListener.LISTEN_CELL_LOCATION);
-
- Looper.loop();
- }
- });
-
- assertFalse(mOnCellLocationChangedCalled);
- t.start();
-
- synchronized (mLock) {
- while(!mOnCellLocationChangedCalled){
- mLock.wait();
- }
- }
- t.checkException();
- assertTrue(mOnCellLocationChangedCalled);
- }
-
- public void testOnCallStateChanged() throws Throwable {
- if (mCm.getNetworkInfo(ConnectivityManager.TYPE_MOBILE) == null) {
- Log.d(TAG, "Skipping test that requires ConnectivityManager.TYPE_MOBILE");
- return;
- }
-
- TestThread t = new TestThread(new Runnable() {
- public void run() {
- Looper.prepare();
-
- mListener = new PhoneStateListener() {
- @Override
- public void onCallStateChanged(int state, String incomingNumber) {
- synchronized(mLock) {
- mOnCallStateChangedCalled = true;
- mLock.notify();
- }
- }
- };
- mTelephonyManager.listen(mListener, PhoneStateListener.LISTEN_CALL_STATE);
-
- Looper.loop();
- }
- });
-
- assertFalse(mOnCallStateChangedCalled);
- t.start();
-
- synchronized (mLock) {
- while(!mOnCallStateChangedCalled){
- mLock.wait();
- }
- }
- t.checkException();
- assertTrue(mOnCallStateChangedCalled);
- }
-
- public void testOnDataConnectionStateChanged() throws Throwable {
- if (mCm.getNetworkInfo(ConnectivityManager.TYPE_MOBILE) == null) {
- Log.d(TAG, "Skipping test that requires ConnectivityManager.TYPE_MOBILE");
- return;
- }
-
- TestThread t = new TestThread(new Runnable() {
- public void run() {
- Looper.prepare();
-
- mListener = new PhoneStateListener() {
- @Override
- public void onDataConnectionStateChanged(int state) {
- synchronized(mLock) {
- mOnDataConnectionStateChangedCalled = true;
- mLock.notify();
- }
- }
- @Override
- public void onDataConnectionStateChanged(int state, int networkType) {
- synchronized(mLock) {
- mOnDataConnectionStateChangedWithNetworkTypeCalled = true;
- mLock.notify();
- }
- }
- };
- mTelephonyManager.listen(
- mListener, PhoneStateListener.LISTEN_DATA_CONNECTION_STATE);
-
- Looper.loop();
- }
- });
-
- assertFalse(mOnDataConnectionStateChangedCalled);
- assertFalse(mOnDataConnectionStateChangedWithNetworkTypeCalled);
- t.start();
-
- synchronized (mLock) {
- while(!mOnDataConnectionStateChangedCalled ||
- !mOnDataConnectionStateChangedWithNetworkTypeCalled){
- mLock.wait();
- }
- }
- t.checkException();
- assertTrue(mOnDataConnectionStateChangedCalled);
- assertTrue(mOnDataConnectionStateChangedWithNetworkTypeCalled);
- }
-
- public void testOnDataActivity() throws Throwable {
- if (mCm.getNetworkInfo(ConnectivityManager.TYPE_MOBILE) == null) {
- Log.d(TAG, "Skipping test that requires ConnectivityManager.TYPE_MOBILE");
- return;
- }
-
- TestThread t = new TestThread(new Runnable() {
- public void run() {
- Looper.prepare();
-
- mListener = new PhoneStateListener() {
- @Override
- public void onDataActivity(int direction) {
- synchronized(mLock) {
- mOnDataActivityCalled = true;
- mLock.notify();
- }
- }
- };
- mTelephonyManager.listen(mListener, PhoneStateListener.LISTEN_DATA_ACTIVITY);
-
- Looper.loop();
- }
- });
-
- assertFalse(mOnDataActivityCalled);
- t.start();
-
- synchronized (mLock) {
- while(!mOnDataActivityCalled){
- mLock.wait();
- }
- }
- t.checkException();
- assertTrue(mOnDataActivityCalled);
- }
-
- public void testOnCellInfoChanged() throws Throwable {
- if (mCm.getNetworkInfo(ConnectivityManager.TYPE_MOBILE) == null) {
- Log.d(TAG, "Skipping test that requires ConnectivityManager.TYPE_MOBILE");
- return;
- }
-
- TestThread t = new TestThread(new Runnable() {
- public void run() {
- Looper.prepare();
-
- mListener = new PhoneStateListener() {
- @Override
- public void onCellInfoChanged(List<CellInfo> cellInfo) {
- synchronized(mLock) {
- mOnCellInfoChangedCalled = true;
- mLock.notify();
- }
- }
- };
- mTelephonyManager.listen(mListener, PhoneStateListener.LISTEN_CELL_INFO);
-
- Looper.loop();
- }
- });
-
- assertFalse(mOnDataActivityCalled);
- t.start();
-
- synchronized (mLock) {
- while(!mOnCellInfoChangedCalled){
- mLock.wait();
- }
- }
- t.checkException();
- assertTrue(mOnCellInfoChangedCalled);
- }
-
- public void testOnUserMobileDataStateChanged() throws Throwable {
- if (mCm.getNetworkInfo(ConnectivityManager.TYPE_MOBILE) == null) {
- Log.d(TAG, "Skipping test that requires ConnectivityManager.TYPE_MOBILE");
- return;
- }
-
- TestThread t = new TestThread(new Runnable() {
- public void run() {
- Looper.prepare();
-
- mListener = new PhoneStateListener() {
- @Override
- public void onUserMobileDataStateChanged(boolean state) {
- synchronized(mLock) {
- mOnUserMobileDataStateChanged = true;
- mLock.notify();
- }
- }
- };
- mTelephonyManager.listen(
- mListener, PhoneStateListener.LISTEN_USER_MOBILE_DATA_STATE);
-
- Looper.loop();
- }
- });
-
- assertFalse(mOnUserMobileDataStateChanged);
- t.start();
-
- synchronized (mLock) {
- while(!mOnUserMobileDataStateChanged){
- mLock.wait();
- }
- }
- t.checkException();
- assertTrue(mOnUserMobileDataStateChanged);
- }
-}
diff --git a/tests/tests/text/Android.mk b/tests/tests/telephony4/Android.mk
similarity index 63%
copy from tests/tests/text/Android.mk
copy to tests/tests/telephony4/Android.mk
index ffa5f9eb..293224f 100644
--- a/tests/tests/text/Android.mk
+++ b/tests/tests/telephony4/Android.mk
@@ -1,4 +1,4 @@
-# Copyright (C) 2008 The Android Open Source Project
+# Copyright (C) 2019 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.
@@ -12,6 +12,7 @@
# See the License for the specific language governing permissions and
# limitations under the License.
+
LOCAL_PATH:= $(call my-dir)
include $(CLEAR_VARS)
@@ -21,24 +22,27 @@
# and when built explicitly put it in the data partition
LOCAL_MODULE_PATH := $(TARGET_OUT_DATA_APPS)
-LOCAL_JAVA_LIBRARIES := android.test.runner.stubs android.test.base.stubs
+LOCAL_JAVA_LIBRARIES := telephony-common \
+ android.test.runner.stubs \
+ android.test.base.stubs
-LOCAL_STATIC_JAVA_LIBRARIES += \
- compatibility-device-util \
- ctsdeviceutillegacy \
+LOCAL_STATIC_JAVA_LIBRARIES := \
ctstestrunner \
- android-support-test \
- mockito-target-minus-junit4 \
- ub-uiautomator
+ compatibility-device-util \
+ truth-prebuilt
+
+LOCAL_HOST_SHARED_LIBRARIES := compatibility-device-telephony-preconditions
LOCAL_SRC_FILES := $(call all-java-files-under, src)
-LOCAL_PACKAGE_NAME := CtsTextTestCases
+LOCAL_PACKAGE_NAME := CtsSimRestrictedApisTestCases
+LOCAL_PRIVATE_PLATFORM_APIS := true
# Tag this module as a cts test artifact
-LOCAL_COMPATIBILITY_SUITE := cts vts general-tests cts_instant
+LOCAL_COMPATIBILITY_SUITE := cts vts general-tests
-# Enforce public / test api only
-LOCAL_SDK_VERSION := test_current
+LOCAL_CERTIFICATE := cts/tests/tests/telephony4/certs/android_telephony_cts_testkey
+
include $(BUILD_CTS_PACKAGE)
+include $(call all-makefiles-under,$(LOCAL_PATH))
diff --git a/tests/tests/telephony4/AndroidManifest.xml b/tests/tests/telephony4/AndroidManifest.xml
new file mode 100644
index 0000000..b292bb1
--- /dev/null
+++ b/tests/tests/telephony4/AndroidManifest.xml
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2019 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.telephony4.cts">
+
+ <application>
+ <uses-library android:name="android.test.runner" />
+ </application>
+
+ <instrumentation android:name="android.support.test.runner.AndroidJUnitRunner"
+ android:targetPackage="android.telephony4.cts"
+ android:label="CTS tests of android.telephony4">
+ <meta-data android:name="listener"
+ android:value="com.android.cts.runner.CtsTestRunListener" />
+ </instrumentation>
+
+</manifest>
+
diff --git a/tests/libcore/coreplatformapi/AndroidTest.xml b/tests/tests/telephony4/AndroidTest.xml
similarity index 69%
rename from tests/libcore/coreplatformapi/AndroidTest.xml
rename to tests/tests/telephony4/AndroidTest.xml
index 907fb2d..636ecbb1 100644
--- a/tests/libcore/coreplatformapi/AndroidTest.xml
+++ b/tests/tests/telephony4/AndroidTest.xml
@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2018 The Android Open Source Project
+<!-- Copyright (C) 2019 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.
@@ -13,16 +13,15 @@
See the License for the specific language governing permissions and
limitations under the License.
-->
-<configuration description="Config for CTS Libcore core platform API test cases">
+<configuration description="Config for CTS Telephony4 test cases">
<option name="test-suite-tag" value="cts" />
- <option name="config-descriptor:metadata" key="component" value="libcore" />
+ <option name="config-descriptor:metadata" key="component" value="telecom" />
+ <option name="not-shardable" value="true" />
<target_preparer class="com.android.tradefed.targetprep.suite.SuiteApkInstaller">
<option name="cleanup-apks" value="true" />
- <option name="test-file-name" value="CtsLibcoreCorePlatformApiTestCases.apk" />
+ <option name="test-file-name" value="CtsSimRestrictedApisTestCases.apk" />
</target_preparer>
<test class="com.android.tradefed.testtype.AndroidJUnitTest" >
- <option name="package" value="android.libcore.cts.coreplatformapi" />
- <option name="runtime-hint" value="1m"/>
- <option name="hidden-api-checks" value="false"/>
+ <option name="package" value="android.telephony4.cts" />
</test>
</configuration>
diff --git a/tests/tests/telephony4/certs/android_telephony_cts_testkey.pk8 b/tests/tests/telephony4/certs/android_telephony_cts_testkey.pk8
new file mode 100644
index 0000000..f83d5ed
--- /dev/null
+++ b/tests/tests/telephony4/certs/android_telephony_cts_testkey.pk8
Binary files differ
diff --git a/tests/tests/telephony4/certs/android_telephony_cts_testkey.x509.pem b/tests/tests/telephony4/certs/android_telephony_cts_testkey.x509.pem
new file mode 100644
index 0000000..29ffd6a
--- /dev/null
+++ b/tests/tests/telephony4/certs/android_telephony_cts_testkey.x509.pem
@@ -0,0 +1,30 @@
+-----BEGIN CERTIFICATE-----
+MIIF9TCCA92gAwIBAgIVAIja2SQYIM1wfIrwgObEUdBk/MfkMA0GCSqGSIb3DQEBCwUAMIGKMQsw
+CQYDVQQGEwJVUzETMBEGA1UECBMKQ2FsaWZvcm5pYTEWMBQGA1UEBxMNTW91bnRhaW4gVmlldzEU
+MBIGA1UEChMLR29vZ2xlIEluYy4xEDAOBgNVBAsTB0FuZHJvaWQxJjAkBgNVBAMMHWFuZHJvaWRf
+dGVsZXBob255X2N0c190ZXN0a2V5MB4XDTE5MDExMTE5MzMwM1oXDTQ5MDExMTE5MzMwM1owgYox
+CzAJBgNVBAYTAlVTMRMwEQYDVQQIEwpDYWxpZm9ybmlhMRYwFAYDVQQHEw1Nb3VudGFpbiBWaWV3
+MRQwEgYDVQQKEwtHb29nbGUgSW5jLjEQMA4GA1UECxMHQW5kcm9pZDEmMCQGA1UEAwwdYW5kcm9p
+ZF90ZWxlcGhvbnlfY3RzX3Rlc3RrZXkwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQC9
+IXCTl7o3J6gy5YleQRFm5Xahth5hwpC7b/cfZiSW25AqNLZRcZJZDwYiJIpqOu773Hr5fEZMV5c1
+tYivwdwKnoGlWiqrpvwafIQxsAPtKoiSsB6r6Zx4hZBDzf5M+PRi3ieUrPrwaiGeVy1n4nPhcpHy
+bzE2G+ZkfzxRYRmmObi8+UC4lkI2dL1Y17hjNmWpeJrfhvl67K2gMmAtwjW2UxhyOcACg8Mya1eA
+VyqQgiEfMb52FK1opshHnGpIcLjY7UT1IesOZpWu3OWqiOw/KCU+nJaEemYFYceGR14RGfKk9r1N
+hcRhZLXPfZHr9TPsJ/O/oKrF3Q+TxoUJIhQ3lcYREftrqMZNDUUANENnfd1Bviu2atschG5Ohchk
+MiuKDadMl++LOkfGjoTikQXUHGxb4GIfgLJDmkp6+Andc2iZ2pRPm6zQmHXWmcwtz3RvyGtK0oYJ
+xwpVy0InE/Ao1sH8LrYvBPWKDVHbG2v+ydYYrx39ScBLgXQ4gxmTNU8+YX3zXVaGWMPuVP2GfyBl
+O+fl27RZO/XZlC28TQEMAvytSyeTs4blubRlLgcf9wAv774a797g7uSRSZ+8aqumatPrtZnhBojU
+2U4zuQilE5JGIIvM5ZGWUNMMkY5bB4bnw36oSK7kup8dyLlT7Jgfpc5RuzYPKzU+OcH/k0SeZwID
+AQABo1AwTjAMBgNVHRMEBTADAQH/MB0GA1UdDgQWBBR4+8+XqYU6x7dqy/fwqz5eG2TQIjAfBgNV
+HSMEGDAWgBR4+8+XqYU6x7dqy/fwqz5eG2TQIjANBgkqhkiG9w0BAQsFAAOCAgEAaxTiY0j+Xgig
+WnsfqJRCV7Qn6LFhCyS2zc96g+m0CkiPLW83BFkVND9JaAUVw3GIUKDEtZkUy3v5L4//QmfdYIbH
+IBX5d/GJAVkH4MRFb47Mr2qu6t33eNiDaRzJe5WIQ+3qI1P0/2ihqKOAEC8OSWQWzY8eWB9O4vKp
+U/0JENOcSTfthce7dDhCCqw3P0Xmo9xW1x9YqcAPzNcQE7Lm68MeOB9esoTlIFS7R9tRp17pBU8Y
+Lw9WSRFy6jBYX1Wf83M96+WPNQensLymnXMDuwJhoNV5MnGMkqsASfkzZwLxcLRKlt4gJ4gmmPlM
+mIeJCcMvUJIMOlYcNEiBF4i4CkzA/ThxPRXSCZdQKjzM5YG7Sj3uEJTYgDq+50k/nKnhqKymZhQN
+pXtax3/2ivonWfNaWWIYBEY3aRQTb3IwTRjM1ib6Aj4sIjATzP0vowmYoQf/iv5HKYyndyRcy4zR
+LeOUbU5Hk0Rhc896eOFshwuB8VQ/6kiIPWN4VRNXn/hjT+p5y+ww8IM1crLV+ftdRDhDKbgxNfo1
+R1uhZgRryzWBmFEz6wSKDctdVeZ087e3pfze+V3/hrT2gevoYtcMHT7+qmNssnDbUinXJicQAQBn
+Wl2lx+PwyRnQ1dAozjcpytqXNmRF/881E2MvtdAN5Y4F5d0fh32Yi455xQ5UNb0=
+-----END CERTIFICATE-----
+
diff --git a/tests/tests/telephony/src/android/telephony/cts/SimRestrictedApisTest.java b/tests/tests/telephony4/src/android/telephony4/cts/SimRestrictedApisTest.java
similarity index 88%
rename from tests/tests/telephony/src/android/telephony/cts/SimRestrictedApisTest.java
rename to tests/tests/telephony4/src/android/telephony4/cts/SimRestrictedApisTest.java
index b15a4e8..c1189a2 100644
--- a/tests/tests/telephony/src/android/telephony/cts/SimRestrictedApisTest.java
+++ b/tests/tests/telephony4/src/android/telephony4/cts/SimRestrictedApisTest.java
@@ -14,7 +14,7 @@
* limitations under the License.
*/
-package android.telephony.cts;
+package android.telephony4.cts;
import android.content.Context;
import android.telephony.SmsManager;
@@ -59,7 +59,7 @@
public void testSetLine1NumberForDisplay() {
try {
if (isSimCardPresent()) {
- TelephonyManager.getDefault().setLine1NumberForDisplay("", "");
+ mTelephonyManager.setLine1NumberForDisplay("", "");
fail("Expected SecurityException. App doesn't have carrier privileges.");
}
} catch (SecurityException expected) {
@@ -74,7 +74,7 @@
public void testSetLine1NumberForDisplay2() {
try {
if (isSimCardPresent()) {
- TelephonyManager.getDefault().setLine1NumberForDisplay(0, "", "");
+ mTelephonyManager.setLine1NumberForDisplay(0, "", "");
fail("Expected SecurityException. App doesn't have carrier privileges.");
}
} catch (SecurityException expected) {
@@ -89,7 +89,7 @@
public void testIccOpenLogicalChannel() {
try {
if (isSimCardPresent()) {
- TelephonyManager.getDefault().iccOpenLogicalChannel("");
+ mTelephonyManager.iccOpenLogicalChannel("");
fail("Expected SecurityException. App doesn't have carrier privileges.");
}
} catch (SecurityException expected) {
@@ -104,7 +104,7 @@
public void testIccCloseLogicalChannel() {
try {
if (isSimCardPresent()) {
- TelephonyManager.getDefault().iccCloseLogicalChannel(0);
+ mTelephonyManager.iccCloseLogicalChannel(0);
fail("Expected SecurityException. App doesn't have carrier privileges.");
}
} catch (SecurityException expected) {
@@ -119,7 +119,7 @@
public void testIccTransmitApduLogicalChannel() {
try {
if (isSimCardPresent()) {
- TelephonyManager.getDefault().iccTransmitApduLogicalChannel(0, 0, 0, 0, 0, 0, "");
+ mTelephonyManager.iccTransmitApduLogicalChannel(0, 0, 0, 0, 0, 0, "");
fail("Expected SecurityException. App doesn't have carrier privileges.");
}
} catch (SecurityException expected) {
@@ -134,7 +134,7 @@
public void testIccTransmitApduBasicChannel() {
try {
if (isSimCardPresent()) {
- TelephonyManager.getDefault().iccTransmitApduBasicChannel(0, 0, 0, 0, 0, "");
+ mTelephonyManager.iccTransmitApduBasicChannel(0, 0, 0, 0, 0, "");
fail("Expected SecurityException. App doesn't have carrier privileges.");
}
} catch (SecurityException expected) {
@@ -149,7 +149,7 @@
public void testSendEnvelopeWithStatus() {
try {
if (isSimCardPresent()) {
- TelephonyManager.getDefault().sendEnvelopeWithStatus("");
+ mTelephonyManager.sendEnvelopeWithStatus("");
fail("Expected SecurityException. App doesn't have carrier privileges.");
}
} catch (SecurityException expected) {
@@ -163,7 +163,7 @@
public void testNvReadItem() {
try {
if (isSimCardPresent()) {
- TelephonyManager.getDefault().nvReadItem(0);
+ mTelephonyManager.nvReadItem(0);
fail("Expected SecurityException. App doesn't have carrier privileges.");
}
} catch (SecurityException expected) {
@@ -177,7 +177,7 @@
public void testNvWriteItem() {
try {
if (isSimCardPresent()) {
- TelephonyManager.getDefault().nvWriteItem(0, "");
+ mTelephonyManager.nvWriteItem(0, "");
fail("Expected SecurityException. App doesn't have carrier privileges.");
}
} catch (SecurityException expected) {
@@ -191,7 +191,7 @@
public void testNvWriteCdmaPrl() {
try {
if (isSimCardPresent()) {
- TelephonyManager.getDefault().nvWriteCdmaPrl(null);
+ mTelephonyManager.nvWriteCdmaPrl(null);
fail("Expected SecurityException. App doesn't have carrier privileges.");
}
} catch (SecurityException expected) {
@@ -205,7 +205,7 @@
public void testNvResetConfig() {
try {
if (isSimCardPresent()) {
- TelephonyManager.getDefault().nvResetConfig(0);
+ mTelephonyManager.nvResetConfig(1);
fail("Expected SecurityException. App doesn't have carrier privileges.");
}
} catch (SecurityException expected) {
@@ -220,7 +220,7 @@
public void testGetPreferredNetworkType() {
try {
if (isSimCardPresent()) {
- TelephonyManager.getDefault().getPreferredNetworkType(0);
+ mTelephonyManager.getPreferredNetworkType(0);
fail("Expected SecurityException. App doesn't have carrier privileges.");
}
} catch (SecurityException expected) {
@@ -235,7 +235,7 @@
public void testSetPreferredNetworkTypeToGlobal() {
try {
if (isSimCardPresent()) {
- TelephonyManager.getDefault().setPreferredNetworkTypeToGlobal();
+ mTelephonyManager.setPreferredNetworkTypeToGlobal();
fail("Expected SecurityException. App doesn't have carrier privileges.");
}
} catch (SecurityException expected) {
@@ -246,7 +246,7 @@
* Tests that the test apk doesn't have carrier previliges.
*/
public void testHasCarrierPrivileges() {
- if (TelephonyManager.getDefault().hasCarrierPrivileges()) {
+ if (mTelephonyManager.hasCarrierPrivileges()) {
fail("App unexpectedly has carrier privileges");
}
}
@@ -259,7 +259,7 @@
public void testSetOperatorBrandOverride() {
try {
if (isSimCardPresent()) {
- TelephonyManager.getDefault().setOperatorBrandOverride("");
+ mTelephonyManager.setOperatorBrandOverride("");
fail("Expected SecurityException. App doesn't have carrier privileges.");
}
} catch (SecurityException expected) {
@@ -274,7 +274,7 @@
public void testGetIccAuthentication() {
try {
if (isSimCardPresent()) {
- TelephonyManager.getDefault().getIccAuthentication(TelephonyManager.APPTYPE_USIM,
+ mTelephonyManager.getIccAuthentication(TelephonyManager.APPTYPE_USIM,
TelephonyManager.AUTHTYPE_EAP_AKA, "");
fail("Expected SecurityException. App doesn't have carrier privileges.");
}
diff --git a/tests/tests/telephonyprovider/src/android/telephonyprovider/cts/MmsPartTest.java b/tests/tests/telephonyprovider/src/android/telephonyprovider/cts/MmsPartTest.java
new file mode 100644
index 0000000..e6ec35a
--- /dev/null
+++ b/tests/tests/telephonyprovider/src/android/telephonyprovider/cts/MmsPartTest.java
@@ -0,0 +1,138 @@
+/*
+ * Copyright (C) 2019 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.telephonyprovider.cts;
+
+import static android.support.test.InstrumentationRegistry.getInstrumentation;
+import static android.telephonyprovider.cts.DefaultSmsAppHelper.setDefaultSmsApp;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import android.content.ContentResolver;
+import android.content.ContentValues;
+import android.database.Cursor;
+import android.net.Uri;
+import android.provider.Telephony;
+import android.support.test.InstrumentationRegistry;
+
+import org.junit.AfterClass;
+import org.junit.Before;
+import org.junit.Test;
+
+import javax.annotation.Nullable;
+
+public class MmsPartTest {
+ private ContentResolver mContentResolver;
+
+ /**
+ * Parts must be inserted in relation to a message, this message ID is used for inserting a
+ * part when the message ID is not important in relation to the current test.
+ */
+ private static final String TEST_MESSAGE_ID = "100";
+
+ @Before
+ public void setupTestEnvironment() {
+ cleanup();
+ mContentResolver = getInstrumentation().getContext().getContentResolver();
+ }
+
+ @AfterClass
+ public static void cleanup() {
+ ContentResolver contentResolver =
+ InstrumentationRegistry.getInstrumentation().getContext().getContentResolver();
+
+ setDefaultSmsApp(true);
+ contentResolver.delete(Telephony.Mms.Part.CONTENT_URI, null, null);
+ setDefaultSmsApp(false);
+ }
+
+ @Test
+ public void testMmsPartInsert_cannotInsertPartWithDataColumn() {
+ setDefaultSmsApp(true);
+
+ ContentValues values = new ContentValues();
+ values.put(Telephony.Mms.Part._DATA, "/dev/urandom");
+ values.put(Telephony.Mms.Part.NAME, "testMmsPartInsert_cannotInsertPartWithDataColumn");
+
+ Uri uri = insertTestMmsPartWithValues(values);
+ assertThat(uri).isNull();
+ }
+
+ @Test
+ public void testMmsPartInsert_canInsertPartWithoutDataColumn() {
+ setDefaultSmsApp(true);
+
+ String name = "testMmsInsert_canInsertPartWithoutDataColumn";
+
+ Uri uri = insertTestMmsPartWithName(name);
+ assertThatMmsPartInsertSucceeded(uri, name);
+ }
+
+ @Test
+ public void testMmsPart_deletedPartIdsAreNotReused() {
+ setDefaultSmsApp(true);
+
+ long id1 = insertAndVerifyMmsPartReturningId("testMmsPart_deletedPartIdsAreNotReused_1");
+
+ deletePartById(id1);
+
+ long id2 = insertAndVerifyMmsPartReturningId("testMmsPart_deletedPartIdsAreNotReused_2");
+
+ assertThat(id2).isGreaterThan(id1);
+ }
+
+ private long insertAndVerifyMmsPartReturningId(String name) {
+ Uri uri = insertTestMmsPartWithName(name);
+ assertThatMmsPartInsertSucceeded(uri, name);
+ return Long.parseLong(uri.getLastPathSegment());
+ }
+
+ private void deletePartById(long partId) {
+ Uri uri = Uri.withAppendedPath(Telephony.Mms.Part.CONTENT_URI, Long.toString(partId));
+ int deletedRows = mContentResolver.delete(uri, null, null);
+ assertThat(deletedRows).isEqualTo(1);
+ }
+
+ private Uri insertTestMmsPartWithName(String name) {
+ ContentValues values = new ContentValues();
+ values.put(Telephony.Mms.Part.NAME, name);
+ return insertTestMmsPartWithValues(values);
+ }
+
+ private Uri insertTestMmsPartWithValues(ContentValues values) {
+ Uri insertUri = Telephony.Mms.CONTENT_URI.buildUpon()
+ .appendPath(TEST_MESSAGE_ID)
+ .appendPath("part")
+ .build();
+
+ Uri uri = mContentResolver.insert(insertUri, values);
+ return uri;
+ }
+
+ private void assertThatMmsPartInsertSucceeded(@Nullable Uri uriReturnedFromInsert,
+ String nameOfAttemptedInsert) {
+ assertThat(uriReturnedFromInsert).isNotNull();
+
+ Cursor cursor = mContentResolver.query(uriReturnedFromInsert, null, null, null);
+
+ assertThat(cursor.getCount()).isEqualTo(1);
+
+ cursor.moveToNext();
+ String actualName = cursor.getString(cursor.getColumnIndex(Telephony.Mms.Part.NAME));
+ assertThat(actualName).isEqualTo(nameOfAttemptedInsert);
+ }
+
+}
diff --git a/tests/tests/telephonyprovider/src/android/telephonyprovider/cts/MmsTest.java b/tests/tests/telephonyprovider/src/android/telephonyprovider/cts/MmsTest.java
index e48be31..4922864 100644
--- a/tests/tests/telephonyprovider/src/android/telephonyprovider/cts/MmsTest.java
+++ b/tests/tests/telephonyprovider/src/android/telephonyprovider/cts/MmsTest.java
@@ -29,7 +29,6 @@
import android.support.test.InstrumentationRegistry;
import android.support.test.filters.SmallTest;
-import org.junit.After;
import org.junit.AfterClass;
import org.junit.Before;
import org.junit.Test;
@@ -159,16 +158,6 @@
assertThatMmsInsertSucceeded(uri, expectedSubject);
}
- @Test
- public void testMmsInsert_cannotInsertPartWithDataColumn() {
- setDefaultSmsApp(true);
- Uri uri = Uri.parse("content://mms/100/part");
- ContentValues values = new ContentValues();
- values.put("_data", "/dev/urandom");
- Uri uri2 = mContentResolver.insert(uri, values);
- assertThat(uri2).isNull();
- }
-
/**
* Asserts that a URI returned from an MMS insert operation represents a failed insert.
*
diff --git a/tests/tests/telephonyprovider/src/android/telephonyprovider/cts/ThreadsTest.java b/tests/tests/telephonyprovider/src/android/telephonyprovider/cts/ThreadsTest.java
new file mode 100644
index 0000000..505ab82
--- /dev/null
+++ b/tests/tests/telephonyprovider/src/android/telephonyprovider/cts/ThreadsTest.java
@@ -0,0 +1,78 @@
+package android.telephonyprovider.cts;
+
+import static android.support.test.InstrumentationRegistry.getInstrumentation;
+import static android.telephonyprovider.cts.DefaultSmsAppHelper.setDefaultSmsApp;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import android.content.ContentResolver;
+import android.content.ContentValues;
+import android.content.Context;
+import android.net.Uri;
+import android.provider.Telephony;
+import android.support.test.InstrumentationRegistry;
+import android.support.test.filters.SmallTest;
+
+import org.junit.AfterClass;
+import org.junit.Before;
+import org.junit.Test;
+
+@SmallTest
+public class ThreadsTest {
+ private Context mContext;
+ private ContentResolver mContentResolver;
+
+ @Before
+ public void setupTestEnvironment() {
+ cleanup();
+ mContext = getInstrumentation().getContext();
+ mContentResolver = mContext.getContentResolver();
+ }
+
+ @AfterClass
+ public static void cleanup() {
+ ContentResolver contentResolver =
+ InstrumentationRegistry.getInstrumentation().getContext().getContentResolver();
+
+ setDefaultSmsApp(true);
+ contentResolver.delete(Telephony.Threads.CONTENT_URI, null, null);
+ setDefaultSmsApp(false);
+ }
+
+ @Test
+ public void testThreadDeletion_doNotReuseThreadIdsFromEmptyThreads() {
+ setDefaultSmsApp(true);
+
+ String destination1 = "+19998880001";
+ String destination2 = "+19998880002";
+
+ long threadId1 = Telephony.Threads.getOrCreateThreadId(mContext, destination1);
+
+ Uri inboxUri = saveToTelephony(threadId1, destination1, "testThreadDeletion body");
+
+ // The URI returned by the insert operation points to the message ID in the inbox. Though
+ // this is a valid ID for queries, the SMS provider does not handle it for delete
+ // operations. This takes the ID off the end of the URI and creates a URI pointing at that
+ // row from the root of the SMS provider.
+ Uri rootUri =
+ Uri.withAppendedPath(Telephony.Sms.CONTENT_URI, inboxUri.getLastPathSegment());
+
+ int deletedCount = mContentResolver.delete(rootUri, null, null);
+
+ assertThat(deletedCount).isEqualTo(1);
+
+ long threadId2 = Telephony.Threads.getOrCreateThreadId(mContext, destination2);
+
+ assertThat(threadId2).isGreaterThan(threadId1);
+ }
+
+ private Uri saveToTelephony(long threadId, String address, String body) {
+ ContentValues contentValues = new ContentValues();
+ contentValues.put(Telephony.Sms.THREAD_ID, threadId);
+ contentValues.put(Telephony.Sms.ADDRESS, address);
+ contentValues.put(Telephony.Sms.BODY, body);
+
+ return mContext.getContentResolver().insert(Telephony.Sms.Inbox.CONTENT_URI, contentValues);
+ }
+}
+
diff --git a/tests/tests/text/Android.bp b/tests/tests/text/Android.bp
new file mode 100644
index 0000000..8670814
--- /dev/null
+++ b/tests/tests/text/Android.bp
@@ -0,0 +1,45 @@
+// 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.
+
+android_test {
+ name: "CtsTextTestCases",
+ defaults: ["cts_defaults"],
+ sdk_version: "test_current",
+
+ srcs: [
+ "src/**/*.java",
+ "src/**/*.kt",
+ ],
+
+ static_libs: [
+ "compatibility-device-util",
+ "ctsdeviceutillegacy",
+ "ctstestrunner",
+ "mockito-target-minus-junit4",
+ "android-support-test",
+ "ub-uiautomator",
+ ],
+
+ libs: [
+ "android.test.runner.stubs",
+ "android.test.base.stubs",
+ ],
+
+ test_suites: [
+ "cts",
+ "vts",
+ "general-tests",
+ "cts_instant",
+ ],
+}
diff --git a/tests/tests/text/src/android/text/util/cts/LinkifyTest.java b/tests/tests/text/src/android/text/util/cts/LinkifyTest.java
index 9a7e39a..7c7694e 100644
--- a/tests/tests/text/src/android/text/util/cts/LinkifyTest.java
+++ b/tests/tests/text/src/android/text/util/cts/LinkifyTest.java
@@ -21,10 +21,6 @@
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertTrue;
-import static org.mockito.ArgumentMatchers.anyString;
-import static org.mockito.Mockito.spy;
-import static org.mockito.Mockito.times;
-import static org.mockito.Mockito.verify;
import android.content.Context;
import android.support.test.InstrumentationRegistry;
@@ -46,6 +42,7 @@
import org.mockito.ArgumentMatcher;
import java.util.Locale;
+import java.util.function.Function;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
@@ -464,23 +461,15 @@
}
}
- public class MyUrlSpanFactory extends Linkify.UrlSpanFactory {
- @Override
- public URLSpan create(String url) {
- return new MyUrlSpan(url);
- }
- }
-
@Test
public void testAddLinks_UrlSpanFactory_withSpannable() {
final String text = "a https://android.com a +1 123 456 7878 a android@android.com a";
final Spannable spannable = new SpannableString(text);
final int mask = Linkify.WEB_URLS | Linkify.PHONE_NUMBERS | Linkify.EMAIL_ADDRESSES;
- final Linkify.UrlSpanFactory urlSpanFactory = spy(new MyUrlSpanFactory());
+ final Function<String, URLSpan> spanFactory = (String string) -> new MyUrlSpan(string);
- Linkify.addLinks(spannable, mask, urlSpanFactory);
+ Linkify.addLinks(spannable, mask, spanFactory);
- verify(urlSpanFactory, times(3)).create(anyString());
final MyUrlSpan[] myUrlSpans = spannable.getSpans(0, spannable.length(), MyUrlSpan.class);
assertNotNull(myUrlSpans);
assertEquals(3, myUrlSpans.length);
@@ -496,12 +485,10 @@
public void testAddLinks_UrlSpanFactory_withSpannableAndFilter() {
final String text = "google.pattern, test:AZ0101.pattern";
final SpannableString spannable = new SpannableString(text);
- final Linkify.UrlSpanFactory urlSpanFactory = spy(new MyUrlSpanFactory());
+ final Function<String, URLSpan> spanFactory = (String string) -> new MyUrlSpan(string);
Linkify.addLinks(spannable, LINKIFY_TEST_PATTERN, "test:", null /*schemes*/,
- null /*matchFilter*/, null /*transformFilter*/, urlSpanFactory);
-
- verify(urlSpanFactory, times(2)).create(anyString());
+ null /*matchFilter*/, null /*transformFilter*/, spanFactory);
final MyUrlSpan[] myUrlSpans = spannable.getSpans(0, spannable.length(), MyUrlSpan.class);
assertNotNull(myUrlSpans);
@@ -513,13 +500,6 @@
assertArrayEquals(myUrlSpans, urlSpans);
}
- @Test
- public void testDefaultUrlSpanFactory() {
- URLSpan urlSpan = new Linkify.UrlSpanFactory().create("some url");
- assertNotNull(urlSpan);
- assertEquals("some url", urlSpan.getURL());
- }
-
// WEB_URLS Related Tests
@Test
diff --git a/tests/tests/tools/processors/view_inspector/Android.bp b/tests/tests/tools/processors/view_inspector/Android.bp
new file mode 100644
index 0000000..bcebde1
--- /dev/null
+++ b/tests/tests/tools/processors/view_inspector/Android.bp
@@ -0,0 +1,34 @@
+// Copyright 2019 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.
+
+android_test {
+ name: "CtsViewInspectorAnnotationProcessorTestCases",
+ sdk_version: "test_current",
+
+ srcs: ["src/**/*.java"],
+
+ plugins: ["view-inspector-annotation-processor"],
+
+ static_libs: [
+ "android-support-test",
+ "compatibility-device-util",
+ "ctstestrunner",
+ ],
+
+ test_suites: [
+ "cts",
+ "vts",
+ "general-tests",
+ ]
+}
diff --git a/tests/tests/tools/processors/view_inspector/AndroidManifest.xml b/tests/tests/tools/processors/view_inspector/AndroidManifest.xml
new file mode 100644
index 0000000..e6574d7
--- /dev/null
+++ b/tests/tests/tools/processors/view_inspector/AndroidManifest.xml
@@ -0,0 +1,35 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ * Copyright 2019 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.processor.view.inspector.cts">
+
+ <uses-permission android:name="android.permission.DISABLE_KEYGUARD" />
+ <application>
+ <uses-library android:name="android.test.runner" />
+ </application>
+
+ <instrumentation android:name="android.support.test.runner.AndroidJUnitRunner"
+ android:targetPackage="android.processor.view.inspector.cts"
+ android:label="CTS tests of android.processor.view.inspector">
+ <meta-data android:name="listener"
+ android:value="com.android.cts.runner.CtsTestRunListener" />
+ </instrumentation>
+
+</manifest>
+
diff --git a/tests/libcore/coreplatformapi/AndroidTest.xml b/tests/tests/tools/processors/view_inspector/AndroidTest.xml
similarity index 69%
copy from tests/libcore/coreplatformapi/AndroidTest.xml
copy to tests/tests/tools/processors/view_inspector/AndroidTest.xml
index 907fb2d..dab96b2 100644
--- a/tests/libcore/coreplatformapi/AndroidTest.xml
+++ b/tests/tests/tools/processors/view_inspector/AndroidTest.xml
@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2018 The Android Open Source Project
+<!-- Copyright 2019 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.
@@ -13,16 +13,18 @@
See the License for the specific language governing permissions and
limitations under the License.
-->
-<configuration description="Config for CTS Libcore core platform API test cases">
+<configuration description="Config for CTS view inspector annotation processor test cases">
+
<option name="test-suite-tag" value="cts" />
- <option name="config-descriptor:metadata" key="component" value="libcore" />
+ <option name="config-descriptor:metadata" key="component" value="uitoolkit" />
+
<target_preparer class="com.android.tradefed.targetprep.suite.SuiteApkInstaller">
<option name="cleanup-apks" value="true" />
- <option name="test-file-name" value="CtsLibcoreCorePlatformApiTestCases.apk" />
+ <option name="test-file-name" value="CtsViewInspectorAnnotationProcessorTestCases.apk" />
</target_preparer>
+
<test class="com.android.tradefed.testtype.AndroidJUnitTest" >
- <option name="package" value="android.libcore.cts.coreplatformapi" />
- <option name="runtime-hint" value="1m"/>
- <option name="hidden-api-checks" value="false"/>
+ <option name="package" value="android.processor.view.inspector.cts" />
+ <option name="runtime-hint" value="30s" />
</test>
</configuration>
diff --git a/tests/tests/tools/processors/view_inspector/src/android/processor/view/inspector/cts/PlatformInspectableProcessorTest.java b/tests/tests/tools/processors/view_inspector/src/android/processor/view/inspector/cts/PlatformInspectableProcessorTest.java
new file mode 100644
index 0000000..4088797
--- /dev/null
+++ b/tests/tests/tools/processors/view_inspector/src/android/processor/view/inspector/cts/PlatformInspectableProcessorTest.java
@@ -0,0 +1,444 @@
+/*
+ * Copyright 2019 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.processor.view.inspector.cts;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotEquals;
+import static org.junit.Assert.assertNull;
+import static org.junit.Assert.fail;
+
+import android.R;
+import android.content.res.Resources;
+import android.graphics.Color;
+import android.support.test.filters.SmallTest;
+import android.support.test.runner.AndroidJUnit4;
+import android.view.inspector.InspectableNodeName;
+import android.view.inspector.InspectableProperty;
+import android.view.inspector.InspectableProperty.ValueType;
+import android.view.inspector.InspectionCompanion;
+
+import androidx.annotation.ColorInt;
+import androidx.annotation.ColorLong;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import java.util.Objects;
+import java.util.Random;
+
+/**
+ * Behavioral tests for {@link android.processor.view.inspector.PlatformInspectableProcessor}.
+ */
+@SmallTest
+@RunWith(AndroidJUnit4.class)
+public class PlatformInspectableProcessorTest {
+ private Random mRandom;
+ private TestPropertyMapper mPropertyMapper;
+ private TestPropertyReader mPropertyReader;
+
+ @Before
+ public void setup() {
+ mRandom = new Random();
+ mPropertyMapper = new TestPropertyMapper();
+ mPropertyReader = new TestPropertyReader(mPropertyMapper);
+ }
+
+ @InspectableNodeName("my_node")
+ class NodeNameInspectable {
+ }
+
+
+ @Test
+ public void testNodeName() {
+ assertEquals("my_node", loadCompanion(NodeNameInspectable.class).getNodeName());
+ assertNull(loadCompanion(IntPropertyInspectable.class).getNodeName());
+ }
+
+ class IntPropertyInspectable {
+ private final int mValue;
+
+ IntPropertyInspectable(Random seed) {
+ mValue = seed.nextInt();
+ }
+
+ @InspectableProperty
+ public int getValue() {
+ return mValue;
+ }
+ }
+
+ @Test
+ public void testMapAndReadInt() {
+ IntPropertyInspectable inspectable = new IntPropertyInspectable(mRandom);
+ mapAndRead(inspectable);
+ assertEquals(inspectable.getValue(), mPropertyReader.get("value"));
+ }
+
+ @Test
+ public void testInferredAttributeId() {
+ loadCompanion(IntPropertyInspectable.class).mapProperties(mPropertyMapper);
+ assertEquals(R.attr.value, mPropertyMapper.getAttributeId("value"));
+ }
+
+ @Test(expected = InspectionCompanion.UninitializedPropertyMapException.class)
+ public void testUninitializedPropertyMap() {
+ IntPropertyInspectable inspectable = new IntPropertyInspectable(mRandom);
+ loadCompanion(IntPropertyInspectable.class).readProperties(inspectable, mPropertyReader);
+ }
+
+ class NamedPropertyInspectable {
+ private final int mValue;
+
+ NamedPropertyInspectable(Random seed) {
+ mValue = seed.nextInt();
+ }
+
+ @InspectableProperty(name = "myNamedValue", hasAttributeId = false)
+ public int getValue() {
+ return mValue;
+ }
+ }
+
+ @Test
+ public void testNamedProperty() {
+ NamedPropertyInspectable inspectable = new NamedPropertyInspectable(mRandom);
+ mapAndRead(inspectable);
+ assertEquals(0, mPropertyMapper.getId("value"));
+ assertEquals(inspectable.getValue(), mPropertyReader.get("myNamedValue"));
+ }
+
+ class HasAttributeIdFalseInspectable {
+ @InspectableProperty(hasAttributeId = false)
+ public int getValue() {
+ return 0;
+ }
+ }
+
+ @Test
+ public void testHasAttributeIdFalse() {
+ loadCompanion(HasAttributeIdFalseInspectable.class).mapProperties(mPropertyMapper);
+ assertEquals(Resources.ID_NULL, mPropertyMapper.getAttributeId("value"));
+ }
+
+ class AttributeIdEqualsInspectable {
+ @InspectableProperty(attributeId = 0xdecafbad)
+ public int getValue() {
+ return 0;
+ }
+ }
+
+ @Test
+ public void testAttributeIdEquals() {
+ loadCompanion(AttributeIdEqualsInspectable.class).mapProperties(mPropertyMapper);
+ assertEquals(0xdecafbad, mPropertyMapper.getAttributeId("value"));
+ }
+
+ class InferredPropertyNameInspectable {
+ private final int mValueA;
+ private final int mValueB;
+ private final int mValueC;
+
+ InferredPropertyNameInspectable(Random seed) {
+ mValueA = seed.nextInt();
+ mValueB = seed.nextInt();
+ mValueC = seed.nextInt();
+ }
+
+ @InspectableProperty(hasAttributeId = false)
+ public int getValueA() {
+ return mValueA;
+ }
+
+ @InspectableProperty(hasAttributeId = false)
+ public int isValueB() {
+ return mValueB;
+ }
+
+ @InspectableProperty(hasAttributeId = false)
+ public int obtainValueC() {
+ return mValueC;
+ }
+ }
+
+ @Test
+ public void testInferredPropertyName() {
+ InferredPropertyNameInspectable inspectable = new InferredPropertyNameInspectable(mRandom);
+ mapAndRead(inspectable);
+ assertEquals(inspectable.getValueA(), mPropertyReader.get("valueA"));
+ assertEquals(inspectable.isValueB(), mPropertyReader.get("isValueB"));
+ assertEquals(inspectable.obtainValueC(), mPropertyReader.get("obtainValueC"));
+ }
+
+ class InferredBooleanNameInspectable {
+ private final boolean mValueA;
+ private final boolean mValueB;
+ private final boolean mValueC;
+
+ InferredBooleanNameInspectable(Random seed) {
+ mValueA = seed.nextBoolean();
+ mValueB = seed.nextBoolean();
+ mValueC = seed.nextBoolean();
+ }
+
+ @InspectableProperty(hasAttributeId = false)
+ public boolean getValueA() {
+ return mValueA;
+ }
+
+ @InspectableProperty(hasAttributeId = false)
+ public boolean isValueB() {
+ return mValueB;
+ }
+
+ @InspectableProperty(hasAttributeId = false)
+ public boolean obtainValueC() {
+ return mValueC;
+ }
+ }
+
+ @Test
+ public void testInferredBooleanName() {
+ InferredBooleanNameInspectable inspectable = new InferredBooleanNameInspectable(mRandom);
+ mapAndRead(inspectable);
+ assertEquals(inspectable.getValueA(), mPropertyReader.get("valueA"));
+ assertEquals(inspectable.isValueB(), mPropertyReader.get("valueB"));
+ assertEquals(inspectable.obtainValueC(), mPropertyReader.get("obtainValueC"));
+ }
+
+ class ColorInspectable {
+ private final int mColorInt;
+ private final long mColorLong;
+
+ private final Color mColorObject;
+
+ ColorInspectable(Random seed) {
+ mColorInt = seed.nextInt();
+ mColorLong = Color.pack(seed.nextInt());
+ mColorObject = Color.valueOf(seed.nextInt());
+ }
+
+ @InspectableProperty(hasAttributeId = false)
+ @ColorInt
+ public int getColorInt() {
+ return mColorInt;
+ }
+
+ @InspectableProperty(hasAttributeId = false)
+ @ColorLong
+ public long getColorLong() {
+ return mColorLong;
+ }
+
+ @InspectableProperty(hasAttributeId = false)
+ public Color getColorObject() {
+ return mColorObject;
+ }
+ }
+
+ @Test
+ public void testColorTypeInference() {
+ ColorInspectable inspectable = new ColorInspectable(mRandom);
+ mapAndRead(inspectable);
+ assertEquals(inspectable.getColorInt(), mPropertyReader.get("colorInt"));
+ assertEquals(inspectable.getColorLong(), mPropertyReader.get("colorLong"));
+ assertEquals(inspectable.getColorObject(), mPropertyReader.get("colorObject"));
+ assertEquals(ValueType.COLOR, mPropertyMapper.getValueType("colorInt"));
+ assertEquals(ValueType.COLOR, mPropertyMapper.getValueType("colorLong"));
+ assertEquals(ValueType.COLOR, mPropertyMapper.getValueType("colorObject"));
+ }
+
+ class ValueTypeInspectable {
+ private final int mColor;
+ private final int mGravity;
+ private final int mValue;
+
+ ValueTypeInspectable(Random seed) {
+ mColor = seed.nextInt();
+ mGravity = seed.nextInt();
+ mValue = seed.nextInt();
+ }
+
+ @InspectableProperty(valueType = ValueType.COLOR)
+ public int getColor() {
+ return mColor;
+ }
+
+ @InspectableProperty(valueType = ValueType.GRAVITY)
+ public int getGravity() {
+ return mGravity;
+ }
+
+ @InspectableProperty(valueType = ValueType.NONE)
+ @ColorInt
+ public int getValue() {
+ return mValue;
+ }
+ }
+
+ @Test
+ public void testValueTypeEquals() {
+ ValueTypeInspectable inspectable = new ValueTypeInspectable(mRandom);
+ mapAndRead(inspectable);
+ assertEquals(inspectable.getColor(), mPropertyReader.get("color"));
+ assertEquals(inspectable.getGravity(), mPropertyReader.get("gravity"));
+ assertEquals(inspectable.getValue(), mPropertyReader.get("value"));
+ assertEquals(ValueType.COLOR, mPropertyMapper.getValueType("color"));
+ assertEquals(ValueType.GRAVITY, mPropertyMapper.getValueType("gravity"));
+ assertEquals(ValueType.NONE, mPropertyMapper.getValueType("value"));
+ }
+
+ class PrimitivePropertiesInspectable {
+ private final boolean mBoolean;
+ private final byte mByte;
+ private final char mChar;
+ private final double mDouble;
+ private final float mFloat;
+ private final int mInt;
+ private final long mLong;
+ private final short mShort;
+
+ PrimitivePropertiesInspectable(Random seed) {
+ mBoolean = seed.nextBoolean();
+ mByte = (byte) seed.nextInt();
+ mChar = randomLetter(seed);
+ mDouble = seed.nextDouble();
+ mFloat = seed.nextFloat();
+ mInt = seed.nextInt();
+ mLong = seed.nextLong();
+ mShort = (short) seed.nextInt();
+ }
+
+ @InspectableProperty(hasAttributeId = false)
+ public boolean getBoolean() {
+ return mBoolean;
+ }
+
+ @InspectableProperty(hasAttributeId = false)
+ public byte getByte() {
+ return mByte;
+ }
+
+ @InspectableProperty(hasAttributeId = false)
+ public char getChar() {
+ return mChar;
+ }
+
+ @InspectableProperty(hasAttributeId = false)
+ public double getDouble() {
+ return mDouble;
+ }
+
+ @InspectableProperty(hasAttributeId = false)
+ public float getFloat() {
+ return mFloat;
+ }
+
+ @InspectableProperty(hasAttributeId = false)
+ public int getInt() {
+ return mInt;
+ }
+
+ @InspectableProperty(hasAttributeId = false)
+ public long getLong() {
+ return mLong;
+ }
+
+ @InspectableProperty(hasAttributeId = false)
+ public short getShort() {
+ return mShort;
+ }
+ }
+
+ @Test
+ public void testPrimitiveProperties() {
+ PrimitivePropertiesInspectable inspectable = new PrimitivePropertiesInspectable(mRandom);
+ mapAndRead(inspectable);
+ assertEquals(inspectable.getBoolean(), mPropertyReader.get("boolean"));
+ assertEquals(inspectable.getByte(), mPropertyReader.get("byte"));
+ assertEquals(inspectable.getChar(), mPropertyReader.get("char"));
+ assertEquals(inspectable.getDouble(), mPropertyReader.get("double"));
+ assertEquals(inspectable.getFloat(), mPropertyReader.get("float"));
+ assertEquals(inspectable.getInt(), mPropertyReader.get("int"));
+ assertEquals(inspectable.getLong(), mPropertyReader.get("long"));
+ assertEquals(inspectable.getShort(), mPropertyReader.get("short"));
+ }
+
+ class ObjectPropertiesInspectable {
+ private final String mText;
+
+ ObjectPropertiesInspectable(Random seed) {
+ final StringBuilder stringBuilder = new StringBuilder();
+ final int length = seed.nextInt(8) + 8;
+
+ for (int i = 0; i < length; i++) {
+ stringBuilder.append(randomLetter(seed));
+ }
+
+ mText = stringBuilder.toString();
+ }
+
+ @InspectableProperty
+ public String getText() {
+ return mText;
+ }
+
+ @InspectableProperty(hasAttributeId = false)
+ public Objects getNull() {
+ return null;
+ }
+ }
+
+ @Test
+ public void testObjectProperties() {
+ ObjectPropertiesInspectable inspectable = new ObjectPropertiesInspectable(mRandom);
+ mapAndRead(inspectable);
+ assertEquals(inspectable.getText(), mPropertyReader.get("text"));
+ assertNull(mPropertyReader.get("null"));
+ assertNotEquals(0, mPropertyMapper.getId("null"));
+ }
+
+ @SuppressWarnings("unchecked")
+ private <T> void mapAndRead(T inspectable) {
+ InspectionCompanion<T> companion = loadCompanion((Class<T>) inspectable.getClass());
+ companion.mapProperties(mPropertyMapper);
+ companion.readProperties(inspectable, mPropertyReader);
+ }
+
+ @SuppressWarnings("unchecked")
+ private <T> InspectionCompanion<T> loadCompanion(Class<T> cls) {
+ final ClassLoader classLoader = cls.getClassLoader();
+ final String companionName = String.format("%s$$InspectionCompanion", cls.getName());
+
+ try {
+ final Class<InspectionCompanion<T>> companion =
+ (Class<InspectionCompanion<T>>) classLoader.loadClass(companionName);
+ return companion.newInstance();
+ } catch (ClassNotFoundException e) {
+ fail(String.format("Unable to load companion for %s", cls.getCanonicalName()));
+ } catch (InstantiationException | IllegalAccessException e) {
+ fail(String.format("Unable to instantiate companion for %s", cls.getCanonicalName()));
+ }
+
+ return null;
+ }
+
+ private char randomLetter(Random random) {
+ final String alphabet = "abcdefghijklmnopqrstuvwxyz";
+ return alphabet.charAt(random.nextInt(alphabet.length()));
+ }
+}
diff --git a/tests/tests/tools/processors/view_inspector/src/android/processor/view/inspector/cts/TestPropertyMapper.java b/tests/tests/tools/processors/view_inspector/src/android/processor/view/inspector/cts/TestPropertyMapper.java
new file mode 100644
index 0000000..6cdaaf1
--- /dev/null
+++ b/tests/tests/tools/processors/view_inspector/src/android/processor/view/inspector/cts/TestPropertyMapper.java
@@ -0,0 +1,119 @@
+/*
+ * Copyright 2019 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.processor.view.inspector.cts;
+
+import android.view.inspector.InspectableProperty.ValueType;
+import android.view.inspector.IntEnumMapping;
+import android.view.inspector.IntFlagMapping;
+import android.view.inspector.PropertyMapper;
+
+import java.util.HashMap;
+
+class TestPropertyMapper implements PropertyMapper {
+ private final HashMap<String, Integer> mPropertyIds = new HashMap<>();
+ private final HashMap<String, Integer> mAttributeIds = new HashMap<>();
+ private final HashMap<String, ValueType> mValueTypes = new HashMap<>();
+ private int mNextId = 1;
+
+ int getId(String name) {
+ return mPropertyIds.getOrDefault(name, 0);
+ }
+
+ int getAttributeId(String name) {
+ return mAttributeIds.getOrDefault(name, 0);
+ }
+
+ ValueType getValueType(String name) {
+ return mValueTypes.getOrDefault(name, ValueType.NONE);
+ }
+
+ @Override
+ public int mapBoolean(String name, int attributeId) {
+ return map(name, attributeId);
+ }
+
+ @Override
+ public int mapByte(String name, int attributeId) {
+ return map(name, attributeId);
+ }
+
+ @Override
+ public int mapChar(String name, int attributeId) {
+ return map(name, attributeId);
+ }
+
+ @Override
+ public int mapDouble(String name, int attributeId) {
+ return map(name, attributeId);
+ }
+
+ @Override
+ public int mapFloat(String name, int attributeId) {
+ return map(name, attributeId);
+ }
+
+ @Override
+ public int mapInt(String name, int attributeId) { return map(name, attributeId); }
+
+ @Override
+ public int mapLong(String name, int attributeId) {
+ return map(name, attributeId);
+ }
+
+ @Override
+ public int mapShort(String name, int attributeId) {
+ return map(name, attributeId);
+ }
+
+ @Override
+ public int mapObject(String name, int attributeId) {
+ return map(name, attributeId);
+ }
+
+ @Override
+ public int mapColor(String name, int attributeId) {
+ return map(name, attributeId, ValueType.COLOR);
+ }
+
+ @Override
+ public int mapGravity(String name, int attributeId) {
+ return map(name, attributeId, ValueType.GRAVITY);
+ }
+
+ @Override
+ public int mapIntEnum(String name, int attributeId, IntEnumMapping intEnumMapping) {
+ return map(name, attributeId, ValueType.INT_ENUM);
+ }
+
+ @Override
+ public int mapIntFlag(String name, int attributeId, IntFlagMapping intFlagMapping) {
+ return map(name, attributeId, ValueType.INT_FLAG);
+ }
+
+ private int map(String name, int attributeId) {
+ return map(name, attributeId, ValueType.NONE);
+ }
+
+ private int map(String name, int attributeId, ValueType valueType) {
+ if (mPropertyIds.containsKey(name)) {
+ throw new PropertyConflictException(name, "all", "all");
+ }
+ mAttributeIds.put(name, attributeId);
+ mValueTypes.put(name, valueType);
+ return mPropertyIds.computeIfAbsent(name, n -> mNextId++);
+ }
+}
diff --git a/tests/tests/tools/processors/view_inspector/src/android/processor/view/inspector/cts/TestPropertyReader.java b/tests/tests/tools/processors/view_inspector/src/android/processor/view/inspector/cts/TestPropertyReader.java
new file mode 100644
index 0000000..100e733
--- /dev/null
+++ b/tests/tests/tools/processors/view_inspector/src/android/processor/view/inspector/cts/TestPropertyReader.java
@@ -0,0 +1,116 @@
+/*
+ * Copyright 2019 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.processor.view.inspector.cts;
+
+import android.graphics.Color;
+import android.util.SparseArray;
+import android.view.inspector.PropertyReader;
+
+import java.util.Objects;
+
+
+class TestPropertyReader implements PropertyReader {
+ private final TestPropertyMapper mPropertyMapper;
+ private final SparseArray<Object> mProperties = new SparseArray<>();
+
+ TestPropertyReader(TestPropertyMapper propertyMapper) {
+ mPropertyMapper = Objects.requireNonNull(propertyMapper);
+ }
+
+ Object get(int id) {
+ return mProperties.get(id);
+ }
+
+ Object get(String name) {
+ return mProperties.get(mPropertyMapper.getId(name));
+ }
+
+ @Override
+ public void readBoolean(int id, boolean value) {
+ mProperties.put(id, value);
+ }
+
+ @Override
+ public void readByte(int id, byte value) {
+ mProperties.put(id, value);
+ }
+
+ @Override
+ public void readChar(int id, char value) {
+ mProperties.put(id, value);
+ }
+
+ @Override
+ public void readDouble(int id, double value) {
+ mProperties.put(id, value);
+ }
+
+ @Override
+ public void readFloat(int id, float value) {
+ mProperties.put(id, value);
+ }
+
+ @Override
+ public void readInt(int id, int value) {
+ mProperties.put(id, value);
+ }
+
+ @Override
+ public void readLong(int id, long value) {
+ mProperties.put(id, value);
+ }
+
+ @Override
+ public void readShort(int id, short value) {
+ mProperties.put(id, value);
+ }
+
+ @Override
+ public void readObject(int id, Object value) {
+ mProperties.put(id, value);
+ }
+
+ @Override
+ public void readColor(int id, int value) {
+ mProperties.put(id, value);
+ }
+
+ @Override
+ public void readColor(int id, long value) {
+ mProperties.put(id, value);
+ }
+
+ @Override
+ public void readColor(int id, Color value) {
+ mProperties.put(id, value);
+ }
+
+ @Override
+ public void readGravity(int id, int value) {
+ mProperties.put(id, value);
+ }
+
+ @Override
+ public void readIntEnum(int id, int value) {
+ mProperties.put(id, value);
+ }
+
+ @Override
+ public void readIntFlag(int id, int value) {
+ mProperties.put(id, value);
+ }
+}
diff --git a/tests/tests/uiautomation/src/android/app/uiautomation/cts/UiAutomationTest.java b/tests/tests/uiautomation/src/android/app/uiautomation/cts/UiAutomationTest.java
index e45d3db..898f329 100755
--- a/tests/tests/uiautomation/src/android/app/uiautomation/cts/UiAutomationTest.java
+++ b/tests/tests/uiautomation/src/android/app/uiautomation/cts/UiAutomationTest.java
@@ -78,6 +78,7 @@
grantWriteSecureSettingsPermission(uiAutomation);
}
+ @AppModeFull
@Test
public void testAdoptAllShellPermissions() {
final Context context = getInstrumentation().getContext();
@@ -137,6 +138,7 @@
}
}
+ @AppModeFull
@Test
public void testAdoptSomeShellPermissions() {
final Context context = getInstrumentation().getContext();
diff --git a/tests/tests/uirendering/src/android/uirendering/cts/bitmapverifiers/SamplePointWideGamutVerifier.java b/tests/tests/uirendering/src/android/uirendering/cts/bitmapverifiers/SamplePointWideGamutVerifier.java
index c075105..d2cb027 100644
--- a/tests/tests/uirendering/src/android/uirendering/cts/bitmapverifiers/SamplePointWideGamutVerifier.java
+++ b/tests/tests/uirendering/src/android/uirendering/cts/bitmapverifiers/SamplePointWideGamutVerifier.java
@@ -16,19 +16,20 @@
package android.uirendering.cts.bitmapverifiers;
+import android.graphics.Bitmap;
import android.graphics.Color;
-import android.graphics.ColorSpace;
import android.graphics.Point;
import android.util.Half;
import android.util.Log;
+import org.junit.Assert;
+
import java.nio.ByteBuffer;
+import java.nio.ByteOrder;
-public class SamplePointWideGamutVerifier extends WideGamutBitmapVerifier {
+public class SamplePointWideGamutVerifier extends BitmapVerifier {
private static final String TAG = "SamplePointWideGamut";
- private static final ColorSpace SCRGB = ColorSpace.get(ColorSpace.Named.EXTENDED_SRGB);
-
private final Point[] mPoints;
private final Color[] mColors;
private final float mEps;
@@ -40,31 +41,68 @@
}
@Override
- public boolean verify(ByteBuffer bitmap, int offset, int stride, int width, int height) {
+ public boolean verify(Bitmap bitmap) {
+ Assert.assertTrue("You cannot use this verifier with an bitmap whose ColorSpace is not "
+ + "wide gamut: " + bitmap.getColorSpace(), bitmap.getColorSpace().isWideGamut());
+
+ ByteBuffer dst = ByteBuffer.allocateDirect(bitmap.getAllocationByteCount());
+ bitmap.copyPixelsToBuffer(dst);
+ dst.rewind();
+ dst.order(ByteOrder.LITTLE_ENDIAN);
+
+ int width = bitmap.getWidth();
+ int height = bitmap.getHeight();
+ int stride = bitmap.getRowBytes();
+
boolean success = true;
for (int i = 0; i < mPoints.length; i++) {
Point p = mPoints[i];
Color c = mColors[i];
- int index = p.y * stride + (p.x << 3);
- float r = Half.toFloat(bitmap.getShort(index));
- float g = Half.toFloat(bitmap.getShort(index + 2));
- float b = Half.toFloat(bitmap.getShort(index + 4));
+ float r, g, b, a;
+
+ if (bitmap.getConfig() == Bitmap.Config.RGBA_F16) {
+ int index = p.y * stride + (p.x << 3);
+ r = Half.toFloat(dst.getShort(index));
+ g = Half.toFloat(dst.getShort(index + 2));
+ b = Half.toFloat(dst.getShort(index + 4));
+ a = Half.toFloat(dst.getShort(index + 6));
+ } else if (bitmap.getConfig() == Bitmap.Config.ARGB_8888) {
+ int index = p.y * stride + (p.x << 2);
+ r = dst.get(index + 0) / 255.0f;
+ g = dst.get(index + 1) / 255.0f;
+ b = dst.get(index + 2) / 255.0f;
+ a = dst.get(index + 3) / 255.0f;
+ } else {
+ Assert.fail("This verifier does not support the provided bitmap config: "
+ + bitmap.getConfig());
+ return false;
+ }
+
+ Color bitmapColor = Color.valueOf(r, g, b, a, bitmap.getColorSpace());
+ Color convertedBitmapColor = bitmapColor.convert(c.getColorSpace());
boolean localSuccess = true;
- if (!floatCompare(c.red(), r, mEps)) localSuccess = false;
- if (!floatCompare(c.green(), g, mEps)) localSuccess = false;
- if (!floatCompare(c.blue(), b, mEps)) localSuccess = false;
+ if (!floatCompare(c.red(), convertedBitmapColor.red(), mEps)) localSuccess = false;
+ if (!floatCompare(c.green(), convertedBitmapColor.green(), mEps)) localSuccess = false;
+ if (!floatCompare(c.blue(), convertedBitmapColor.blue(), mEps)) localSuccess = false;
+ if (!floatCompare(c.alpha(), convertedBitmapColor.alpha(), mEps)) localSuccess = false;
if (!localSuccess) {
success = false;
Log.w(TAG, "Expected " + c.toString() + " at " + p.x + "x" + p.y
- + ", got " + Color.valueOf(r, g, b, 1.0f, SCRGB).toString());
+ + ", got " + convertedBitmapColor.toString());
}
}
return success;
}
+ @Override
+ public boolean verify(int[] bitmap, int offset, int stride, int width, int height) {
+ Assert.fail("This verifier requires more info than can be encoded in sRGB (int) values");
+ return false;
+ }
+
private static boolean floatCompare(float a, float b, float eps) {
return Float.compare(a, b) == 0 || Math.abs(a - b) <= eps;
}
diff --git a/tests/tests/uirendering/src/android/uirendering/cts/bitmapverifiers/WideGamutBitmapVerifier.java b/tests/tests/uirendering/src/android/uirendering/cts/bitmapverifiers/WideGamutBitmapVerifier.java
deleted file mode 100644
index 0c11a064..0000000
--- a/tests/tests/uirendering/src/android/uirendering/cts/bitmapverifiers/WideGamutBitmapVerifier.java
+++ /dev/null
@@ -1,46 +0,0 @@
-/*
- * Copyright (C) 2017 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.uirendering.cts.bitmapverifiers;
-
-import android.graphics.Bitmap;
-
-import java.nio.ByteBuffer;
-import java.nio.ByteOrder;
-
-public abstract class WideGamutBitmapVerifier extends BitmapVerifier {
- @Override
- public boolean verify(Bitmap bitmap) {
- ByteBuffer dst = ByteBuffer.allocateDirect(bitmap.getAllocationByteCount());
- bitmap.copyPixelsToBuffer(dst);
- dst.rewind();
- dst.order(ByteOrder.LITTLE_ENDIAN);
-
- int width = bitmap.getWidth();
- int height = bitmap.getHeight();
- return verify(dst, 0, bitmap.getRowBytes(), width, height);
- }
-
- public abstract boolean verify(ByteBuffer bitmap, int offset, int stride,
- int width, int height);
-
- @Override
- public boolean verify(int[] bitmap, int offset, int stride, int width, int height) {
- // This method is never called, we use
- // verify(ByteBuffer bitmap, int offset, int stride, int width, int height) instead
- return false;
- }
-}
diff --git a/tests/tests/view/jni/Android.mk b/tests/tests/view/jni/Android.mk
index f1aad68..85c073b 100644
--- a/tests/tests/view/jni/Android.mk
+++ b/tests/tests/view/jni/Android.mk
@@ -24,12 +24,15 @@
LOCAL_SRC_FILES := \
CtsViewJniOnLoad.cpp \
+ android_view_cts_ASurfaceControlTest.cpp \
android_view_cts_ChoreographerNativeTest.cpp
LOCAL_C_INCLUDES := $(JNI_H_INCLUDE)
-LOCAL_SHARED_LIBRARIES := libandroid libnativehelper_compat_libc++ liblog
+LOCAL_SHARED_LIBRARIES := libandroid libnativehelper_compat_libc++ liblog libsync
-LOCAL_CXX_STL := libc++_static
+LOCAL_NDK_STL_VARIANT := c++_static
+
+LOCAL_SDK_VERSION := current
include $(BUILD_SHARED_LIBRARY)
diff --git a/tests/tests/view/jni/CtsViewJniOnLoad.cpp b/tests/tests/view/jni/CtsViewJniOnLoad.cpp
index 1a7ef3c..a6f50ca 100644
--- a/tests/tests/view/jni/CtsViewJniOnLoad.cpp
+++ b/tests/tests/view/jni/CtsViewJniOnLoad.cpp
@@ -17,8 +17,8 @@
#include <jni.h>
#define LOG_TAG "CtsViewJniOnLoad"
-#include <utils/Log.h>
+extern int register_android_view_cts_ASurfaceControlTest(JNIEnv *);
extern int register_android_view_cts_ChoreographerNativeTest(JNIEnv* env);
jint JNI_OnLoad(JavaVM *vm, void *) {
@@ -26,6 +26,9 @@
if (vm->GetEnv((void**)&env, JNI_VERSION_1_4) != JNI_OK) {
return JNI_ERR;
}
+ if (register_android_view_cts_ASurfaceControlTest(env)) {
+ return JNI_ERR;
+ }
if (register_android_view_cts_ChoreographerNativeTest(env)) {
return JNI_ERR;
}
diff --git a/tests/tests/view/jni/android_view_cts_ASurfaceControlTest.cpp b/tests/tests/view/jni/android_view_cts_ASurfaceControlTest.cpp
new file mode 100644
index 0000000..dd6a186
--- /dev/null
+++ b/tests/tests/view/jni/android_view_cts_ASurfaceControlTest.cpp
@@ -0,0 +1,461 @@
+/*
+ * Copyright 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#define LOG_TAG "ASurfaceControlTest"
+
+#include <sys/types.h>
+#include <sys/time.h>
+#include <unistd.h>
+
+#include <array>
+#include <cinttypes>
+#include <string>
+
+#include <android/hardware_buffer.h>
+#include <android/log.h>
+#include <android/native_window_jni.h>
+#include <android/surface_control.h>
+#include <android/sync.h>
+
+#include <jni.h>
+
+namespace {
+
+// Raises a java exception
+static void fail(JNIEnv* env, const char* format, ...) {
+ va_list args;
+
+ va_start(args, format);
+ char* msg;
+ vasprintf(&msg, format, args);
+ va_end(args);
+
+ jclass exClass;
+ const char* className = "java/lang/AssertionError";
+ exClass = env->FindClass(className);
+ env->ThrowNew(exClass, msg);
+ free(msg);
+}
+
+#define ASSERT(condition, format, args...) \
+ if (!(condition)) { \
+ fail(env, format, ##args); \
+ return; \
+ }
+
+static AHardwareBuffer* allocateBuffer(int32_t width, int32_t height) {
+ AHardwareBuffer* buffer = nullptr;
+ AHardwareBuffer_Desc desc = {};
+ desc.width = width;
+ desc.height = height;
+ desc.layers = 1;
+ desc.usage = AHARDWAREBUFFER_USAGE_COMPOSER_OVERLAY | AHARDWAREBUFFER_USAGE_CPU_WRITE_OFTEN;
+ desc.format = AHARDWAREBUFFER_FORMAT_R8G8B8A8_UNORM;
+
+ AHardwareBuffer_allocate(&desc, &buffer);
+
+ return buffer;
+}
+
+static void fillRegion(void* data, int32_t left, int32_t top, int32_t right,
+ int32_t bottom, uint32_t color, uint32_t stride) {
+ uint32_t* ptr = static_cast<uint32_t*>(data);
+
+ ptr += stride * top;
+
+ for (uint32_t y = top; y < bottom; y++) {
+ for (uint32_t x = left; x < right; x++) {
+ ptr[x] = color;
+ }
+ ptr += stride;
+ }
+}
+
+static bool getSolidBuffer(int32_t width, int32_t height, uint32_t color,
+ AHardwareBuffer** outHardwareBuffer,
+ int* outFence) {
+ AHardwareBuffer* buffer = allocateBuffer(width, height);
+ if (!buffer) {
+ return true;
+ }
+
+ AHardwareBuffer_Desc desc = {};
+ AHardwareBuffer_describe(buffer, &desc);
+
+ void* data = nullptr;
+ const ARect rect{0, 0, width, height};
+ AHardwareBuffer_lock(buffer, AHARDWAREBUFFER_USAGE_CPU_WRITE_OFTEN, -1, &rect,
+ &data);
+ if (!data) {
+ return true;
+ }
+
+ fillRegion(data, 0, 0, width, height, color, desc.stride);
+
+ AHardwareBuffer_unlock(buffer, outFence);
+
+ *outHardwareBuffer = buffer;
+ return false;
+}
+
+static bool getQuadrantBuffer(int32_t width, int32_t height, jint colorTopLeft,
+ jint colorTopRight, jint colorBottomRight,
+ jint colorBottomLeft,
+ AHardwareBuffer** outHardwareBuffer,
+ int* outFence) {
+ AHardwareBuffer* buffer = allocateBuffer(width, height);
+ if (!buffer) {
+ return true;
+ }
+
+ AHardwareBuffer_Desc desc = {};
+ AHardwareBuffer_describe(buffer, &desc);
+
+ void* data = nullptr;
+ const ARect rect{0, 0, width, height};
+ AHardwareBuffer_lock(buffer, AHARDWAREBUFFER_USAGE_CPU_WRITE_OFTEN, -1, &rect,
+ &data);
+ if (!data) {
+ return true;
+ }
+
+ fillRegion(data, 0, 0, width / 2, height / 2, colorTopLeft, desc.stride);
+ fillRegion(data, width / 2, 0, width, height / 2, colorTopRight, desc.stride);
+ fillRegion(data, 0, height / 2, width / 2, height, colorBottomLeft,
+ desc.stride);
+ fillRegion(data, width / 2, height / 2, width, height, colorBottomRight,
+ desc.stride);
+
+ AHardwareBuffer_unlock(buffer, outFence);
+
+ *outHardwareBuffer = buffer;
+ return false;
+}
+
+jlong SurfaceTransaction_create(JNIEnv* /*env*/, jclass) {
+ return reinterpret_cast<jlong>(ASurfaceTransaction_create());
+}
+
+void SurfaceTransaction_delete(JNIEnv* /*env*/, jclass, jlong surfaceTransaction) {
+ ASurfaceTransaction_delete(
+ reinterpret_cast<ASurfaceTransaction*>(surfaceTransaction));
+}
+
+void SurfaceTransaction_apply(JNIEnv* /*env*/, jclass, jlong surfaceTransaction) {
+ ASurfaceTransaction_apply(
+ reinterpret_cast<ASurfaceTransaction*>(surfaceTransaction));
+}
+
+long SurfaceControl_createFromWindow(JNIEnv* env, jclass, jobject jSurface) {
+ if (!jSurface) {
+ return 0;
+ }
+
+ ANativeWindow* window = ANativeWindow_fromSurface(env, jSurface);
+ if (!window) {
+ return 0;
+ }
+
+ const std::string debugName = "SurfaceControl_createFromWindowLayer";
+ ASurfaceControl* surfaceControl =
+ ASurfaceControl_createFromWindow(window, debugName.c_str());
+ if (!surfaceControl) {
+ return 0;
+ }
+
+ ANativeWindow_release(window);
+
+ return reinterpret_cast<jlong>(surfaceControl);
+}
+
+jlong SurfaceControl_create(JNIEnv* /*env*/, jclass, jlong parentSurfaceControlId) {
+ ASurfaceControl* surfaceControl = nullptr;
+ const std::string debugName = "SurfaceControl_create";
+
+ surfaceControl = ASurfaceControl_create(
+ reinterpret_cast<ASurfaceControl*>(parentSurfaceControlId),
+ debugName.c_str());
+
+ return reinterpret_cast<jlong>(surfaceControl);
+}
+
+void SurfaceControl_release(JNIEnv* /*env*/, jclass, jlong surfaceControl) {
+ ASurfaceControl_release(reinterpret_cast<ASurfaceControl*>(surfaceControl));
+}
+
+jlong SurfaceTransaction_setSolidBuffer(JNIEnv* /*env*/, jclass,
+ jlong surfaceControl,
+ jlong surfaceTransaction, jint width,
+ jint height, jint color) {
+ AHardwareBuffer* buffer = nullptr;
+ int fence = -1;
+
+ bool err = getSolidBuffer(width, height, color, &buffer, &fence);
+ if (err) {
+ return 0;
+ }
+
+ ASurfaceTransaction_setBuffer(
+ reinterpret_cast<ASurfaceTransaction*>(surfaceTransaction),
+ reinterpret_cast<ASurfaceControl*>(surfaceControl), buffer, fence);
+
+ return reinterpret_cast<jlong>(buffer);
+}
+
+jlong SurfaceTransaction_setQuadrantBuffer(
+ JNIEnv* /*env*/, jclass, jlong surfaceControl, jlong surfaceTransaction,
+ jint width, jint height, jint colorTopLeft, jint colorTopRight,
+ jint colorBottomRight, jint colorBottomLeft) {
+ AHardwareBuffer* buffer = nullptr;
+ int fence = -1;
+
+ bool err =
+ getQuadrantBuffer(width, height, colorTopLeft, colorTopRight,
+ colorBottomRight, colorBottomLeft, &buffer, &fence);
+ if (err) {
+ return 0;
+ }
+
+ ASurfaceTransaction_setBuffer(
+ reinterpret_cast<ASurfaceTransaction*>(surfaceTransaction),
+ reinterpret_cast<ASurfaceControl*>(surfaceControl), buffer, fence);
+
+ return reinterpret_cast<jlong>(buffer);
+}
+
+void SurfaceTransaction_releaseBuffer(JNIEnv* /*env*/, jclass, jlong buffer) {
+ AHardwareBuffer_release(reinterpret_cast<AHardwareBuffer*>(buffer));
+}
+
+void SurfaceTransaction_setVisibility(JNIEnv* /*env*/, jclass,
+ jlong surfaceControl,
+ jlong surfaceTransaction, jboolean show) {
+ int8_t visibility = (show) ? ASURFACE_TRANSACTION_VISIBILITY_SHOW :
+ ASURFACE_TRANSACTION_VISIBILITY_HIDE;
+ ASurfaceTransaction_setVisibility(
+ reinterpret_cast<ASurfaceTransaction*>(surfaceTransaction),
+ reinterpret_cast<ASurfaceControl*>(surfaceControl), visibility);
+}
+
+void SurfaceTransaction_setBufferOpaque(JNIEnv* /*env*/, jclass,
+ jlong surfaceControl,
+ jlong surfaceTransaction,
+ jboolean opaque) {
+ int8_t transparency = (opaque) ? ASURFACE_TRANSACTION_TRANSPARENCY_OPAQUE :
+ ASURFACE_TRANSACTION_TRANSPARENCY_TRANSPARENT;
+ ASurfaceTransaction_setBufferTransparency(
+ reinterpret_cast<ASurfaceTransaction*>(surfaceTransaction),
+ reinterpret_cast<ASurfaceControl*>(surfaceControl), transparency);
+}
+
+void SurfaceTransaction_setGeometry(JNIEnv* /*env*/, jclass,
+ jlong surfaceControl,
+ jlong surfaceTransaction,
+ jint srcLeft, jint srcTop, jint srcRight, jint srcBottom,
+ jint dstLeft, jint dstTop, jint dstRight, jint dstBottom,
+ jint transform) {
+ const ARect src{srcLeft, srcTop, srcRight, srcBottom};
+ const ARect dst{dstLeft, dstTop, dstRight, dstBottom};
+ ASurfaceTransaction_setGeometry(
+ reinterpret_cast<ASurfaceTransaction*>(surfaceTransaction),
+ reinterpret_cast<ASurfaceControl*>(surfaceControl), src, dst, transform);
+}
+
+void SurfaceTransaction_setDamageRegion(JNIEnv* /*env*/, jclass,
+ jlong surfaceControl,
+ jlong surfaceTransaction, jint left,
+ jint top, jint right, jint bottom) {
+ const ARect rect[] = {{left, top, right, bottom}};
+ ASurfaceTransaction_setDamageRegion(
+ reinterpret_cast<ASurfaceTransaction*>(surfaceTransaction),
+ reinterpret_cast<ASurfaceControl*>(surfaceControl), rect, 1);
+}
+
+void SurfaceTransaction_setZOrder(JNIEnv* /*env*/, jclass, jlong surfaceControl,
+ jlong surfaceTransaction, jint z) {
+ ASurfaceTransaction_setZOrder(
+ reinterpret_cast<ASurfaceTransaction*>(surfaceTransaction),
+ reinterpret_cast<ASurfaceControl*>(surfaceControl), z);
+}
+
+static void onComplete(void* context, ASurfaceTransactionStats* stats) {
+ if (!stats) {
+ return;
+ }
+
+ int64_t latchTime = ASurfaceTransactionStats_getLatchTime(stats);
+ if (latchTime < 0) {
+ return;
+ }
+
+ ASurfaceControl** surfaceControls = nullptr;
+ size_t surfaceControlsSize = 0;
+ ASurfaceTransactionStats_getASurfaceControls(stats, &surfaceControls, &surfaceControlsSize);
+
+ for (int i = 0; i < surfaceControlsSize; i++) {
+ ASurfaceControl* surfaceControl = surfaceControls[i];
+
+ int64_t acquireTime = ASurfaceTransactionStats_getAcquireTime(stats, surfaceControl);
+ if (acquireTime < -1) {
+ return;
+ }
+
+ int previousReleaseFence = ASurfaceTransactionStats_getPreviousReleaseFenceFd(
+ stats, surfaceControl);
+ close(previousReleaseFence);
+ }
+
+ int presentFence = ASurfaceTransactionStats_getPresentFenceFd(stats);
+
+ if (!context) {
+ close(presentFence);
+ return;
+ }
+
+ int* contextIntPtr = reinterpret_cast<int*>(context);
+ contextIntPtr[0]++;
+ contextIntPtr[1] = presentFence;
+}
+
+jlong SurfaceTransaction_setOnComplete(JNIEnv* /*env*/, jclass, jlong surfaceTransaction) {
+ int* context = new int[2];
+ context[0] = 0;
+ context[1] = -1;
+
+ ASurfaceTransaction_setOnComplete(
+ reinterpret_cast<ASurfaceTransaction*>(surfaceTransaction),
+ reinterpret_cast<void*>(context), onComplete);
+ return reinterpret_cast<jlong>(context);
+}
+
+void SurfaceTransaction_checkOnComplete(JNIEnv* env, jclass, jlong context,
+ jlong desiredPresentTime) {
+ ASSERT(context != 0, "invalid context")
+
+ int* contextPtr = reinterpret_cast<int*>(context);
+ int data = contextPtr[0];
+ int presentFence = contextPtr[1];
+
+ delete[] contextPtr;
+
+ if (desiredPresentTime < 0) {
+ close(presentFence);
+ ASSERT(data >= 1, "did not receive a callback")
+ ASSERT(data <= 1, "received too many callbacks")
+ return;
+ }
+
+ struct sync_file_info* syncFileInfo = sync_file_info(presentFence);
+ ASSERT(syncFileInfo, "invalid fence")
+
+ if (syncFileInfo->status != 1) {
+ sync_file_info_free(syncFileInfo);
+ ASSERT(syncFileInfo->status == 1, "fence did not signal")
+ }
+
+ uint64_t presentTime = 0;
+ struct sync_fence_info* syncFenceInfo = sync_get_fence_info(syncFileInfo);
+ for (size_t i = 0; i < syncFileInfo->num_fences; i++) {
+ if (syncFenceInfo[i].timestamp_ns > presentTime) {
+ presentTime = syncFenceInfo[i].timestamp_ns;
+ }
+ }
+
+ sync_file_info_free(syncFileInfo);
+ close(presentFence);
+
+ // In the worst case the worst present time should be no more than three frames off from the
+ // desired present time. Since the test case is using a virtual display and there are no
+ // requirements for virtual display refresh rate timing, lets assume a refresh rate of 16fps.
+ ASSERT(presentTime < desiredPresentTime + 0.188 * 1e9, "transaction was presented too late");
+ ASSERT(presentTime >= desiredPresentTime, "transaction was presented too early");
+
+ ASSERT(data >= 1, "did not receive a callback")
+ ASSERT(data <= 1, "received too many callbacks")
+}
+
+jlong SurfaceTransaction_setDesiredPresentTime(JNIEnv* /*env*/, jclass, jlong surfaceTransaction,
+ jlong desiredPresentTimeOffset) {
+ struct timespec t;
+ t.tv_sec = t.tv_nsec = 0;
+ clock_gettime(CLOCK_MONOTONIC, &t);
+ int64_t currentTime = ((int64_t) t.tv_sec)*1000000000LL + t.tv_nsec;
+
+ int64_t desiredPresentTime = currentTime + desiredPresentTimeOffset;
+
+ ASurfaceTransaction_setDesiredPresentTime(
+ reinterpret_cast<ASurfaceTransaction*>(surfaceTransaction), desiredPresentTime);
+
+ return desiredPresentTime;
+}
+
+void SurfaceTransaction_setBufferAlpha(JNIEnv* /*env*/, jclass,
+ jlong surfaceControl,
+ jlong surfaceTransaction, jdouble alpha) {
+ ASurfaceTransaction_setBufferAlpha(
+ reinterpret_cast<ASurfaceTransaction*>(surfaceTransaction),
+ reinterpret_cast<ASurfaceControl*>(surfaceControl), alpha);
+}
+
+void SurfaceTransaction_reparent(JNIEnv* /*env*/, jclass, jlong surfaceControl,
+ jlong newParentSurfaceControl, jlong surfaceTransaction) {
+ ASurfaceTransaction_reparent(
+ reinterpret_cast<ASurfaceTransaction*>(surfaceTransaction),
+ reinterpret_cast<ASurfaceControl*>(surfaceControl),
+ reinterpret_cast<ASurfaceControl*>(newParentSurfaceControl));
+}
+
+void SurfaceTransaction_setColor(JNIEnv* /*env*/, jclass, jlong surfaceControl,
+ jlong surfaceTransaction, jfloat r,
+ jfloat g, jfloat b, jfloat alpha) {
+ ASurfaceTransaction_setColor(
+ reinterpret_cast<ASurfaceTransaction*>(surfaceTransaction),
+ reinterpret_cast<ASurfaceControl*>(surfaceControl),
+ r, g, b, alpha, ADATASPACE_UNKNOWN);
+}
+
+const std::array<JNINativeMethod, 20> JNI_METHODS = {{
+ {"nSurfaceTransaction_create", "()J", (void*)SurfaceTransaction_create},
+ {"nSurfaceTransaction_delete", "(J)V", (void*)SurfaceTransaction_delete},
+ {"nSurfaceTransaction_apply", "(J)V", (void*)SurfaceTransaction_apply},
+ {"nSurfaceControl_createFromWindow", "(Landroid/view/Surface;)J",
+ (void*)SurfaceControl_createFromWindow},
+ {"nSurfaceControl_create", "(J)J", (void*)SurfaceControl_create},
+ {"nSurfaceControl_release", "(J)V", (void*)SurfaceControl_release},
+ {"nSurfaceTransaction_setSolidBuffer", "(JJIII)J", (void*)SurfaceTransaction_setSolidBuffer},
+ {"nSurfaceTransaction_setQuadrantBuffer", "(JJIIIIII)J",
+ (void*)SurfaceTransaction_setQuadrantBuffer},
+ {"nSurfaceTransaction_releaseBuffer", "(J)V", (void*)SurfaceTransaction_releaseBuffer},
+ {"nSurfaceTransaction_setVisibility", "(JJZ)V", (void*)SurfaceTransaction_setVisibility},
+ {"nSurfaceTransaction_setBufferOpaque", "(JJZ)V", (void*)SurfaceTransaction_setBufferOpaque},
+ {"nSurfaceTransaction_setGeometry", "(JJIIIIIIIII)V", (void*)SurfaceTransaction_setGeometry},
+ {"nSurfaceTransaction_setDamageRegion", "(JJIIII)V", (void*)SurfaceTransaction_setDamageRegion},
+ {"nSurfaceTransaction_setZOrder", "(JJI)V", (void*)SurfaceTransaction_setZOrder},
+ {"nSurfaceTransaction_setOnComplete", "(J)J", (void*)SurfaceTransaction_setOnComplete},
+ {"nSurfaceTransaction_checkOnComplete", "(JJ)V", (void*)SurfaceTransaction_checkOnComplete},
+ {"nSurfaceTransaction_setDesiredPresentTime", "(JJ)J",
+ (void*)SurfaceTransaction_setDesiredPresentTime},
+ {"nSurfaceTransaction_setBufferAlpha", "(JJD)V", (void*)SurfaceTransaction_setBufferAlpha},
+ {"nSurfaceTransaction_reparent", "(JJJ)V", (void*)SurfaceTransaction_reparent},
+ {"nSurfaceTransaction_setColor", "(JJFFFF)V", (void*)SurfaceTransaction_setColor},
+}};
+
+} // anonymous namespace
+
+jint register_android_view_cts_ASurfaceControlTest(JNIEnv* env) {
+ jclass clazz = env->FindClass("android/view/cts/ASurfaceControlTest");
+ return env->RegisterNatives(clazz, JNI_METHODS.data(), JNI_METHODS.size());
+}
diff --git a/tests/tests/view/src/android/view/cts/ASurfaceControlTest.java b/tests/tests/view/src/android/view/cts/ASurfaceControlTest.java
new file mode 100644
index 0000000..eb9f513
--- /dev/null
+++ b/tests/tests/view/src/android/view/cts/ASurfaceControlTest.java
@@ -0,0 +1,1356 @@
+/*
+ * Copyright 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.view.cts;
+
+import static org.junit.Assert.assertTrue;
+
+import android.animation.ObjectAnimator;
+import android.animation.PropertyValuesHolder;
+import android.animation.ValueAnimator;
+import android.support.test.rule.ActivityTestRule;
+import android.support.test.runner.AndroidJUnit4;
+import android.support.test.uiautomator.UiObjectNotFoundException;
+import android.test.suitebuilder.annotation.LargeTest;
+import android.util.Log;
+import android.view.Surface;
+import android.view.SurfaceHolder;
+import android.view.View;
+import android.view.animation.LinearInterpolator;
+import android.view.cts.surfacevalidator.AnimationFactory;
+import android.view.cts.surfacevalidator.CapturedActivity;
+import android.view.cts.surfacevalidator.PixelChecker;
+import android.view.cts.surfacevalidator.PixelColor;
+import android.view.cts.surfacevalidator.SurfaceControlTestCase;
+
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.rules.TestName;
+import org.junit.runner.RunWith;
+
+import java.util.HashSet;
+import java.util.Set;
+
+@LargeTest
+@RunWith(AndroidJUnit4.class)
+public class ASurfaceControlTest {
+ static {
+ System.loadLibrary("ctsview_jni");
+ }
+
+ private static final String TAG = ASurfaceControlTest.class.getSimpleName();
+ private static final boolean DEBUG = false;
+
+ private static final int DEFAULT_LAYOUT_WIDTH = 100;
+ private static final int DEFAULT_LAYOUT_HEIGHT = 100;
+ private static final int DEFAULT_BUFFER_WIDTH = 640;
+ private static final int DEFAULT_BUFFER_HEIGHT = 480;
+
+ @Rule
+ public ActivityTestRule<CapturedActivity> mActivityRule =
+ new ActivityTestRule<>(CapturedActivity.class);
+
+ @Rule
+ public TestName mName = new TestName();
+
+ private CapturedActivity mActivity;
+
+ @Before
+ public void setup() {
+ mActivity = mActivityRule.getActivity();
+ }
+
+ /**
+ * Want to be especially sure we don't leave up the permission dialog, so try and dismiss
+ * after test.
+ */
+ @After
+ public void tearDown() throws UiObjectNotFoundException {
+ mActivity.dismissPermissionDialog();
+ }
+
+ ///////////////////////////////////////////////////////////////////////////
+ // SurfaceHolder.Callbacks
+ ///////////////////////////////////////////////////////////////////////////
+
+ private abstract class BasicSurfaceHolderCallback implements SurfaceHolder.Callback {
+ private Set<Long> mSurfaceControls = new HashSet<Long>();
+ private Set<Long> mBuffers = new HashSet<Long>();
+
+ @Override
+ public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {}
+
+ @Override
+ public void surfaceDestroyed(SurfaceHolder holder) {
+ for (Long surfaceControl : mSurfaceControls) {
+ reparent(surfaceControl, 0);
+ nSurfaceControl_release(surfaceControl);
+ }
+ mSurfaceControls.clear();
+
+ for (Long buffer : mBuffers) {
+ nSurfaceTransaction_releaseBuffer(buffer);
+ }
+ mBuffers.clear();
+ }
+
+ public long createSurfaceTransaction() {
+ long surfaceTransaction = nSurfaceTransaction_create();
+ assertTrue("failed to create surface transaction", surfaceTransaction != 0);
+ return surfaceTransaction;
+ }
+
+ public void applySurfaceTransaction(long surfaceTransaction) {
+ nSurfaceTransaction_apply(surfaceTransaction);
+ }
+
+ public void deleteSurfaceTransaction(long surfaceTransaction) {
+ nSurfaceTransaction_delete(surfaceTransaction);
+ }
+
+ public void applyAndDeleteSurfaceTransaction(long surfaceTransaction) {
+ nSurfaceTransaction_apply(surfaceTransaction);
+ nSurfaceTransaction_delete(surfaceTransaction);
+ }
+
+ public long createFromWindow(Surface surface) {
+ long surfaceControl = nSurfaceControl_createFromWindow(surface);
+ assertTrue("failed to create surface control", surfaceControl != 0);
+
+ mSurfaceControls.add(surfaceControl);
+ return surfaceControl;
+ }
+
+ public long create(long parentSurfaceControl) {
+ long childSurfaceControl = nSurfaceControl_create(parentSurfaceControl);
+ assertTrue("failed to create child surface control", childSurfaceControl != 0);
+
+ mSurfaceControls.add(childSurfaceControl);
+ return childSurfaceControl;
+ }
+
+ public void setSolidBuffer(
+ long surfaceControl, long surfaceTransaction, int width, int height, int color) {
+ long buffer = nSurfaceTransaction_setSolidBuffer(
+ surfaceControl, surfaceTransaction, width, height, color);
+ assertTrue("failed to set buffer", buffer != 0);
+ mBuffers.add(buffer);
+ }
+
+ public void setSolidBuffer(long surfaceControl, int width, int height, int color) {
+ long surfaceTransaction = createSurfaceTransaction();
+ setSolidBuffer(surfaceControl, surfaceTransaction, width, height, color);
+ applyAndDeleteSurfaceTransaction(surfaceTransaction);
+ }
+
+ public void setQuadrantBuffer(long surfaceControl, long surfaceTransaction, int width,
+ int height, int colorTopLeft, int colorTopRight, int colorBottomRight,
+ int colorBottomLeft) {
+ long buffer = nSurfaceTransaction_setQuadrantBuffer(surfaceControl, surfaceTransaction,
+ width, height, colorTopLeft, colorTopRight, colorBottomRight, colorBottomLeft);
+ assertTrue("failed to set buffer", buffer != 0);
+ mBuffers.add(buffer);
+ }
+
+ public void setQuadrantBuffer(long surfaceControl, int width, int height, int colorTopLeft,
+ int colorTopRight, int colorBottomRight, int colorBottomLeft) {
+ long surfaceTransaction = createSurfaceTransaction();
+ setQuadrantBuffer(surfaceControl, surfaceTransaction, width, height, colorTopLeft,
+ colorTopRight, colorBottomRight, colorBottomLeft);
+ applyAndDeleteSurfaceTransaction(surfaceTransaction);
+ }
+
+ public void setVisibility(long surfaceControl, long surfaceTransaction, boolean visible) {
+ nSurfaceTransaction_setVisibility(surfaceControl, surfaceTransaction, visible);
+ }
+
+ public void setVisibility(long surfaceControl, boolean visible) {
+ long surfaceTransaction = createSurfaceTransaction();
+ setVisibility(surfaceControl, surfaceTransaction, visible);
+ applyAndDeleteSurfaceTransaction(surfaceTransaction);
+ }
+
+ public void setBufferOpaque(long surfaceControl, long surfaceTransaction, boolean opaque) {
+ nSurfaceTransaction_setBufferOpaque(surfaceControl, surfaceTransaction, opaque);
+ }
+
+ public void setBufferOpaque(long surfaceControl, boolean opaque) {
+ long surfaceTransaction = createSurfaceTransaction();
+ setBufferOpaque(surfaceControl, surfaceTransaction, opaque);
+ applyAndDeleteSurfaceTransaction(surfaceTransaction);
+ }
+
+ public void setGeometry(long surfaceControl, long surfaceTransaction, int srcLeft,
+ int srcTop, int srcRight, int srcBottom, int dstLeft, int dstTop, int dstRight,
+ int dstBottom, int transform) {
+ nSurfaceTransaction_setGeometry(
+ surfaceControl, surfaceTransaction, srcLeft, srcTop, srcRight, srcBottom,
+ dstLeft, dstTop, dstRight, dstBottom, transform);
+ }
+
+ public void setGeometry(long surfaceControl, int srcLeft, int srcTop, int srcRight,
+ int srcBottom, int dstLeft, int dstTop, int dstRight, int dstBottom,
+ int transform) {
+ long surfaceTransaction = createSurfaceTransaction();
+ setGeometry(surfaceControl, surfaceTransaction, srcLeft, srcTop, srcRight, srcBottom,
+ dstLeft, dstTop, dstRight, dstBottom, transform);
+ applyAndDeleteSurfaceTransaction(surfaceTransaction);
+ }
+
+ public void setDamageRegion(long surfaceControl, long surfaceTransaction, int left, int top,
+ int right, int bottom) {
+ nSurfaceTransaction_setDamageRegion(
+ surfaceControl, surfaceTransaction, left, top, right, bottom);
+ }
+
+ public void setDamageRegion(long surfaceControl, int left, int top, int right, int bottom) {
+ long surfaceTransaction = createSurfaceTransaction();
+ setDamageRegion(surfaceControl, surfaceTransaction, left, top, right, bottom);
+ applyAndDeleteSurfaceTransaction(surfaceTransaction);
+ }
+
+ public void setZOrder(long surfaceControl, long surfaceTransaction, int z) {
+ nSurfaceTransaction_setZOrder(surfaceControl, surfaceTransaction, z);
+ }
+
+ public void setZOrder(long surfaceControl, int z) {
+ long surfaceTransaction = createSurfaceTransaction();
+ setZOrder(surfaceControl, surfaceTransaction, z);
+ applyAndDeleteSurfaceTransaction(surfaceTransaction);
+ }
+
+ public void setBufferAlpha(long surfaceControl, long surfaceTransaction, double alpha) {
+ nSurfaceTransaction_setBufferAlpha(surfaceControl, surfaceTransaction, alpha);
+ }
+
+ public void setBufferAlpha(long surfaceControl, double alpha) {
+ long surfaceTransaction = createSurfaceTransaction();
+ setBufferAlpha(surfaceControl, surfaceTransaction, alpha);
+ applyAndDeleteSurfaceTransaction(surfaceTransaction);
+ }
+
+ public void reparent(long surfaceControl, long newParentSurfaceControl,
+ long surfaceTransaction) {
+ nSurfaceTransaction_reparent(surfaceControl, newParentSurfaceControl,
+ surfaceTransaction);
+ }
+
+ public void reparent(long surfaceControl, long newParentSurfaceControl) {
+ long surfaceTransaction = createSurfaceTransaction();
+ reparent(surfaceControl, newParentSurfaceControl, surfaceTransaction);
+ applyAndDeleteSurfaceTransaction(surfaceTransaction);
+ }
+ }
+
+ ///////////////////////////////////////////////////////////////////////////
+ // AnimationFactories
+ ///////////////////////////////////////////////////////////////////////////
+
+ private static ValueAnimator makeInfinite(ValueAnimator a) {
+ a.setRepeatMode(ObjectAnimator.REVERSE);
+ a.setRepeatCount(ObjectAnimator.INFINITE);
+ a.setDuration(200);
+ a.setInterpolator(new LinearInterpolator());
+ return a;
+ }
+
+ private static AnimationFactory sTranslateAnimationFactory = view -> {
+ PropertyValuesHolder pvhX = PropertyValuesHolder.ofFloat(View.TRANSLATION_X, 10f, 30f);
+ PropertyValuesHolder pvhY = PropertyValuesHolder.ofFloat(View.TRANSLATION_Y, 10f, 30f);
+ return makeInfinite(ObjectAnimator.ofPropertyValuesHolder(view, pvhX, pvhY));
+ };
+
+ ///////////////////////////////////////////////////////////////////////////
+ // Tests
+ ///////////////////////////////////////////////////////////////////////////
+
+ private void verifyTest(SurfaceHolder.Callback callback, PixelChecker pixelChecker)
+ throws Throwable {
+ mActivity.verifyTest(new SurfaceControlTestCase(callback, sTranslateAnimationFactory,
+ pixelChecker,
+ DEFAULT_LAYOUT_WIDTH, DEFAULT_LAYOUT_HEIGHT,
+ DEFAULT_BUFFER_WIDTH, DEFAULT_BUFFER_HEIGHT),
+ mName);
+ }
+
+ @Test
+ public void testSurfaceTransaction_create() {
+ mActivity.dismissPermissionDialog();
+
+ long surfaceTransaction = nSurfaceTransaction_create();
+ assertTrue("failed to create surface transaction", surfaceTransaction != 0);
+
+ nSurfaceTransaction_delete(surfaceTransaction);
+ }
+
+ @Test
+ public void testSurfaceTransaction_apply() {
+ mActivity.dismissPermissionDialog();
+
+ long surfaceTransaction = nSurfaceTransaction_create();
+ assertTrue("failed to create surface transaction", surfaceTransaction != 0);
+
+ Log.e("Transaction", "created: " + surfaceTransaction);
+
+ nSurfaceTransaction_apply(surfaceTransaction);
+ nSurfaceTransaction_delete(surfaceTransaction);
+ }
+
+ // INTRO: The following tests run a series of commands and verify the
+ // output based on the number of pixels with a certain color on the display.
+ //
+ // The interface being tested is a NDK api but the only way to record the display
+ // through public apis is in through the SDK. So the test logic and test verification
+ // is in Java but the hooks that call into the NDK api are jni code.
+ //
+ // The set up is done during the surfaceCreated callback. In most cases, the
+ // test uses the opportunity to create a child layer through createFromWindow and
+ // performs operations on the child layer.
+ //
+ // When there is no visible buffer for the layer(s) the color defaults to black.
+ // The test cases allow a +/- 10% error rate. This is based on the error
+ // rate allowed in the SurfaceViewSyncTests
+
+ @Test
+ public void testSurfaceControl_createFromWindow() throws Throwable {
+ verifyTest(
+ new BasicSurfaceHolderCallback() {
+ @Override
+ public void surfaceCreated(SurfaceHolder holder) {
+ long surfaceControl = createFromWindow(holder.getSurface());
+ }
+ },
+ new PixelChecker(PixelColor.BLACK) { //10000
+ @Override
+ public boolean checkPixels(int pixelCount, int width, int height) {
+ return pixelCount > 9000 && pixelCount < 11000;
+ }
+ });
+ }
+
+ @Test
+ public void testSurfaceControl_create() throws Throwable {
+ verifyTest(
+ new BasicSurfaceHolderCallback() {
+ @Override
+ public void surfaceCreated(SurfaceHolder holder) {
+ long parentSurfaceControl = createFromWindow(holder.getSurface());
+ long childSurfaceControl = create(parentSurfaceControl);
+ }
+ },
+ new PixelChecker(PixelColor.BLACK) { //10000
+ @Override
+ public boolean checkPixels(int pixelCount, int width, int height) {
+ return pixelCount > 9000 && pixelCount < 11000;
+ }
+ });
+ }
+
+ @Test
+ public void testSurfaceTransaction_setBuffer() throws Throwable {
+ verifyTest(
+ new BasicSurfaceHolderCallback() {
+ @Override
+ public void surfaceCreated(SurfaceHolder holder) {
+ long surfaceControl = createFromWindow(holder.getSurface());
+ setSolidBuffer(surfaceControl, DEFAULT_LAYOUT_WIDTH, DEFAULT_LAYOUT_HEIGHT,
+ PixelColor.RED);
+ }
+ },
+ new PixelChecker(PixelColor.RED) { //10000
+ @Override
+ public boolean checkPixels(int pixelCount, int width, int height) {
+ return pixelCount > 9000 && pixelCount < 11000;
+ }
+ });
+ }
+
+ @Test
+ public void testSurfaceTransaction_setBuffer_parentAndChild() throws Throwable {
+ verifyTest(
+ new BasicSurfaceHolderCallback() {
+ @Override
+ public void surfaceCreated(SurfaceHolder holder) {
+ long parentSurfaceControl = createFromWindow(holder.getSurface());
+ long childSurfaceControl = create(parentSurfaceControl);
+
+ setSolidBuffer(parentSurfaceControl, DEFAULT_LAYOUT_WIDTH,
+ DEFAULT_LAYOUT_HEIGHT, PixelColor.BLUE);
+ setSolidBuffer(childSurfaceControl, DEFAULT_LAYOUT_WIDTH,
+ DEFAULT_LAYOUT_HEIGHT, PixelColor.RED);
+ }
+ },
+ new PixelChecker(PixelColor.RED) { //10000
+ @Override
+ public boolean checkPixels(int pixelCount, int width, int height) {
+ return pixelCount > 9000 && pixelCount < 11000;
+ }
+ });
+ }
+
+ @Test
+ public void testSurfaceTransaction_setBuffer_childOnly() throws Throwable {
+ verifyTest(
+ new BasicSurfaceHolderCallback() {
+ @Override
+ public void surfaceCreated(SurfaceHolder holder) {
+ long parentSurfaceControl = createFromWindow(holder.getSurface());
+ long childSurfaceControl = create(parentSurfaceControl);
+
+ setSolidBuffer(childSurfaceControl, DEFAULT_LAYOUT_WIDTH,
+ DEFAULT_LAYOUT_HEIGHT, PixelColor.RED);
+ }
+ },
+ new PixelChecker(PixelColor.RED) { //10000
+ @Override
+ public boolean checkPixels(int pixelCount, int width, int height) {
+ return pixelCount > 9000 && pixelCount < 11000;
+ }
+ });
+ }
+
+ @Test
+ public void testSurfaceTransaction_setVisibility_show() throws Throwable {
+ verifyTest(
+ new BasicSurfaceHolderCallback() {
+ @Override
+ public void surfaceCreated(SurfaceHolder holder) {
+ long surfaceControl = createFromWindow(holder.getSurface());
+
+ setSolidBuffer(surfaceControl, DEFAULT_LAYOUT_WIDTH, DEFAULT_LAYOUT_HEIGHT,
+ PixelColor.RED);
+ setVisibility(surfaceControl, true);
+ }
+ },
+ new PixelChecker(PixelColor.RED) { //10000
+ @Override
+ public boolean checkPixels(int pixelCount, int width, int height) {
+ return pixelCount > 9000 && pixelCount < 11000;
+ }
+ });
+ }
+
+ @Test
+ public void testSurfaceTransaction_setVisibility_hide() throws Throwable {
+ verifyTest(
+ new BasicSurfaceHolderCallback() {
+ @Override
+ public void surfaceCreated(SurfaceHolder holder) {
+ long surfaceControl = createFromWindow(holder.getSurface());
+
+ setSolidBuffer(surfaceControl, DEFAULT_LAYOUT_WIDTH, DEFAULT_LAYOUT_HEIGHT,
+ PixelColor.RED);
+ setVisibility(surfaceControl, false);
+ }
+ },
+ new PixelChecker(PixelColor.BLACK) { //10000
+ @Override
+ public boolean checkPixels(int pixelCount, int width, int height) {
+ return pixelCount > 9000 && pixelCount < 11000;
+ }
+ });
+ }
+
+ @Test
+ public void testSurfaceTransaction_setBufferOpaque_opaque() throws Throwable {
+ verifyTest(
+ new BasicSurfaceHolderCallback() {
+ @Override
+ public void surfaceCreated(SurfaceHolder holder) {
+ long surfaceControl = createFromWindow(holder.getSurface());
+
+ setSolidBuffer(surfaceControl, DEFAULT_LAYOUT_WIDTH, DEFAULT_LAYOUT_HEIGHT,
+ PixelColor.RED);
+ setBufferOpaque(surfaceControl, true);
+ }
+ },
+ new PixelChecker(PixelColor.RED) { //10000
+ @Override
+ public boolean checkPixels(int pixelCount, int width, int height) {
+ return pixelCount > 9000 && pixelCount < 11000;
+ }
+ });
+ }
+
+ @Test
+ public void testSurfaceTransaction_setBufferOpaque_transparent() throws Throwable {
+ verifyTest(
+ new BasicSurfaceHolderCallback() {
+ @Override
+ public void surfaceCreated(SurfaceHolder holder) {
+ long surfaceControl = createFromWindow(holder.getSurface());
+
+ setSolidBuffer(surfaceControl, DEFAULT_LAYOUT_WIDTH, DEFAULT_LAYOUT_HEIGHT,
+ PixelColor.TRANSPARENT_RED);
+ setBufferOpaque(surfaceControl, false);
+ }
+ },
+ // setBufferOpaque is an optimization that can be used by SurfaceFlinger.
+ // It isn't required to affect SurfaceFlinger's behavior.
+ //
+ // Ideally we would check for a specific blending of red with a layer below
+ // it. Unfortunately we don't know what blending the layer will use and
+ // we don't know what variation the GPU/DPU/blitter might have. Although
+ // we don't know what shade of red might be present, we can at least check
+ // that the optimization doesn't cause the framework to drop the buffer entirely.
+ new PixelChecker(PixelColor.BLACK) {
+ @Override
+ public boolean checkPixels(int pixelCount, int width, int height) {
+ return pixelCount == 0;
+ }
+ });
+ }
+
+ @Test
+ public void testSurfaceTransaction_setDestinationRect() throws Throwable {
+ verifyTest(
+ new BasicSurfaceHolderCallback() {
+ @Override
+ public void surfaceCreated(SurfaceHolder holder) {
+ long surfaceControl = createFromWindow(holder.getSurface());
+
+ setSolidBuffer(surfaceControl, DEFAULT_LAYOUT_WIDTH, DEFAULT_LAYOUT_HEIGHT,
+ PixelColor.RED);
+ setGeometry(surfaceControl, 0, 0, 100, 100, 0, 0, 640, 480, 0);
+ }
+ },
+ new PixelChecker(PixelColor.RED) { //10000
+ @Override
+ public boolean checkPixels(int pixelCount, int width, int height) {
+ return pixelCount > 9000 && pixelCount < 11000;
+ }
+ });
+ }
+
+ @Test
+ public void testSurfaceTransaction_setDestinationRect_small() throws Throwable {
+ verifyTest(
+ new BasicSurfaceHolderCallback() {
+ @Override
+ public void surfaceCreated(SurfaceHolder holder) {
+ long surfaceControl = createFromWindow(holder.getSurface());
+
+ setSolidBuffer(surfaceControl, DEFAULT_LAYOUT_WIDTH, DEFAULT_LAYOUT_HEIGHT,
+ PixelColor.RED);
+ setGeometry(surfaceControl, 0, 0, 100, 100, 64, 48, 320, 240, 0);
+ }
+ },
+ new PixelChecker(PixelColor.RED) { //1600
+ @Override
+ public boolean checkPixels(int pixelCount, int width, int height) {
+ return pixelCount > 1440 && pixelCount < 1760;
+ }
+ });
+ }
+
+ @Test
+ public void testSurfaceTransaction_setDestinationRect_childSmall() throws Throwable {
+ verifyTest(
+ new BasicSurfaceHolderCallback() {
+ @Override
+ public void surfaceCreated(SurfaceHolder holder) {
+ long parentSurfaceControl = createFromWindow(holder.getSurface());
+ long childSurfaceControl = create(parentSurfaceControl);
+
+ setSolidBuffer(childSurfaceControl, DEFAULT_LAYOUT_WIDTH,
+ DEFAULT_LAYOUT_HEIGHT, PixelColor.RED);
+ setGeometry(childSurfaceControl, 0, 0, 100, 100, 64, 48, 320, 240, 0);
+ }
+ },
+ new PixelChecker(PixelColor.RED) { //1600
+ @Override
+ public boolean checkPixels(int pixelCount, int width, int height) {
+ return pixelCount > 1440 && pixelCount < 1760;
+ }
+ });
+ }
+
+ @Test
+ public void testSurfaceTransaction_setDestinationRect_extraLarge() throws Throwable {
+ verifyTest(
+ new BasicSurfaceHolderCallback() {
+ @Override
+ public void surfaceCreated(SurfaceHolder holder) {
+ long surfaceControl = createFromWindow(holder.getSurface());
+
+ setSolidBuffer(surfaceControl, DEFAULT_LAYOUT_WIDTH, DEFAULT_LAYOUT_HEIGHT,
+ PixelColor.RED);
+ setGeometry(surfaceControl, 0, 0, 100, 100, -100, -100, 740, 580, 0);
+ }
+ },
+ new PixelChecker(PixelColor.RED) { //10000
+ @Override
+ public boolean checkPixels(int pixelCount, int width, int height) {
+ return pixelCount > 9000 && pixelCount < 11000;
+ }
+ });
+ }
+
+ @Test
+ public void testSurfaceTransaction_setDestinationRect_childExtraLarge() throws Throwable {
+ verifyTest(
+ new BasicSurfaceHolderCallback() {
+ @Override
+ public void surfaceCreated(SurfaceHolder holder) {
+ long parentSurfaceControl = createFromWindow(holder.getSurface());
+ long childSurfaceControl = create(parentSurfaceControl);
+
+ setSolidBuffer(childSurfaceControl, DEFAULT_LAYOUT_WIDTH,
+ DEFAULT_LAYOUT_HEIGHT, PixelColor.RED);
+ setGeometry(childSurfaceControl, 0, 0, 100, 100, -100, -100, 740, 580, 0);
+ }
+ },
+ new PixelChecker(PixelColor.RED) { //10000
+ @Override
+ public boolean checkPixels(int pixelCount, int width, int height) {
+ return pixelCount > 9000 && pixelCount < 11000;
+ }
+ });
+ }
+
+ @Test
+ public void testSurfaceTransaction_setDestinationRect_negativeOffset() throws Throwable {
+ verifyTest(
+ new BasicSurfaceHolderCallback() {
+ @Override
+ public void surfaceCreated(SurfaceHolder holder) {
+ long surfaceControl = createFromWindow(holder.getSurface());
+
+ setSolidBuffer(surfaceControl, DEFAULT_LAYOUT_WIDTH, DEFAULT_LAYOUT_HEIGHT,
+ PixelColor.RED);
+ setGeometry(surfaceControl, 0, 0, 100, 100, -32, -24, 320, 240, 0);
+ }
+ },
+ new PixelChecker(PixelColor.RED) { //2500
+ @Override
+ public boolean checkPixels(int pixelCount, int width, int height) {
+ return pixelCount > 2250 && pixelCount < 2750;
+ }
+ });
+ }
+
+ @Test
+ public void testSurfaceTransaction_setDestinationRect_outOfParentBounds() throws Throwable {
+ verifyTest(
+ new BasicSurfaceHolderCallback() {
+ @Override
+ public void surfaceCreated(SurfaceHolder holder) {
+ long surfaceControl = createFromWindow(holder.getSurface());
+
+ setSolidBuffer(surfaceControl, DEFAULT_LAYOUT_WIDTH, DEFAULT_LAYOUT_HEIGHT,
+ PixelColor.RED);
+ setGeometry(surfaceControl, 0, 0, 100, 100, 320, 240, 704, 504, 0);
+ }
+ },
+ new PixelChecker(PixelColor.RED) { //2500
+ @Override
+ public boolean checkPixels(int pixelCount, int width, int height) {
+ return pixelCount > 2250 && pixelCount < 2750;
+ }
+ });
+ }
+
+ @Test
+ public void testSurfaceTransaction_setDestinationRect_twoLayers() throws Throwable {
+ BasicSurfaceHolderCallback callback = new BasicSurfaceHolderCallback() {
+ @Override
+ public void surfaceCreated(SurfaceHolder holder) {
+ long surfaceControl1 = createFromWindow(holder.getSurface());
+ long surfaceControl2 = createFromWindow(holder.getSurface());
+
+ setSolidBuffer(surfaceControl1, DEFAULT_LAYOUT_WIDTH, DEFAULT_LAYOUT_HEIGHT,
+ PixelColor.RED);
+ setSolidBuffer(surfaceControl2, DEFAULT_LAYOUT_WIDTH, DEFAULT_LAYOUT_HEIGHT,
+ PixelColor.BLUE);
+ setGeometry(surfaceControl1, 0, 0, 100, 100, 64, 48, 192, 192, 0);
+ setGeometry(surfaceControl2, 0, 0, 100, 100, 448, 96, 576, 240, 0);
+ }
+ };
+ verifyTest(callback,
+ new PixelChecker(PixelColor.RED) { //600
+ @Override
+ public boolean checkPixels(int pixelCount, int width, int height) {
+ return pixelCount > 540 && pixelCount < 660;
+ }
+ });
+ verifyTest(callback,
+ new PixelChecker(PixelColor.BLUE) { //600
+ @Override
+ public boolean checkPixels(int pixelCount, int width, int height) {
+ return pixelCount > 540 && pixelCount < 660;
+ }
+ });
+ }
+
+ @Test
+ public void testSurfaceTransaction_setSourceRect() throws Throwable {
+ BasicSurfaceHolderCallback callback = new BasicSurfaceHolderCallback() {
+ @Override
+ public void surfaceCreated(SurfaceHolder holder) {
+ long surfaceControl = createFromWindow(holder.getSurface());
+
+ setQuadrantBuffer(surfaceControl, DEFAULT_LAYOUT_WIDTH,
+ DEFAULT_LAYOUT_HEIGHT, PixelColor.RED, PixelColor.BLUE,
+ PixelColor.BLACK, PixelColor.GREEN);
+ setGeometry(surfaceControl, 0, 0, 100, 100, 0, 0, 640, 480, 0);
+ }
+ };
+ verifyTest(callback,
+ new PixelChecker(PixelColor.RED) { //2500
+ @Override
+ public boolean checkPixels(int pixelCount, int width, int height) {
+ return pixelCount > 2250 && pixelCount < 2750;
+ }
+ });
+ verifyTest(callback,
+ new PixelChecker(PixelColor.BLUE) { //2500
+ @Override
+ public boolean checkPixels(int pixelCount, int width, int height) {
+ return pixelCount > 2250 && pixelCount < 2750;
+ }
+ });
+ verifyTest(callback,
+ new PixelChecker(PixelColor.BLACK) { //2500
+ @Override
+ public boolean checkPixels(int pixelCount, int width, int height) {
+ return pixelCount > 2250 && pixelCount < 2750;
+ }
+ });
+ verifyTest(callback,
+ new PixelChecker(PixelColor.GREEN) { //2500
+ @Override
+ public boolean checkPixels(int pixelCount, int width, int height) {
+ return pixelCount > 2250 && pixelCount < 2750;
+ }
+ });
+ }
+
+ @Test
+ public void testSurfaceTransaction_setSourceRect_smallCentered() throws Throwable {
+ BasicSurfaceHolderCallback callback = new BasicSurfaceHolderCallback() {
+ @Override
+ public void surfaceCreated(SurfaceHolder holder) {
+ long surfaceControl = createFromWindow(holder.getSurface());
+
+ setQuadrantBuffer(surfaceControl, DEFAULT_LAYOUT_WIDTH,
+ DEFAULT_LAYOUT_HEIGHT, PixelColor.RED, PixelColor.BLUE,
+ PixelColor.BLACK, PixelColor.GREEN);
+ setGeometry(surfaceControl, 10, 10, 90, 90, 0, 0, 640, 480, 0);
+ }
+ };
+ verifyTest(callback,
+ new PixelChecker(PixelColor.RED) { //2500
+ @Override
+ public boolean checkPixels(int pixelCount, int width, int height) {
+ return pixelCount > 2250 && pixelCount < 2750;
+ }
+ });
+ verifyTest(callback,
+ new PixelChecker(PixelColor.BLUE) { //2500
+ @Override
+ public boolean checkPixels(int pixelCount, int width, int height) {
+ return pixelCount > 2250 && pixelCount < 2750;
+ }
+ });
+ verifyTest(callback,
+ new PixelChecker(PixelColor.BLACK) { //2500
+ @Override
+ public boolean checkPixels(int pixelCount, int width, int height) {
+ return pixelCount > 2250 && pixelCount < 2750;
+ }
+ });
+ verifyTest(callback,
+ new PixelChecker(PixelColor.GREEN) { //2500
+ @Override
+ public boolean checkPixels(int pixelCount, int width, int height) {
+ return pixelCount > 2250 && pixelCount < 2750;
+ }
+ });
+ }
+
+ @Test
+ public void testSurfaceTransaction_setSourceRect_small() throws Throwable {
+ verifyTest(
+ new BasicSurfaceHolderCallback() {
+ @Override
+ public void surfaceCreated(SurfaceHolder holder) {
+ long surfaceControl = createFromWindow(holder.getSurface());
+
+ setQuadrantBuffer(surfaceControl, DEFAULT_LAYOUT_WIDTH,
+ DEFAULT_LAYOUT_HEIGHT, PixelColor.RED, PixelColor.BLUE,
+ PixelColor.BLACK, PixelColor.GREEN);
+ setGeometry(surfaceControl, 60, 10, 90, 90, 0, 0, 640, 480, 0);
+ }
+ },
+ new PixelChecker(PixelColor.BLACK) { //5000
+ @Override
+ public boolean checkPixels(int pixelCount, int width, int height) {
+ return pixelCount > 4500 && pixelCount < 5500;
+ }
+ });
+ }
+
+ @Test
+ public void testSurfaceTransaction_setSourceRect_extraLarge() throws Throwable {
+ BasicSurfaceHolderCallback callback = new BasicSurfaceHolderCallback() {
+ @Override
+ public void surfaceCreated(SurfaceHolder holder) {
+ long surfaceControl = createFromWindow(holder.getSurface());
+
+ setQuadrantBuffer(surfaceControl, DEFAULT_LAYOUT_WIDTH,
+ DEFAULT_LAYOUT_HEIGHT, PixelColor.RED, PixelColor.BLUE,
+ PixelColor.BLACK, PixelColor.GREEN);
+ setGeometry(surfaceControl, -50, -50, 150, 150, 0, 0, 640, 480, 0);
+ }
+ };
+ verifyTest(callback,
+ new PixelChecker(PixelColor.RED) { //2500
+ @Override
+ public boolean checkPixels(int pixelCount, int width, int height) {
+ return pixelCount > 2250 && pixelCount < 2750;
+ }
+ });
+ verifyTest(callback,
+ new PixelChecker(PixelColor.BLUE) { //2500
+ @Override
+ public boolean checkPixels(int pixelCount, int width, int height) {
+ return pixelCount > 2250 && pixelCount < 2750;
+ }
+ });
+ verifyTest(callback,
+ new PixelChecker(PixelColor.BLACK) { //2500
+ @Override
+ public boolean checkPixels(int pixelCount, int width, int height) {
+ return pixelCount > 2250 && pixelCount < 2750;
+ }
+ });
+ verifyTest(callback,
+ new PixelChecker(PixelColor.GREEN) { //2500
+ @Override
+ public boolean checkPixels(int pixelCount, int width, int height) {
+ return pixelCount > 2250 && pixelCount < 2750;
+ }
+ });
+ }
+
+ @Test
+ public void testSurfaceTransaction_setSourceRect_badOffset() throws Throwable {
+ verifyTest(
+ new BasicSurfaceHolderCallback() {
+ @Override
+ public void surfaceCreated(SurfaceHolder holder) {
+ long surfaceControl = createFromWindow(holder.getSurface());
+
+ setQuadrantBuffer(surfaceControl, DEFAULT_LAYOUT_WIDTH,
+ DEFAULT_LAYOUT_HEIGHT, PixelColor.RED, PixelColor.BLUE,
+ PixelColor.BLACK, PixelColor.GREEN);
+ setGeometry(surfaceControl, -50, -50, 50, 50, 0, 0, 640, 480, 0);
+ }
+ },
+ new PixelChecker(PixelColor.RED) { //10000
+ @Override
+ public boolean checkPixels(int pixelCount, int width, int height) {
+ return pixelCount > 9000 && pixelCount < 11000;
+ }
+ });
+ }
+
+ @Test
+ public void testSurfaceTransaction_setTransform_flipH() throws Throwable {
+ verifyTest(
+ new BasicSurfaceHolderCallback() {
+ @Override
+ public void surfaceCreated(SurfaceHolder holder) {
+ long surfaceControl = createFromWindow(holder.getSurface());
+
+ setQuadrantBuffer(surfaceControl, DEFAULT_LAYOUT_WIDTH,
+ DEFAULT_LAYOUT_HEIGHT, PixelColor.RED, PixelColor.BLUE,
+ PixelColor.BLACK, PixelColor.GREEN);
+ setGeometry(surfaceControl, 60, 10, 90, 90, 0, 0, 640, 480,
+ /*NATIVE_WINDOW_TRANSFORM_FLIP_H*/ 1);
+ }
+ },
+ new PixelChecker(PixelColor.BLUE) { //5000
+ @Override
+ public boolean checkPixels(int pixelCount, int width, int height) {
+ return pixelCount > 4500 && pixelCount < 5500;
+ }
+ });
+ }
+
+ @Test
+ public void testSurfaceTransaction_setTransform_rotate180() throws Throwable {
+ verifyTest(
+ new BasicSurfaceHolderCallback() {
+ @Override
+ public void surfaceCreated(SurfaceHolder holder) {
+ long surfaceControl = createFromWindow(holder.getSurface());
+
+ setQuadrantBuffer(surfaceControl, DEFAULT_LAYOUT_WIDTH,
+ DEFAULT_LAYOUT_HEIGHT, PixelColor.RED, PixelColor.BLUE,
+ PixelColor.BLACK, PixelColor.GREEN);
+ setGeometry(surfaceControl, 60, 10, 90, 90, 0, 0, 640, 480,
+ /*NATIVE_WINDOW_TRANSFORM_ROT_180*/ 3);
+ }
+ },
+ new PixelChecker(PixelColor.BLUE) { //5000
+ @Override
+ public boolean checkPixels(int pixelCount, int width, int height) {
+ return pixelCount > 4500 && pixelCount < 5500;
+ }
+ });
+ }
+
+ @Test
+ public void testSurfaceTransaction_setDamageRegion_all() throws Throwable {
+ verifyTest(
+ new BasicSurfaceHolderCallback() {
+ @Override
+ public void surfaceCreated(SurfaceHolder holder) {
+ long surfaceControl = createFromWindow(holder.getSurface());
+ setSolidBuffer(surfaceControl, DEFAULT_LAYOUT_WIDTH, DEFAULT_LAYOUT_HEIGHT,
+ PixelColor.RED);
+
+ long surfaceTransaction = createSurfaceTransaction();
+ setSolidBuffer(surfaceControl, surfaceTransaction, DEFAULT_LAYOUT_WIDTH,
+ DEFAULT_LAYOUT_HEIGHT, PixelColor.BLUE);
+ setDamageRegion(surfaceControl, surfaceTransaction, 0, 0, 100, 100);
+ applyAndDeleteSurfaceTransaction(surfaceTransaction);
+ }
+ },
+ new PixelChecker(PixelColor.BLUE) { //10000
+ @Override
+ public boolean checkPixels(int pixelCount, int width, int height) {
+ return pixelCount > 9000 && pixelCount < 11000;
+ }
+ });
+ }
+
+ @Test
+ public void testSurfaceTransaction_setZOrder_zero() throws Throwable {
+ verifyTest(
+ new BasicSurfaceHolderCallback() {
+ @Override
+ public void surfaceCreated(SurfaceHolder holder) {
+ long surfaceControl1 = createFromWindow(holder.getSurface());
+ long surfaceControl2 = createFromWindow(holder.getSurface());
+ setSolidBuffer(surfaceControl1, DEFAULT_LAYOUT_WIDTH, DEFAULT_LAYOUT_HEIGHT,
+ PixelColor.RED);
+ setSolidBuffer(surfaceControl2, DEFAULT_LAYOUT_WIDTH, DEFAULT_LAYOUT_HEIGHT,
+ PixelColor.BLACK);
+
+ setZOrder(surfaceControl1, 1);
+ setZOrder(surfaceControl2, 0);
+ }
+ },
+ new PixelChecker(PixelColor.BLACK) {
+ @Override
+ public boolean checkPixels(int pixelCount, int width, int height) {
+ return pixelCount == 0;
+ }
+ });
+ }
+
+ @Test
+ public void testSurfaceTransaction_setZOrder_positive() throws Throwable {
+ verifyTest(
+ new BasicSurfaceHolderCallback() {
+ @Override
+ public void surfaceCreated(SurfaceHolder holder) {
+ long surfaceControl1 = createFromWindow(holder.getSurface());
+ long surfaceControl2 = createFromWindow(holder.getSurface());
+ setSolidBuffer(surfaceControl1, DEFAULT_LAYOUT_WIDTH, DEFAULT_LAYOUT_HEIGHT,
+ PixelColor.RED);
+ setSolidBuffer(surfaceControl2, DEFAULT_LAYOUT_WIDTH, DEFAULT_LAYOUT_HEIGHT,
+ PixelColor.BLACK);
+
+ setZOrder(surfaceControl1, 1);
+ setZOrder(surfaceControl2, 5);
+ }
+ },
+ new PixelChecker(PixelColor.RED) {
+ @Override
+ public boolean checkPixels(int pixelCount, int width, int height) {
+ return pixelCount == 0;
+ }
+ });
+ }
+
+ @Test
+ public void testSurfaceTransaction_setZOrder_negative() throws Throwable {
+ verifyTest(
+ new BasicSurfaceHolderCallback() {
+ @Override
+ public void surfaceCreated(SurfaceHolder holder) {
+ long surfaceControl1 = createFromWindow(holder.getSurface());
+ long surfaceControl2 = createFromWindow(holder.getSurface());
+ setSolidBuffer(surfaceControl1, DEFAULT_LAYOUT_WIDTH, DEFAULT_LAYOUT_HEIGHT,
+ PixelColor.RED);
+ setSolidBuffer(surfaceControl2, DEFAULT_LAYOUT_WIDTH, DEFAULT_LAYOUT_HEIGHT,
+ PixelColor.BLACK);
+
+ setZOrder(surfaceControl1, 1);
+ setZOrder(surfaceControl2, -15);
+ }
+ },
+ new PixelChecker(PixelColor.BLACK) {
+ @Override
+ public boolean checkPixels(int pixelCount, int width, int height) {
+ return pixelCount == 0;
+ }
+ });
+ }
+
+ @Test
+ public void testSurfaceTransaction_setZOrder_max() throws Throwable {
+ verifyTest(
+ new BasicSurfaceHolderCallback() {
+ @Override
+ public void surfaceCreated(SurfaceHolder holder) {
+ long surfaceControl1 = createFromWindow(holder.getSurface());
+ long surfaceControl2 = createFromWindow(holder.getSurface());
+ setSolidBuffer(surfaceControl1, DEFAULT_LAYOUT_WIDTH, DEFAULT_LAYOUT_HEIGHT,
+ PixelColor.RED);
+ setSolidBuffer(surfaceControl2, DEFAULT_LAYOUT_WIDTH, DEFAULT_LAYOUT_HEIGHT,
+ PixelColor.BLACK);
+
+ setZOrder(surfaceControl1, 1);
+ setZOrder(surfaceControl2, Integer.MAX_VALUE);
+ }
+ },
+ new PixelChecker(PixelColor.RED) {
+ @Override
+ public boolean checkPixels(int pixelCount, int width, int height) {
+ return pixelCount == 0;
+ }
+ });
+ }
+
+ @Test
+ public void testSurfaceTransaction_setZOrder_min() throws Throwable {
+ verifyTest(
+ new BasicSurfaceHolderCallback() {
+ @Override
+ public void surfaceCreated(SurfaceHolder holder) {
+ long surfaceControl1 = createFromWindow(holder.getSurface());
+ long surfaceControl2 = createFromWindow(holder.getSurface());
+ setSolidBuffer(surfaceControl1, DEFAULT_LAYOUT_WIDTH, DEFAULT_LAYOUT_HEIGHT,
+ PixelColor.RED);
+ setSolidBuffer(surfaceControl2, DEFAULT_LAYOUT_WIDTH, DEFAULT_LAYOUT_HEIGHT,
+ PixelColor.BLACK);
+
+ setZOrder(surfaceControl1, 1);
+ setZOrder(surfaceControl2, Integer.MIN_VALUE);
+ }
+ },
+ new PixelChecker(PixelColor.BLACK) {
+ @Override
+ public boolean checkPixels(int pixelCount, int width, int height) {
+ return pixelCount == 0;
+ }
+ });
+ }
+
+ @Test
+ public void testSurfaceTransaction_setOnComplete() throws Throwable {
+ verifyTest(
+ new BasicSurfaceHolderCallback() {
+ private long mContext;
+
+ @Override
+ public void surfaceCreated(SurfaceHolder holder) {
+ long surfaceControl = createFromWindow(holder.getSurface());
+
+ long surfaceTransaction = createSurfaceTransaction();
+ setSolidBuffer(surfaceControl, surfaceTransaction, DEFAULT_LAYOUT_WIDTH,
+ DEFAULT_LAYOUT_HEIGHT, PixelColor.RED);
+ mContext = nSurfaceTransaction_setOnComplete(surfaceTransaction);
+ applyAndDeleteSurfaceTransaction(surfaceTransaction);
+ }
+ @Override
+ public void surfaceDestroyed(SurfaceHolder holder) {
+ super.surfaceDestroyed(holder);
+ nSurfaceTransaction_checkOnComplete(mContext, -1);
+ }
+ },
+ new PixelChecker(PixelColor.RED) { //10000
+ @Override
+ public boolean checkPixels(int pixelCount, int width, int height) {
+ return pixelCount > 9000 && pixelCount < 11000;
+ }
+ });
+ }
+
+ @Test
+ public void testSurfaceTransaction_setDesiredPresentTime_now() throws Throwable {
+ verifyTest(
+ new BasicSurfaceHolderCallback() {
+ private long mContext;
+ private long mDesiredPresentTime;
+
+ @Override
+ public void surfaceCreated(SurfaceHolder holder) {
+ long surfaceControl = createFromWindow(holder.getSurface());
+
+ long surfaceTransaction = createSurfaceTransaction();
+ setSolidBuffer(surfaceControl, surfaceTransaction, DEFAULT_LAYOUT_WIDTH,
+ DEFAULT_LAYOUT_HEIGHT, PixelColor.RED);
+ mDesiredPresentTime = nSurfaceTransaction_setDesiredPresentTime(
+ surfaceTransaction, 0);
+ mContext = nSurfaceTransaction_setOnComplete(surfaceTransaction);
+ applyAndDeleteSurfaceTransaction(surfaceTransaction);
+ }
+ @Override
+ public void surfaceDestroyed(SurfaceHolder holder) {
+ super.surfaceDestroyed(holder);
+ nSurfaceTransaction_checkOnComplete(mContext, mDesiredPresentTime);
+ }
+ },
+ new PixelChecker(PixelColor.RED) { //10000
+ @Override
+ public boolean checkPixels(int pixelCount, int width, int height) {
+ return pixelCount > 9000 && pixelCount < 11000;
+ }
+ });
+ }
+
+ @Test
+ public void testSurfaceTransaction_setDesiredPresentTime_30ms() throws Throwable {
+ verifyTest(
+ new BasicSurfaceHolderCallback() {
+ private long mContext;
+ private long mDesiredPresentTime;
+
+ @Override
+ public void surfaceCreated(SurfaceHolder holder) {
+ long surfaceControl = createFromWindow(holder.getSurface());
+
+ long surfaceTransaction = createSurfaceTransaction();
+ setSolidBuffer(surfaceControl, surfaceTransaction, DEFAULT_LAYOUT_WIDTH,
+ DEFAULT_LAYOUT_HEIGHT, PixelColor.RED);
+ mDesiredPresentTime = nSurfaceTransaction_setDesiredPresentTime(
+ surfaceTransaction, 30000000);
+ mContext = nSurfaceTransaction_setOnComplete(surfaceTransaction);
+ applyAndDeleteSurfaceTransaction(surfaceTransaction);
+ }
+ @Override
+ public void surfaceDestroyed(SurfaceHolder holder) {
+ super.surfaceDestroyed(holder);
+ nSurfaceTransaction_checkOnComplete(mContext, mDesiredPresentTime);
+ }
+ },
+ new PixelChecker(PixelColor.RED) { //10000
+ @Override
+ public boolean checkPixels(int pixelCount, int width, int height) {
+ return pixelCount > 9000 && pixelCount < 11000;
+ }
+ });
+ }
+
+ @Test
+ public void testSurfaceTransaction_setDesiredPresentTime_100ms() throws Throwable {
+ verifyTest(
+ new BasicSurfaceHolderCallback() {
+ private long mContext;
+ private long mDesiredPresentTime;
+
+ @Override
+ public void surfaceCreated(SurfaceHolder holder) {
+ long surfaceControl = createFromWindow(holder.getSurface());
+
+ long surfaceTransaction = createSurfaceTransaction();
+ setSolidBuffer(surfaceControl, surfaceTransaction, DEFAULT_LAYOUT_WIDTH,
+ DEFAULT_LAYOUT_HEIGHT, PixelColor.RED);
+ mDesiredPresentTime = nSurfaceTransaction_setDesiredPresentTime(
+ surfaceTransaction, 100000000);
+ mContext = nSurfaceTransaction_setOnComplete(surfaceTransaction);
+ applyAndDeleteSurfaceTransaction(surfaceTransaction);
+ }
+ @Override
+ public void surfaceDestroyed(SurfaceHolder holder) {
+ super.surfaceDestroyed(holder);
+ nSurfaceTransaction_checkOnComplete(mContext, mDesiredPresentTime);
+ }
+ },
+ new PixelChecker(PixelColor.RED) { //10000
+ @Override
+ public boolean checkPixels(int pixelCount, int width, int height) {
+ return pixelCount > 9000 && pixelCount < 11000;
+ }
+ });
+ }
+
+ @Test
+ public void testSurfaceTransaction_setBufferAlpha_1_0() throws Throwable {
+ verifyTest(
+ new BasicSurfaceHolderCallback() {
+ @Override
+ public void surfaceCreated(SurfaceHolder holder) {
+ long surfaceControl = createFromWindow(holder.getSurface());
+
+ setSolidBuffer(surfaceControl, DEFAULT_LAYOUT_WIDTH, DEFAULT_LAYOUT_HEIGHT,
+ PixelColor.RED);
+ setBufferAlpha(surfaceControl, 1.0);
+ }
+ },
+ new PixelChecker(PixelColor.RED) { //10000
+ @Override
+ public boolean checkPixels(int pixelCount, int width, int height) {
+ return pixelCount > 9000 && pixelCount < 11000;
+ }
+ });
+ }
+
+ @Test
+ public void testSurfaceTransaction_setBufferAlpha_0_5() throws Throwable {
+ BasicSurfaceHolderCallback callback = new BasicSurfaceHolderCallback() {
+ @Override
+ public void surfaceCreated(SurfaceHolder holder) {
+ long surfaceControl = createFromWindow(holder.getSurface());
+
+ setSolidBuffer(surfaceControl, DEFAULT_LAYOUT_WIDTH, DEFAULT_LAYOUT_HEIGHT,
+ PixelColor.RED);
+ setBufferAlpha(surfaceControl, 0.5);
+ }
+ };
+ verifyTest(callback,
+ new PixelChecker(PixelColor.BLACK) {
+ @Override
+ public boolean checkPixels(int pixelCount, int width, int height) {
+ return pixelCount == 0;
+ }
+ });
+ verifyTest(callback,
+ new PixelChecker(PixelColor.RED) {
+ @Override
+ public boolean checkPixels(int pixelCount, int width, int height) {
+ return pixelCount == 0;
+ }
+ });
+ }
+
+ @Test
+ public void testSurfaceTransaction_setBufferAlpha_0_0() throws Throwable {
+ verifyTest(
+ new BasicSurfaceHolderCallback() {
+ @Override
+ public void surfaceCreated(SurfaceHolder holder) {
+ long surfaceControl = createFromWindow(holder.getSurface());
+
+ setSolidBuffer(surfaceControl, DEFAULT_LAYOUT_WIDTH, DEFAULT_LAYOUT_HEIGHT,
+ PixelColor.RED);
+ setBufferAlpha(surfaceControl, 0.0);
+ }
+ },
+ new PixelChecker(PixelColor.BLACK) { //10000
+ @Override
+ public boolean checkPixels(int pixelCount, int width, int height) {
+ return pixelCount > 9000 && pixelCount < 11000;
+ }
+ });
+ }
+
+ @Test
+ public void testSurfaceTransaction_reparent() throws Throwable {
+ verifyTest(
+ new BasicSurfaceHolderCallback() {
+ @Override
+ public void surfaceCreated(SurfaceHolder holder) {
+ long parentSurfaceControl1 = createFromWindow(holder.getSurface());
+ long parentSurfaceControl2 = createFromWindow(holder.getSurface());
+ long childSurfaceControl = create(parentSurfaceControl1);
+
+ setGeometry(parentSurfaceControl1, 0, 0, 100, 100, 0, 0, 160, 480, 0);
+ setGeometry(parentSurfaceControl2, 0, 0, 100, 100, 160, 0, 640, 480, 0);
+
+ setSolidBuffer(childSurfaceControl, DEFAULT_LAYOUT_WIDTH,
+ DEFAULT_LAYOUT_HEIGHT, PixelColor.RED);
+
+ reparent(childSurfaceControl, parentSurfaceControl2);
+ }
+ },
+ new PixelChecker(PixelColor.RED) { //7500
+ @Override
+ public boolean checkPixels(int pixelCount, int width, int height) {
+ return pixelCount > 6750 && pixelCount < 8250;
+ }
+ });
+ }
+
+ @Test
+ public void testSurfaceTransaction_reparent_null() throws Throwable {
+ verifyTest(
+ new BasicSurfaceHolderCallback() {
+ @Override
+ public void surfaceCreated(SurfaceHolder holder) {
+ long parentSurfaceControl = createFromWindow(holder.getSurface());
+ long childSurfaceControl = create(parentSurfaceControl);
+
+ setSolidBuffer(childSurfaceControl, DEFAULT_LAYOUT_WIDTH,
+ DEFAULT_LAYOUT_HEIGHT, PixelColor.RED);
+
+ reparent(childSurfaceControl, 0);
+ }
+ },
+ new PixelChecker(PixelColor.BLACK) { //10000
+ @Override
+ public boolean checkPixels(int pixelCount, int width, int height) {
+ return pixelCount > 9000 && pixelCount < 11000;
+ }
+ });
+ }
+
+ ///////////////////////////////////////////////////////////////////////////
+ // Native function prototypes
+ ///////////////////////////////////////////////////////////////////////////
+
+ private static native long nSurfaceTransaction_create();
+ private static native void nSurfaceTransaction_delete(long surfaceTransaction);
+ private static native void nSurfaceTransaction_apply(long surfaceTransaction);
+ private static native long nSurfaceControl_createFromWindow(Surface surface);
+ private static native long nSurfaceControl_create(long surfaceControl);
+ private static native void nSurfaceControl_release(long surfaceControl);
+ private static native long nSurfaceTransaction_setSolidBuffer(
+ long surfaceControl, long surfaceTransaction, int width, int height, int color);
+ private static native long nSurfaceTransaction_setQuadrantBuffer(long surfaceControl,
+ long surfaceTransaction, int width, int height, int colorTopLeft, int colorTopRight,
+ int colorBottomRight, int colorBottomLeft);
+ private static native void nSurfaceTransaction_releaseBuffer(long buffer);
+ private static native void nSurfaceTransaction_setVisibility(
+ long surfaceControl, long surfaceTransaction, boolean show);
+ private static native void nSurfaceTransaction_setBufferOpaque(
+ long surfaceControl, long surfaceTransaction, boolean opaque);
+ private static native void nSurfaceTransaction_setGeometry(
+ long surfaceControl, long surfaceTransaction, int srcRight, int srcTop, int srcLeft,
+ int srcBottom, int dstRight, int dstTop, int dstLeft, int dstBottom, int transform);
+ private static native void nSurfaceTransaction_setDamageRegion(
+ long surfaceControl, long surfaceTransaction, int right, int top, int left, int bottom);
+ private static native void nSurfaceTransaction_setZOrder(
+ long surfaceControl, long surfaceTransaction, int z);
+ private static native long nSurfaceTransaction_setOnComplete(long surfaceTransaction);
+ private static native void nSurfaceTransaction_checkOnComplete(long context,
+ long desiredPresentTime);
+ private static native long nSurfaceTransaction_setDesiredPresentTime(long surfaceTransaction,
+ long desiredPresentTimeOffset);
+ private static native void nSurfaceTransaction_setBufferAlpha(long surfaceControl,
+ long surfaceTransaction, double alpha);
+ private static native void nSurfaceTransaction_reparent(long surfaceControl,
+ long newParentSurfaceControl, long surfaceTransaction);
+ private static native void nSurfaceTransaction_setColor(long surfaceControl,
+ long surfaceTransaction, float r, float g, float b, float alpha);
+}
diff --git a/tests/tests/view/src/android/view/cts/SurfaceControlTest.java b/tests/tests/view/src/android/view/cts/SurfaceControlTest.java
new file mode 100644
index 0000000..e02b286
--- /dev/null
+++ b/tests/tests/view/src/android/view/cts/SurfaceControlTest.java
@@ -0,0 +1,185 @@
+/*
+ * Copyright 2019 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.view.cts;
+
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.assertFalse;
+
+import android.graphics.Canvas;
+import android.graphics.Color;
+import android.support.test.rule.ActivityTestRule;
+import android.support.test.runner.AndroidJUnit4;
+import android.support.test.uiautomator.UiObjectNotFoundException;
+import android.test.suitebuilder.annotation.LargeTest;
+import android.util.Log;
+import android.view.cts.surfacevalidator.CapturedActivity;
+import android.view.cts.surfacevalidator.PixelChecker;
+import android.view.cts.surfacevalidator.PixelColor;
+import android.view.cts.surfacevalidator.SurfaceControlTestCase;
+import android.view.SurfaceControl;
+import android.view.Surface;
+
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.rules.TestName;
+
+@LargeTest
+public class SurfaceControlTest {
+ private static final int DEFAULT_LAYOUT_WIDTH = 100;
+ private static final int DEFAULT_LAYOUT_HEIGHT = 100;
+ private static final int DEFAULT_BUFFER_WIDTH = 640;
+ private static final int DEFAULT_BUFFER_HEIGHT = 480;
+
+ @Rule
+ public ActivityTestRule<CapturedActivity> mActivityRule =
+ new ActivityTestRule<>(CapturedActivity.class);
+
+ @Rule
+ public TestName mName = new TestName();
+ private CapturedActivity mActivity;
+
+ private void verifyTest(SurfaceControlTestCase.ParentSurfaceConsumer psc,
+ PixelChecker pixelChecker) throws Throwable {
+ mActivity.verifyTest(new SurfaceControlTestCase(psc, null,
+ pixelChecker, DEFAULT_LAYOUT_WIDTH, DEFAULT_LAYOUT_HEIGHT,
+ DEFAULT_BUFFER_WIDTH, DEFAULT_BUFFER_HEIGHT),
+ mName);
+ }
+
+ @Before
+ public void setup() {
+ mActivity = mActivityRule.getActivity();
+ mActivity.dismissPermissionDialog();
+ }
+
+ /**
+ * Want to be especially sure we don't leave up the permission dialog, so try and dismiss
+ * after test.
+ */
+ @After
+ public void tearDown() throws UiObjectNotFoundException {
+ mActivity.dismissPermissionDialog();
+ }
+
+ @Test
+ public void testLifecycle() {
+ final SurfaceControl.Builder b = new SurfaceControl.Builder();
+ final SurfaceControl sc = b.build();
+
+ assertTrue("Failed to build SurfaceControl", sc != null);
+ assertTrue(sc.isValid());
+ sc.release();
+ assertFalse(sc.isValid());
+ }
+
+ private SurfaceControl buildDefaultSurface(SurfaceControl parent) {
+ return new SurfaceControl.Builder()
+ .setBufferSize(DEFAULT_BUFFER_WIDTH, DEFAULT_BUFFER_HEIGHT)
+ .setParent(parent)
+ .build();
+
+ }
+
+ void fillWithColor(SurfaceControl sc, int color) {
+ Surface s = new Surface(sc);
+
+ Canvas c = s.lockHardwareCanvas();
+ c.drawColor(color);
+ s.unlockCanvasAndPost(c);
+ }
+
+ private SurfaceControl buildDefaultRedSurface(SurfaceControl parent) {
+ final SurfaceControl sc = buildDefaultSurface(parent);
+ fillWithColor(sc, Color.RED);
+ return sc;
+ }
+
+ /**
+ * Verify that showing a 100x100 surface filled with RED produces roughly 10,000 red pixels.
+ */
+ @Test
+ public void testShow() throws Throwable {
+ verifyTest(
+ new SurfaceControlTestCase.ParentSurfaceConsumer () {
+ @Override
+ public void addChildren(SurfaceControl parent) {
+ final SurfaceControl sc = buildDefaultRedSurface(parent);
+
+ new SurfaceControl.Transaction().setVisibility(sc, true).apply();
+
+ sc.release();
+ }
+ },
+ new PixelChecker(PixelColor.RED) { //10000
+ @Override
+ public boolean checkPixels(int pixelCount, int width, int height) {
+ return pixelCount > 9000 && pixelCount < 11000;
+ }
+ });
+ }
+
+ /**
+ * The same setup as testShow, however we hide the surface and verify that we don't see Red.
+ */
+ @Test
+ public void testHide() throws Throwable {
+ verifyTest(
+ new SurfaceControlTestCase.ParentSurfaceConsumer () {
+ @Override
+ public void addChildren(SurfaceControl parent) {
+ final SurfaceControl sc = buildDefaultRedSurface(parent);
+
+ new SurfaceControl.Transaction().setVisibility(sc, false).apply();
+
+ sc.release();
+ }
+ },
+ new PixelChecker(PixelColor.BLACK) { //10000
+ @Override
+ public boolean checkPixels(int pixelCount, int width, int height) {
+ return pixelCount > 9000 && pixelCount < 11000;
+ }
+ });
+ }
+
+ /**
+ * Here we use the same red-surface set up but construct it off-screen and then re-parent it.
+ */
+ @Test
+ public void testReparent() throws Throwable {
+ verifyTest(
+ new SurfaceControlTestCase.ParentSurfaceConsumer () {
+ @Override
+ public void addChildren(SurfaceControl parent) {
+ final SurfaceControl sc = buildDefaultRedSurface(null);
+
+ new SurfaceControl.Transaction().setVisibility(sc, true)
+ .reparent(sc, parent)
+ .apply();
+
+ sc.release();
+ }
+ },
+ new PixelChecker(PixelColor.RED) { //10000
+ @Override
+ public boolean checkPixels(int pixelCount, int width, int height) {
+ return pixelCount > 9000 && pixelCount < 11000;
+ }
+ });
+ }
+}
diff --git a/tests/tests/view/src/android/view/cts/SurfaceViewSyncTest.java b/tests/tests/view/src/android/view/cts/SurfaceViewSyncTest.java
index e3744fd..de73a79 100644
--- a/tests/tests/view/src/android/view/cts/SurfaceViewSyncTest.java
+++ b/tests/tests/view/src/android/view/cts/SurfaceViewSyncTest.java
@@ -15,25 +15,19 @@
*/
package android.view.cts;
-import static org.junit.Assert.assertTrue;
-
import android.animation.ObjectAnimator;
import android.animation.PropertyValuesHolder;
import android.animation.ValueAnimator;
import android.annotation.SuppressLint;
-import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.media.MediaPlayer;
-import android.os.Environment;
import android.support.test.filters.LargeTest;
import android.support.test.filters.RequiresDevice;
import android.support.test.rule.ActivityTestRule;
import android.support.test.runner.AndroidJUnit4;
import android.support.test.uiautomator.UiObjectNotFoundException;
-import android.util.Log;
-import android.util.SparseArray;
import android.view.Gravity;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
@@ -43,6 +37,7 @@
import android.view.cts.surfacevalidator.AnimationFactory;
import android.view.cts.surfacevalidator.AnimationTestCase;
import android.view.cts.surfacevalidator.CapturedActivity;
+import android.view.cts.surfacevalidator.PixelChecker;
import android.view.cts.surfacevalidator.ViewFactory;
import android.widget.FrameLayout;
@@ -53,11 +48,6 @@
import org.junit.rules.TestName;
import org.junit.runner.RunWith;
-import java.io.File;
-import java.io.FileOutputStream;
-import java.io.IOException;
-import java.util.concurrent.TimeUnit;
-
@RunWith(AndroidJUnit4.class)
@LargeTest
@SuppressLint("RtlHardcoded")
@@ -190,71 +180,13 @@
};
///////////////////////////////////////////////////////////////////////////
- // Bad frame capture
- ///////////////////////////////////////////////////////////////////////////
-
- private void saveFailureCaptures(SparseArray<Bitmap> failFrames) {
- if (failFrames.size() == 0) return;
-
- String directoryName = Environment.getExternalStorageDirectory()
- + "/" + getClass().getSimpleName()
- + "/" + mName.getMethodName();
- File testDirectory = new File(directoryName);
- if (testDirectory.exists()) {
- String[] children = testDirectory.list();
- if (children == null) {
- return;
- }
- for (String file : children) {
- new File(testDirectory, file).delete();
- }
- } else {
- testDirectory.mkdirs();
- }
-
- for (int i = 0; i < failFrames.size(); i++) {
- int frameNr = failFrames.keyAt(i);
- Bitmap bitmap = failFrames.valueAt(i);
-
- String bitmapName = "frame_" + frameNr + ".png";
- Log.d(TAG, "Saving file : " + bitmapName + " in directory : " + directoryName);
-
- File file = new File(directoryName, bitmapName);
- try (FileOutputStream fileStream = new FileOutputStream(file)) {
- bitmap.compress(Bitmap.CompressFormat.PNG, 85, fileStream);
- fileStream.flush();
- } catch (IOException e) {
- e.printStackTrace();
- }
- }
- }
-
- ///////////////////////////////////////////////////////////////////////////
// Tests
///////////////////////////////////////////////////////////////////////////
- private void verifyTest(AnimationTestCase testCase) throws Throwable {
- CapturedActivity.TestResult result = mActivity.runTest(testCase);
- saveFailureCaptures(result.failures);
-
- float failRatio = 1.0f * result.failFrames / (result.failFrames + result.passFrames);
- assertTrue("Error: " + failRatio + " fail ratio - extremely high, is activity obstructed?",
- failRatio < 0.95f);
- assertTrue("Error: " + result.failFrames
- + " incorrect frames observed - incorrect positioning",
- result.failFrames == 0);
- float framesPerSecond = 1.0f * result.passFrames
- / TimeUnit.MILLISECONDS.toSeconds(mActivity.getCaptureDurationMs());
- assertTrue("Error, only " + result.passFrames
- + " frames observed, virtual display only capturing at "
- + framesPerSecond + " frames per second",
- result.passFrames > 100);
- }
-
/** Draws a moving 10x10 black rectangle, validates 100 pixels of black are seen each frame */
@Test
public void testSmallRect() throws Throwable {
- verifyTest(new AnimationTestCase(
+ mActivity.verifyTest(new AnimationTestCase(
context -> new View(context) {
// draw a single pixel
final Paint sBlackPaint = new Paint();
@@ -273,8 +205,12 @@
},
new FrameLayout.LayoutParams(100, 100, Gravity.LEFT | Gravity.TOP),
view -> makeInfinite(ObjectAnimator.ofInt(view, "offset", 10, 30)),
- (blackishPixelCount, width, height) ->
- blackishPixelCount >= 90 && blackishPixelCount <= 110));
+ new PixelChecker() {
+ @Override
+ public boolean checkPixels(int blackishPixelCount, int width, int height) {
+ return blackishPixelCount >= 90 && blackishPixelCount <= 110;
+ }
+ }), mName);
}
/**
@@ -283,56 +219,80 @@
*/
@Test
public void testEmptySurfaceView() throws Throwable {
- verifyTest(new AnimationTestCase(
+ mActivity.verifyTest(new AnimationTestCase(
sEmptySurfaceViewFactory,
new FrameLayout.LayoutParams(100, 100, Gravity.LEFT | Gravity.TOP),
sTranslateAnimationFactory,
- (blackishPixelCount, width, height) ->
- blackishPixelCount > 9000 && blackishPixelCount < 11000));
+ new PixelChecker() {
+ @Override
+ public boolean checkPixels(int blackishPixelCount, int width, int height) {
+ return blackishPixelCount > 9000 && blackishPixelCount < 11000;
+ }
+ }), mName);
}
@Test
public void testSurfaceViewSmallScale() throws Throwable {
- verifyTest(new AnimationTestCase(
+ mActivity.verifyTest(new AnimationTestCase(
sGreenSurfaceViewFactory,
new FrameLayout.LayoutParams(320, 240, Gravity.LEFT | Gravity.TOP),
sSmallScaleAnimationFactory,
- (blackishPixelCount, width, height) -> blackishPixelCount == 0));
+ new PixelChecker() {
+ @Override
+ public boolean checkPixels(int blackishPixelCount, int width, int height) {
+ return blackishPixelCount == 0;
+ }
+ }), mName);
}
@Test
public void testSurfaceViewBigScale() throws Throwable {
- verifyTest(new AnimationTestCase(
+ mActivity.verifyTest(new AnimationTestCase(
sGreenSurfaceViewFactory,
new FrameLayout.LayoutParams(640, 480, Gravity.LEFT | Gravity.TOP),
sBigScaleAnimationFactory,
- (blackishPixelCount, width, height) -> blackishPixelCount == 0));
+ new PixelChecker() {
+ @Override
+ public boolean checkPixels(int blackishPixelCount, int width, int height) {
+ return blackishPixelCount == 0;
+ }
+ }), mName);
}
@Test
public void testVideoSurfaceViewTranslate() throws Throwable {
- verifyTest(new AnimationTestCase(
+ mActivity.verifyTest(new AnimationTestCase(
sVideoViewFactory,
new FrameLayout.LayoutParams(640, 480, Gravity.LEFT | Gravity.TOP),
sTranslateAnimationFactory,
- (blackishPixelCount, width, height) -> blackishPixelCount == 0));
+ new PixelChecker() {
+ @Override
+ public boolean checkPixels(int blackishPixelCount, int width, int height) {
+ return blackishPixelCount == 0;
+ }
+ }), mName);
}
@Test
public void testVideoSurfaceViewRotated() throws Throwable {
- verifyTest(new AnimationTestCase(
+ mActivity.verifyTest(new AnimationTestCase(
sVideoViewFactory,
new FrameLayout.LayoutParams(100, 100, Gravity.LEFT | Gravity.TOP),
view -> makeInfinite(ObjectAnimator.ofPropertyValuesHolder(view,
PropertyValuesHolder.ofFloat(View.TRANSLATION_X, 10f, 30f),
PropertyValuesHolder.ofFloat(View.TRANSLATION_Y, 10f, 30f),
PropertyValuesHolder.ofFloat(View.ROTATION, 45f, 45f))),
- (blackishPixelCount, width, height) -> blackishPixelCount == 0));
+ new PixelChecker() {
+ @Override
+ public boolean checkPixels(int blackishPixelCount, int width, int height) {
+ return blackishPixelCount == 0;
+ }
+ }), mName);
}
@Test
public void testVideoSurfaceViewEdgeCoverage() throws Throwable {
- verifyTest(new AnimationTestCase(
+ mActivity.verifyTest(new AnimationTestCase(
sVideoViewFactory,
new FrameLayout.LayoutParams(640, 480, Gravity.CENTER),
view -> {
@@ -345,12 +305,17 @@
PropertyValuesHolder.ofFloat(View.TRANSLATION_X, -x, 0, x, 0, -x),
PropertyValuesHolder.ofFloat(View.TRANSLATION_Y, 0, -y, 0, y, 0)));
},
- (blackishPixelCount, width, height) -> blackishPixelCount == 0));
+ new PixelChecker() {
+ @Override
+ public boolean checkPixels(int blackishPixelCount, int width, int height) {
+ return blackishPixelCount == 0;
+ }
+ }), mName);
}
@Test
public void testVideoSurfaceViewCornerCoverage() throws Throwable {
- verifyTest(new AnimationTestCase(
+ mActivity.verifyTest(new AnimationTestCase(
sVideoViewFactory,
new FrameLayout.LayoutParams(640, 480, Gravity.CENTER),
view -> {
@@ -363,6 +328,11 @@
PropertyValuesHolder.ofFloat(View.TRANSLATION_X, -x, x, x, -x, -x),
PropertyValuesHolder.ofFloat(View.TRANSLATION_Y, -y, -y, y, y, -y)));
},
- (blackishPixelCount, width, height) -> blackishPixelCount == 0));
+ new PixelChecker() {
+ @Override
+ public boolean checkPixels(int blackishPixelCount, int width, int height) {
+ return blackishPixelCount == 0;
+ }
+ }), mName);
}
}
diff --git a/tests/tests/view/src/android/view/cts/TextureViewCtsActivity.java b/tests/tests/view/src/android/view/cts/TextureViewCtsActivity.java
index aec746a..66b1539 100644
--- a/tests/tests/view/src/android/view/cts/TextureViewCtsActivity.java
+++ b/tests/tests/view/src/android/view/cts/TextureViewCtsActivity.java
@@ -358,6 +358,9 @@
case TextureViewTest.EGL_GL_COLORSPACE_DISPLAY_P3_LINEAR_EXT:
eglColorSpaceString = "EGL_EXT_gl_colorspace_display_p3_linear";
break;
+ case TextureViewTest.EGL_GL_COLORSPACE_DISPLAY_P3_PASSTHROUGH_EXT:
+ eglColorSpaceString = "EGL_EXT_gl_colorspace_display_p3_passthrough";
+ break;
case TextureViewTest.EGL_GL_COLORSPACE_SRGB_KHR:
eglColorSpaceString = "EGL_KHR_gl_colorspace";
break;
diff --git a/tests/tests/view/src/android/view/cts/TextureViewTest.java b/tests/tests/view/src/android/view/cts/TextureViewTest.java
index 53b108f..b3b8744 100644
--- a/tests/tests/view/src/android/view/cts/TextureViewTest.java
+++ b/tests/tests/view/src/android/view/cts/TextureViewTest.java
@@ -62,6 +62,7 @@
static final int EGL_GL_COLORSPACE_LINEAR_KHR = 0x308A;
static final int EGL_GL_COLORSPACE_DISPLAY_P3_EXT = 0x3363;
static final int EGL_GL_COLORSPACE_DISPLAY_P3_LINEAR_EXT = 0x3362;
+ static final int EGL_GL_COLORSPACE_DISPLAY_P3_PASSTHROUGH_EXT = 0x3490;
static final int EGL_GL_COLORSPACE_SCRGB_EXT = 0x3351;
static final int EGL_GL_COLORSPACE_SCRGB_LINEAR_EXT = 0x3350;
@@ -226,6 +227,20 @@
}
@Test
+ public void testGetBitmap_8888_PassthroughP3() throws Throwable {
+ testGetBitmap(EGL_GL_COLORSPACE_DISPLAY_P3_PASSTHROUGH_EXT,
+ ColorSpace.get(ColorSpace.Named.DISPLAY_P3), false, true,
+ new FP16Compare(ColorSpace.Named.EXTENDED_SRGB));
+ }
+
+ @Test
+ public void testGetBitmap_FP16_PassthroughP3() throws Throwable {
+ testGetBitmap(EGL_GL_COLORSPACE_DISPLAY_P3_PASSTHROUGH_EXT,
+ ColorSpace.get(ColorSpace.Named.DISPLAY_P3), true, true,
+ new FP16Compare(ColorSpace.Named.EXTENDED_SRGB));
+ }
+
+ @Test
public void testGetBitmap_FP16_LinearP3() throws Throwable {
ColorSpace.Rgb displayP3 = (ColorSpace.Rgb) ColorSpace.get(ColorSpace.Named.DISPLAY_P3);
ColorSpace.Rgb linearDisplayP3 = new ColorSpace.Rgb(
diff --git a/tests/tests/view/src/android/view/cts/WindowTest.java b/tests/tests/view/src/android/view/cts/WindowTest.java
index 76b1a1c..ecbb973 100644
--- a/tests/tests/view/src/android/view/cts/WindowTest.java
+++ b/tests/tests/view/src/android/view/cts/WindowTest.java
@@ -704,8 +704,6 @@
mPresentation.button1.getWidth() / 2,
mPresentation.button1.getY() + mPresentation.button1.getHeight() / 2);
assertTrue(waitingSemaphore.tryAcquire(5, TimeUnit.SECONDS));
-
- destroyPresentation();
}
private void checkPresentationButtonFocus(final boolean button1Focused,
diff --git a/tests/tests/view/src/android/view/cts/surfacevalidator/AnimationTestCase.java b/tests/tests/view/src/android/view/cts/surfacevalidator/AnimationTestCase.java
index 74ee5ee..3ebfc79 100644
--- a/tests/tests/view/src/android/view/cts/surfacevalidator/AnimationTestCase.java
+++ b/tests/tests/view/src/android/view/cts/surfacevalidator/AnimationTestCase.java
@@ -20,7 +20,7 @@
import android.view.View;
import android.widget.FrameLayout;
-public class AnimationTestCase {
+public class AnimationTestCase implements ISurfaceValidatorTestCase {
private final ViewFactory mViewFactory;
private final FrameLayout.LayoutParams mLayoutParams;
private final AnimationFactory mAnimationFactory;
@@ -39,7 +39,7 @@
mPixelChecker = pixelChecker;
}
- PixelChecker getChecker() {
+ public PixelChecker getChecker() {
return mPixelChecker;
}
diff --git a/tests/tests/view/src/android/view/cts/surfacevalidator/CapturedActivity.java b/tests/tests/view/src/android/view/cts/surfacevalidator/CapturedActivity.java
index e1b2353..4d77ae4 100644
--- a/tests/tests/view/src/android/view/cts/surfacevalidator/CapturedActivity.java
+++ b/tests/tests/view/src/android/view/cts/surfacevalidator/CapturedActivity.java
@@ -31,6 +31,7 @@
import android.media.projection.MediaProjection;
import android.media.projection.MediaProjectionManager;
import android.os.Bundle;
+import android.os.Environment;
import android.os.Handler;
import android.os.Looper;
import android.support.test.InstrumentationRegistry;
@@ -47,6 +48,11 @@
import android.view.cts.R;
import android.widget.FrameLayout;
+import org.junit.rules.TestName;
+
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.IOException;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.TimeUnit;
@@ -160,7 +166,7 @@
return mOnEmbedded ? 100000 : 10000;
}
- public TestResult runTest(AnimationTestCase animationTestCase) throws Throwable {
+ public TestResult runTest(ISurfaceValidatorTestCase animationTestCase) throws Throwable {
TestResult testResult = new TestResult();
if (mOnWatch) {
/**
@@ -260,6 +266,61 @@
return testResult;
}
+ private void saveFailureCaptures(SparseArray<Bitmap> failFrames, TestName name) {
+ if (failFrames.size() == 0) return;
+
+ String directoryName = Environment.getExternalStorageDirectory()
+ + "/" + getClass().getSimpleName()
+ + "/" + name.getMethodName();
+ File testDirectory = new File(directoryName);
+ if (testDirectory.exists()) {
+ String[] children = testDirectory.list();
+ if (children == null) {
+ return;
+ }
+ for (String file : children) {
+ new File(testDirectory, file).delete();
+ }
+ } else {
+ testDirectory.mkdirs();
+ }
+
+ for (int i = 0; i < failFrames.size(); i++) {
+ int frameNr = failFrames.keyAt(i);
+ Bitmap bitmap = failFrames.valueAt(i);
+
+ String bitmapName = "frame_" + frameNr + ".png";
+ Log.d(TAG, "Saving file : " + bitmapName + " in directory : " + directoryName);
+
+ File file = new File(directoryName, bitmapName);
+ try (FileOutputStream fileStream = new FileOutputStream(file)) {
+ bitmap.compress(Bitmap.CompressFormat.PNG, 85, fileStream);
+ fileStream.flush();
+ } catch (IOException e) {
+ e.printStackTrace();
+ }
+ }
+ }
+
+ public void verifyTest(ISurfaceValidatorTestCase testCase, TestName name) throws Throwable {
+ CapturedActivity.TestResult result = runTest(testCase);
+ saveFailureCaptures(result.failures, name);
+
+ float failRatio = 1.0f * result.failFrames / (result.failFrames + result.passFrames);
+ assertTrue("Error: " + failRatio + " fail ratio - extremely high, is activity obstructed?",
+ failRatio < 0.95f);
+ assertTrue("Error: " + result.failFrames
+ + " incorrect frames observed - incorrect positioning",
+ result.failFrames == 0);
+
+ float framesPerSecond = 1.0f * result.passFrames
+ / TimeUnit.MILLISECONDS.toSeconds(getCaptureDurationMs());
+ assertTrue("Error, only " + result.passFrames
+ + " frames observed, virtual display only capturing at "
+ + framesPerSecond + " frames per second",
+ result.passFrames > 100);
+ }
+
private class MediaProjectionCallback extends MediaProjection.Callback {
@Override
public void onStop() {
diff --git a/tests/tests/view/src/android/view/cts/surfacevalidator/ISurfaceValidatorTestCase.java b/tests/tests/view/src/android/view/cts/surfacevalidator/ISurfaceValidatorTestCase.java
new file mode 100644
index 0000000..3b74958
--- /dev/null
+++ b/tests/tests/view/src/android/view/cts/surfacevalidator/ISurfaceValidatorTestCase.java
@@ -0,0 +1,27 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package android.view.cts.surfacevalidator;
+
+import android.content.Context;
+import android.widget.FrameLayout;
+
+public interface ISurfaceValidatorTestCase {
+ PixelChecker getChecker();
+
+ void start(Context context, FrameLayout parent);
+
+ void end();
+}
diff --git a/tests/tests/view/src/android/view/cts/surfacevalidator/PixelChecker.java b/tests/tests/view/src/android/view/cts/surfacevalidator/PixelChecker.java
index 76f0adc..860d11b 100644
--- a/tests/tests/view/src/android/view/cts/surfacevalidator/PixelChecker.java
+++ b/tests/tests/view/src/android/view/cts/surfacevalidator/PixelChecker.java
@@ -15,6 +15,20 @@
*/
package android.view.cts.surfacevalidator;
-public interface PixelChecker {
- boolean checkPixels(int blackishPixelCount, int width, int height);
-}
\ No newline at end of file
+public abstract class PixelChecker {
+ private PixelColor mPixelColor;
+
+ public PixelChecker() {
+ mPixelColor = new PixelColor();
+ }
+
+ public PixelChecker(int color) {
+ mPixelColor = new PixelColor(color);
+ }
+
+ PixelColor getColor() {
+ return mPixelColor;
+ }
+
+ public abstract boolean checkPixels(int matchingPixelCount, int width, int height);
+}
diff --git a/tests/tests/view/src/android/view/cts/surfacevalidator/PixelColor.java b/tests/tests/view/src/android/view/cts/surfacevalidator/PixelColor.java
new file mode 100644
index 0000000..a7395bb
--- /dev/null
+++ b/tests/tests/view/src/android/view/cts/surfacevalidator/PixelColor.java
@@ -0,0 +1,80 @@
+/*
+ * 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.view.cts.surfacevalidator;
+
+public class PixelColor {
+ public static final int BLACK = 0xFF000000;
+ public static final int RED = 0xFF0000FF;
+ public static final int GREEN = 0xFF00FF00;
+ public static final int BLUE = 0xFFFF0000;
+
+ public static final int TRANSPARENT_RED = 0x7F0000FF;
+
+ // Default to black
+ public short mMinAlpha;
+ public short mMaxAlpha;
+ public short mMinRed;
+ public short mMaxRed;
+ public short mMinBlue;
+ public short mMaxBlue;
+ public short mMinGreen;
+ public short mMaxGreen;
+
+ public PixelColor(int color) {
+ short alpha = (short) ((color >> 24) & 0xFF);
+ short blue = (short) ((color >> 16) & 0xFF);
+ short green = (short) ((color >> 8) & 0xFF);
+ short red = (short) (color & 0xFF);
+
+ mMinAlpha = (short) getMinValue(alpha);
+ mMaxAlpha = (short) getMaxValue(alpha);
+ mMinRed = (short) getMinValue(red);
+ mMaxRed = (short) getMaxValue(red);
+ mMinBlue = (short) getMinValue(blue);
+ mMaxBlue = (short) getMaxValue(blue);
+ mMinGreen = (short) getMinValue(green);
+ mMaxGreen = (short) getMaxValue(green);
+ }
+
+ public PixelColor() {
+ this(BLACK);
+ }
+
+ private int getMinValue(short color) {
+ if (color - 4 > 0) {
+ return color - 4;
+ }
+ return 0;
+ }
+
+ private int getMaxValue(short color) {
+ if (color + 4 < 0xFF) {
+ return color + 4;
+ }
+ return 0xFF;
+ }
+
+ public void addToPixelCounter(ScriptC_PixelCounter script) {
+ script.set_MIN_ALPHA(mMinAlpha);
+ script.set_MAX_ALPHA(mMaxAlpha);
+ script.set_MIN_RED(mMinRed);
+ script.set_MAX_RED(mMaxRed);
+ script.set_MIN_BLUE(mMinBlue);
+ script.set_MAX_BLUE(mMaxBlue);
+ script.set_MIN_GREEN(mMinGreen);
+ script.set_MAX_GREEN(mMaxGreen);
+ }
+}
diff --git a/tests/tests/view/src/android/view/cts/surfacevalidator/PixelCounter.rs b/tests/tests/view/src/android/view/cts/surfacevalidator/PixelCounter.rs
index 12e024c..b4fe3be 100644
--- a/tests/tests/view/src/android/view/cts/surfacevalidator/PixelCounter.rs
+++ b/tests/tests/view/src/android/view/cts/surfacevalidator/PixelCounter.rs
@@ -17,14 +17,26 @@
#pragma rs java_package_name(android.view.cts.surfacevalidator)
#pragma rs reduce(countBlackishPixels) accumulator(countBlackishPixelsAccum) combiner(countBlackishPixelsCombiner)
-uchar THRESHOLD;
+uchar MIN_ALPHA;
+uchar MAX_ALPHA;
+uchar MIN_RED;
+uchar MAX_RED;
+uchar MIN_GREEN;
+uchar MAX_GREEN;
+uchar MIN_BLUE;
+uchar MAX_BLUE;
int BOUNDS[4];
static void countBlackishPixelsAccum(int *accum, uchar4 pixel, uint32_t x, uint32_t y) {
- if (pixel.r < THRESHOLD
- && pixel.g < THRESHOLD
- && pixel.b < THRESHOLD
+ if (pixel.a <= MAX_ALPHA
+ && pixel.a >= MIN_ALPHA
+ && pixel.r <= MAX_RED
+ && pixel.r >= MIN_RED
+ && pixel.g <= MAX_GREEN
+ && pixel.g >= MIN_GREEN
+ && pixel.b <= MAX_BLUE
+ && pixel.b >= MIN_BLUE
&& x >= BOUNDS[0]
&& x < BOUNDS[2]
&& y >= BOUNDS[1]
diff --git a/tests/tests/view/src/android/view/cts/surfacevalidator/SurfaceControlTestCase.java b/tests/tests/view/src/android/view/cts/surfacevalidator/SurfaceControlTestCase.java
new file mode 100644
index 0000000..9c8c871
--- /dev/null
+++ b/tests/tests/view/src/android/view/cts/surfacevalidator/SurfaceControlTestCase.java
@@ -0,0 +1,127 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package android.view.cts.surfacevalidator;
+
+import android.animation.ValueAnimator;
+import android.content.Context;
+import android.view.Gravity;
+import android.view.SurfaceControl;
+import android.view.SurfaceHolder;
+import android.view.SurfaceView;
+import android.view.View;
+import android.widget.FrameLayout;
+
+public class SurfaceControlTestCase implements ISurfaceValidatorTestCase {
+ private final SurfaceViewFactory mViewFactory;
+ private final FrameLayout.LayoutParams mLayoutParams;
+ private final AnimationFactory mAnimationFactory;
+ private final PixelChecker mPixelChecker;
+
+ private final int mBufferWidth;
+ private final int mBufferHeight;
+
+ private FrameLayout mParent;
+ private ValueAnimator mAnimator;
+
+ public static abstract class ParentSurfaceConsumer {
+ abstract public void addChildren(SurfaceControl parent);
+ };
+
+ private static class ParentSurfaceHolder implements SurfaceHolder.Callback {
+ ParentSurfaceConsumer mPsc;
+ SurfaceView mSurfaceView;
+
+ ParentSurfaceHolder(ParentSurfaceConsumer psc) {
+ mPsc = psc;
+ }
+
+ public void surfaceCreated(SurfaceHolder holder) {
+ mPsc.addChildren(mSurfaceView.getSurfaceControl());
+ }
+ public void surfaceDestroyed(SurfaceHolder holder) {
+ }
+ public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
+ }
+ };
+
+ public SurfaceControlTestCase(SurfaceHolder.Callback callback,
+ AnimationFactory animationFactory, PixelChecker pixelChecker,
+ int layoutWidth, int layoutHeight, int bufferWidth, int bufferHeight) {
+ mViewFactory = new SurfaceViewFactory(callback);
+ mLayoutParams =
+ new FrameLayout.LayoutParams(layoutWidth, layoutHeight, Gravity.LEFT | Gravity.TOP);
+ mAnimationFactory = animationFactory;
+ mPixelChecker = pixelChecker;
+ mBufferWidth = bufferWidth;
+ mBufferHeight = bufferHeight;
+ }
+
+ public SurfaceControlTestCase(ParentSurfaceConsumer psc,
+ AnimationFactory animationFactory, PixelChecker pixelChecker,
+ int layoutWidth, int layoutHeight, int bufferWidth, int bufferHeight) {
+ this(new ParentSurfaceHolder(psc), animationFactory, pixelChecker,
+ layoutWidth, layoutHeight, bufferWidth, bufferHeight);
+ }
+
+ public PixelChecker getChecker() {
+ return mPixelChecker;
+ }
+
+ public void start(Context context, FrameLayout parent) {
+ View view = mViewFactory.createView(context);
+ if (mViewFactory.mCallback instanceof ParentSurfaceHolder) {
+ ParentSurfaceHolder psh = (ParentSurfaceHolder) mViewFactory.mCallback;
+ psh.mSurfaceView = (SurfaceView) view;
+ }
+
+ mParent = parent;
+ mParent.addView(view, mLayoutParams);
+
+ if (mAnimationFactory != null) {
+ mAnimator = mAnimationFactory.createAnimator(view);
+ mAnimator.start();
+ }
+ }
+
+ public void end() {
+ if (mAnimator != null) {
+ mAnimator.end();
+ mAnimator = null;
+ }
+ mParent.removeAllViews();
+ }
+
+ private class SurfaceViewFactory implements ViewFactory {
+ private SurfaceHolder.Callback mCallback;
+
+ SurfaceViewFactory(SurfaceHolder.Callback callback) {
+ mCallback = callback;
+ }
+
+ public View createView(Context context) {
+ SurfaceView surfaceView = new SurfaceView(context);
+
+ // prevent transparent region optimization, which is invalid for a SurfaceView moving
+ // around
+ surfaceView.setWillNotDraw(false);
+
+ surfaceView.getHolder().setFixedSize(mBufferWidth, mBufferHeight);
+ surfaceView.getHolder().addCallback(mCallback);
+
+ return surfaceView;
+ }
+ }
+}
diff --git a/tests/tests/view/src/android/view/cts/surfacevalidator/SurfacePixelValidator.java b/tests/tests/view/src/android/view/cts/surfacevalidator/SurfacePixelValidator.java
index 1a8bc0db..c2fb007 100644
--- a/tests/tests/view/src/android/view/cts/surfacevalidator/SurfacePixelValidator.java
+++ b/tests/tests/view/src/android/view/cts/surfacevalidator/SurfacePixelValidator.java
@@ -39,9 +39,6 @@
*/
private static final int NUM_FIRST_FRAMES_SKIPPED = 8;
- // If no channel is greater than this value, pixel will be considered 'blackish'.
- private static final short PIXEL_CHANNEL_THRESHOLD = 4;
-
private static final int MAX_CAPTURED_FAILURES = 5;
private final int mWidth;
@@ -120,7 +117,7 @@
mInPixelsAllocation = createBufferQueueAllocation();
mScript.set_BOUNDS(new int[] {boundsToCheck.left, boundsToCheck.top,
boundsToCheck.right, boundsToCheck.bottom});
- mScript.set_THRESHOLD(PIXEL_CHANNEL_THRESHOLD);
+ pixelChecker.getColor().addToPixelCounter(mScript);
mInPixelsAllocation.setOnBufferAvailableListener(
allocation -> mWorkerHandler.post(mConsumeRunnable));
diff --git a/tests/tests/view/src/android/view/inspector/cts/IntEnumMappingTest.java b/tests/tests/view/src/android/view/inspector/cts/IntEnumMappingTest.java
index 6729491..98c8dd7 100644
--- a/tests/tests/view/src/android/view/inspector/cts/IntEnumMappingTest.java
+++ b/tests/tests/view/src/android/view/inspector/cts/IntEnumMappingTest.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2018 The Android Open Source Project
+ * Copyright 2019 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.
@@ -27,19 +27,46 @@
import org.junit.runner.RunWith;
/**
- * Tests for {@link IntEnumMapping}
+ * Tests for {@link IntEnumMapping}.
*/
@SmallTest
@RunWith(AndroidJUnit4.class)
-public final class IntEnumMappingTest {
+public class IntEnumMappingTest {
@Test
- public void testMapping() {
+ public void testSimpleValue() {
IntEnumMapping mapping = new IntEnumMapping.Builder()
- .addValue("ONE", 1)
- .addValue("TWO", 2)
+ .addValue("ZERO", 0)
.build();
- assertNull(mapping.nameOf(0));
- assertEquals("ONE", mapping.nameOf(1));
- assertEquals("TWO", mapping.nameOf(2));
+ assertEquals("ZERO", mapping.get(0));
+ }
+
+ @Test
+ public void testMissingValue() {
+ IntEnumMapping mapping = new IntEnumMapping.Builder()
+ .addValue("ZERO", 0)
+ .build();
+ assertNull(mapping.get(1));
+ }
+
+ @Test
+ public void testBuilderReuse() {
+ IntEnumMapping.Builder builder = new IntEnumMapping.Builder();
+
+ builder.addValue("ONE", 1);
+ IntEnumMapping mapping1 = builder.build();
+
+ assertEquals("ONE", mapping1.get(1));
+
+ builder.addValue("TWO", 2);
+ IntEnumMapping mapping2 = builder.build();
+
+ assertEquals("ONE", mapping2.get(1));
+ assertEquals("TWO", mapping2.get(2));
+ assertNull(mapping1.get(2));
+ }
+
+ @Test(expected = NullPointerException.class)
+ public void testNullName() {
+ new IntEnumMapping.Builder().addValue(null, 0);
}
}
diff --git a/tests/tests/view/src/android/view/inspector/cts/IntFlagMappingTest.java b/tests/tests/view/src/android/view/inspector/cts/IntFlagMappingTest.java
index ba3a3af..ce93d30 100644
--- a/tests/tests/view/src/android/view/inspector/cts/IntFlagMappingTest.java
+++ b/tests/tests/view/src/android/view/inspector/cts/IntFlagMappingTest.java
@@ -16,7 +16,8 @@
package android.view.inspector.cts;
-import static org.junit.Assert.assertArrayEquals;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
import android.support.test.filters.SmallTest;
import android.support.test.runner.AndroidJUnit4;
@@ -25,8 +26,14 @@
import org.junit.Test;
import org.junit.runner.RunWith;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.HashSet;
+import java.util.Set;
+
/**
- * Tests for {@link IntFlagMapping}
+ * Tests for {@link IntFlagMapping}.
*/
@SmallTest
@RunWith(AndroidJUnit4.class)
@@ -38,11 +45,11 @@
.addFlag("TWO", 2)
.build();
- assertArrayEquals(new String[0], mapping.namesOf(0));
- assertArrayEquals(new String[] {"ONE"}, mapping.namesOf(1));
- assertArrayEquals(new String[] {"TWO"}, mapping.namesOf(2));
- assertArrayEquals(new String[] {"ONE", "TWO"}, mapping.namesOf(3));
- assertArrayEquals(new String[0], mapping.namesOf(4));
+ assertEmpty(mapping.get(0));
+ assertEquals(setOf("ONE"), mapping.get(1));
+ assertEquals(setOf("TWO"), mapping.get(2));
+ assertEquals(setOf("ONE", "TWO"), mapping.get(3));
+ assertEmpty(mapping.get(4));
}
@Test
@@ -53,11 +60,11 @@
.build();
- assertArrayEquals(new String[0], mapping.namesOf(0));
- assertArrayEquals(new String[] {"ONE"}, mapping.namesOf(1));
- assertArrayEquals(new String[] {"TWO"}, mapping.namesOf(2));
- assertArrayEquals(new String[0], mapping.namesOf(3));
- assertArrayEquals(new String[0], mapping.namesOf(4));
+ assertEmpty(mapping.get(0));
+ assertEquals(setOf("ONE"), mapping.get(1));
+ assertEquals(setOf("TWO"), mapping.get(2));
+ assertEmpty(mapping.get(3));
+ assertEmpty(mapping.get(4));
}
@Test
@@ -69,13 +76,28 @@
.build();
- assertArrayEquals(new String[0], mapping.namesOf(0));
- assertArrayEquals(new String[] {"ONE"}, mapping.namesOf(1));
- assertArrayEquals(new String[] {"TWO"}, mapping.namesOf(2));
- assertArrayEquals(new String[0], mapping.namesOf(3));
- assertArrayEquals(new String[] {"FOUR"}, mapping.namesOf(4));
- assertArrayEquals(new String[] {"ONE", "FOUR"}, mapping.namesOf(5));
- assertArrayEquals(new String[] {"TWO", "FOUR"}, mapping.namesOf(6));
- assertArrayEquals(new String[] {"FOUR"}, mapping.namesOf(7));
+ assertEmpty(mapping.get(0));
+ assertEquals(setOf("ONE"), mapping.get(1));
+ assertEquals(setOf("TWO"), mapping.get(2));
+ assertEmpty(mapping.get(3));
+ assertEquals(setOf("FOUR"), mapping.get(4));
+ assertEquals(setOf("ONE", "FOUR"), mapping.get(5));
+ assertEquals(setOf("TWO", "FOUR"), mapping.get(6));
+ assertEquals(setOf("FOUR"), mapping.get(7));
+ }
+
+ @Test(expected = NullPointerException.class)
+ public void testNullName() {
+ new IntFlagMapping.Builder().addFlag(null, 0);
+ }
+
+ private static Set<String> setOf(String... values) {
+ final Set<String> set = new HashSet<>(values.length);
+ set.addAll(Arrays.asList(values));
+ return Collections.unmodifiableSet(set);
+ }
+
+ private static void assertEmpty(Collection collection) {
+ assertTrue(collection.isEmpty());
}
}
diff --git a/tests/tests/view/src/android/view/textclassifier/cts/ConversationActionsTest.java b/tests/tests/view/src/android/view/textclassifier/cts/ConversationActionsTest.java
index 54f6166..8e34571 100644
--- a/tests/tests/view/src/android/view/textclassifier/cts/ConversationActionsTest.java
+++ b/tests/tests/view/src/android/view/textclassifier/cts/ConversationActionsTest.java
@@ -29,7 +29,9 @@
import android.support.test.InstrumentationRegistry;
import android.support.test.filters.SmallTest;
import android.support.test.runner.AndroidJUnit4;
+import android.view.textclassifier.ConversationAction;
import android.view.textclassifier.ConversationActions;
+import android.view.textclassifier.TextClassifier;
import org.junit.Test;
import org.junit.runner.RunWith;
@@ -97,16 +99,16 @@
@Test
public void testTypeConfig_full() {
- ConversationActions.TypeConfig typeConfig =
- new ConversationActions.TypeConfig.Builder()
+ TextClassifier.EntityConfig typeConfig =
+ new TextClassifier.EntityConfig.Builder()
.setIncludedTypes(
- Collections.singletonList(ConversationActions.TYPE_OPEN_URL))
+ Collections.singletonList(ConversationAction.TYPE_OPEN_URL))
.setExcludedTypes(
- Collections.singletonList(ConversationActions.TYPE_CALL_PHONE))
+ Collections.singletonList(ConversationAction.TYPE_CALL_PHONE))
.build();
- ConversationActions.TypeConfig recovered =
- parcelizeDeparcelize(typeConfig, ConversationActions.TypeConfig.CREATOR);
+ TextClassifier.EntityConfig recovered =
+ parcelizeDeparcelize(typeConfig, TextClassifier.EntityConfig.CREATOR);
assertFullTypeConfig(typeConfig);
assertFullTypeConfig(recovered);
@@ -114,17 +116,17 @@
@Test
public void testTypeConfig_full_notIncludeTypesFromTextClassifier() {
- ConversationActions.TypeConfig typeConfig =
- new ConversationActions.TypeConfig.Builder()
+ TextClassifier.EntityConfig typeConfig =
+ new TextClassifier.EntityConfig.Builder()
.includeTypesFromTextClassifier(false)
.setIncludedTypes(
- Collections.singletonList(ConversationActions.TYPE_OPEN_URL))
+ Collections.singletonList(ConversationAction.TYPE_OPEN_URL))
.setExcludedTypes(
- Collections.singletonList(ConversationActions.TYPE_CALL_PHONE))
+ Collections.singletonList(ConversationAction.TYPE_CALL_PHONE))
.build();
- ConversationActions.TypeConfig recovered =
- parcelizeDeparcelize(typeConfig, ConversationActions.TypeConfig.CREATOR);
+ TextClassifier.EntityConfig recovered =
+ parcelizeDeparcelize(typeConfig, TextClassifier.EntityConfig.CREATOR);
assertFullTypeConfig_notIncludeTypesFromTextClassifier(typeConfig);
assertFullTypeConfig_notIncludeTypesFromTextClassifier(recovered);
@@ -132,11 +134,11 @@
@Test
public void testTypeConfig_minimal() {
- ConversationActions.TypeConfig typeConfig =
- new ConversationActions.TypeConfig.Builder().build();
+ TextClassifier.EntityConfig typeConfig =
+ new TextClassifier.EntityConfig.Builder().build();
- ConversationActions.TypeConfig recovered =
- parcelizeDeparcelize(typeConfig, ConversationActions.TypeConfig.CREATOR);
+ TextClassifier.EntityConfig recovered =
+ parcelizeDeparcelize(typeConfig, TextClassifier.EntityConfig.CREATOR);
assertMinimalTypeConfig(typeConfig);
assertMinimalTypeConfig(recovered);
@@ -166,14 +168,16 @@
new ConversationActions.Message.Builder(PERSON)
.setText(TEXT)
.build();
- ConversationActions.TypeConfig typeConfig =
- new ConversationActions.TypeConfig.Builder()
+ TextClassifier.EntityConfig typeConfig =
+ new TextClassifier.EntityConfig.Builder()
.includeTypesFromTextClassifier(false)
.build();
ConversationActions.Request request =
new ConversationActions.Request.Builder(Collections.singletonList(message))
.setConversationId(CONVERSATION_ID)
- .setHints(Collections.singletonList(ConversationActions.HINT_FOR_IN_APP))
+ .setHints(
+ Collections.singletonList(
+ ConversationActions.Request.HINT_FOR_IN_APP))
.setMaxSuggestions(10)
.setTypeConfig(typeConfig)
.build();
@@ -187,14 +191,14 @@
@Test
public void testConversationAction_minimal() {
- ConversationActions.ConversationAction conversationAction =
- new ConversationActions.ConversationAction.Builder(
- ConversationActions.TYPE_CALL_PHONE)
+ ConversationAction conversationAction =
+ new ConversationAction.Builder(
+ ConversationAction.TYPE_CALL_PHONE)
.build();
- ConversationActions.ConversationAction recovered =
+ ConversationAction recovered =
parcelizeDeparcelize(conversationAction,
- ConversationActions.ConversationAction.CREATOR);
+ ConversationAction.CREATOR);
assertMinimalConversationAction(conversationAction);
assertMinimalConversationAction(recovered);
@@ -202,18 +206,18 @@
@Test
public void testConversationAction_full() {
- ConversationActions.ConversationAction conversationAction =
- new ConversationActions.ConversationAction.Builder(
- ConversationActions.TYPE_CALL_PHONE)
+ ConversationAction conversationAction =
+ new ConversationAction.Builder(
+ ConversationAction.TYPE_CALL_PHONE)
.setConfidenceScore(1.0f)
.setTextReply(TEXT)
.setAction(REMOTE_ACTION)
.setExtras(EXTRAS)
.build();
- ConversationActions.ConversationAction recovered =
+ ConversationAction recovered =
parcelizeDeparcelize(conversationAction,
- ConversationActions.ConversationAction.CREATOR);
+ ConversationAction.CREATOR);
assertFullConversationAction(conversationAction);
assertFullConversationAction(recovered);
@@ -221,9 +225,9 @@
@Test
public void testConversationActions_full() {
- ConversationActions.ConversationAction conversationAction =
- new ConversationActions.ConversationAction.Builder(
- ConversationActions.TYPE_CALL_PHONE)
+ ConversationAction conversationAction =
+ new ConversationAction.Builder(
+ ConversationAction.TYPE_CALL_PHONE)
.build();
ConversationActions conversationActions =
@@ -238,9 +242,9 @@
@Test
public void testConversationActions_minimal() {
- ConversationActions.ConversationAction conversationAction =
- new ConversationActions.ConversationAction.Builder(
- ConversationActions.TYPE_CALL_PHONE)
+ ConversationAction conversationAction =
+ new ConversationAction.Builder(
+ ConversationAction.TYPE_CALL_PHONE)
.build();
ConversationActions conversationActions =
@@ -266,40 +270,42 @@
assertThat(message.getReferenceTime()).isNull();
}
- private void assertFullTypeConfig(ConversationActions.TypeConfig typeConfig) {
+ private void assertFullTypeConfig(TextClassifier.EntityConfig typeConfig) {
List<String> extraTypesFromTextClassifier = Arrays.asList(
- ConversationActions.TYPE_CALL_PHONE,
- ConversationActions.TYPE_CREATE_REMINDER);
+ ConversationAction.TYPE_CALL_PHONE,
+ ConversationAction.TYPE_CREATE_REMINDER);
- Collection<String> resolvedTypes = typeConfig.resolveTypes(extraTypesFromTextClassifier);
+ Collection<String> resolvedTypes =
+ typeConfig.resolveEntityListModifications(extraTypesFromTextClassifier);
assertThat(typeConfig.shouldIncludeTypesFromTextClassifier()).isTrue();
- assertThat(typeConfig.resolveTypes(Collections.emptyList()))
- .containsExactly(ConversationActions.TYPE_OPEN_URL);
+ assertThat(typeConfig.resolveEntityListModifications(Collections.emptyList()))
+ .containsExactly(ConversationAction.TYPE_OPEN_URL);
assertThat(resolvedTypes).containsExactly(
- ConversationActions.TYPE_OPEN_URL, ConversationActions.TYPE_CREATE_REMINDER);
+ ConversationAction.TYPE_OPEN_URL, ConversationAction.TYPE_CREATE_REMINDER);
}
private void assertFullTypeConfig_notIncludeTypesFromTextClassifier(
- ConversationActions.TypeConfig typeConfig) {
+ TextClassifier.EntityConfig typeConfig) {
List<String> extraTypesFromTextClassifier = Arrays.asList(
- ConversationActions.TYPE_CALL_PHONE,
- ConversationActions.TYPE_CREATE_REMINDER);
+ ConversationAction.TYPE_CALL_PHONE,
+ ConversationAction.TYPE_CREATE_REMINDER);
- Collection<String> resolvedTypes = typeConfig.resolveTypes(extraTypesFromTextClassifier);
+ Collection<String> resolvedTypes =
+ typeConfig.resolveEntityListModifications(extraTypesFromTextClassifier);
assertThat(typeConfig.shouldIncludeTypesFromTextClassifier()).isFalse();
- assertThat(typeConfig.resolveTypes(Collections.emptyList()))
- .containsExactly(ConversationActions.TYPE_OPEN_URL);
- assertThat(resolvedTypes).containsExactly(ConversationActions.TYPE_OPEN_URL);
+ assertThat(typeConfig.resolveEntityListModifications(Collections.emptyList()))
+ .containsExactly(ConversationAction.TYPE_OPEN_URL);
+ assertThat(resolvedTypes).containsExactly(ConversationAction.TYPE_OPEN_URL);
}
- private void assertMinimalTypeConfig(ConversationActions.TypeConfig typeConfig) {
+ private void assertMinimalTypeConfig(TextClassifier.EntityConfig typeConfig) {
assertThat(typeConfig.shouldIncludeTypesFromTextClassifier()).isTrue();
- assertThat(typeConfig.resolveTypes(Collections.emptyList())).isEmpty();
- assertThat(typeConfig.resolveTypes(
- Collections.singletonList(ConversationActions.TYPE_OPEN_URL))).containsExactly(
- ConversationActions.TYPE_OPEN_URL);
+ assertThat(typeConfig.resolveEntityListModifications(Collections.emptyList())).isEmpty();
+ assertThat(typeConfig.resolveEntityListModifications(
+ Collections.singletonList(ConversationAction.TYPE_OPEN_URL))).containsExactly(
+ ConversationAction.TYPE_OPEN_URL);
}
private void assertMinimalRequest(ConversationActions.Request request) {
@@ -316,24 +322,24 @@
assertThat(request.getConversation()).hasSize(1);
assertThat(request.getConversation().get(0).getText().toString()).isEqualTo(TEXT);
assertThat(request.getConversation().get(0).getAuthor()).isEqualTo(PERSON);
- assertThat(request.getHints()).containsExactly(ConversationActions.HINT_FOR_IN_APP);
+ assertThat(request.getHints()).containsExactly(ConversationActions.Request.HINT_FOR_IN_APP);
assertThat(request.getMaxSuggestions()).isEqualTo(10);
assertThat(request.getTypeConfig().shouldIncludeTypesFromTextClassifier()).isFalse();
assertThat(request.getConversationId()).isEqualTo(CONVERSATION_ID);
}
private void assertMinimalConversationAction(
- ConversationActions.ConversationAction conversationAction) {
+ ConversationAction conversationAction) {
assertThat(conversationAction.getAction()).isNull();
assertThat(conversationAction.getConfidenceScore()).isWithin(FLOAT_TOLERANCE).of(0.0f);
- assertThat(conversationAction.getType()).isEqualTo(ConversationActions.TYPE_CALL_PHONE);
+ assertThat(conversationAction.getType()).isEqualTo(ConversationAction.TYPE_CALL_PHONE);
}
private void assertFullConversationAction(
- ConversationActions.ConversationAction conversationAction) {
+ ConversationAction conversationAction) {
assertThat(conversationAction.getAction().getTitle()).isEqualTo(TEXT);
assertThat(conversationAction.getConfidenceScore()).isWithin(FLOAT_TOLERANCE).of(1.0f);
- assertThat(conversationAction.getType()).isEqualTo(ConversationActions.TYPE_CALL_PHONE);
+ assertThat(conversationAction.getType()).isEqualTo(ConversationAction.TYPE_CALL_PHONE);
assertThat(conversationAction.getTextReply()).isEqualTo(TEXT);
assertThat(conversationAction.getExtras().keySet()).containsExactly(TEXT);
}
@@ -341,14 +347,14 @@
private void assertMinimalConversationActions(ConversationActions conversationActions) {
assertThat(conversationActions.getConversationActions()).hasSize(1);
assertThat(conversationActions.getConversationActions().get(0).getType())
- .isEqualTo(ConversationActions.TYPE_CALL_PHONE);
+ .isEqualTo(ConversationAction.TYPE_CALL_PHONE);
assertThat(conversationActions.getId()).isNull();
}
private void assertFullConversationActions(ConversationActions conversationActions) {
assertThat(conversationActions.getConversationActions()).hasSize(1);
assertThat(conversationActions.getConversationActions().get(0).getType())
- .isEqualTo(ConversationActions.TYPE_CALL_PHONE);
+ .isEqualTo(ConversationAction.TYPE_CALL_PHONE);
assertThat(conversationActions.getId()).isEqualTo(ID);
}
diff --git a/tests/tests/view/src/android/view/textclassifier/cts/TextClassificationManagerTest.java b/tests/tests/view/src/android/view/textclassifier/cts/TextClassificationManagerTest.java
index 1cd65b8..3a33b86 100644
--- a/tests/tests/view/src/android/view/textclassifier/cts/TextClassificationManagerTest.java
+++ b/tests/tests/view/src/android/view/textclassifier/cts/TextClassificationManagerTest.java
@@ -30,6 +30,7 @@
import android.support.test.InstrumentationRegistry;
import android.support.test.filters.SmallTest;
import android.support.test.runner.AndroidJUnit4;
+import android.view.textclassifier.ConversationAction;
import android.view.textclassifier.ConversationActions;
import android.view.textclassifier.SelectionEvent;
import android.view.textclassifier.TextClassification;
@@ -80,12 +81,17 @@
new TextLanguage.Request.Builder(TEXT)
.setExtras(BUNDLE)
.build();
- private static final ConversationActions.Message MESSAGE =
- new ConversationActions.Message.Builder(ConversationActions.Message.PERSON_USER_REMOTE)
+ private static final ConversationActions.Message FIRST_MESSAGE =
+ new ConversationActions.Message.Builder(ConversationActions.Message.PERSON_USER_SELF)
+ .setText(TEXT)
+ .build();
+ private static final ConversationActions.Message SECOND_MESSAGE =
+ new ConversationActions.Message.Builder(ConversationActions.Message.PERSON_USER_OTHERS)
.setText(TEXT)
.build();
private static final ConversationActions.Request CONVERSATION_ACTIONS_REQUEST =
- new ConversationActions.Request.Builder(Arrays.asList(MESSAGE)).build();
+ new ConversationActions.Request.Builder(
+ Arrays.asList(FIRST_MESSAGE, SECOND_MESSAGE)).build();
private TextClassificationManager mManager;
private TextClassifier mClassifier;
@@ -273,10 +279,10 @@
private static void assertValidResult(ConversationActions conversationActions) {
assertNotNull(conversationActions);
- List<ConversationActions.ConversationAction> conversationActionsList =
+ List<ConversationAction> conversationActionsList =
conversationActions.getConversationActions();
assertNotNull(conversationActionsList);
- for (ConversationActions.ConversationAction conversationAction : conversationActionsList) {
+ for (ConversationAction conversationAction : conversationActionsList) {
assertThat(conversationAction.getAction()).isNotNull();
assertThat(conversationAction.getType()).isNotNull();
assertThat(conversationAction.getConfidenceScore()).isGreaterThan(0f);
diff --git a/tests/tests/view/src/android/view/textclassifier/cts/TextClassifierEventTest.java b/tests/tests/view/src/android/view/textclassifier/cts/TextClassifierEventTest.java
index f1ca661..f84f2bf 100644
--- a/tests/tests/view/src/android/view/textclassifier/cts/TextClassifierEventTest.java
+++ b/tests/tests/view/src/android/view/textclassifier/cts/TextClassifierEventTest.java
@@ -20,7 +20,6 @@
import android.os.Bundle;
import android.os.Parcel;
-import android.support.test.InstrumentationRegistry;
import android.support.test.filters.SmallTest;
import android.support.test.runner.AndroidJUnit4;
import android.view.textclassifier.TextClassificationContext;
@@ -34,18 +33,108 @@
@SmallTest
@RunWith(AndroidJUnit4.class)
public class TextClassifierEventTest {
+ private static final float TOLERANCE = 0.000001f;
@Test
public void testMinimumEvent() {
- final TextClassifierEvent event = new TextClassifierEvent.Builder(
+ final TextClassifierEvent event = createMinimalTextClassifierEvent();
+
+ assertMinimalTextClassifierEvent(event);
+ }
+
+ @Test
+ public void testParcelUnparcel_minimumEvent() {
+ final TextClassifierEvent event = createMinimalTextClassifierEvent();
+
+ final Parcel parcel = Parcel.obtain();
+ event.writeToParcel(parcel, event.describeContents());
+ parcel.setDataPosition(0);
+ final TextClassifierEvent result = TextClassifierEvent.CREATOR.createFromParcel(parcel);
+
+ assertMinimalTextClassifierEvent(result);
+ }
+
+ @Test
+ public void testFullEvent() {
+ final long eventTime = System.currentTimeMillis();
+ final TextClassifierEvent event = createFullTextClassifierEvent(eventTime);
+
+ assertFullEvent(event, eventTime);
+ }
+
+ @Test
+ public void testParcelUnparcel_fullEvent() {
+ final long eventTime = System.currentTimeMillis();
+ final TextClassifierEvent event = createFullTextClassifierEvent(eventTime);
+
+ final Parcel parcel = Parcel.obtain();
+ event.writeToParcel(parcel, event.describeContents());
+ parcel.setDataPosition(0);
+ final TextClassifierEvent result = TextClassifierEvent.CREATOR.createFromParcel(parcel);
+
+ assertFullEvent(result, eventTime);
+ }
+
+ private TextClassifierEvent createFullTextClassifierEvent(long eventTime) {
+ final Bundle extra = new Bundle();
+ extra.putString("key", "value");
+ return new TextClassifierEvent.Builder(
+ TextClassifierEvent.CATEGORY_LINKIFY,
+ TextClassifierEvent.TYPE_LINK_CLICKED)
+ .setEventIndex(2)
+ .setEventTime(eventTime)
+ .setEntityTypes(TextClassifier.TYPE_ADDRESS)
+ .setRelativeWordStartIndex(1)
+ .setRelativeWordEndIndex(2)
+ .setRelativeSuggestedWordStartIndex(-1)
+ .setRelativeSuggestedWordEndIndex(3)
+ .setLanguage("en")
+ .setResultId("androidtc-en-v606-1234")
+ .setActionIndices(1, 2, 5)
+ .setExtras(extra)
+ .setEventContext(new TextClassificationContext.Builder(
+ "pkg", TextClassifier.WIDGET_TYPE_TEXTVIEW)
+ .setWidgetVersion(TextView.class.getName())
+ .build())
+ .setScore(0.5f)
+ .setEntityTypes(TextClassifier.TYPE_ADDRESS, TextClassifier.TYPE_DATE)
+ .build();
+ }
+
+ private void assertFullEvent(TextClassifierEvent event, long expectedEventTime) {
+ assertThat(event.getEventCategory()).isEqualTo(TextClassifierEvent.CATEGORY_LINKIFY);
+ assertThat(event.getEventType()).isEqualTo(TextClassifierEvent.TYPE_LINK_CLICKED);
+ assertThat(event.getEventIndex()).isEqualTo(2);
+ assertThat(event.getEventTime()).isEqualTo(expectedEventTime);
+ assertThat(event.getEntityTypes()).asList()
+ .containsExactly(TextClassifier.TYPE_ADDRESS, TextClassifier.TYPE_DATE);
+ assertThat(event.getRelativeWordStartIndex()).isEqualTo(1);
+ assertThat(event.getRelativeWordEndIndex()).isEqualTo(2);
+ assertThat(event.getRelativeSuggestedWordStartIndex()).isEqualTo(-1);
+ assertThat(event.getRelativeSuggestedWordEndIndex()).isEqualTo(3);
+ assertThat(event.getLanguage()).isEqualTo("en");
+ assertThat(event.getResultId()).isEqualTo("androidtc-en-v606-1234");
+ assertThat(event.getActionIndices()).asList().containsExactly(1, 2, 5);
+ assertThat(event.getExtras().get("key")).isEqualTo("value");
+ assertThat(event.getEventContext().getPackageName()).isEqualTo("pkg");
+ assertThat(event.getEventContext().getWidgetType())
+ .isEqualTo(TextClassifier.WIDGET_TYPE_TEXTVIEW);
+ assertThat(event.getEventContext().getWidgetVersion()).isEqualTo(TextView.class.getName());
+ assertThat(event.getScore()).isWithin(TOLERANCE).of(0.5f);
+ }
+
+ private TextClassifierEvent createMinimalTextClassifierEvent() {
+ return new TextClassifierEvent.Builder(
TextClassifierEvent.CATEGORY_UNDEFINED, TextClassifierEvent.TYPE_UNDEFINED)
.build();
+ }
+ private void assertMinimalTextClassifierEvent(TextClassifierEvent event) {
assertThat(event.getEventCategory()).isEqualTo(TextClassifierEvent.CATEGORY_UNDEFINED);
assertThat(event.getEventType()).isEqualTo(TextClassifierEvent.TYPE_UNDEFINED);
assertThat(event.getEventIndex()).isEqualTo(0);
assertThat(event.getEventTime()).isEqualTo(0);
- assertThat(event.getEntityType()).isNull();
+ assertThat(event.getEntityTypes()).isEmpty();
assertThat(event.getRelativeWordStartIndex()).isEqualTo(0);
assertThat(event.getRelativeWordEndIndex()).isEqualTo(0);
assertThat(event.getRelativeSuggestedWordStartIndex()).isEqualTo(0);
@@ -53,102 +142,8 @@
assertThat(event.getLanguage()).isNull();
assertThat(event.getResultId()).isNull();
assertThat(event.getActionIndices()).isEmpty();
- assertThat(event.getExtras()).isEqualTo(Bundle.EMPTY);
+ assertThat(event.getExtras().size()).isEqualTo(0);
assertThat(event.getEventContext()).isNull();
- }
-
- @Test
- public void testFullEvent() {
- final Bundle extra = new Bundle();
- extra.putString("key", "value");
- final long now = System.currentTimeMillis();
- final String resultId = "androidtc-en-v606-1234";
- final TextClassifierEvent event = new TextClassifierEvent.Builder(
- TextClassifierEvent.CATEGORY_LINKIFY,
- TextClassifierEvent.TYPE_LINK_CLICKED)
- .setEventIndex(2)
- .setEventTime(now)
- .setEntityType(TextClassifier.TYPE_ADDRESS)
- .setRelativeWordStartIndex(1)
- .setRelativeWordEndIndex(2)
- .setRelativeSuggestedWordStartIndex(-1)
- .setRelativeSuggestedWordEndIndex(3)
- .setLanguage("en")
- .setResultId(resultId)
- .setActionIndices(1, 2, 5)
- .setExtras(extra)
- .setEventContext(new TextClassificationContext.Builder(
- "pkg", TextClassifier.WIDGET_TYPE_TEXTVIEW)
- .setWidgetVersion(TextView.class.getName())
- .build())
- .build();
-
- assertThat(event.getEventCategory()).isEqualTo(TextClassifierEvent.CATEGORY_LINKIFY);
- assertThat(event.getEventType()).isEqualTo(TextClassifierEvent.TYPE_LINK_CLICKED);
- assertThat(event.getEventIndex()).isEqualTo(2);
- assertThat(event.getEventTime()).isEqualTo(now);
- assertThat(event.getEntityType()).isEqualTo(TextClassifier.TYPE_ADDRESS);
- assertThat(event.getRelativeWordStartIndex()).isEqualTo(1);
- assertThat(event.getRelativeWordEndIndex()).isEqualTo(2);
- assertThat(event.getRelativeSuggestedWordStartIndex()).isEqualTo(-1);
- assertThat(event.getRelativeSuggestedWordEndIndex()).isEqualTo(3);
- assertThat(event.getLanguage()).isEqualTo("en");
- assertThat(event.getResultId()).isEqualTo(resultId);
- assertThat(event.getActionIndices()).asList().containsExactly(1, 2, 5);
- assertThat(event.getExtras().get("key")).isEqualTo("value");
- assertThat(event.getEventContext().getPackageName()).isEqualTo("pkg");
- assertThat(event.getEventContext().getWidgetType())
- .isEqualTo(TextClassifier.WIDGET_TYPE_TEXTVIEW);
- assertThat(event.getEventContext().getWidgetVersion()).isEqualTo(TextView.class.getName());
- }
-
- @Test
- public void testParcelUnparcel() {
- final Bundle extra = new Bundle();
- extra.putString("k", "v");
- final TextClassifierEvent event = new TextClassifierEvent.Builder(
- TextClassifierEvent.CATEGORY_SELECTION,
- TextClassifierEvent.TYPE_SELECTION_MODIFIED)
- .setEventIndex(1)
- .setEventTime(1000)
- .setEntityType(TextClassifier.TYPE_DATE)
- .setRelativeWordStartIndex(4)
- .setRelativeWordEndIndex(3)
- .setRelativeSuggestedWordStartIndex(2)
- .setRelativeSuggestedWordEndIndex(1)
- .setLanguage("de")
- .setResultId("id")
- .setActionIndices(3)
- .setExtras(extra)
- .setEventContext(new TextClassificationContext.Builder(
- InstrumentationRegistry.getTargetContext().getPackageName(),
- TextClassifier.WIDGET_TYPE_UNSELECTABLE_TEXTVIEW)
- .setWidgetVersion("notification")
- .build())
- .build();
-
- final Parcel parcel = Parcel.obtain();
- event.writeToParcel(parcel, event.describeContents());
- parcel.setDataPosition(0);
- final TextClassifierEvent result = TextClassifierEvent.CREATOR.createFromParcel(parcel);
-
- assertThat(result.getEventCategory()).isEqualTo(TextClassifierEvent.CATEGORY_SELECTION);
- assertThat(result.getEventType()).isEqualTo(TextClassifierEvent.TYPE_SELECTION_MODIFIED);
- assertThat(result.getEventIndex()).isEqualTo(1);
- assertThat(result.getEventTime()).isEqualTo(1000);
- assertThat(result.getEntityType()).isEqualTo(TextClassifier.TYPE_DATE);
- assertThat(result.getRelativeWordStartIndex()).isEqualTo(4);
- assertThat(result.getRelativeWordEndIndex()).isEqualTo(3);
- assertThat(result.getRelativeSuggestedWordStartIndex()).isEqualTo(2);
- assertThat(result.getRelativeSuggestedWordEndIndex()).isEqualTo(1);
- assertThat(result.getLanguage()).isEqualTo("de");
- assertThat(result.getResultId()).isEqualTo("id");
- assertThat(result.getActionIndices()).asList().containsExactly(3);
- assertThat(result.getExtras().get("k")).isEqualTo("v");
- assertThat(result.getEventContext().getPackageName())
- .isEqualTo(InstrumentationRegistry.getTargetContext().getPackageName());
- assertThat(result.getEventContext().getWidgetType())
- .isEqualTo(TextClassifier.WIDGET_TYPE_UNSELECTABLE_TEXTVIEW);
- assertThat(result.getEventContext().getWidgetVersion()).isEqualTo("notification");
+ assertThat(event.getEntityTypes()).isEmpty();
}
}
diff --git a/tests/tests/voiceinteraction/service/src/android/voiceinteraction/service/MainInteractionSession.java b/tests/tests/voiceinteraction/service/src/android/voiceinteraction/service/MainInteractionSession.java
index 203be4d..6f82d6f 100644
--- a/tests/tests/voiceinteraction/service/src/android/voiceinteraction/service/MainInteractionSession.java
+++ b/tests/tests/voiceinteraction/service/src/android/voiceinteraction/service/MainInteractionSession.java
@@ -17,15 +17,12 @@
package android.voiceinteraction.service;
import android.app.VoiceInteractor;
-import android.app.VoiceInteractor.Prompt;
import android.content.Context;
import android.content.Intent;
import android.content.pm.LauncherApps;
import android.os.AsyncTask;
import android.os.Bundle;
import android.service.voice.VoiceInteractionSession;
-import android.service.voice.VoiceInteractionSession.ConfirmationRequest;
-import android.service.voice.VoiceInteractionSession.PickOptionRequest;
import android.util.Log;
import android.voiceinteraction.common.Utils;
diff --git a/tests/tests/voiceinteraction/src/android/voiceinteraction/cts/TestLocalInteractionActivity.java b/tests/tests/voiceinteraction/src/android/voiceinteraction/cts/TestLocalInteractionActivity.java
index 4999fbe..b5d5938 100644
--- a/tests/tests/voiceinteraction/src/android/voiceinteraction/cts/TestLocalInteractionActivity.java
+++ b/tests/tests/voiceinteraction/src/android/voiceinteraction/cts/TestLocalInteractionActivity.java
@@ -17,9 +17,6 @@
package android.voiceinteraction.cts;
import android.app.Activity;
-import android.content.Intent;
-import android.content.ComponentName;
-import android.content.Context;
import android.os.Bundle;
import android.util.Log;
import android.voiceinteraction.common.Utils;
diff --git a/tests/tests/voiceinteraction/src/android/voiceinteraction/cts/VoiceInteractionTest.java b/tests/tests/voiceinteraction/src/android/voiceinteraction/cts/VoiceInteractionTest.java
index 1abd00f..732cff2 100644
--- a/tests/tests/voiceinteraction/src/android/voiceinteraction/cts/VoiceInteractionTest.java
+++ b/tests/tests/voiceinteraction/src/android/voiceinteraction/cts/VoiceInteractionTest.java
@@ -43,6 +43,7 @@
private TestResultsReceiver mReceiver;
private Bundle mResults;
private final CountDownLatch mLatch = new CountDownLatch(1);
+ // TODO: convert test to JUnit4 so we can use @RequiredFeatureRule instead
protected boolean mHasFeature;
protected static final String FEATURE_VOICE_RECOGNIZERS = "android.software.voice_recognizers";
@@ -53,13 +54,14 @@
@Override
protected void setUp() throws Exception {
super.setUp();
- startTestActivity();
+
mContext = getInstrumentation().getTargetContext();
mHasFeature = mContext.getPackageManager().hasSystemFeature(FEATURE_VOICE_RECOGNIZERS);
- if (mHasFeature) {
- mReceiver = new TestResultsReceiver();
- mContext.registerReceiver(mReceiver, new IntentFilter(Utils.BROADCAST_INTENT));
- }
+ if (!mHasFeature) return;
+
+ mReceiver = new TestResultsReceiver();
+ mContext.registerReceiver(mReceiver, new IntentFilter(Utils.BROADCAST_INTENT));
+ startTestActivity();
}
@Override
@@ -87,12 +89,13 @@
}
public void testAll() throws Exception {
- VoiceInteractionTestReceiver.waitSessionStarted(this, 5, TimeUnit.SECONDS);
-
if (!mHasFeature) {
Log.i(TAG, "The device doesn't support feature: " + FEATURE_VOICE_RECOGNIZERS);
return;
}
+
+ VoiceInteractionTestReceiver.waitSessionStarted(this, 5, TimeUnit.SECONDS);
+
if (!mLatch.await(TIMEOUT_MS, TimeUnit.MILLISECONDS)) {
fail("Failed to receive broadcast in " + TIMEOUT_MS + "msec");
return;
@@ -116,7 +119,7 @@
}
private void verifySingleTestcaseResult(Utils.TestCaseType testCaseType, String result) {
- Log.i(TAG, "Recevied testresult: " + result + " for " + testCaseType);
+ Log.i(TAG, "Received testresult: " + result + " for " + testCaseType);
switch (testCaseType) {
case ABORT_REQUEST_CANCEL_TEST:
assertTrue(result.equals(Utils.ABORT_REQUEST_CANCEL_SUCCESS));
diff --git a/tests/tests/voiceinteraction/testapp/src/android/voiceinteraction/testapp/TestApp.java b/tests/tests/voiceinteraction/testapp/src/android/voiceinteraction/testapp/TestApp.java
index 7c6cf53..11f330e 100644
--- a/tests/tests/voiceinteraction/testapp/src/android/voiceinteraction/testapp/TestApp.java
+++ b/tests/tests/voiceinteraction/testapp/src/android/voiceinteraction/testapp/TestApp.java
@@ -26,11 +26,9 @@
import android.app.VoiceInteractor.PickOptionRequest.Option;
import android.app.VoiceInteractor.Prompt;
import android.content.BroadcastReceiver;
-import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
-import android.service.voice.VoiceInteractionService;
import android.util.Log;
import java.util.ArrayList;
@@ -134,10 +132,10 @@
}
private void broadcastResults() {
- Intent intent = new Intent(Utils.BROADCAST_INTENT);
- intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
- intent.putExtras(mTotalInfo);
- Log.i(TAG, "broadcasting: " + intent.toString() + ", Bundle = " + mTotalInfo.toString());
+ Intent intent = new Intent(Utils.BROADCAST_INTENT)
+ .addFlags(Intent.FLAG_RECEIVER_FOREGROUND | Intent.FLAG_RECEIVER_REGISTERED_ONLY)
+ .putExtras(mTotalInfo);
+ Log.i(TAG, "broadcasting: " + intent + ", Bundle = " + mTotalInfo);
sendOrderedBroadcast(intent, null, new DoneReceiver(),
null, Activity.RESULT_OK, null, null);
}
diff --git a/tests/tests/webkit/src/android/webkit/cts/ChromeClient.java b/tests/tests/webkit/src/android/webkit/cts/ChromeClient.java
index ca61b24..5435cf8 100644
--- a/tests/tests/webkit/src/android/webkit/cts/ChromeClient.java
+++ b/tests/tests/webkit/src/android/webkit/cts/ChromeClient.java
@@ -16,7 +16,7 @@
package android.webkit.cts;
import android.webkit.ConsoleMessage;
-import android.webkit.cts.WebViewOnUiThread.WaitForProgressClient;
+import android.webkit.cts.WebViewSyncLoader.WaitForProgressClient;
// A chrome client for listening webview chrome events.
class ChromeClient extends WaitForProgressClient {
diff --git a/tests/tests/webkit/src/android/webkit/cts/GeolocationTest.java b/tests/tests/webkit/src/android/webkit/cts/GeolocationTest.java
index fb646c9..e240978 100644
--- a/tests/tests/webkit/src/android/webkit/cts/GeolocationTest.java
+++ b/tests/tests/webkit/src/android/webkit/cts/GeolocationTest.java
@@ -35,8 +35,8 @@
import android.webkit.WebResourceResponse;
import android.webkit.WebView;
import android.webkit.WebViewClient;
-import android.webkit.cts.WebViewOnUiThread.WaitForLoadedClient;
-import android.webkit.cts.WebViewOnUiThread.WaitForProgressClient;
+import android.webkit.cts.WebViewSyncLoader.WaitForLoadedClient;
+import android.webkit.cts.WebViewSyncLoader.WaitForProgressClient;
import com.android.compatibility.common.util.LocationUtils;
import com.android.compatibility.common.util.NullWebViewUtils;
diff --git a/tests/tests/webkit/src/android/webkit/cts/HttpAuthHandlerTest.java b/tests/tests/webkit/src/android/webkit/cts/HttpAuthHandlerTest.java
index 9b7a5bf..f4724cf 100644
--- a/tests/tests/webkit/src/android/webkit/cts/HttpAuthHandlerTest.java
+++ b/tests/tests/webkit/src/android/webkit/cts/HttpAuthHandlerTest.java
@@ -19,7 +19,7 @@
import android.test.ActivityInstrumentationTestCase2;
import android.webkit.HttpAuthHandler;
import android.webkit.WebView;
-import android.webkit.cts.WebViewOnUiThread.WaitForLoadedClient;
+import android.webkit.cts.WebViewSyncLoader.WaitForLoadedClient;
import com.android.compatibility.common.util.NullWebViewUtils;
diff --git a/tests/tests/webkit/src/android/webkit/cts/ServiceWorkerClientTest.java b/tests/tests/webkit/src/android/webkit/cts/ServiceWorkerClientTest.java
index cc1704b..2b9e8e5 100644
--- a/tests/tests/webkit/src/android/webkit/cts/ServiceWorkerClientTest.java
+++ b/tests/tests/webkit/src/android/webkit/cts/ServiceWorkerClientTest.java
@@ -25,7 +25,7 @@
import android.webkit.WebResourceRequest;
import android.webkit.WebView;
import android.webkit.WebViewClient;
-import android.webkit.cts.WebViewOnUiThread.WaitForLoadedClient;
+import android.webkit.cts.WebViewSyncLoader.WaitForLoadedClient;
import com.android.compatibility.common.util.NullWebViewUtils;
import com.android.compatibility.common.util.PollingCheck;
diff --git a/tests/tests/webkit/src/android/webkit/cts/TracingControllerTest.java b/tests/tests/webkit/src/android/webkit/cts/TracingControllerTest.java
index 9bc0daa..32f2df0 100644
--- a/tests/tests/webkit/src/android/webkit/cts/TracingControllerTest.java
+++ b/tests/tests/webkit/src/android/webkit/cts/TracingControllerTest.java
@@ -20,7 +20,7 @@
import android.webkit.TracingConfig;
import android.webkit.TracingController;
import android.webkit.WebView;
-import android.webkit.cts.WebViewOnUiThread.WaitForLoadedClient;
+import android.webkit.cts.WebViewSyncLoader.WaitForLoadedClient;
import com.android.compatibility.common.util.NullWebViewUtils;
import com.android.compatibility.common.util.PollingCheck;
diff --git a/tests/tests/webkit/src/android/webkit/cts/WebChromeClientTest.java b/tests/tests/webkit/src/android/webkit/cts/WebChromeClientTest.java
index b67322a..c881de4 100644
--- a/tests/tests/webkit/src/android/webkit/cts/WebChromeClientTest.java
+++ b/tests/tests/webkit/src/android/webkit/cts/WebChromeClientTest.java
@@ -27,7 +27,7 @@
import android.webkit.WebIconDatabase;
import android.webkit.WebSettings;
import android.webkit.WebView;
-import android.webkit.cts.WebViewOnUiThread.WaitForProgressClient;
+import android.webkit.cts.WebViewSyncLoader.WaitForProgressClient;
import com.android.compatibility.common.util.NullWebViewUtils;
import com.android.compatibility.common.util.PollingCheck;
diff --git a/tests/tests/webkit/src/android/webkit/cts/WebHistoryItemTest.java b/tests/tests/webkit/src/android/webkit/cts/WebHistoryItemTest.java
index 84a5efc..d2c54f0 100644
--- a/tests/tests/webkit/src/android/webkit/cts/WebHistoryItemTest.java
+++ b/tests/tests/webkit/src/android/webkit/cts/WebHistoryItemTest.java
@@ -19,7 +19,7 @@
import android.graphics.Bitmap;
import android.test.ActivityInstrumentationTestCase2;
import android.webkit.WebBackForwardList;
-import android.webkit.cts.WebViewOnUiThread.WaitForProgressClient;
+import android.webkit.cts.WebViewSyncLoader.WaitForProgressClient;
import android.webkit.WebHistoryItem;
import android.webkit.WebIconDatabase;
import android.webkit.WebView;
diff --git a/tests/tests/webkit/src/android/webkit/cts/WebSettingsTest.java b/tests/tests/webkit/src/android/webkit/cts/WebSettingsTest.java
index 542b66e..eac21a9 100644
--- a/tests/tests/webkit/src/android/webkit/cts/WebSettingsTest.java
+++ b/tests/tests/webkit/src/android/webkit/cts/WebSettingsTest.java
@@ -34,8 +34,8 @@
import android.webkit.WebStorage;
import android.webkit.WebView;
import android.webkit.WebViewClient;
-import android.webkit.cts.WebViewOnUiThread.WaitForLoadedClient;
-import android.webkit.cts.WebViewOnUiThread.WaitForProgressClient;
+import android.webkit.cts.WebViewSyncLoader.WaitForLoadedClient;
+import android.webkit.cts.WebViewSyncLoader.WaitForProgressClient;
import com.android.compatibility.common.util.NullWebViewUtils;
import com.android.compatibility.common.util.PollingCheck;
diff --git a/tests/tests/webkit/src/android/webkit/cts/WebViewClientTest.java b/tests/tests/webkit/src/android/webkit/cts/WebViewClientTest.java
index 997f876..c29054a 100644
--- a/tests/tests/webkit/src/android/webkit/cts/WebViewClientTest.java
+++ b/tests/tests/webkit/src/android/webkit/cts/WebViewClientTest.java
@@ -34,7 +34,7 @@
import android.webkit.WebSettings;
import android.webkit.WebView;
import android.webkit.WebViewClient;
-import android.webkit.cts.WebViewOnUiThread.WaitForLoadedClient;
+import android.webkit.cts.WebViewSyncLoader.WaitForLoadedClient;
import android.util.Pair;
import com.android.compatibility.common.util.NullWebViewUtils;
diff --git a/tests/tests/webkit/src/android/webkit/cts/WebViewSslTest.java b/tests/tests/webkit/src/android/webkit/cts/WebViewSslTest.java
index e6c79db..7fd8fc8 100644
--- a/tests/tests/webkit/src/android/webkit/cts/WebViewSslTest.java
+++ b/tests/tests/webkit/src/android/webkit/cts/WebViewSslTest.java
@@ -29,7 +29,7 @@
import android.webkit.WebSettings;
import android.webkit.WebView;
import android.webkit.WebViewClient;
-import android.webkit.cts.WebViewOnUiThread.WaitForLoadedClient;
+import android.webkit.cts.WebViewSyncLoader.WaitForLoadedClient;
import com.android.compatibility.common.util.NullWebViewUtils;
import com.android.compatibility.common.util.PollingCheck;
@@ -727,12 +727,23 @@
mOnUiThread.clearSslPreferences();
mOnUiThread.loadUrlAndWaitForCompletion(url);
// Page NOT loaded OK...
- // In this case, we must NOT have received the onReceivedSslError callback as that is for
- // recoverable (e.g. server auth) errors, whereas failing mandatory client auth is non-
- // recoverable and should drop straight through to a load error.
- assertFalse(webViewClient.wasOnReceivedSslErrorCalled());
- assertFalse(TestHtmlConstants.HELLO_WORLD_TITLE.equals(mOnUiThread.getTitle()));
- assertEquals(WebViewClient.ERROR_FAILED_SSL_HANDSHAKE, webViewClient.onReceivedErrorCode());
+ //
+ // In this test, we expect both a recoverable and non-recoverable error:
+ //
+ // 1. WebView does not trust the test server's certificate. This is a recoverable error, so
+ // WebView invokes #onReceivedSslError (and the WebViewClient calls #proceed). We don't
+ // specifically intend to test this part of the scenario, but we can't easily mock out
+ // WebView's certificate roots.
+ // 2. WebView proceeds with the handshake without providing client authentication. The
+ // server fails the client. This is non-recoverable, so WebView invokes
+ // #onReceivedError.
+ //
+ // We only assert the second error, since earlier WebView versions had a bug in which
+ // WebView hit error 2 first, which prevented it from hitting error 1.
+ assertFalse("Title should not be updated, since page load should have failed",
+ TestHtmlConstants.HELLO_WORLD_TITLE.equals(mOnUiThread.getTitle()));
+ assertEquals("Expected ERROR_FAILED_SSL_HANDSHAKE in onReceivedError",
+ WebViewClient.ERROR_FAILED_SSL_HANDSHAKE, webViewClient.onReceivedErrorCode());
}
public void testProceedClientCertRequest() throws Throwable {
diff --git a/tests/tests/webkit/src/android/webkit/cts/WebViewTest.java b/tests/tests/webkit/src/android/webkit/cts/WebViewTest.java
index 6922d74..2f95f82 100644
--- a/tests/tests/webkit/src/android/webkit/cts/WebViewTest.java
+++ b/tests/tests/webkit/src/android/webkit/cts/WebViewTest.java
@@ -74,8 +74,8 @@
import android.webkit.WebView.VisualStateCallback;
import android.webkit.WebViewClient;
import android.webkit.WebViewDatabase;
-import android.webkit.cts.WebViewOnUiThread.WaitForLoadedClient;
-import android.webkit.cts.WebViewOnUiThread.WaitForProgressClient;
+import android.webkit.cts.WebViewSyncLoader.WaitForLoadedClient;
+import android.webkit.cts.WebViewSyncLoader.WaitForProgressClient;
import android.widget.LinearLayout;
import com.android.compatibility.common.util.NullWebViewUtils;
@@ -954,7 +954,7 @@
childOnUiThread.addJavascriptInterface(obj, "dummy");
final SettableFuture<Void> onCreateWindowFuture = SettableFuture.create();
- mOnUiThread.setWebChromeClient(new WebViewOnUiThread.WaitForProgressClient(mOnUiThread) {
+ mOnUiThread.setWebChromeClient(new WebViewSyncLoader.WaitForProgressClient(mOnUiThread) {
@Override
public boolean onCreateWindow(
WebView view, boolean isDialog, boolean isUserGesture, Message resultMsg) {
diff --git a/tests/tests/widget/res/layout/textview_isHorizontallyScrolling_layout.xml b/tests/tests/widget/res/layout/textview_isHorizontallyScrollable_layout.xml
similarity index 100%
rename from tests/tests/widget/res/layout/textview_isHorizontallyScrolling_layout.xml
rename to tests/tests/widget/res/layout/textview_isHorizontallyScrollable_layout.xml
diff --git a/tests/tests/widget/src/android/widget/cts/PopupWindowTest.java b/tests/tests/widget/src/android/widget/cts/PopupWindowTest.java
index 4384c0c..f083053 100644
--- a/tests/tests/widget/src/android/widget/cts/PopupWindowTest.java
+++ b/tests/tests/widget/src/android/widget/cts/PopupWindowTest.java
@@ -1428,7 +1428,8 @@
final View anchor = mActivity.findViewById(R.id.anchor_middle);
final LayoutParams anchorLayoutParams = anchor.getLayoutParams();
- final int[] originalLocation = mPopupWindow.getContentView().getLocationOnScreen();
+ final int[] originalLocation = new int[2];
+ mPopupWindow.getContentView().getLocationOnScreen(originalLocation);
final int deltaX = 30;
final int deltaY = 20;
@@ -1562,8 +1563,10 @@
mPopupWindow.getContentView().findViewById(R.id.anchor_middle)));
mInstrumentation.waitForIdleSync();
- final int[] popupLocation = mPopupWindow.getContentView().getLocationOnScreen();
- final int[] subPopupLocation = subPopup.getContentView().getLocationOnScreen();
+ final int[] popupLocation = new int[2];
+ mPopupWindow.getContentView().getLocationOnScreen(popupLocation);
+ final int[] subPopupLocation = new int[2];
+ subPopup.getContentView().getLocationOnScreen(subPopupLocation);
final int deltaX = 20;
final int deltaY = 30;
@@ -1579,11 +1582,13 @@
// the anchor change), we need to wait until all traversals are done.
mInstrumentation.waitForIdleSync();
- final int[] newPopupLocation = mPopupWindow.getContentView().getLocationOnScreen();
+ final int[] newPopupLocation = new int[2];
+ mPopupWindow.getContentView().getLocationOnScreen(newPopupLocation);
assertEquals(popupLocation[0] - deltaX, newPopupLocation[0]);
assertEquals(popupLocation[1] - deltaY, newPopupLocation[1]);
- final int[] newSubPopupLocation = subPopup.getContentView().getLocationOnScreen();
+ final int[] newSubPopupLocation = new int[2];
+ subPopup.getContentView().getLocationOnScreen(newSubPopupLocation);
assertEquals(subPopupLocation[0] - deltaX, newSubPopupLocation[0]);
assertEquals(subPopupLocation[1] - deltaY, newSubPopupLocation[1]);
}
@@ -1598,7 +1603,8 @@
}
private void assertPopupLocation(int[] originalLocation, int deltaX, int deltaY) {
- final int[] actualLocation = mPopupWindow.getContentView().getLocationOnScreen();
+ final int[] actualLocation = new int[2];
+ mPopupWindow.getContentView().getLocationOnScreen(actualLocation);
assertEquals(originalLocation[0] - deltaX, actualLocation[0]);
assertEquals(originalLocation[1] - deltaY, actualLocation[1]);
}
diff --git a/tests/tests/widget/src/android/widget/cts/TextViewIsHorizontallyScrollingTest.java b/tests/tests/widget/src/android/widget/cts/TextViewIsHorizontallyScrollableTest.java
similarity index 81%
rename from tests/tests/widget/src/android/widget/cts/TextViewIsHorizontallyScrollingTest.java
rename to tests/tests/widget/src/android/widget/cts/TextViewIsHorizontallyScrollableTest.java
index f3e3847..4dd1bf7 100644
--- a/tests/tests/widget/src/android/widget/cts/TextViewIsHorizontallyScrollingTest.java
+++ b/tests/tests/widget/src/android/widget/cts/TextViewIsHorizontallyScrollableTest.java
@@ -33,18 +33,18 @@
/**
- * Test {@link TextView#isHorizontallyScrolling}.
+ * Test {@link TextView#isHorizontallyScrollable}.
*/
@SmallTest
@RunWith(AndroidJUnit4.class)
-public class TextViewIsHorizontallyScrollingTest {
+public class TextViewIsHorizontallyScrollableTest {
private ViewGroup mViewGroup;
@Before
public void setup() {
final Context context = InstrumentationRegistry.getInstrumentation().getTargetContext();
final LayoutInflater inflater = LayoutInflater.from(context);
- mViewGroup = (ViewGroup) inflater.inflate(R.layout.textview_isHorizontallyScrolling_layout,
+ mViewGroup = (ViewGroup) inflater.inflate(R.layout.textview_isHorizontallyScrollable_layout,
null);
}
@@ -53,7 +53,7 @@
final TextView textView = mViewGroup.findViewById(
R.id.textView_scrollHorizontally_default);
- assertFalse(textView.isHorizontallyScrolling());
+ assertFalse(textView.isHorizontallyScrollable());
}
@Test
@@ -62,7 +62,7 @@
R.id.textView_scrollHorizontally_default);
textView.setHorizontallyScrolling(true);
- assertTrue(textView.isHorizontallyScrolling());
+ assertTrue(textView.isHorizontallyScrollable());
}
@Test
@@ -70,10 +70,10 @@
final TextView textView = mViewGroup.findViewById(
R.id.textView_scrollHorizontally_default);
textView.setHorizontallyScrolling(true);
- assertTrue(textView.isHorizontallyScrolling());
+ assertTrue(textView.isHorizontallyScrollable());
textView.setHorizontallyScrolling(false);
- assertFalse(textView.isHorizontallyScrolling());
+ assertFalse(textView.isHorizontallyScrollable());
}
@Test
@@ -82,42 +82,42 @@
R.id.textView_scrollHorizontally_true);
// It should return true here. But because of this bug b/120448952,
// singleLine will overwrite scrollHorizontally.
- assertFalse(textViewTrue.isHorizontallyScrolling());
+ assertFalse(textViewTrue.isHorizontallyScrollable());
final TextView textViewFalse = mViewGroup.findViewById(
R.id.textView_scrollHorizontally_false);
- assertFalse(textViewFalse.isHorizontallyScrolling());
+ assertFalse(textViewFalse.isHorizontallyScrollable());
}
@Test
public void testIsHorizontallyScrollingSetInXML_returnTrueWhenSingleLineIsTrue() {
final TextView textViewDefault = mViewGroup.findViewById(
R.id.textView_scrollHorizontally_default_singleLine_true);
- assertTrue(textViewDefault.isHorizontallyScrolling());
+ assertTrue(textViewDefault.isHorizontallyScrollable());
final TextView textViewTrue = mViewGroup.findViewById(
R.id.textView_scrollHorizontally_true_singleLine_true);
- assertTrue(textViewTrue.isHorizontallyScrolling());
+ assertTrue(textViewTrue.isHorizontallyScrollable());
final TextView textViewFalse = mViewGroup.findViewById(
R.id.textView_scrollHorizontally_false_singleLine_true);
- assertTrue(textViewFalse.isHorizontallyScrolling());
+ assertTrue(textViewFalse.isHorizontallyScrollable());
}
@Test
public void testIsHorizontallyScrollingSetInXML_returnGivenValueWhenSingleLineIsFalse() {
final TextView textViewDefault = mViewGroup.findViewById(
R.id.textView_scrollHorizontally_default_singleLine_false);
- assertFalse(textViewDefault.isHorizontallyScrolling());
+ assertFalse(textViewDefault.isHorizontallyScrollable());
final TextView textViewTrue = mViewGroup.findViewById(
R.id.textView_scrollHorizontally_true_singleLine_false);
// It should return true here. But because of this bug b/120448952,
// singleLine will overwrite scrollHorizontally.
- assertFalse(textViewTrue.isHorizontallyScrolling());
+ assertFalse(textViewTrue.isHorizontallyScrollable());
final TextView textViewFalse = mViewGroup.findViewById(
R.id.textView_scrollHorizontally_false_singleLine_false);
- assertFalse(textViewFalse.isHorizontallyScrolling());
+ assertFalse(textViewFalse.isHorizontallyScrollable());
}
}
diff --git a/tools/vm-tests-tf/src/dot/junit/opcodes/add_double/d/T_add_double_2.d.done b/tools/vm-tests-tf/src/dot/junit/opcodes/add_double/d/T_add_double_2.d.done
deleted file mode 100644
index da30626..0000000
--- a/tools/vm-tests-tf/src/dot/junit/opcodes/add_double/d/T_add_double_2.d.done
+++ /dev/null
@@ -1,34 +0,0 @@
-; 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.
-
-.source T_add_double_2.java
-.class public dot.junit.opcodes.add_double.d.T_add_double_2
-.super java/lang/Object
-
-
-.method public <init>()V
-.limit regs 1
- invoke-direct {v0}, java/lang/Object/<init>()V
- return-void
-.end method
-
-.method public run(DD)D
-.limit regs 7
-
- const v3, 3.1415
- add-double v0, v3, v5
- return-wide v5
-.end method
-
-
diff --git a/tools/vm-tests-tf/src/dot/junit/opcodes/add_double_2addr/d/T_add_double_2addr_2.d.done b/tools/vm-tests-tf/src/dot/junit/opcodes/add_double_2addr/d/T_add_double_2addr_2.d.done
deleted file mode 100644
index 3633e01..0000000
--- a/tools/vm-tests-tf/src/dot/junit/opcodes/add_double_2addr/d/T_add_double_2addr_2.d.done
+++ /dev/null
@@ -1,34 +0,0 @@
-; 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.
-
-.source T_add_double_2addr_2.java
-.class public dot.junit.opcodes.add_double_2addr.d.T_add_double_2addr_2
-.super java/lang/Object
-
-
-.method public <init>()V
-.limit regs 1
- invoke-direct {v0}, java/lang/Object/<init>()V
- return-void
-.end method
-
-.method public run(DD)D
-.limit regs 7
-
- const v3, 3.1415
- add-double/2addr v3, v5
- return-wide v5
-.end method
-
-
diff --git a/tools/vm-tests-tf/src/dot/junit/opcodes/add_long/d/T_add_long_4.d.done b/tools/vm-tests-tf/src/dot/junit/opcodes/add_long/d/T_add_long_4.d.done
deleted file mode 100644
index 9dab202..0000000
--- a/tools/vm-tests-tf/src/dot/junit/opcodes/add_long/d/T_add_long_4.d.done
+++ /dev/null
@@ -1,35 +0,0 @@
-; 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.
-
-.source T_add_long_4.java
-.class public dot.junit.opcodes.add_long.d.T_add_long_4
-.super java/lang/Object
-
-
-.method public <init>()V
-.limit regs 1
-
- invoke-direct {v0}, java/lang/Object/<init>()V
- return-void
-.end method
-
-.method public run(JJ)J
-.limit regs 7
-
- const v5, 12345.0
- add-long v0, v3, v5
- return-wide v3
-.end method
-
-
diff --git a/tools/vm-tests-tf/src/dot/junit/opcodes/add_long_2addr/d/T_add_long_2addr_4.d.done b/tools/vm-tests-tf/src/dot/junit/opcodes/add_long_2addr/d/T_add_long_2addr_4.d.done
deleted file mode 100644
index 1073b6c..0000000
--- a/tools/vm-tests-tf/src/dot/junit/opcodes/add_long_2addr/d/T_add_long_2addr_4.d.done
+++ /dev/null
@@ -1,35 +0,0 @@
-; 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.
-
-.source T_add_long_2addr_4.java
-.class public dot.junit.opcodes.add_long_2addr.d.T_add_long_2addr_4
-.super java/lang/Object
-
-
-.method public <init>()V
-.limit regs 1
-
- invoke-direct {v0}, java/lang/Object/<init>()V
- return-void
-.end method
-
-.method public run(JJ)J
-.limit regs 7
-
- const v5, 12345.0
- add-long/2addr v3, v5
- return-wide v3
-.end method
-
-
diff --git a/tools/vm-tests-tf/src/dot/junit/opcodes/and_long/d/T_and_long_2.d.done b/tools/vm-tests-tf/src/dot/junit/opcodes/and_long/d/T_and_long_2.d.done
deleted file mode 100644
index 7c9185c..0000000
--- a/tools/vm-tests-tf/src/dot/junit/opcodes/and_long/d/T_and_long_2.d.done
+++ /dev/null
@@ -1,35 +0,0 @@
-; 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.
-
-.source T_and_long_2.java
-.class public dot.junit.opcodes.and_long.d.T_and_long_2
-.super java/lang/Object
-
-
-.method public <init>()V
-.limit regs 1
-
- invoke-direct {v0}, java/lang/Object/<init>()V
- return-void
-.end method
-
-.method public run(JJ)J
-.limit regs 14
-
- const v10, 3.1415
- and-long v0, v10, v12
- return-wide v0
-.end method
-
-
diff --git a/tools/vm-tests-tf/src/dot/junit/opcodes/and_long_2addr/d/T_and_long_2addr_2.d.done b/tools/vm-tests-tf/src/dot/junit/opcodes/and_long_2addr/d/T_and_long_2addr_2.d.done
deleted file mode 100644
index e1a4376..0000000
--- a/tools/vm-tests-tf/src/dot/junit/opcodes/and_long_2addr/d/T_and_long_2addr_2.d.done
+++ /dev/null
@@ -1,35 +0,0 @@
-; 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.
-
-.source T_and_long_2addr_2.java
-.class public dot.junit.opcodes.and_long_2addr.d.T_and_long_2addr_2
-.super java/lang/Object
-
-
-.method public <init>()V
-.limit regs 1
-
- invoke-direct {v0}, java/lang/Object/<init>()V
- return-void
-.end method
-
-.method public run(JJ)J
-.limit regs 14
-
- const v0, 3.1415
- and-long/2addr v0, v12
- return-wide v10
-.end method
-
-
diff --git a/tools/vm-tests-tf/src/dot/junit/opcodes/aput_object/d/T_aput_object_3.d.done b/tools/vm-tests-tf/src/dot/junit/opcodes/aput_object/d/T_aput_object_3.d.done
deleted file mode 100644
index 4b2642d..0000000
--- a/tools/vm-tests-tf/src/dot/junit/opcodes/aput_object/d/T_aput_object_3.d.done
+++ /dev/null
@@ -1,132 +0,0 @@
-; 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.
-
-.source TestStubs.java
-.interface abstract dot.junit.opcodes.aput_object.d.SuperInterface
-
-.source TestStubs.java
-.interface public dot.junit.opcodes.aput_object.d.SuperInterface2
-
-.source TestStubs.java
-.class public dot.junit.opcodes.aput_object.d.SuperClass
-.super java/lang/Object
-.implements dot.junit.opcodes.aput_object.d.SuperInterface
-.method public <init>()V
-.limit regs 1
-
- invoke-direct {v0}, java/lang/Object/<init>()V
- return-void
-.end method
-
-.source TestStubs.java
-.class public dot.junit.opcodes.aput_object.d.SubClass
-.super dot.junit.opcodes.aput_object.d.SuperClass
-.method public <init>()V
-.limit regs 1
-
- invoke-direct {v0}, dot/junit/opcodes/aput_object/d/SuperClass/<init>()V
- return-void
-.end method
-
-
-.source T_aput_object_3.java
-.class public dot.junit.opcodes.aput_object.d.T_aput_object_3
-.super java/lang/Object
-
-
-.method public <init>()V
-.limit regs 1
-
- invoke-direct {v0}, java/lang/Object/<init>()V
- return-void
-.end method
-
-.method public run()I
-.limit regs 32
-
- const v1, 0
-
- const v0, 1
- ; v2 = SubClass[]
- new-array v2, v0, [Ldot/junit/opcodes/aput_object/d/SubClass;
-
- ; v3 = SuperClass[]
- new-array v3, v0, [Ldot/junit/opcodes/aput_object/d/SuperClass;
-
- ; v4 = SubClass
- new-instance v4, dot/junit/opcodes/aput_object/d/SubClass
- invoke-direct {v4}, dot/junit/opcodes/aput_object/d/SubClass/<init>()V
-
- ; v5 = SuperClass
- new-instance v5, dot/junit/opcodes/aput_object/d/SuperClass
- invoke-direct {v5}, dot/junit/opcodes/aput_object/d/SuperClass/<init>()V
-
- ; v6 = SuperInterface[]
- new-array v6, v0, [Ldot/junit/opcodes/aput_object/d/SuperInterface;
-
- ; v7 = Object[]
- new-array v7, v0, [Ljava/lang/Object;
-
- ; v8 = SuperInterface2[]
- new-array v8, v0, [Ldot/junit/opcodes/aput_object/d/SuperInterface2;
-
- const/4 v0, 0
-
-; (SubClass -> SuperClass[])
- aput-object v4, v3, v0
-
-; (SubClass -> SuperInterface[])
- aput-object v4, v6, v0
-
-; (SubClass -> Object[])
- aput-object v4, v7, v0
-
-; !(SuperClass -> SubClass[])
-Label10:
- aput-object v5, v2, v0
-Label11:
- goto Label2
-Label12:
- add-int/lit8 v1, v1, 1
- goto Label2
-
-; !(SuperClass -> SuperInterface2[])
-Label2:
-Label20:
- aput-object v5, v8, v0
-Label21:
- goto Label3
-Label22:
- add-int/lit8 v1, v1, 1
- goto Label3
-
-; !(SubClass[] -> SuperInterface[])
-Label3:
-Label30:
- aput-object v2, v6, v0
-Label31:
- goto Label4
-Label32:
- add-int/lit8 v1, v1, 1
- goto Label4
-
-Label4:
- return v1
-
-.catch java/lang/ArrayStoreException from Label10 to Label11 using Label12
-.catch java/lang/ArrayStoreException from Label20 to Label21 using Label22
-.catch java/lang/ArrayStoreException from Label30 to Label31 using Label32
-.end method
-
-
diff --git a/tools/vm-tests-tf/src/dot/junit/opcodes/check_cast/d/T_check_cast_2.d.done b/tools/vm-tests-tf/src/dot/junit/opcodes/check_cast/d/T_check_cast_2.d.done
deleted file mode 100644
index b7472cc..0000000
--- a/tools/vm-tests-tf/src/dot/junit/opcodes/check_cast/d/T_check_cast_2.d.done
+++ /dev/null
@@ -1,149 +0,0 @@
-; 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.
-
-.source TestStubs.java
-.interface public dot.junit.opcodes.check_cast.d.T_check_cast_2.SuperInterface
-
-.source TestStubs.java
-.interface public dot.junit.opcodes.check_cast.d.T_check_cast_2.SuperInterface2
-
-.source TestStubs.java
-.class public dot.junit.opcodes.check_cast.d.T_check_cast_2.SuperClass
-.super java/lang/Object
-.implements dot/junit/opcodes/check_cast/d/T_check_cast_2/SuperInterface
-
-.method public <init>()V
-.limit regs 1
-
- invoke-direct {v0}, java/lang/Object/<init>()V
- return-void
-.end method
-
-.source TestStubs.java
-.class public dot.junit.opcodes.check_cast.d.T_check_cast_2.SubClass
-.super dot/junit/opcodes/check_cast/d/T_check_cast_2/SuperClass
-
-.method public <init>()V
-.limit regs 1
-
- invoke-direct {v0}, dot/junit/opcodes/check_cast/d/T_check_cast_2/SuperClass/<init>()V
- return-void
-.end method
-
-
-.source T_check_cast_2.java
-.class public dot.junit.opcodes.check_cast.d.T_check_cast_2
-.super java/lang/Object
-
-
-.method public <init>()V
-.limit regs 1
-
- invoke-direct {v0}, java/lang/Object/<init>()V
- return-void
-.end method
-
-.method public run()I
-.limit regs 20
-
- const v1, 0
-
-; (SubClass instanceof SuperClass)
- new-instance v10, dot/junit/opcodes/check_cast/d/T_check_cast_2/SubClass
- invoke-direct {v10}, dot/junit/opcodes/check_cast/d/T_check_cast_2/SubClass/<init>()V
- check-cast v10, dot/junit/opcodes/check_cast/d/T_check_cast_2/SuperClass
-
-; (SubClass[] instanceof SuperClass[])
- const v11, 1
- new-array v10, v11, [Ldot/junit/opcodes/check_cast/d/T_check_cast_2/SubClass;
- check-cast v10, [Ldot/junit/opcodes/check_cast/d/T_check_cast_2/SuperClass;
-
-
-; (SubClass[] instanceof Object)
- new-array v10, v11, [Ldot/junit/opcodes/check_cast/d/T_check_cast_2/SubClass;
- check-cast v10, java/lang/Object
-
-; (SubClass instanceof SuperInterface)
- new-instance v10, dot/junit/opcodes/check_cast/d/T_check_cast_2/SubClass
- invoke-direct {v10}, dot/junit/opcodes/check_cast/d/T_check_cast_2/SubClass/<init>()V
- check-cast v10, dot/junit/opcodes/check_cast/d/T_check_cast_2/SuperInterface
-
-
-; !(SuperClass instanceof SubClass)
-Label1:
- new-instance v10, dot/junit/opcodes/check_cast/d/T_check_cast_2/SuperClass
- invoke-direct {v10}, dot/junit/opcodes/check_cast/d/T_check_cast_2/SuperClass/<init>()V
-Label10:
- check-cast v10, dot/junit/opcodes/check_cast/d/T_check_cast_2/SubClass
-Label11:
- goto Label2
-Label12:
- add-int/lit16 v1, v1, 1
- goto Label2
-
-; !(SubClass instanceof SuperInterface2)
-Label2:
- new-instance v10, dot/junit/opcodes/check_cast/d/T_check_cast_2/SubClass
- invoke-direct {v10}, dot/junit/opcodes/check_cast/d/T_check_cast_2/SubClass/<init>()V
-Label20:
- check-cast v10, dot/junit/opcodes/check_cast/d/T_check_cast_2/SuperInterface2
-Label21:
- goto Label3
-Label22:
- add-int/lit16 v1, v1, 1
- goto Label3
-
-; !(SubClass[] instanceof SuperInterface)
-Label3:
- new-array v10, v11, [Ldot/junit/opcodes/check_cast/d/T_check_cast_2/SubClass;
-Label30:
- check-cast v10, dot/junit/opcodes/check_cast/d/T_check_cast_2/SuperInterface
-Label31:
- goto Label4
-Label32:
- add-int/lit16 v1, v1, 1
- goto Label4
-
-; !(SubClass[] instanceof SubClass)
-Label4:
- new-array v10, v11, [Ldot/junit/opcodes/check_cast/d/T_check_cast_2/SubClass;
-Label40:
- check-cast v10, dot/junit/opcodes/check_cast/d/T_check_cast_2/SubClass
-Label41:
- goto Label5
-Label42:
- add-int/lit16 v1, v1, 1
- goto Label5
-
-; !(SuperClass[] instanceof SubClass[])
-Label5:
- new-array v10, v11, [Ldot/junit/opcodes/check_cast/d/T_check_cast_2/SuperClass;
-Label50:
- check-cast v10, [Ldot/junit/opcodes/check_cast/d/T_check_cast_2/SubClass;
-Label51:
- goto Label6
-Label52:
- add-int/lit16 v1, v1, 1
-
-Label6:
- return v1
-
-.catch java/lang/ClassCastException from Label10 to Label11 using Label12
-.catch java/lang/ClassCastException from Label20 to Label21 using Label22
-.catch java/lang/ClassCastException from Label30 to Label31 using Label32
-.catch java/lang/ClassCastException from Label40 to Label41 using Label42
-.catch java/lang/ClassCastException from Label50 to Label51 using Label52
-.end method
-
-
diff --git a/tools/vm-tests-tf/src/dot/junit/opcodes/cmp_long/d/T_cmp_long_3.d.done b/tools/vm-tests-tf/src/dot/junit/opcodes/cmp_long/d/T_cmp_long_3.d.done
deleted file mode 100644
index 3d25d6b..0000000
--- a/tools/vm-tests-tf/src/dot/junit/opcodes/cmp_long/d/T_cmp_long_3.d.done
+++ /dev/null
@@ -1,34 +0,0 @@
-; 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.
-
-.source T_cmp_long_3.java
-.class public dot.junit.opcodes.cmp_long.d.T_cmp_long_3
-.super java/lang/Object
-
-
-.method public <init>()V
-.limit regs 1
- invoke-direct {v0}, java/lang/Object/<init>()V
- return-void
-.end method
-
-.method public run(JJ)I
-.limit regs 14
-
- const v10, 3.1415
- cmp-long v0, v10, v12
- return v0
-.end method
-
-
diff --git a/tools/vm-tests-tf/src/dot/junit/opcodes/cmpg_double/d/T_cmpg_double_2.d.done b/tools/vm-tests-tf/src/dot/junit/opcodes/cmpg_double/d/T_cmpg_double_2.d.done
deleted file mode 100644
index 5704511..0000000
--- a/tools/vm-tests-tf/src/dot/junit/opcodes/cmpg_double/d/T_cmpg_double_2.d.done
+++ /dev/null
@@ -1,34 +0,0 @@
-; 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.
-
-.source T_cmpg_double_2.java
-.class public dot.junit.opcodes.cmpg_double.d.T_cmpg_double_2
-.super java/lang/Object
-
-
-.method public <init>()V
-.limit regs 1
- invoke-direct {v0}, java/lang/Object/<init>()V
- return-void
-.end method
-
-.method public run(DD)I
-.limit regs 16
-
- const v14, 3.14
- cmpg-double v0, v12, v14
- return v0
-.end method
-
-
diff --git a/tools/vm-tests-tf/src/dot/junit/opcodes/cmpl_double/d/T_cmpl_double_2.d.done b/tools/vm-tests-tf/src/dot/junit/opcodes/cmpl_double/d/T_cmpl_double_2.d.done
deleted file mode 100644
index 49566ce..0000000
--- a/tools/vm-tests-tf/src/dot/junit/opcodes/cmpl_double/d/T_cmpl_double_2.d.done
+++ /dev/null
@@ -1,34 +0,0 @@
-; 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.
-
-.source T_cmpl_double_2.java
-.class public dot.junit.opcodes.cmpl_double.d.T_cmpl_double_2
-.super java/lang/Object
-
-
-.method public <init>()V
-.limit regs 1
- invoke-direct {v0}, java/lang/Object/<init>()V
- return-void
-.end method
-
-.method public run(DD)I
-.limit regs 16
-
- const v14, 3.14
- cmpl-double v0, v12, v14
- return v0
-.end method
-
-
diff --git a/tools/vm-tests-tf/src/dot/junit/opcodes/const_class/d/T_const_class_1.d.done b/tools/vm-tests-tf/src/dot/junit/opcodes/const_class/d/T_const_class_1.d.done
deleted file mode 100644
index 6359d92..0000000
--- a/tools/vm-tests-tf/src/dot/junit/opcodes/const_class/d/T_const_class_1.d.done
+++ /dev/null
@@ -1,34 +0,0 @@
-; 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.
-
-.source T_const_class_1.java
-.class public dot.junit.opcodes.const_class.d.T_const_class_1
-.super java/lang/Object
-
-
-.method public <init>()V
-.limit regs 1
-
- invoke-direct {v0}, java/lang/Object/<init>()V
- return-void
-.end method
-
-.method public run()Ljava/lang/Class;
-.limit regs 255
-
- const-class v254, java/lang/String
- return-object v254
-.end method
-
-
diff --git a/tools/vm-tests-tf/src/dot/junit/opcodes/const_class/d/T_const_class_3.d.done b/tools/vm-tests-tf/src/dot/junit/opcodes/const_class/d/T_const_class_3.d.done
deleted file mode 100644
index 50da342..0000000
--- a/tools/vm-tests-tf/src/dot/junit/opcodes/const_class/d/T_const_class_3.d.done
+++ /dev/null
@@ -1,35 +0,0 @@
-; 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.
-
-.source T_const_class_3.java
-.class public dot.junit.opcodes.const_class.d.T_const_class_3
-.super java/lang/Object
-
-
-.method public <init>()V
-.limit regs 1
-
- invoke-direct {v0}, java/lang/Object/<init>()V
- return-void
-.end method
-
-.method public run()V
-.limit regs 3
-
- const-class v3, java/lang/Object
-
- return-void
-.end method
-
-
diff --git a/tools/vm-tests-tf/src/dot/junit/opcodes/const_class/d/T_const_class_4.d.done b/tools/vm-tests-tf/src/dot/junit/opcodes/const_class/d/T_const_class_4.d.done
deleted file mode 100644
index 6f6b7b9..0000000
--- a/tools/vm-tests-tf/src/dot/junit/opcodes/const_class/d/T_const_class_4.d.done
+++ /dev/null
@@ -1,35 +0,0 @@
-; 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.
-
-.source T_const_class_4.java
-.class public dot.junit.opcodes.const_class.d.T_const_class_4
-.super java/lang/Object
-
-
-.method public <init>()V
-.limit regs 1
-
- invoke-direct {v0}, java/lang/Object/<init>()V
- return-void
-.end method
-
-.method public run()J
-.limit regs 3
- const-wide v0, 1234
- const-class v1, java/lang/Object
-
- return-wide v0
-.end method
-
-
diff --git a/tools/vm-tests-tf/src/dot/junit/opcodes/const_class/d/T_const_class_5.d.done b/tools/vm-tests-tf/src/dot/junit/opcodes/const_class/d/T_const_class_5.d.done
deleted file mode 100644
index 24186a5..0000000
--- a/tools/vm-tests-tf/src/dot/junit/opcodes/const_class/d/T_const_class_5.d.done
+++ /dev/null
@@ -1,34 +0,0 @@
-; 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.
-
-.source T_const_class_5.java
-.class public dot.junit.opcodes.const_class.d.T_const_class_5
-.super java/lang/Object
-
-
-.method public <init>()V
-.limit regs 1
-
- invoke-direct {v0}, java/lang/Object/<init>()V
- return-void
-.end method
-
-.method public run()Ljava/lang/String;
-.limit regs 255
-
- const-class v254, java/lang/Object
- return-object v254
-.end method
-
-
diff --git a/tools/vm-tests-tf/src/dot/junit/opcodes/const_class/d/T_const_class_6.d.done b/tools/vm-tests-tf/src/dot/junit/opcodes/const_class/d/T_const_class_6.d.done
deleted file mode 100644
index bd893c9..0000000
--- a/tools/vm-tests-tf/src/dot/junit/opcodes/const_class/d/T_const_class_6.d.done
+++ /dev/null
@@ -1,34 +0,0 @@
-; 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.
-
-.source T_const_class_6.java
-.class public dot.junit.opcodes.const_class.d.T_const_class_6
-.super java/lang/Object
-
-
-.method public <init>()V
-.limit regs 1
-
- invoke-direct {v0}, java/lang/Object/<init>()V
- return-void
-.end method
-
-.method public run()Ljava/lang/Class;
-.limit regs 255
-
- const-class v254, java/lang/StringNNNNN
- return-object v254
-.end method
-
-
diff --git a/tools/vm-tests-tf/src/dot/junit/opcodes/const_class/d/T_const_class_7.d.done b/tools/vm-tests-tf/src/dot/junit/opcodes/const_class/d/T_const_class_7.d.done
deleted file mode 100644
index 20d9749..0000000
--- a/tools/vm-tests-tf/src/dot/junit/opcodes/const_class/d/T_const_class_7.d.done
+++ /dev/null
@@ -1,34 +0,0 @@
-; 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.
-
-.source T_const_class_7.java
-.class public dot.junit.opcodes.const_class.d.T_const_class_7
-.super java/lang/Object
-
-
-.method public <init>()V
-.limit regs 1
-
- invoke-direct {v0}, java/lang/Object/<init>()V
- return-void
-.end method
-
-.method public run()Ljava/lang/Class;
-.limit regs 255
-
- const-class v254, dot/junit/opcodes/const_class/TestStubs
- return-object v254
-.end method
-
-
diff --git a/tools/vm-tests-tf/src/dot/junit/opcodes/const_wide/d/T_const_wide_2.d.done b/tools/vm-tests-tf/src/dot/junit/opcodes/const_wide/d/T_const_wide_2.d.done
deleted file mode 100644
index b2ddede..0000000
--- a/tools/vm-tests-tf/src/dot/junit/opcodes/const_wide/d/T_const_wide_2.d.done
+++ /dev/null
@@ -1,34 +0,0 @@
-; 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.
-
-.source T_const_wide_2.java
-.class public dot.junit.opcodes.const_wide.d.T_const_wide_2
-.super java/lang/Object
-
-
-.method public <init>()V
-.limit regs 1
-
- invoke-direct {v0}, java/lang/Object/<init>()V
- return-void
-.end method
-
-.method public run()J
-.limit regs 255
-
- const-wide v253, 20000000000
- return-wide v253
-.end method
-
-
diff --git a/tools/vm-tests-tf/src/dot/junit/opcodes/const_wide_high16/d/T_const_wide_high16_1.d.done b/tools/vm-tests-tf/src/dot/junit/opcodes/const_wide_high16/d/T_const_wide_high16_1.d.done
deleted file mode 100644
index c051462..0000000
--- a/tools/vm-tests-tf/src/dot/junit/opcodes/const_wide_high16/d/T_const_wide_high16_1.d.done
+++ /dev/null
@@ -1,34 +0,0 @@
-; 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.
-
-.source T_const_wide_high16_1.java
-.class public dot.junit.opcodes.const_wide_high16.d.T_const_wide_high16_1
-.super java/lang/Object
-
-
-.method public <init>()V
-.limit regs 1
-
- invoke-direct {v0}, java/lang/Object/<init>()V
- return-void
-.end method
-
-.method public run()J
-.limit regs 255
-
- const-wide/high16 v252, 0x1234000000000000
- return-wide v252
-.end method
-
-
diff --git a/tools/vm-tests-tf/src/dot/junit/opcodes/const_wide_high16/d/T_const_wide_high16_3.d.done b/tools/vm-tests-tf/src/dot/junit/opcodes/const_wide_high16/d/T_const_wide_high16_3.d.done
deleted file mode 100644
index 24a577c..0000000
--- a/tools/vm-tests-tf/src/dot/junit/opcodes/const_wide_high16/d/T_const_wide_high16_3.d.done
+++ /dev/null
@@ -1,35 +0,0 @@
-; 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.
-
-.source T_const_wide_high16_3.java
-.class public dot.junit.opcodes.const_wide_high16.d.T_const_wide_high16_3
-.super java/lang/Object
-
-
-.method public <init>()V
-.limit regs 1
-
- invoke-direct {v0}, java/lang/Object/<init>()V
- return-void
-.end method
-
-.method public run()V
-.limit regs 3
-
- const-wide/high16 v3, 0x1234000000000000
-
- return-void
-.end method
-
-
diff --git a/tools/vm-tests-tf/src/dot/junit/opcodes/const_wide_high16/d/T_const_wide_high16_4.d.done b/tools/vm-tests-tf/src/dot/junit/opcodes/const_wide_high16/d/T_const_wide_high16_4.d.done
deleted file mode 100644
index 614e5a5..0000000
--- a/tools/vm-tests-tf/src/dot/junit/opcodes/const_wide_high16/d/T_const_wide_high16_4.d.done
+++ /dev/null
@@ -1,35 +0,0 @@
-; 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.
-
-.source T_const_wide_high16_4.java
-.class public dot.junit.opcodes.const_wide_high16.d.T_const_wide_high16_4
-.super java/lang/Object
-
-
-.method public <init>()V
-.limit regs 1
-
- invoke-direct {v0}, java/lang/Object/<init>()V
- return-void
-.end method
-
-.method public run()J
-.limit regs 3
- const-wide v0, 1234
- const-wide/high16 v1, 0x1234000000000000
-
- return-wide v0
-.end method
-
-
diff --git a/tools/vm-tests-tf/src/dot/junit/opcodes/div_double/d/T_div_double_2.d.done b/tools/vm-tests-tf/src/dot/junit/opcodes/div_double/d/T_div_double_2.d.done
deleted file mode 100644
index e09176a..0000000
--- a/tools/vm-tests-tf/src/dot/junit/opcodes/div_double/d/T_div_double_2.d.done
+++ /dev/null
@@ -1,34 +0,0 @@
-; 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.
-
-.source T_div_double_2.java
-.class public dot.junit.opcodes.div_double.d.T_div_double_2
-.super java/lang/Object
-
-
-.method public <init>()V
-.limit regs 1
- invoke-direct {v0}, java/lang/Object/<init>()V
- return-void
-.end method
-
-.method public run(DD)D
-.limit regs 14
-
- const v10, 3.1415
- div-double v0, v10, v12
- return-wide v0
-.end method
-
-
diff --git a/tools/vm-tests-tf/src/dot/junit/opcodes/div_double_2addr/d/T_div_double_2addr_2.d.done b/tools/vm-tests-tf/src/dot/junit/opcodes/div_double_2addr/d/T_div_double_2addr_2.d.done
deleted file mode 100644
index 5921ceb..0000000
--- a/tools/vm-tests-tf/src/dot/junit/opcodes/div_double_2addr/d/T_div_double_2addr_2.d.done
+++ /dev/null
@@ -1,34 +0,0 @@
-; 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.
-
-.source T_div_double_2addr_2.java
-.class public dot.junit.opcodes.div_double_2addr.d.T_div_double_2addr_2
-.super java/lang/Object
-
-
-.method public <init>()V
-.limit regs 1
- invoke-direct {v0}, java/lang/Object/<init>()V
- return-void
-.end method
-
-.method public run(DD)D
-.limit regs 14
-
- const v0, 3.1415
- div-double/2addr v0, v12
- return-wide v10
-.end method
-
-
diff --git a/tools/vm-tests-tf/src/dot/junit/opcodes/div_long/d/T_div_long_4.d.done b/tools/vm-tests-tf/src/dot/junit/opcodes/div_long/d/T_div_long_4.d.done
deleted file mode 100644
index 409b45a..0000000
--- a/tools/vm-tests-tf/src/dot/junit/opcodes/div_long/d/T_div_long_4.d.done
+++ /dev/null
@@ -1,35 +0,0 @@
-; 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.
-
-.source T_div_long_4.java
-.class public dot.junit.opcodes.div_long.d.T_div_long_4
-.super java/lang/Object
-
-
-.method public <init>()V
-.limit regs 1
-
- invoke-direct {v0}, java/lang/Object/<init>()V
- return-void
-.end method
-
-.method public run(JJ)J
-.limit regs 14
-
- const v10, 3.14
- div-long v0, v10, v12
- return-wide v12
-.end method
-
-
diff --git a/tools/vm-tests-tf/src/dot/junit/opcodes/div_long_2addr/d/T_div_long_2addr_4.d.done b/tools/vm-tests-tf/src/dot/junit/opcodes/div_long_2addr/d/T_div_long_2addr_4.d.done
deleted file mode 100644
index 6d91919..0000000
--- a/tools/vm-tests-tf/src/dot/junit/opcodes/div_long_2addr/d/T_div_long_2addr_4.d.done
+++ /dev/null
@@ -1,35 +0,0 @@
-; 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.
-
-.source T_div_long_2addr_4.java
-.class public dot.junit.opcodes.div_long_2addr.d.T_div_long_2addr_4
-.super java/lang/Object
-
-
-.method public <init>()V
-.limit regs 1
-
- invoke-direct {v0}, java/lang/Object/<init>()V
- return-void
-.end method
-
-.method public run(JJ)J
-.limit regs 14
-
- const v0, 3.14
- div-long/2addr v0, v12
- return-wide v10
-.end method
-
-
diff --git a/tools/vm-tests-tf/src/dot/junit/opcodes/double_to_float/d/T_double_to_float_2.d.done b/tools/vm-tests-tf/src/dot/junit/opcodes/double_to_float/d/T_double_to_float_2.d.done
deleted file mode 100644
index 402cfac..0000000
--- a/tools/vm-tests-tf/src/dot/junit/opcodes/double_to_float/d/T_double_to_float_2.d.done
+++ /dev/null
@@ -1,35 +0,0 @@
-; 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.
-
-.source T_double_to_float_2.java
-.class public dot.junit.opcodes.double_to_float.d.T_double_to_float_2
-.super java/lang/Object
-
-
-.method public <init>()V
-.limit regs 1
-
- invoke-direct {v0}, java/lang/Object/<init>()V
- return-void
-.end method
-
-.method public run(D)F
-.limit regs 8
-
- const v6, 3.14
- double-to-float v0, v6
- return v6
-.end method
-
-
diff --git a/tools/vm-tests-tf/src/dot/junit/opcodes/double_to_float/d/T_double_to_float_4.d.done b/tools/vm-tests-tf/src/dot/junit/opcodes/double_to_float/d/T_double_to_float_4.d.done
deleted file mode 100644
index 135e7ff..0000000
--- a/tools/vm-tests-tf/src/dot/junit/opcodes/double_to_float/d/T_double_to_float_4.d.done
+++ /dev/null
@@ -1,36 +0,0 @@
-; 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.
-
-.source T_double_to_float_4.java
-.class public dot.junit.opcodes.double_to_float.d.T_double_to_float_4
-.super java/lang/Object
-
-
-.method public <init>()V
-.limit regs 1
-
- invoke-direct {v0}, java/lang/Object/<init>()V
- return-void
-.end method
-
-.method public run(D)F
-.limit regs 8
-
- double-to-float v0, v5
-
- const v3, 3.14
- return v3
-.end method
-
-
diff --git a/tools/vm-tests-tf/src/dot/junit/opcodes/double_to_int/d/T_double_to_int_2.d.done b/tools/vm-tests-tf/src/dot/junit/opcodes/double_to_int/d/T_double_to_int_2.d.done
deleted file mode 100644
index 7e3a98b..0000000
--- a/tools/vm-tests-tf/src/dot/junit/opcodes/double_to_int/d/T_double_to_int_2.d.done
+++ /dev/null
@@ -1,36 +0,0 @@
-; 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.
-
-.source T_double_to_int_2.java
-.class public dot.junit.opcodes.double_to_int.d.T_double_to_int_2
-.super java/lang/Object
-
-
-.method public <init>()V
-.limit regs 1
-
- invoke-direct {v0}, java/lang/Object/<init>()V
- return-void
-.end method
-
-.method public run(D)I
-.limit regs 8
-
- const v6, 3.14
- double-to-int v0, v6
- const v1, 123
- return v1
-.end method
-
-
diff --git a/tools/vm-tests-tf/src/dot/junit/opcodes/double_to_long/d/T_double_to_long_2.d.done b/tools/vm-tests-tf/src/dot/junit/opcodes/double_to_long/d/T_double_to_long_2.d.done
deleted file mode 100644
index 54740b6..0000000
--- a/tools/vm-tests-tf/src/dot/junit/opcodes/double_to_long/d/T_double_to_long_2.d.done
+++ /dev/null
@@ -1,36 +0,0 @@
-; 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.
-
-.source T_double_to_long_2.java
-.class public dot.junit.opcodes.double_to_long.d.T_double_to_long_2
-.super java/lang/Object
-
-
-.method public <init>()V
-.limit regs 1
-
- invoke-direct {v0}, java/lang/Object/<init>()V
- return-void
-.end method
-
-.method public run(D)J
-.limit regs 8
-
- const v6, 3.14
- double-to-long v0, v6
- const-wide v2, 123
- return-wide v2
-.end method
-
-
diff --git a/tools/vm-tests-tf/src/dot/junit/opcodes/fill_array_data/d/T_fill_array_data_1.d.done b/tools/vm-tests-tf/src/dot/junit/opcodes/fill_array_data/d/T_fill_array_data_1.d.done
deleted file mode 100644
index 1c97601..0000000
--- a/tools/vm-tests-tf/src/dot/junit/opcodes/fill_array_data/d/T_fill_array_data_1.d.done
+++ /dev/null
@@ -1,42 +0,0 @@
-; 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.
-
-.source T_fill_array_data_1.java
-.class public dot.junit.opcodes.fill_array_data.d.T_fill_array_data_1
-.super java/lang/Object
-
-
-.method public <init>()V
-.limit regs 1
-
- invoke-direct {v0}, java/lang/Object/<init>()V
- return-void
-.end method
-
-.method public run([I)V
-.limit regs 10
-
- fill-array-data v9 I
- 1
- 2
- 3
- 4
- 5
- fill-array-data-end
-
-
- return-void
-.end method
-
-
diff --git a/tools/vm-tests-tf/src/dot/junit/opcodes/fill_array_data/d/T_fill_array_data_11.d.done b/tools/vm-tests-tf/src/dot/junit/opcodes/fill_array_data/d/T_fill_array_data_11.d.done
deleted file mode 100644
index b462d1c..0000000
--- a/tools/vm-tests-tf/src/dot/junit/opcodes/fill_array_data/d/T_fill_array_data_11.d.done
+++ /dev/null
@@ -1,42 +0,0 @@
-; 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.
-
-.source T_fill_array_data_11.java
-.class public dot.junit.opcodes.fill_array_data.d.T_fill_array_data_11
-.super java/lang/Object
-
-
-.method public <init>()V
-.limit regs 1
-
- invoke-direct {v0}, java/lang/Object/<init>()V
- return-void
-.end method
-
-.method public run([I)V
-.limit regs 10
-
- fill-array-data v9 I
- 1
- 2
- 3
- 4
- 5
- fill-array-data-end
-
-
- return-void
-.end method
-
-
diff --git a/tools/vm-tests-tf/src/dot/junit/opcodes/fill_array_data/d/T_fill_array_data_12.d.done b/tools/vm-tests-tf/src/dot/junit/opcodes/fill_array_data/d/T_fill_array_data_12.d.done
deleted file mode 100644
index c3ce952..0000000
--- a/tools/vm-tests-tf/src/dot/junit/opcodes/fill_array_data/d/T_fill_array_data_12.d.done
+++ /dev/null
@@ -1,43 +0,0 @@
-; 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.
-
-.source T_fill_array_data_12.java
-.class public dot.junit.opcodes.fill_array_data.d.T_fill_array_data_12
-.super java/lang/Object
-
-
-.method public <init>()V
-.limit regs 1
-
- invoke-direct {v0}, java/lang/Object/<init>()V
- return-void
-.end method
-
-.method public run([I)V
-.limit regs 10
-
- goto Label0
- fill-array-data v9 I
- 1
- 2
- 3
- 4
- 5
- fill-array-data-end
-
- return-void
-Label0:
-.end method
-
-
diff --git a/tools/vm-tests-tf/src/dot/junit/opcodes/fill_array_data/d/T_fill_array_data_13.d.done b/tools/vm-tests-tf/src/dot/junit/opcodes/fill_array_data/d/T_fill_array_data_13.d.done
deleted file mode 100644
index 0066d29..0000000
--- a/tools/vm-tests-tf/src/dot/junit/opcodes/fill_array_data/d/T_fill_array_data_13.d.done
+++ /dev/null
@@ -1,42 +0,0 @@
-; 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.
-
-.source T_fill_array_data_13.java
-.class public dot.junit.opcodes.fill_array_data.d.T_fill_array_data_13
-.super java/lang/Object
-
-
-.method public <init>()V
-.limit regs 1
-
- invoke-direct {v0}, java/lang/Object/<init>()V
- return-void
-.end method
-
-.method public run([I)V
-.limit regs 10
-
- fill-array-data v9 I
- 1
- 2
- 3
- 4
- 5
- fill-array-data-end
-
-
- return-void
-.end method
-
-
diff --git a/tools/vm-tests-tf/src/dot/junit/opcodes/fill_array_data/d/T_fill_array_data_2.d.done b/tools/vm-tests-tf/src/dot/junit/opcodes/fill_array_data/d/T_fill_array_data_2.d.done
deleted file mode 100644
index 6167ef7..0000000
--- a/tools/vm-tests-tf/src/dot/junit/opcodes/fill_array_data/d/T_fill_array_data_2.d.done
+++ /dev/null
@@ -1,40 +0,0 @@
-; 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.
-
-.source T_fill_array_data_2.java
-.class public dot.junit.opcodes.fill_array_data.d.T_fill_array_data_2
-.super java/lang/Object
-
-
-.method public <init>()V
-.limit regs 1
-
- invoke-direct {v0}, java/lang/Object/<init>()V
- return-void
-.end method
-
-.method public run([D)V
-.limit regs 10
-
- fill-array-data v9 D
- 1.0
- 2.0
- 3.0
- 4.0
- 5.0
- fill-array-data-end
- return-void
-.end method
-
-
diff --git a/tools/vm-tests-tf/src/dot/junit/opcodes/fill_array_data/d/T_fill_array_data_3.d.done b/tools/vm-tests-tf/src/dot/junit/opcodes/fill_array_data/d/T_fill_array_data_3.d.done
deleted file mode 100644
index e6ecd1e..0000000
--- a/tools/vm-tests-tf/src/dot/junit/opcodes/fill_array_data/d/T_fill_array_data_3.d.done
+++ /dev/null
@@ -1,42 +0,0 @@
-; 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.
-
-.source T_fill_array_data_3.java
-.class public dot.junit.opcodes.fill_array_data.d.T_fill_array_data_3
-.super java/lang/Object
-
-
-.method public <init>()V
-.limit regs 1
-
- invoke-direct {v0}, java/lang/Object/<init>()V
- return-void
-.end method
-
-.method public run([I)V
-.limit regs 10
-
- fill-array-data v10 I
- 1
- 2
- 3
- 4
- 5
- fill-array-data-end
-
-
- return-void
-.end method
-
-
diff --git a/tools/vm-tests-tf/src/dot/junit/opcodes/fill_array_data/d/T_fill_array_data_4.d.done b/tools/vm-tests-tf/src/dot/junit/opcodes/fill_array_data/d/T_fill_array_data_4.d.done
deleted file mode 100644
index 221ef8b..0000000
--- a/tools/vm-tests-tf/src/dot/junit/opcodes/fill_array_data/d/T_fill_array_data_4.d.done
+++ /dev/null
@@ -1,42 +0,0 @@
-; 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.
-
-.source T_fill_array_data_4.java
-.class public dot.junit.opcodes.fill_array_data.d.T_fill_array_data_4
-.super java/lang/Object
-
-
-.method public <init>()V
-.limit regs 1
-
- invoke-direct {v0}, java/lang/Object/<init>()V
- return-void
-.end method
-
-.method public run(D[I)V
-.limit regs 10
-
- fill-array-data v7 I
- 1
- 2
- 3
- 4
- 5
- fill-array-data-end
-
-
- return-void
-.end method
-
-
diff --git a/tools/vm-tests-tf/src/dot/junit/opcodes/fill_array_data/d/T_fill_array_data_5.d.done b/tools/vm-tests-tf/src/dot/junit/opcodes/fill_array_data/d/T_fill_array_data_5.d.done
deleted file mode 100644
index cc98351..0000000
--- a/tools/vm-tests-tf/src/dot/junit/opcodes/fill_array_data/d/T_fill_array_data_5.d.done
+++ /dev/null
@@ -1,42 +0,0 @@
-; 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.
-
-.source T_fill_array_data_5.java
-.class public dot.junit.opcodes.fill_array_data.d.T_fill_array_data_5
-.super java/lang/Object
-
-
-.method public <init>()V
-.limit regs 1
-
- invoke-direct {v0}, java/lang/Object/<init>()V
- return-void
-.end method
-
-.method public run(J[I)V
-.limit regs 10
-
- fill-array-data v7 I
- 1
- 2
- 3
- 4
- 5
- fill-array-data-end
-
-
- return-void
-.end method
-
-
diff --git a/tools/vm-tests-tf/src/dot/junit/opcodes/fill_array_data/d/T_fill_array_data_6.d.done b/tools/vm-tests-tf/src/dot/junit/opcodes/fill_array_data/d/T_fill_array_data_6.d.done
deleted file mode 100644
index 61990a1..0000000
--- a/tools/vm-tests-tf/src/dot/junit/opcodes/fill_array_data/d/T_fill_array_data_6.d.done
+++ /dev/null
@@ -1,42 +0,0 @@
-; 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.
-
-.source T_fill_array_data_6.java
-.class public dot.junit.opcodes.fill_array_data.d.T_fill_array_data_6
-.super java/lang/Object
-
-
-.method public <init>()V
-.limit regs 1
-
- invoke-direct {v0}, java/lang/Object/<init>()V
- return-void
-.end method
-
-.method public run([I)V
-.limit regs 10
-
- fill-array-data v8 I
- 0
- 0
- 0
- 0
- 0
- fill-array-data-end
-
-
- return-void
-.end method
-
-
diff --git a/tools/vm-tests-tf/src/dot/junit/opcodes/fill_array_data/d/T_fill_array_data_7.d.done b/tools/vm-tests-tf/src/dot/junit/opcodes/fill_array_data/d/T_fill_array_data_7.d.done
deleted file mode 100644
index 8ba5155..0000000
--- a/tools/vm-tests-tf/src/dot/junit/opcodes/fill_array_data/d/T_fill_array_data_7.d.done
+++ /dev/null
@@ -1,42 +0,0 @@
-; 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.
-
-.source T_fill_array_data_7.java
-.class public dot.junit.opcodes.fill_array_data.d.T_fill_array_data_7
-.super java/lang/Object
-
-
-.method public <init>()V
-.limit regs 1
-
- invoke-direct {v0}, java/lang/Object/<init>()V
- return-void
-.end method
-
-.method public run([Ljava/lang/Object;)V
-.limit regs 10
-
- fill-array-data v9 I
- 0
- 0
- 0
- 0
- 0
- fill-array-data-end
-
-
- return-void
-.end method
-
-
diff --git a/tools/vm-tests-tf/src/dot/junit/opcodes/fill_array_data/d/T_fill_array_data_8.d.done b/tools/vm-tests-tf/src/dot/junit/opcodes/fill_array_data/d/T_fill_array_data_8.d.done
deleted file mode 100644
index e90eb86..0000000
--- a/tools/vm-tests-tf/src/dot/junit/opcodes/fill_array_data/d/T_fill_array_data_8.d.done
+++ /dev/null
@@ -1,42 +0,0 @@
-; 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.
-
-.source T_fill_array_data_8.java
-.class public dot.junit.opcodes.fill_array_data.d.T_fill_array_data_8
-.super java/lang/Object
-
-
-.method public <init>()V
-.limit regs 1
-
- invoke-direct {v0}, java/lang/Object/<init>()V
- return-void
-.end method
-
-.method public run([D)V
-.limit regs 10
-
- fill-array-data v9 I
- 1
- 2
- 3
- 4
- 5
- fill-array-data-end
-
-
- return-void
-.end method
-
-
diff --git a/tools/vm-tests-tf/src/dot/junit/opcodes/fill_array_data/d/T_fill_array_data_9.d.done b/tools/vm-tests-tf/src/dot/junit/opcodes/fill_array_data/d/T_fill_array_data_9.d.done
deleted file mode 100644
index 0a5e008..0000000
--- a/tools/vm-tests-tf/src/dot/junit/opcodes/fill_array_data/d/T_fill_array_data_9.d.done
+++ /dev/null
@@ -1,42 +0,0 @@
-; 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.
-
-.source T_fill_array_data_9.java
-.class public dot.junit.opcodes.fill_array_data.d.T_fill_array_data_9
-.super java/lang/Object
-
-
-.method public <init>()V
-.limit regs 1
-
- invoke-direct {v0}, java/lang/Object/<init>()V
- return-void
-.end method
-
-.method public run([I)V
-.limit regs 10
-
- fill-array-data v9 I
- 1
- 2
- 3
- 4
- 5
- fill-array-data-end
-
-
- return-void
-.end method
-
-
diff --git a/tools/vm-tests-tf/src/dot/junit/opcodes/float_to_double/d/T_float_to_double_4.d.done b/tools/vm-tests-tf/src/dot/junit/opcodes/float_to_double/d/T_float_to_double_4.d.done
deleted file mode 100644
index 32f2b0a..0000000
--- a/tools/vm-tests-tf/src/dot/junit/opcodes/float_to_double/d/T_float_to_double_4.d.done
+++ /dev/null
@@ -1,35 +0,0 @@
-; 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.
-
-.source T_float_to_double_4.java
-.class public dot.junit.opcodes.float_to_double.d.T_float_to_double_4
-.super java/lang/Object
-
-
-.method public <init>()V
-.limit regs 1
-
- invoke-direct {v0}, java/lang/Object/<init>()V
- return-void
-.end method
-
-.method public run()D
-.limit regs 1
-
- const v0, 3.14
- float-to-double v0, v0
- return-wide v0
-.end method
-
-
diff --git a/tools/vm-tests-tf/src/dot/junit/opcodes/float_to_long/d/T_float_to_long_4.d.done b/tools/vm-tests-tf/src/dot/junit/opcodes/float_to_long/d/T_float_to_long_4.d.done
deleted file mode 100644
index 69d1e57..0000000
--- a/tools/vm-tests-tf/src/dot/junit/opcodes/float_to_long/d/T_float_to_long_4.d.done
+++ /dev/null
@@ -1,35 +0,0 @@
-; 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.
-
-.source T_float_to_long_4.java
-.class public dot.junit.opcodes.float_to_long.d.T_float_to_long_4
-.super java/lang/Object
-
-
-.method public <init>()V
-.limit regs 1
-
- invoke-direct {v0}, java/lang/Object/<init>()V
- return-void
-.end method
-
-.method public run()J
-.limit regs 1
-
- const v0, 3.14
- float-to-long v0, v0
- return-wide v0
-.end method
-
-
diff --git a/tools/vm-tests-tf/src/dot/junit/opcodes/goto_16/d/T_goto_16_1.d.done b/tools/vm-tests-tf/src/dot/junit/opcodes/goto_16/d/T_goto_16_1.d.done
deleted file mode 100644
index caa4ad0..0000000
--- a/tools/vm-tests-tf/src/dot/junit/opcodes/goto_16/d/T_goto_16_1.d.done
+++ /dev/null
@@ -1,44 +0,0 @@
-; 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.
-
-.source T_goto_16_1.java
-.class public dot.junit.opcodes.goto_16.d.T_goto_16_1
-.super java/lang/Object
-
-
-.method public <init>()V
-.limit regs 1
-
- invoke-direct {v0}, java/lang/Object/<init>()V
- return-void
-.end method
-
-.method public run(I)I
-.limit regs 5
-; test positive offset
- goto/16 Label2
-LabelReturn:
- return v4
-
-Label2:
- add-int/lit8 v4, v4, -1
- if-lez v4, LabelExit
-; test negative offset
- goto/16 Label2
-
-LabelExit:
- goto LabelReturn
-.end method
-
-
diff --git a/tools/vm-tests-tf/src/dot/junit/opcodes/goto_16/d/T_goto_16_2.d.done b/tools/vm-tests-tf/src/dot/junit/opcodes/goto_16/d/T_goto_16_2.d.done
deleted file mode 100644
index 7162694..0000000
--- a/tools/vm-tests-tf/src/dot/junit/opcodes/goto_16/d/T_goto_16_2.d.done
+++ /dev/null
@@ -1,34 +0,0 @@
-; 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.
-
-.source T_goto_16_2.java
-.class public dot.junit.opcodes.goto_16.d.T_goto_16_2
-.super java/lang/Object
-
-
-.method public <init>()V
-.limit regs 1
-
- invoke-direct {v0}, java/lang/Object/<init>()V
- return-void
-.end method
-
-.method public run(I)I
-.limit regs 5
- goto/16 Label2
-Label2:
- return v4
-.end method
-
-
diff --git a/tools/vm-tests-tf/src/dot/junit/opcodes/goto_16/d/T_goto_16_3.d.done b/tools/vm-tests-tf/src/dot/junit/opcodes/goto_16/d/T_goto_16_3.d.done
deleted file mode 100644
index fcaa68d..0000000
--- a/tools/vm-tests-tf/src/dot/junit/opcodes/goto_16/d/T_goto_16_3.d.done
+++ /dev/null
@@ -1,34 +0,0 @@
-; 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.
-
-.source T_goto_16_3.java
-.class public dot.junit.opcodes.goto_16.d.T_goto_16_3
-.super java/lang/Object
-
-
-.method public <init>()V
-.limit regs 1
-
- invoke-direct {v0}, java/lang/Object/<init>()V
- return-void
-.end method
-
-.method public run(I)I
-.limit regs 5
- goto/16 Label2
-Label2:
- return v4
-.end method
-
-
diff --git a/tools/vm-tests-tf/src/dot/junit/opcodes/goto_16/d/T_goto_16_4.d.done b/tools/vm-tests-tf/src/dot/junit/opcodes/goto_16/d/T_goto_16_4.d.done
deleted file mode 100644
index 746c325..0000000
--- a/tools/vm-tests-tf/src/dot/junit/opcodes/goto_16/d/T_goto_16_4.d.done
+++ /dev/null
@@ -1,34 +0,0 @@
-; 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.
-
-.source T_goto_16_4.java
-.class public dot.junit.opcodes.goto_16.d.T_goto_16_4
-.super java/lang/Object
-
-
-.method public <init>()V
-.limit regs 1
-
- invoke-direct {v0}, java/lang/Object/<init>()V
- return-void
-.end method
-
-.method public run(I)I
-.limit regs 5
- goto/16 Label1
-Label1:
- return v4
-.end method
-
-
diff --git a/tools/vm-tests-tf/src/dot/junit/opcodes/goto_32/d/T_goto_32_1.d.done b/tools/vm-tests-tf/src/dot/junit/opcodes/goto_32/d/T_goto_32_1.d.done
deleted file mode 100644
index fd5335a..0000000
--- a/tools/vm-tests-tf/src/dot/junit/opcodes/goto_32/d/T_goto_32_1.d.done
+++ /dev/null
@@ -1,44 +0,0 @@
-; 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.
-
-.source T_goto_32_1.java
-.class public dot.junit.opcodes.goto_32.d.T_goto_32_1
-.super java/lang/Object
-
-
-.method public <init>()V
-.limit regs 1
-
- invoke-direct {v0}, java/lang/Object/<init>()V
- return-void
-.end method
-
-.method public run(I)I
-.limit regs 5
-; test positive offset
- goto/32 Label2
-LabelReturn:
- return v4
-
-Label2:
- add-int/lit8 v4, v4, -1
- if-lez v4, LabelExit
-; test negative offset
- goto/32 Label2
-
-LabelExit:
- goto LabelReturn
-.end method
-
-
diff --git a/tools/vm-tests-tf/src/dot/junit/opcodes/goto_32/d/T_goto_32_2.d.done b/tools/vm-tests-tf/src/dot/junit/opcodes/goto_32/d/T_goto_32_2.d.done
deleted file mode 100644
index 1a76901..0000000
--- a/tools/vm-tests-tf/src/dot/junit/opcodes/goto_32/d/T_goto_32_2.d.done
+++ /dev/null
@@ -1,34 +0,0 @@
-; 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.
-
-.source T_goto_32_2.java
-.class public dot.junit.opcodes.goto_32.d.T_goto_32_2
-.super java/lang/Object
-
-
-.method public <init>()V
-.limit regs 1
-
- invoke-direct {v0}, java/lang/Object/<init>()V
- return-void
-.end method
-
-.method public run(I)I
-.limit regs 5
- goto/32 Label2
-Label2:
- return v4
-.end method
-
-
diff --git a/tools/vm-tests-tf/src/dot/junit/opcodes/goto_32/d/T_goto_32_3.d.done b/tools/vm-tests-tf/src/dot/junit/opcodes/goto_32/d/T_goto_32_3.d.done
deleted file mode 100644
index 6130ae8..0000000
--- a/tools/vm-tests-tf/src/dot/junit/opcodes/goto_32/d/T_goto_32_3.d.done
+++ /dev/null
@@ -1,34 +0,0 @@
-; 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.
-
-.source T_goto_32_3.java
-.class public dot.junit.opcodes.goto_32.d.T_goto_32_3
-.super java/lang/Object
-
-
-.method public <init>()V
-.limit regs 1
-
- invoke-direct {v0}, java/lang/Object/<init>()V
- return-void
-.end method
-
-.method public run(I)I
-.limit regs 5
- goto/32 Label2
-Label2:
- return v4
-.end method
-
-
diff --git a/tools/vm-tests-tf/src/dot/junit/opcodes/goto_32/d/T_goto_32_4.d.done b/tools/vm-tests-tf/src/dot/junit/opcodes/goto_32/d/T_goto_32_4.d.done
deleted file mode 100644
index 624dfaf..0000000
--- a/tools/vm-tests-tf/src/dot/junit/opcodes/goto_32/d/T_goto_32_4.d.done
+++ /dev/null
@@ -1,34 +0,0 @@
-; 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.
-
-.source T_goto_32_4.java
-.class public dot.junit.opcodes.goto_32.d.T_goto_32_4
-.super java/lang/Object
-
-
-.method public <init>()V
-.limit regs 1
-
- invoke-direct {v0}, java/lang/Object/<init>()V
- return-void
-.end method
-
-.method public run(I)I
-.limit regs 5
-Label1:
- goto/32 Label1
- return v4
-.end method
-
-
diff --git a/tools/vm-tests-tf/src/dot/junit/opcodes/iget/d/T_iget_14.d.done b/tools/vm-tests-tf/src/dot/junit/opcodes/iget/d/T_iget_14.d.done
deleted file mode 100644
index faa6271..0000000
--- a/tools/vm-tests-tf/src/dot/junit/opcodes/iget/d/T_iget_14.d.done
+++ /dev/null
@@ -1,35 +0,0 @@
-; 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.
-
-.source T_iget_14.java
-.class public dot.junit.opcodes.iget.d.T_iget_14
-.super java/lang/Object
-
-.field public i1 Ljava/lang/Object;
-
-.method public <init>()V
-.limit regs 1
-
- invoke-direct {v0}, java/lang/Object/<init>()V
- return-void
-.end method
-
-.method public run()V
-.limit regs 3
-
- iget v0, v2, dot.junit.opcodes.iget.d.T_iget_14.i1 Ljava/lang/Object;
- return-void
-.end method
-
-
diff --git a/tools/vm-tests-tf/src/dot/junit/opcodes/iget/d/T_iget_2.d.done b/tools/vm-tests-tf/src/dot/junit/opcodes/iget/d/T_iget_2.d.done
deleted file mode 100644
index bf07640..0000000
--- a/tools/vm-tests-tf/src/dot/junit/opcodes/iget/d/T_iget_2.d.done
+++ /dev/null
@@ -1,44 +0,0 @@
-; 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.
-
-.source T_iget_2.java
-.class public dot.junit.opcodes.iget.d.T_iget_2
-.super java/lang/Object
-
-.field public val F
-
-.method <clinit>()V
-.limit regs 2
- return-void
-.end method
-
-.method public <init>()V
-.limit regs 2
-
- invoke-direct {v1}, java/lang/Object/<init>()V
-
- const v0, 123.0
- iput v0, v1, dot.junit.opcodes.iget.d.T_iget_2.val F
-
- return-void
-.end method
-
-.method public run()F
-.limit regs 4
-
- iget v1, v3, dot.junit.opcodes.iget.d.T_iget_2.val F
- return v1
-.end method
-
-
diff --git a/tools/vm-tests-tf/src/dot/junit/opcodes/iget_boolean/d/T_iget_boolean_14.d.done b/tools/vm-tests-tf/src/dot/junit/opcodes/iget_boolean/d/T_iget_boolean_14.d.done
deleted file mode 100644
index 38a56f6..0000000
--- a/tools/vm-tests-tf/src/dot/junit/opcodes/iget_boolean/d/T_iget_boolean_14.d.done
+++ /dev/null
@@ -1,35 +0,0 @@
-; 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.
-
-.source T_iget_boolean_14.java
-.class public dot.junit.opcodes.iget_boolean.d.T_iget_boolean_14
-.super java/lang/Object
-
-.field public i1 Ljava/lang/Object;
-
-.method public <init>()V
-.limit regs 1
-
- invoke-direct {v0}, java/lang/Object/<init>()V
- return-void
-.end method
-
-.method public run()V
-.limit regs 3
-
- iget-boolean v0, v2, dot.junit.opcodes.iget_boolean.d.T_iget_boolean_14.i1 Ljava/lang/Object;
- return-void
-.end method
-
-
diff --git a/tools/vm-tests-tf/src/dot/junit/opcodes/iget_byte/d/T_iget_byte_14.d.done b/tools/vm-tests-tf/src/dot/junit/opcodes/iget_byte/d/T_iget_byte_14.d.done
deleted file mode 100644
index f33ce5d..0000000
--- a/tools/vm-tests-tf/src/dot/junit/opcodes/iget_byte/d/T_iget_byte_14.d.done
+++ /dev/null
@@ -1,35 +0,0 @@
-; 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.
-
-.source T_iget_byte_14.java
-.class public dot.junit.opcodes.iget_byte.d.T_iget_byte_14
-.super java/lang/Object
-
-.field public i1 Ljava/lang/Object;
-
-.method public <init>()V
-.limit regs 1
-
- invoke-direct {v0}, java/lang/Object/<init>()V
- return-void
-.end method
-
-.method public run()V
-.limit regs 3
-
- iget-byte v0, v2, dot.junit.opcodes.iget_byte.d.T_iget_byte_14.i1 Ljava/lang/Object;
- return-void
-.end method
-
-
diff --git a/tools/vm-tests-tf/src/dot/junit/opcodes/iget_char/d/T_iget_char_14.d.done b/tools/vm-tests-tf/src/dot/junit/opcodes/iget_char/d/T_iget_char_14.d.done
deleted file mode 100644
index 46f0e20..0000000
--- a/tools/vm-tests-tf/src/dot/junit/opcodes/iget_char/d/T_iget_char_14.d.done
+++ /dev/null
@@ -1,35 +0,0 @@
-; 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.
-
-.source T_iget_char_14.java
-.class public dot.junit.opcodes.iget_char.d.T_iget_char_14
-.super java/lang/Object
-
-.field public i1 Ljava/lang/Object;
-
-.method public <init>()V
-.limit regs 1
-
- invoke-direct {v0}, java/lang/Object/<init>()V
- return-void
-.end method
-
-.method public run()V
-.limit regs 3
-
- iget-char v0, v2, dot.junit.opcodes.iget_char.d.T_iget_char_14.i1 Ljava/lang/Object;
- return-void
-.end method
-
-
diff --git a/tools/vm-tests-tf/src/dot/junit/opcodes/iget_object/d/T_iget_object_1.d.done b/tools/vm-tests-tf/src/dot/junit/opcodes/iget_object/d/T_iget_object_1.d.done
deleted file mode 100644
index 5e4967f..0000000
--- a/tools/vm-tests-tf/src/dot/junit/opcodes/iget_object/d/T_iget_object_1.d.done
+++ /dev/null
@@ -1,47 +0,0 @@
-; 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.
-
-.source T_iget_object_1.java
-.class public dot.junit.opcodes.iget_object.d.T_iget_object_1
-.super java/lang/Object
-
-.field public i1 Ljava/lang/Object;
-.field protected p1 Ljava/lang/Object;
-.field private pvt1 Ljava/lang/Object;
-
-.method public <init>()V
-.limit regs 2
-
- invoke-direct {v1}, java/lang/Object/<init>()V
-
- const v0, 0
- iput-object v0, v1, dot.junit.opcodes.iget_object.d.T_iget_object_1.i1 Ljava/lang/Object;
-
- const v0, 0
- iput-object v0, v1, dot.junit.opcodes.iget_object.d.T_iget_object_1.p1 Ljava/lang/Object;
-
- const v0, 0
- iput-object v0, v1, dot.junit.opcodes.iget_object.d.T_iget_object_1.pvt1 Ljava/lang/Object;
-
- return-void
-.end method
-
-.method public run()Ljava/lang/Object;
-.limit regs 3
-
- iget-object v1, v2, dot.junit.opcodes.iget_object.d.T_iget_object_1.i1 Ljava/lang/Object;
- return-object v1
-.end method
-
-
diff --git a/tools/vm-tests-tf/src/dot/junit/opcodes/iget_object/d/T_iget_object_21.d.done b/tools/vm-tests-tf/src/dot/junit/opcodes/iget_object/d/T_iget_object_21.d.done
deleted file mode 100644
index 10143a7..0000000
--- a/tools/vm-tests-tf/src/dot/junit/opcodes/iget_object/d/T_iget_object_21.d.done
+++ /dev/null
@@ -1,42 +0,0 @@
-; 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.
-
-.source T_iget_object_21.java
-.class public dot.junit.opcodes.iget_object.d.T_iget_object_21
-.super java/lang/Object
-
-.field public i1 Ljava/lang/Object;
-
-
-.method public <init>()V
-.limit regs 2
-
- invoke-direct {v1}, java/lang/Object/<init>()V
-
- new-instance v0, java/lang/Object
- invoke-direct {v0}, java/lang/Object/<init>()V
-
- iput-object v0, v1, dot.junit.opcodes.iget_object.d.T_iget_object_21.i1 Ljava/lang/Object;
-
- return-void
-.end method
-
-.method public run()Ljava/lang/String;
-.limit regs 3
-
- iget-object v1, v2, dot.junit.opcodes.iget_object.d.T_iget_object_21.i1 Ljava/lang/String;
- return-object v1
-.end method
-
-
diff --git a/tools/vm-tests-tf/src/dot/junit/opcodes/iget_object/d/T_iget_object_3.d.done b/tools/vm-tests-tf/src/dot/junit/opcodes/iget_object/d/T_iget_object_3.d.done
deleted file mode 100644
index 4999f1a..0000000
--- a/tools/vm-tests-tf/src/dot/junit/opcodes/iget_object/d/T_iget_object_3.d.done
+++ /dev/null
@@ -1,35 +0,0 @@
-; 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.
-
-.source T_iget_object_3.java
-.class public dot.junit.opcodes.iget_object.d.T_iget_object_3
-.super java/lang/Object
-
-.field public i1 Ljava/lang/Object;
-
-.method public <init>()V
-.limit regs 1
-
- invoke-direct {v0}, java/lang/Object/<init>()V
- return-void
-.end method
-
-.method public run()V
-.limit regs 3
-
- iget-object v3, v2, dot.junit.opcodes.iget_object.d.T_iget_object_3.i1 Ljava/lang/Object;
- return-void
-.end method
-
-
diff --git a/tools/vm-tests-tf/src/dot/junit/opcodes/iget_object/d/T_iget_object_30.d.done b/tools/vm-tests-tf/src/dot/junit/opcodes/iget_object/d/T_iget_object_30.d.done
deleted file mode 100644
index 621f235..0000000
--- a/tools/vm-tests-tf/src/dot/junit/opcodes/iget_object/d/T_iget_object_30.d.done
+++ /dev/null
@@ -1,32 +0,0 @@
-; 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.
-
-.source T_iget_object_30.java
-.class public dot.junit.opcodes.iget_object.d.T_iget_object_30
-.super java/lang/Object
-
-.field public st_i1 Ljava/lang/Object;
-
-.method public <init>()V
-.limit regs 1
- invoke-direct {v0}, java/lang/Object/<init>()V
- return-void
-.end method
-
-.method public run()V
-.limit regs 3
- new-instance v0, dot/junit/opcodes/iget_object/d/T_iget_object_30
- iget-object v1, v0, dot.junit.opcodes.iget_object.d.T_iget_object_30.st_i1 Ljava/lang/Object;
-.end method
-
diff --git a/tools/vm-tests-tf/src/dot/junit/opcodes/iget_object/d/T_iget_object_31.d.done b/tools/vm-tests-tf/src/dot/junit/opcodes/iget_object/d/T_iget_object_31.d.done
deleted file mode 100644
index f194ecd..0000000
--- a/tools/vm-tests-tf/src/dot/junit/opcodes/iget_object/d/T_iget_object_31.d.done
+++ /dev/null
@@ -1,32 +0,0 @@
-; 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.
-
-.source T_iget_object_31.java
-.class public dot.junit.opcodes.iget_object.d.T_iget_object_31
-.super java/lang/Object
-
-.field public st_i1 Ldot/junit/opcodes/iget_object/d/T_iget_object_31;
-
-.method public <init>()V
-.limit regs 1
- invoke-direct {v0}, java/lang/Object/<init>()V
- return-void
-.end method
-
-.method public run()Ldot/junit/opcodes/iget_object/d/T_iget_object_31;
-.limit regs 3
- iget v0, v0, dot.junit.opcodes.iget_object.d.T_iget_object_31.st_i1 Ldot/junit/opcodes/iget_object/d/T_iget_object_31;
- return v0
-.end method
-
diff --git a/tools/vm-tests-tf/src/dot/junit/opcodes/iget_object/d/T_iget_object_4.d.done b/tools/vm-tests-tf/src/dot/junit/opcodes/iget_object/d/T_iget_object_4.d.done
deleted file mode 100644
index 9a05156..0000000
--- a/tools/vm-tests-tf/src/dot/junit/opcodes/iget_object/d/T_iget_object_4.d.done
+++ /dev/null
@@ -1,35 +0,0 @@
-; 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.
-
-.source T_iget_object_4.java
-.class public dot.junit.opcodes.iget_object.d.T_iget_object_4
-.super java/lang/Object
-
-.field public i1 Ljava/lang/Object;
-
-.method public <init>()V
-.limit regs 1
-
- invoke-direct {v0}, java/lang/Object/<init>()V
- return-void
-.end method
-
-.method public run()Ljava/lang/Object;
-.limit regs 3
-
- iget-object v1, v2, dot.junit.opcodes.iget_object.d.T_iget_object_4.i1 Ljava/lang/Object;
- return-object v1
-.end method
-
-
diff --git a/tools/vm-tests-tf/src/dot/junit/opcodes/iget_object/d/T_iget_object_5.d.done b/tools/vm-tests-tf/src/dot/junit/opcodes/iget_object/d/T_iget_object_5.d.done
deleted file mode 100644
index ed15e90..0000000
--- a/tools/vm-tests-tf/src/dot/junit/opcodes/iget_object/d/T_iget_object_5.d.done
+++ /dev/null
@@ -1,35 +0,0 @@
-; 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.
-
-.source T_iget_object_5.java
-.class public dot.junit.opcodes.iget_object.d.T_iget_object_5
-.super java/lang/Object
-
-.field public static i1 Ljava/lang/Object;
-
-.method public <init>()V
-.limit regs 4
-
- invoke-direct {v3}, java/lang/Object/<init>()V
- return-void
-.end method
-
-.method public run()Ljava/lang/Object;
-.limit regs 3
-
- iget-object v1, v2, dot.junit.opcodes.iget_object.d.T_iget_object_5.i1 Ljava/lang/Object;
- return-object v1
-.end method
-
-
diff --git a/tools/vm-tests-tf/src/dot/junit/opcodes/iget_object/d/T_iget_object_9.d.done b/tools/vm-tests-tf/src/dot/junit/opcodes/iget_object/d/T_iget_object_9.d.done
deleted file mode 100644
index 7899b37..0000000
--- a/tools/vm-tests-tf/src/dot/junit/opcodes/iget_object/d/T_iget_object_9.d.done
+++ /dev/null
@@ -1,36 +0,0 @@
-; 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.
-
-.source T_iget_object_9.java
-.class public dot.junit.opcodes.iget_object.d.T_iget_object_9
-.super java/lang/Object
-
-.field public i1 Ljava/lang/Object;
-
-.method public <init>()V
-.limit regs 2
-
- invoke-direct {v1}, java/lang/Object/<init>()V
- return-void
-.end method
-
-.method public run()Ljava/lang/Object;
-.limit regs 3
-
- const v0, 0
- iget-object v1, v0, dot.junit.opcodes.iget_object.d.T_iget_object_9.i1 Ljava/lang/Object;
- return-object v1
-.end method
-
-
diff --git a/tools/vm-tests-tf/src/dot/junit/opcodes/iget_short/d/T_iget_short_14.d.done b/tools/vm-tests-tf/src/dot/junit/opcodes/iget_short/d/T_iget_short_14.d.done
deleted file mode 100644
index 9e0367a..0000000
--- a/tools/vm-tests-tf/src/dot/junit/opcodes/iget_short/d/T_iget_short_14.d.done
+++ /dev/null
@@ -1,35 +0,0 @@
-; 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.
-
-.source T_iget_short_14.java
-.class public dot.junit.opcodes.iget_short.d.T_iget_short_14
-.super java/lang/Object
-
-.field public i1 Ljava/lang/Object;
-
-.method public <init>()V
-.limit regs 1
-
- invoke-direct {v0}, java/lang/Object/<init>()V
- return-void
-.end method
-
-.method public run()V
-.limit regs 3
-
- iget-short v0, v2, dot.junit.opcodes.iget_short.d.T_iget_short_14.i1 Ljava/lang/Object;
- return-void
-.end method
-
-
diff --git a/tools/vm-tests-tf/src/dot/junit/opcodes/iget_wide/d/T_iget_wide_1.d.done b/tools/vm-tests-tf/src/dot/junit/opcodes/iget_wide/d/T_iget_wide_1.d.done
deleted file mode 100644
index 3919e04..0000000
--- a/tools/vm-tests-tf/src/dot/junit/opcodes/iget_wide/d/T_iget_wide_1.d.done
+++ /dev/null
@@ -1,48 +0,0 @@
-; 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.
-
-.source T_iget_wide_1.java
-.class public dot.junit.opcodes.iget_wide.d.T_iget_wide_1
-.super java/lang/Object
-
-.field public i1 J
-.field protected p1 J
-.field private pvt1 J
-
-
-.method public <init>()V
-.limit regs 3
-
- invoke-direct {v2}, java/lang/Object/<init>()V
-
- const-wide v0, 12345679890123
- iput-wide v0, v2, dot.junit.opcodes.iget_wide.d.T_iget_wide_1.i1 J
-
- const-wide v0, 10
- iput-wide v0, v2, dot.junit.opcodes.iget_wide.d.T_iget_wide_1.p1 J
-
- const-wide v0, 20
- iput-wide v0, v2, dot.junit.opcodes.iget_wide.d.T_iget_wide_1.pvt1 J
-
- return-void
-.end method
-
-.method public run()J
-.limit regs 3
-
- iget-wide v1, v2, dot.junit.opcodes.iget_wide.d.T_iget_wide_1.i1 J
- return-wide v1
-.end method
-
-
diff --git a/tools/vm-tests-tf/src/dot/junit/opcodes/iget_wide/d/T_iget_wide_14.d.done b/tools/vm-tests-tf/src/dot/junit/opcodes/iget_wide/d/T_iget_wide_14.d.done
deleted file mode 100644
index 3ffdc18..0000000
--- a/tools/vm-tests-tf/src/dot/junit/opcodes/iget_wide/d/T_iget_wide_14.d.done
+++ /dev/null
@@ -1,35 +0,0 @@
-; 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.
-
-.source T_iget_wide_14.java
-.class public dot.junit.opcodes.iget_wide.d.T_iget_wide_14
-.super java/lang/Object
-
-.field public i1 Ljava/lang/Object;
-
-.method public <init>()V
-.limit regs 1
-
- invoke-direct {v0}, java/lang/Object/<init>()V
- return-void
-.end method
-
-.method public run()V
-.limit regs 3
-
- iget-wide v0, v2, dot.junit.opcodes.iget_wide.d.T_iget_wide_14.i1 Ljava/lang/Object;
- return-void
-.end method
-
-
diff --git a/tools/vm-tests-tf/src/dot/junit/opcodes/instance_of/d/T_instance_of_1.d.done b/tools/vm-tests-tf/src/dot/junit/opcodes/instance_of/d/T_instance_of_1.d.done
deleted file mode 100644
index 4741d35..0000000
--- a/tools/vm-tests-tf/src/dot/junit/opcodes/instance_of/d/T_instance_of_1.d.done
+++ /dev/null
@@ -1,32 +0,0 @@
-; 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.
-
-.source T_instance_of_1.java
-.class public dot.junit.opcodes.instance_of.d.T_instance_of_1
-.super java/lang/Object
-
-
-.method public <init>()V
-.limit regs 1
-
- invoke-direct {v0}, java/lang/Object/<init>()V
- return-void
-.end method
-
-.method public run(Ljava/lang/Object;)Z
-.limit regs 5
-
- instance-of v0, v4, java/lang/String
- return v0
-.end method
diff --git a/tools/vm-tests-tf/src/dot/junit/opcodes/instance_of/d/T_instance_of_2.d.done b/tools/vm-tests-tf/src/dot/junit/opcodes/instance_of/d/T_instance_of_2.d.done
deleted file mode 100644
index 1299b54..0000000
--- a/tools/vm-tests-tf/src/dot/junit/opcodes/instance_of/d/T_instance_of_2.d.done
+++ /dev/null
@@ -1,119 +0,0 @@
-; 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.
-
-.source TestStubs.java
-.interface public dot.junit.opcodes.instance_of.d.T_instance_of_2.SuperInterface
-
-.source TestStubs.java
-.interface public dot.junit.opcodes.instance_of.d.T_instance_of_2.SuperInterface2
-
-.source TestStubs.java
-.class public dot.junit.opcodes.instance_of.d.T_instance_of_2.SuperClass
-.super java/lang/Object
-.implements dot/junit/opcodes/instance_of/d/T_instance_of_2/SuperInterface
-
-.method public <init>()V
-.limit regs 1
-
- invoke-direct {v0}, java/lang/Object/<init>()V
- return-void
-.end method
-
-.source TestStubs.java
-.class public dot.junit.opcodes.instance_of.d.T_instance_of_2.SubClass
-.super dot/junit/opcodes/instance_of/d/T_instance_of_2/SuperClass
-
-.method public <init>()V
-.limit regs 1
-
- invoke-direct {v0}, dot/junit/opcodes/instance_of/d/T_instance_of_2/SuperClass/<init>()V
- return-void
-.end method
-
-
-.source T_instance_of_2.java
-.class public dot.junit.opcodes.instance_of.d.T_instance_of_2
-.super java/lang/Object
-
-
-.method public <init>()V
-.limit regs 1
-
- invoke-direct {v0}, java/lang/Object/<init>()V
- return-void
-.end method
-
-.method public run()Z
-.limit regs 20
-
- const v0, 0
-
-; (SubClass instanceof SuperClass)
- new-instance v10, dot/junit/opcodes/instance_of/d/T_instance_of_2/SubClass
- invoke-direct {v10}, dot/junit/opcodes/instance_of/d/T_instance_of_2/SubClass/<init>()V
- instance-of v15, v10, dot/junit/opcodes/instance_of/d/T_instance_of_2/SuperClass
- if-eqz v15, LabelExit
-
-; (SubClass[] instanceof SuperClass[])
- const v11, 1
- new-array v10, v11, [Ldot/junit/opcodes/instance_of/d/T_instance_of_2/SubClass;
- instance-of v15, v10, [Ldot/junit/opcodes/instance_of/d/T_instance_of_2/SuperClass;
- if-eqz v15, LabelExit
-
-; (SubClass[] instanceof Object)
- new-array v10, v11, [Ldot/junit/opcodes/instance_of/d/T_instance_of_2/SubClass;
- instance-of v15, v10, java/lang/Object
- if-eqz v15, LabelExit
-
-; (SubClass instanceof SuperInterface)
- new-instance v10, dot/junit/opcodes/instance_of/d/T_instance_of_2/SubClass
- invoke-direct {v10}, dot/junit/opcodes/instance_of/d/T_instance_of_2/SubClass/<init>()V
- instance-of v15, v10, dot/junit/opcodes/instance_of/d/T_instance_of_2/SuperInterface
- if-eqz v15, LabelExit
-
-; !(SuperClass instanceof SubClass)
- new-instance v10, dot/junit/opcodes/instance_of/d/T_instance_of_2/SuperClass
- invoke-direct {v10}, dot/junit/opcodes/instance_of/d/T_instance_of_2/SuperClass/<init>()V
- instance-of v15, v10, dot/junit/opcodes/instance_of/d/T_instance_of_2/SubClass
- if-nez v15, LabelExit
-
-; !(SubClass instanceof SuperInterface2)
- new-instance v10, dot/junit/opcodes/instance_of/d/T_instance_of_2/SubClass
- invoke-direct {v10}, dot/junit/opcodes/instance_of/d/T_instance_of_2/SubClass/<init>()V
- instance-of v15, v10, dot/junit/opcodes/instance_of/d/T_instance_of_2/SuperInterface2
- if-nez v15, LabelExit
-
-; !(SubClass[] instanceof SuperInterface)
- new-array v10, v11, [Ldot/junit/opcodes/instance_of/d/T_instance_of_2/SubClass;
- instance-of v15, v10, dot/junit/opcodes/instance_of/d/T_instance_of_2/SuperInterface
- if-nez v15, LabelExit
-
-; !(SubClass[] instanceof SubClass)
- new-array v10, v11, [Ldot/junit/opcodes/instance_of/d/T_instance_of_2/SubClass;
- instance-of v15, v10, dot/junit/opcodes/instance_of/d/T_instance_of_2/SubClass
- if-nez v15, LabelExit
-
-; !(SuperClass[] instanceof SubClass[])
- new-array v10, v11, [Ldot/junit/opcodes/instance_of/d/T_instance_of_2/SuperClass;
- instance-of v15, v10, [Ldot/junit/opcodes/instance_of/d/T_instance_of_2/SubClass;
- if-nez v15, LabelExit
-
- const v0, 1
-
-LabelExit:
- return v0
-
-.end method
-
-
diff --git a/tools/vm-tests-tf/src/dot/junit/opcodes/instance_of/d/T_instance_of_3.d.done b/tools/vm-tests-tf/src/dot/junit/opcodes/instance_of/d/T_instance_of_3.d.done
deleted file mode 100644
index 6705dcf..0000000
--- a/tools/vm-tests-tf/src/dot/junit/opcodes/instance_of/d/T_instance_of_3.d.done
+++ /dev/null
@@ -1,33 +0,0 @@
-; 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.
-
-.source T_instance_of_3.java
-.class public dot.junit.opcodes.instance_of.d.T_instance_of_3
-.super java/lang/Object
-
-
-.method public <init>()V
-.limit regs 1
-
- invoke-direct {v0}, java/lang/Object/<init>()V
- return-void
-.end method
-
-.method public run()V
-.limit regs 6
- instance-of v0, v5, dot/junit/opcodes/instance_of/TestStubs
- return-void
-.end method
-
-
diff --git a/tools/vm-tests-tf/src/dot/junit/opcodes/instance_of/d/T_instance_of_4.d.done b/tools/vm-tests-tf/src/dot/junit/opcodes/instance_of/d/T_instance_of_4.d.done
deleted file mode 100644
index fe8b891..0000000
--- a/tools/vm-tests-tf/src/dot/junit/opcodes/instance_of/d/T_instance_of_4.d.done
+++ /dev/null
@@ -1,32 +0,0 @@
-; 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.
-
-.source T_instance_of_4.java
-.class public dot.junit.opcodes.instance_of.d.T_instance_of_4
-.super java/lang/Object
-
-
-.method public <init>()V
-.limit regs 1
-
- invoke-direct {v0}, java/lang/Object/<init>()V
- return-void
-.end method
-
-.method public run(Ljava/lang/Object;)V
-.limit regs 5
-
- instance-of v0, v4, java/lang/String
- return-void
-.end method
diff --git a/tools/vm-tests-tf/src/dot/junit/opcodes/instance_of/d/T_instance_of_5.d.done b/tools/vm-tests-tf/src/dot/junit/opcodes/instance_of/d/T_instance_of_5.d.done
deleted file mode 100644
index eac21b9..0000000
--- a/tools/vm-tests-tf/src/dot/junit/opcodes/instance_of/d/T_instance_of_5.d.done
+++ /dev/null
@@ -1,32 +0,0 @@
-; 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.
-
-.source T_instance_of_5.java
-.class public dot.junit.opcodes.instance_of.d.T_instance_of_5
-.super java/lang/Object
-
-
-.method public <init>()V
-.limit regs 1
-
- invoke-direct {v0}, java/lang/Object/<init>()V
- return-void
-.end method
-
-.method public run(Ljava/lang/Object;)V
-.limit regs 5
- const v3, 1234
- instance-of v1, v3, java/lang/String
- return-void
-.end method
diff --git a/tools/vm-tests-tf/src/dot/junit/opcodes/instance_of/d/T_instance_of_6.d.done b/tools/vm-tests-tf/src/dot/junit/opcodes/instance_of/d/T_instance_of_6.d.done
deleted file mode 100644
index 4c2e649..0000000
--- a/tools/vm-tests-tf/src/dot/junit/opcodes/instance_of/d/T_instance_of_6.d.done
+++ /dev/null
@@ -1,32 +0,0 @@
-; 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.
-
-.source T_instance_of_6.java
-.class public dot.junit.opcodes.instance_of.d.T_instance_of_6
-.super java/lang/Object
-
-
-.method public <init>()V
-.limit regs 1
-
- invoke-direct {v0}, java/lang/Object/<init>()V
- return-void
-.end method
-
-.method public run(Ljava/lang/Object;)V
-.limit regs 5
-
- instance-of v0, v5, java/lang/String
- return-void
-.end method
diff --git a/tools/vm-tests-tf/src/dot/junit/opcodes/instance_of/d/T_instance_of_7.d.done b/tools/vm-tests-tf/src/dot/junit/opcodes/instance_of/d/T_instance_of_7.d.done
deleted file mode 100644
index f0823e7..0000000
--- a/tools/vm-tests-tf/src/dot/junit/opcodes/instance_of/d/T_instance_of_7.d.done
+++ /dev/null
@@ -1,34 +0,0 @@
-; 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.
-
-.source T_instance_of_7.java
-.class public dot.junit.opcodes.instance_of.d.T_instance_of_7
-.super java/lang/Object
-
-
-.method public <init>()V
-.limit regs 1
-
- invoke-direct {v0}, java/lang/Object/<init>()V
- return-void
-.end method
-
-.method public run()V
-.limit regs 6
-
- instance-of v0, v5, dot/junit/opcodes/instance_of/Test_instance_ofN
- return-void
-.end method
-
-
diff --git a/tools/vm-tests-tf/src/dot/junit/opcodes/invoke_direct/d/T_invoke_direct_25.d.done b/tools/vm-tests-tf/src/dot/junit/opcodes/invoke_direct/d/T_invoke_direct_25.d.done
deleted file mode 100644
index 8d872ad..0000000
--- a/tools/vm-tests-tf/src/dot/junit/opcodes/invoke_direct/d/T_invoke_direct_25.d.done
+++ /dev/null
@@ -1,42 +0,0 @@
-; 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.
-
-.source T_invoke_direct_25.java
-.class public dot.junit.opcodes.invoke_direct.d.T_invoke_direct_25
-.super dot/junit/opcodes/invoke_direct/TSuper
-
-
-.method public <init>()V
-.limit regs 2
-
- invoke-direct {v1}, dot/junit/opcodes/invoke_direct/TSuper/<init>()V
- return-void
-.end method
-
-.method private test()V
- return-void
-.end method
-
-.method public run()I
-.limit regs 6
-
- new-instance v2, dot/junit/opcodes/invoke_direct/TPlain
- invoke-direct {v2}, dot/junit/opcodes/invoke_direct/TPlain/<init>()V
-
- invoke-direct {v2}, dot/junit/opcodes/invoke_direct/d/T_invoke_direct_25/test()V
- move-result v0
- return v0
-.end method
-
-
diff --git a/tools/vm-tests-tf/src/dot/junit/opcodes/invoke_direct/d/T_invoke_direct_26.d.done b/tools/vm-tests-tf/src/dot/junit/opcodes/invoke_direct/d/T_invoke_direct_26.d.done
deleted file mode 100644
index 40cce50..0000000
--- a/tools/vm-tests-tf/src/dot/junit/opcodes/invoke_direct/d/T_invoke_direct_26.d.done
+++ /dev/null
@@ -1,58 +0,0 @@
-; 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.
-
-.source TTestInterface.java
-.interface public dot.junit.opcodes.invoke_direct.d.TTestInterface
-
-.method public abstract test()V
-.end method
-
-; =====================================
-
-.source TTestInterfaceImpl.java
-.class public dot.junit.opcodes.invoke_direct.d.TTestInterfaceImpl
-.super java/lang/Object
-.implements dot.junit.opcodes.invoke_direct.d.TTestInterface
-
-.method public <init>()V
-.limit regs 2
-
- invoke-direct {v1}, java/lang/Object/<init>()V
- return-void
-.end method
-
-.method public test()V
- return-void
-.end method
-
-; =====================================
-
-.source T_invoke_direct_26.java
-.class public dot.junit.opcodes.invoke_direct.d.T_invoke_direct_26
-.super dot/junit/opcodes/invoke_direct/d/TTestInterfaceImpl
-
-
-.method public <init>()V
-.limit regs 2
-
- invoke-direct {v1}, dot/junit/opcodes/invoke_direct/d/TTestInterfaceImpl/<init>()V
- return-void
-.end method
-
-.method public run()V
-.limit regs 8
-
- invoke-direct {v7}, dot/junit/opcodes/invoke_direct/d/TTestInterface/test()V
- return-void
-.end method
diff --git a/tools/vm-tests-tf/src/dot/junit/opcodes/invoke_direct/d/T_invoke_direct_27.d.done b/tools/vm-tests-tf/src/dot/junit/opcodes/invoke_direct/d/T_invoke_direct_27.d.done
deleted file mode 100644
index 0ac6b37..0000000
--- a/tools/vm-tests-tf/src/dot/junit/opcodes/invoke_direct/d/T_invoke_direct_27.d.done
+++ /dev/null
@@ -1,41 +0,0 @@
-; 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.
-
-.source T_invoke_direct_27.java
-.class public dot.junit.opcodes.invoke_direct.d.T_invoke_direct_27
-.super java/lang/Object
-
-
-.method public <init>()V
-.limit regs 2
-
- invoke-direct {v1}, java/lang/Object/<init>()V
- return-void
-.end method
-
-.method private test()V
- return-void
-.end method
-
-.method public static run()V
-.limit regs 3
-
- new-instance v0, dot/junit/opcodes/invoke_direct/d/T_invoke_direct_27
-
- invoke-direct {v0}, dot/junit/opcodes/invoke_direct/d/T_invoke_direct_27/test()V
-
- return-void
-.end method
-
-
diff --git a/tools/vm-tests-tf/src/dot/junit/opcodes/invoke_direct/d/T_invoke_direct_4.d.done b/tools/vm-tests-tf/src/dot/junit/opcodes/invoke_direct/d/T_invoke_direct_4.d.done
deleted file mode 100644
index ed919f9..0000000
--- a/tools/vm-tests-tf/src/dot/junit/opcodes/invoke_direct/d/T_invoke_direct_4.d.done
+++ /dev/null
@@ -1,33 +0,0 @@
-; 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.
-
-.source T_invoke_direct_4.java
-.class public dot.junit.opcodes.invoke_direct.d.T_invoke_direct_4
-.super java/lang/Object
-
-.method static <clinit>()V
- return-void
-.end method
-
-.method public <init>()V
-.limit regs 2
- invoke-direct {v1}, java/lang/Object/<init>()V
- return-void
-.end method
-
-.method public run()V
- invoke-direct {}, dot/junit/opcodes/invoke_direct/d/T_invoke_direct_4/<clinit>()V
- return-void
-.end method
-
diff --git a/tools/vm-tests-tf/src/dot/junit/opcodes/invoke_direct/d/T_invoke_direct_9.d.done b/tools/vm-tests-tf/src/dot/junit/opcodes/invoke_direct/d/T_invoke_direct_9.d.done
deleted file mode 100644
index 262b5ff..0000000
--- a/tools/vm-tests-tf/src/dot/junit/opcodes/invoke_direct/d/T_invoke_direct_9.d.done
+++ /dev/null
@@ -1,38 +0,0 @@
-; 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.
-
-.source T_invoke_direct_9.java
-.class public dot.junit.opcodes.invoke_direct.d.T_invoke_direct_9
-.super java/lang/Object
-
-
-.method public <init>()V
-.limit regs 2
-
- invoke-direct {v1}, java/lang/Object/<init>()V
- return-void
-.end method
-
-.method public run()I
-.limit regs 3
-
- invoke-direct {v2}, dot.junit.opcodes.invoke_direct.d.T_invoke_direct_9/toInt()I
-
- move-result v0
- return v0
-.end method
-
-
-.method private native toInt()I
-.end method
diff --git a/tools/vm-tests-tf/src/dot/junit/opcodes/invoke_direct_range/d/T_invoke_direct_range_24.d.done b/tools/vm-tests-tf/src/dot/junit/opcodes/invoke_direct_range/d/T_invoke_direct_range_24.d.done
deleted file mode 100644
index 31a24c4..0000000
--- a/tools/vm-tests-tf/src/dot/junit/opcodes/invoke_direct_range/d/T_invoke_direct_range_24.d.done
+++ /dev/null
@@ -1,70 +0,0 @@
-; 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.
-
-.source T_invoke_direct_range_24.java
-.class public dot.junit.opcodes.invoke_direct_range.d.T_invoke_direct_range_24
-.super java/lang/Object
-
-
-.method public <init>()V
-.limit regs 2
-
- invoke-direct {v1}, java/lang/Object/<init>()V
- return-void
-.end method
-
-.method private test(II)I
-.limit regs 7
- const v0, 999
- const v1, 888
- const v2, 777
-
- div-int v4, v5, v6
-
- return v4
-.end method
-
-.method public run()I
-.limit regs 7
- const v0, 111
- const v1, 222
- const v2, 333
-
-
- const-wide v4, 50
- move-object v3, v6
- invoke-direct {v3..v5}, dot/junit/opcodes/invoke_direct_range/d/T_invoke_direct_range_24/test(II)I
- move-result v3
-
- const v4, 2
- if-ne v3, v4, Label30
-
- const v4, 111
- if-ne v0, v4, Label30
-
- const v4, 222
- if-ne v1, v4, Label30
-
- const v4, 333
- if-ne v2, v4, Label30
-
- const v0, 1
- return v0
-Label30:
- const v0, 0
- return v0
-
-.end method
-
-
diff --git a/tools/vm-tests-tf/src/dot/junit/opcodes/invoke_direct_range/d/T_invoke_direct_range_25.d.done b/tools/vm-tests-tf/src/dot/junit/opcodes/invoke_direct_range/d/T_invoke_direct_range_25.d.done
deleted file mode 100644
index 6c2334e..0000000
--- a/tools/vm-tests-tf/src/dot/junit/opcodes/invoke_direct_range/d/T_invoke_direct_range_25.d.done
+++ /dev/null
@@ -1,42 +0,0 @@
-; 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.
-
-.source T_invoke_direct_range_25.java
-.class public dot.junit.opcodes.invoke_direct_range.d.T_invoke_direct_range_25
-.super dot/junit/opcodes/invoke_direct_range/TSuper
-
-
-.method public <init>()V
-.limit regs 2
-
- invoke-direct {v1}, dot/junit/opcodes/invoke_direct_range/TSuper/<init>()V
- return-void
-.end method
-
-.method private test()V
- return-void
-.end method
-
-.method public run()I
-.limit regs 6
-
- new-instance v2, dot/junit/opcodes/invoke_direct_range/TPlain
- invoke-direct {v2}, dot/junit/opcodes/invoke_direct_range/TPlain/<init>()V
-
- invoke-direct/range {v2}, dot/junit/opcodes/invoke_direct_range/d/T_invoke_direct_range_25/test()V
- move-result v0
- return v0
-.end method
-
-
diff --git a/tools/vm-tests-tf/src/dot/junit/opcodes/invoke_direct_range/d/T_invoke_direct_range_26.d.done b/tools/vm-tests-tf/src/dot/junit/opcodes/invoke_direct_range/d/T_invoke_direct_range_26.d.done
deleted file mode 100644
index 6160fe5..0000000
--- a/tools/vm-tests-tf/src/dot/junit/opcodes/invoke_direct_range/d/T_invoke_direct_range_26.d.done
+++ /dev/null
@@ -1,58 +0,0 @@
-; 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.
-
-.source TTestInterface.java
-.interface public dot.junit.opcodes.invoke_direct_range.d.TTestInterface
-
-.method public abstract test()V
-.end method
-
-; =====================================
-
-.source TTestInterfaceImpl.java
-.class public dot.junit.opcodes.invoke_direct_range.d.TTestInterfaceImpl
-.super java/lang/Object
-.implements dot.junit.opcodes.invoke_direct_range.d.TTestInterface
-
-.method public <init>()V
-.limit regs 2
-
- invoke-direct {v1}, java/lang/Object/<init>()V
- return-void
-.end method
-
-.method public test()V
- return-void
-.end method
-
-; =====================================
-
-.source T_invoke_direct_range_26.java
-.class public dot.junit.opcodes.invoke_direct_range.d.T_invoke_direct_range_26
-.super dot/junit/opcodes/invoke_direct_range/d/TTestInterfaceImpl
-
-
-.method public <init>()V
-.limit regs 2
-
- invoke-direct {v1}, dot/junit/opcodes/invoke_direct_range/d/TTestInterfaceImpl/<init>()V
- return-void
-.end method
-
-.method public run()V
-.limit regs 8
-
- invoke-direct/range {v7}, dot/junit/opcodes/invoke_direct_range/d/TTestInterface/test()V
- return-void
-.end method
diff --git a/tools/vm-tests-tf/src/dot/junit/opcodes/invoke_direct_range/d/T_invoke_direct_range_27.d.done b/tools/vm-tests-tf/src/dot/junit/opcodes/invoke_direct_range/d/T_invoke_direct_range_27.d.done
deleted file mode 100644
index 1073241..0000000
--- a/tools/vm-tests-tf/src/dot/junit/opcodes/invoke_direct_range/d/T_invoke_direct_range_27.d.done
+++ /dev/null
@@ -1,41 +0,0 @@
-; 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.
-
-.source T_invoke_direct_range_27.java
-.class public dot.junit.opcodes.invoke_direct_range.d.T_invoke_direct_range_27
-.super java/lang/Object
-
-
-.method public <init>()V
-.limit regs 2
-
- invoke-direct {v1}, java/lang/Object/<init>()V
- return-void
-.end method
-
-.method private test()V
- return-void
-.end method
-
-.method public static run()V
-.limit regs 3
-
- new-instance v0, dot/junit/opcodes/invoke_direct_range/d/T_invoke_direct_range_27
-
- invoke-direct/range {v0}, dot/junit/opcodes/invoke_direct_range/d/T_invoke_direct_range_27/test()V
-
- return-void
-.end method
-
-
diff --git a/tools/vm-tests-tf/src/dot/junit/opcodes/invoke_direct_range/d/T_invoke_direct_range_4.d.done b/tools/vm-tests-tf/src/dot/junit/opcodes/invoke_direct_range/d/T_invoke_direct_range_4.d.done
deleted file mode 100644
index a7aeae9..0000000
--- a/tools/vm-tests-tf/src/dot/junit/opcodes/invoke_direct_range/d/T_invoke_direct_range_4.d.done
+++ /dev/null
@@ -1,32 +0,0 @@
-; 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.
-
-.source T_invoke_direct_range_4.java
-.class public dot.junit.opcodes.invoke_direct_range.d.T_invoke_direct_range_4
-.super java/lang/Object
-
-.method static <clinit>()V
- return-void
-.end method
-
-.method public <init>()V
-.limit regs 2
- invoke-direct {v1}, java/lang/Object/<init>()V
- return-void
-.end method
-
-.method public run()V
- invoke-direct/range {v0}, dot/junit/opcodes/invoke_direct_range/d/T_invoke_direct_range_4/<clinit>()V
-.end method
-
diff --git a/tools/vm-tests-tf/src/dot/junit/opcodes/invoke_direct_range/d/T_invoke_direct_range_9.d.done b/tools/vm-tests-tf/src/dot/junit/opcodes/invoke_direct_range/d/T_invoke_direct_range_9.d.done
deleted file mode 100644
index 567bd84..0000000
--- a/tools/vm-tests-tf/src/dot/junit/opcodes/invoke_direct_range/d/T_invoke_direct_range_9.d.done
+++ /dev/null
@@ -1,38 +0,0 @@
-; 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.
-
-.source T_invoke_direct_range_9.java
-.class public dot.junit.opcodes.invoke_direct_range.d.T_invoke_direct_range_9
-.super java/lang/Object
-
-
-.method public <init>()V
-.limit regs 2
-
- invoke-direct {v1}, java/lang/Object/<init>()V
- return-void
-.end method
-
-.method public run()I
-.limit regs 3
-
- invoke-direct/range {v2}, dot.junit.opcodes.invoke_direct_range.d.T_invoke_direct_range_9/toInt()I
-
- move-result v0
- return v0
-.end method
-
-
-.method private native toInt()I
-.end method
diff --git a/tools/vm-tests-tf/src/dot/junit/opcodes/invoke_interface/d/T_invoke_interface_23.d.done b/tools/vm-tests-tf/src/dot/junit/opcodes/invoke_interface/d/T_invoke_interface_23.d.done
deleted file mode 100644
index 6709286..0000000
--- a/tools/vm-tests-tf/src/dot/junit/opcodes/invoke_interface/d/T_invoke_interface_23.d.done
+++ /dev/null
@@ -1,49 +0,0 @@
-; 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.
-
-.source ITestDefault2.java
-.interface public dot.junit.opcodes.invoke_interface.d.ITestDefault2
-
-.method public testDefault()V
-.limit regs 2
- return-void
-.end method
-
-.source ITestDefault.java
-.interface public dot.junit.opcodes.invoke_interface.d.ITestDefault
-
-.method public testDefault()V
-.limit regs 2
- return-void
-.end method
-
-.source T_invoke_interface_23.java
-.class public dot.junit.opcodes.invoke_interface.d.T_invoke_interface_23
-.super java/lang/Object
-.implements dot.junit.opcodes.invoke_interface.d.ITestDefault
-.implements dot.junit.opcodes.invoke_interface.d.ITestDefault2
-
-.method public <init>()V
-.limit regs 2
-
- invoke-direct {v1}, java/lang/Object/<init>()V
- return-void
-.end method
-
-.method public run()V
-.limit regs 1
- invoke-interface {v0}, dot/junit/opcodes/invoke_interface/d/ITestDefault/testDefault()V
- return-void
-.end method
-
diff --git a/tools/vm-tests-tf/src/dot/junit/opcodes/invoke_interface/d/T_invoke_interface_24.d.done b/tools/vm-tests-tf/src/dot/junit/opcodes/invoke_interface/d/T_invoke_interface_24.d.done
deleted file mode 100644
index 577510a..0000000
--- a/tools/vm-tests-tf/src/dot/junit/opcodes/invoke_interface/d/T_invoke_interface_24.d.done
+++ /dev/null
@@ -1,58 +0,0 @@
-; 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.
-
-.source ITestDefault2.java
-.interface public dot.junit.opcodes.invoke_interface.d.ITestDefault2
-
-.method public testDefault()V
-.limit regs 2
- return-void
-.end method
-
-.source ITestDefault.java
-.interface public dot.junit.opcodes.invoke_interface.d.ITestDefault
-
-.method public testDefault()V
-.limit regs 2
- return-void
-.end method
-
-.source ITestNonDefault.java
-.interface public dot.junit.opcodes.invoke_interface.d.ITestNonDefault
-.implements dot.junit.opcodes.invoke_interface.d.ITestDefault
-.implements dot.junit.opcodes.invoke_interface.d.ITestDefault2
-
-.method public abstract testDefault()V
-.end method
-
-
-.source T_invoke_interface_24.java
-.class public dot.junit.opcodes.invoke_interface.d.T_invoke_interface_24
-.super java/lang/Object
-.implements dot.junit.opcodes.invoke_interface.d.ITestNonDefault
-.implements dot.junit.opcodes.invoke_interface.d.ITestDefault2
-
-.method public <init>()V
-.limit regs 2
-
- invoke-direct {v1}, java/lang/Object/<init>()V
- return-void
-.end method
-
-.method public run()V
-.limit regs 1
- invoke-interface {v0}, dot/junit/opcodes/invoke_interface/d/ITestDefault2/testDefault()V
- return-void
-.end method
-
diff --git a/tools/vm-tests-tf/src/dot/junit/opcodes/invoke_interface/d/T_invoke_interface_25.d.done b/tools/vm-tests-tf/src/dot/junit/opcodes/invoke_interface/d/T_invoke_interface_25.d.done
deleted file mode 100644
index 19b57b4..0000000
--- a/tools/vm-tests-tf/src/dot/junit/opcodes/invoke_interface/d/T_invoke_interface_25.d.done
+++ /dev/null
@@ -1,40 +0,0 @@
-; 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.
-
-.source ITestDefault.java
-.interface public dot.junit.opcodes.invoke_interface.d.ITestDefault
-
-.method public testDefault()V
-.limit regs 2
- return-void
-.end method
-
-.source T_invoke_interface_25.java
-.class public dot.junit.opcodes.invoke_interface.d.T_invoke_interface_25
-.super java/lang/Object
-.implements dot.junit.opcodes.invoke_interface.d.ITestDefault
-
-.method public <init>()V
-.limit regs 2
-
- invoke-direct {v1}, java/lang/Object/<init>()V
- return-void
-.end method
-
-.method public run()V
-.limit regs 1
- invoke-interface {v0}, dot/junit/opcodes/invoke_interface/d/ITestDefault/testDefault()V
- return-void
-.end method
-
diff --git a/tools/vm-tests-tf/src/dot/junit/opcodes/invoke_interface/d/T_invoke_interface_4.d.done b/tools/vm-tests-tf/src/dot/junit/opcodes/invoke_interface/d/T_invoke_interface_4.d.done
deleted file mode 100644
index a8de67b..0000000
--- a/tools/vm-tests-tf/src/dot/junit/opcodes/invoke_interface/d/T_invoke_interface_4.d.done
+++ /dev/null
@@ -1,39 +0,0 @@
-; 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.
-
-.source T_invoke_interface_4.java
-.class public dot.junit.opcodes.invoke_interface.d.T_invoke_interface_4
-.super java/lang/Object
-
-
-.method public <init>()V
-.limit regs 2
-
- invoke-direct {v1}, java/lang/Object/<init>()V
- return-void
-.end method
-
-.method public test()V
- return-void
-.end method
-
-.method public run()V
-.limit regs 8
-
- invoke-interface {v7}, dot/junit/opcodes/invoke_interface/d/T_invoke_interface_4/test()V
-
- return-void
-.end method
-
-
diff --git a/tools/vm-tests-tf/src/dot/junit/opcodes/invoke_interface_range/d/T_invoke_interface_range_23.d.done b/tools/vm-tests-tf/src/dot/junit/opcodes/invoke_interface_range/d/T_invoke_interface_range_23.d.done
deleted file mode 100644
index 9314daa..0000000
--- a/tools/vm-tests-tf/src/dot/junit/opcodes/invoke_interface_range/d/T_invoke_interface_range_23.d.done
+++ /dev/null
@@ -1,49 +0,0 @@
-; 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.
-
-.source ITestDefault2.java
-.interface public dot.junit.opcodes.invoke_interface_range.d.ITestDefault2
-
-.method public testDefault()V
-.limit regs 2
- return-void
-.end method
-
-.source ITestDefault.java
-.interface public dot.junit.opcodes.invoke_interface_range.d.ITestDefault
-
-.method public testDefault()V
-.limit regs 2
- return-void
-.end method
-
-.source T_invoke_interface_range_23.java
-.class public dot.junit.opcodes.invoke_interface_range.d.T_invoke_interface_range_23
-.super java/lang/Object
-.implements dot.junit.opcodes.invoke_interface_range.d.ITestDefault
-.implements dot.junit.opcodes.invoke_interface_range.d.ITestDefault2
-
-.method public <init>()V
-.limit regs 2
-
- invoke-direct {v1}, java/lang/Object/<init>()V
- return-void
-.end method
-
-.method public run()V
-.limit regs 1
- invoke-interface/range {v0}, dot/junit/opcodes/invoke_interface_range/d/ITestDefault/testDefault()V
- return-void
-.end method
-
diff --git a/tools/vm-tests-tf/src/dot/junit/opcodes/invoke_interface_range/d/T_invoke_interface_range_24.d.done b/tools/vm-tests-tf/src/dot/junit/opcodes/invoke_interface_range/d/T_invoke_interface_range_24.d.done
deleted file mode 100644
index c70dfb6..0000000
--- a/tools/vm-tests-tf/src/dot/junit/opcodes/invoke_interface_range/d/T_invoke_interface_range_24.d.done
+++ /dev/null
@@ -1,58 +0,0 @@
-; 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.
-
-.source ITestDefault2.java
-.interface public dot.junit.opcodes.invoke_interface_range.d.ITestDefault2
-
-.method public testDefault()V
-.limit regs 2
- return-void
-.end method
-
-.source ITestDefault.java
-.interface public dot.junit.opcodes.invoke_interface_range.d.ITestDefault
-
-.method public testDefault()V
-.limit regs 2
- return-void
-.end method
-
-.source ITestNonDefault.java
-.interface public dot.junit.opcodes.invoke_interface_range.d.ITestNonDefault
-.implements dot.junit.opcodes.invoke_interface_range.d.ITestDefault
-.implements dot.junit.opcodes.invoke_interface_range.d.ITestDefault2
-
-.method public abstract testDefault()V
-.end method
-
-
-.source T_invoke_interface_range_24.java
-.class public dot.junit.opcodes.invoke_interface_range.d.T_invoke_interface_range_24
-.super java/lang/Object
-.implements dot.junit.opcodes.invoke_interface_range.d.ITestNonDefault
-.implements dot.junit.opcodes.invoke_interface_range.d.ITestDefault2
-
-.method public <init>()V
-.limit regs 2
-
- invoke-direct {v1}, java/lang/Object/<init>()V
- return-void
-.end method
-
-.method public run()V
-.limit regs 1
- invoke-interface/range {v0}, dot/junit/opcodes/invoke_interface_range/d/ITestDefault2/testDefault()V
- return-void
-.end method
-
diff --git a/tools/vm-tests-tf/src/dot/junit/opcodes/invoke_interface_range/d/T_invoke_interface_range_25.d.done b/tools/vm-tests-tf/src/dot/junit/opcodes/invoke_interface_range/d/T_invoke_interface_range_25.d.done
deleted file mode 100644
index fd10395..0000000
--- a/tools/vm-tests-tf/src/dot/junit/opcodes/invoke_interface_range/d/T_invoke_interface_range_25.d.done
+++ /dev/null
@@ -1,40 +0,0 @@
-; 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.
-
-.source ITestDefault.java
-.interface public dot.junit.opcodes.invoke_interface_range.d.ITestDefault
-
-.method public testDefault()V
-.limit regs 2
- return-void
-.end method
-
-.source T_invoke_interface_range_25.java
-.class public dot.junit.opcodes.invoke_interface_range.d.T_invoke_interface_range_25
-.super java/lang/Object
-.implements dot.junit.opcodes.invoke_interface_range.d.ITestDefault
-
-.method public <init>()V
-.limit regs 2
-
- invoke-direct {v1}, java/lang/Object/<init>()V
- return-void
-.end method
-
-.method public run()V
-.limit regs 1
- invoke-interface/range {v0}, dot/junit/opcodes/invoke_interface_range/d/ITestDefault/testDefault()V
- return-void
-.end method
-
diff --git a/tools/vm-tests-tf/src/dot/junit/opcodes/invoke_interface_range/d/T_invoke_interface_range_4.d.done b/tools/vm-tests-tf/src/dot/junit/opcodes/invoke_interface_range/d/T_invoke_interface_range_4.d.done
deleted file mode 100644
index 8a21324..0000000
--- a/tools/vm-tests-tf/src/dot/junit/opcodes/invoke_interface_range/d/T_invoke_interface_range_4.d.done
+++ /dev/null
@@ -1,39 +0,0 @@
-; 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.
-
-.source T_invoke_interface_range_4.java
-.class public dot.junit.opcodes.invoke_interface_range.d.T_invoke_interface_range_4
-.super java/lang/Object
-
-
-.method public <init>()V
-.limit regs 2
-
- invoke-direct {v1}, java/lang/Object/<init>()V
- return-void
-.end method
-
-.method public test()V
- return-void
-.end method
-
-.method public run()V
-.limit regs 8
-
- invoke-interface/range {v7}, dot/junit/opcodes/invoke_interface_range/d/T_invoke_interface_range_4/test()V
-
- return-void
-.end method
-
-
diff --git a/tools/vm-tests-tf/src/dot/junit/opcodes/invoke_static/d/T_invoke_static_13.d.done b/tools/vm-tests-tf/src/dot/junit/opcodes/invoke_static/d/T_invoke_static_13.d.done
deleted file mode 100644
index 2e78a06..0000000
--- a/tools/vm-tests-tf/src/dot/junit/opcodes/invoke_static/d/T_invoke_static_13.d.done
+++ /dev/null
@@ -1,36 +0,0 @@
-; 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.
-
-.source T_invoke_static_13.java
-.class public dot.junit.opcodes.invoke_static.d.T_invoke_static_13
-.super java/lang/Object
-
-
-.method public <init>()V
-.limit regs 2
-
- invoke-direct {v1}, java/lang/Object/<init>()V
- return-void
-.end method
-
-.method public run()V
-.limit regs 3
-
- const v1, 3.14
-
- invoke-static {v1}, dot/junit/opcodes/invoke_static/TestClass/test1(F)I
- return-void
-.end method
-
-
diff --git a/tools/vm-tests-tf/src/dot/junit/opcodes/invoke_static/d/T_invoke_static_14.d.done b/tools/vm-tests-tf/src/dot/junit/opcodes/invoke_static/d/T_invoke_static_14.d.done
deleted file mode 100644
index ed833e2..0000000
--- a/tools/vm-tests-tf/src/dot/junit/opcodes/invoke_static/d/T_invoke_static_14.d.done
+++ /dev/null
@@ -1,51 +0,0 @@
-; 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.
-
-.source TestClassInitError.java
-.class public dot.junit.opcodes.invoke_static.d.TestClassInitError
-.super java/lang/Object
-
-.method static public <clinit>()V
-.limit regs 2
-
- const v0, 1
- const v1, 0
- div-int v0, v0, v1
- return-void
-.end method
-
-.method static public test()V
- return-void
-.end method
-
-.source T_invoke_static_14.java
-.class public dot.junit.opcodes.invoke_static.d.T_invoke_static_14
-.super java/lang/Object
-
-
-.method public <init>()V
-.limit regs 2
-
- invoke-direct {v1}, java/lang/Object/<init>()V
- return-void
-.end method
-
-.method public run()V
-.limit regs 1
-
- invoke-static {}, dot/junit/opcodes/invoke_static/d/TestClassInitError/test()V
- return-void
-.end method
-
-
diff --git a/tools/vm-tests-tf/src/dot/junit/opcodes/invoke_static/d/T_invoke_static_18.d.done b/tools/vm-tests-tf/src/dot/junit/opcodes/invoke_static/d/T_invoke_static_18.d.done
deleted file mode 100644
index 7332bce..0000000
--- a/tools/vm-tests-tf/src/dot/junit/opcodes/invoke_static/d/T_invoke_static_18.d.done
+++ /dev/null
@@ -1,53 +0,0 @@
-; 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.
-
-.source TestProtected.java
-.class public dot.junit.opcodes.invoke_static.d.TestProtected
-.super java/lang/Object
-
-
-.method public <init>()V
-.limit regs 2
- invoke-direct {v1}, java/lang/Object/<init>()V
- return-void
-.end method
-
-.method protected static testP()I
-.limit regs 2
- const v0, 888
- return v0
-.end method
-
-
-.source T_invoke_static_18.java
-.class public dot.junit.opcodes.invoke_static.d.T_invoke_static_18
-.super java/lang/Object
-
-
-.method public <init>()V
-.limit regs 2
-
- invoke-direct {v1}, java/lang/Object/<init>()V
- return-void
-.end method
-
-.method public run()I
-.limit regs 3
-
- invoke-static {}, dot/junit/opcodes/invoke_static/d/TestProtected/testP()I
- move-result v0
- return v0
-.end method
-
-
diff --git a/tools/vm-tests-tf/src/dot/junit/opcodes/invoke_static/d/T_invoke_static_24.d.done b/tools/vm-tests-tf/src/dot/junit/opcodes/invoke_static/d/T_invoke_static_24.d.done
deleted file mode 100644
index 9a2871f..0000000
--- a/tools/vm-tests-tf/src/dot/junit/opcodes/invoke_static/d/T_invoke_static_24.d.done
+++ /dev/null
@@ -1,58 +0,0 @@
-; 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.
-
-.source TTestInterface.java
-.interface public dot.junit.opcodes.invoke_static.d.TTestInterface
-
-.method public abstract test()V
-.end method
-
-; =====================================
-
-.source TTestInterfaceImpl.java
-.class public dot.junit.opcodes.invoke_static.d.TTestInterfaceImpl
-.super java/lang/Object
-.implements dot.junit.opcodes.invoke_static.d.TTestInterface
-
-.method public <init>()V
-.limit regs 2
-
- invoke-direct {v1}, java/lang/Object/<init>()V
- return-void
-.end method
-
-.method public test()V
- return-void
-.end method
-
-; =====================================
-
-.source T_invoke_static_24.java
-.class public dot.junit.opcodes.invoke_static.d.T_invoke_static_24
-.super dot/junit/opcodes/invoke_static/d/TTestInterfaceImpl
-
-
-.method public <init>()V
-.limit regs 2
-
- invoke-direct {v1}, dot/junit/opcodes/invoke_static/d/TTestInterfaceImpl/<init>()V
- return-void
-.end method
-
-.method public run()V
-.limit regs 8
-
- invoke-static {v7}, dot/junit/opcodes/invoke_static/d/TTestInterface/test()V
- return-void
-.end method
diff --git a/tools/vm-tests-tf/src/dot/junit/opcodes/invoke_static/d/T_invoke_static_6.d.done b/tools/vm-tests-tf/src/dot/junit/opcodes/invoke_static/d/T_invoke_static_6.d.done
deleted file mode 100644
index 969e499..0000000
--- a/tools/vm-tests-tf/src/dot/junit/opcodes/invoke_static/d/T_invoke_static_6.d.done
+++ /dev/null
@@ -1,37 +0,0 @@
-; 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.
-
-.source T_invoke_static_6.java
-.class public dot.junit.opcodes.invoke_static.d.T_invoke_static_6
-.super java/lang/Object
-
-
-.method public <init>()V
-.limit regs 2
-
- invoke-direct {v1}, java/lang/Object/<init>()V
- return-void
-.end method
-
-.method public static native test()V
-.end method
-
-.method public run()V
-.limit regs 1
-
- invoke-static {}, dot/junit/opcodes/invoke_static/d/T_invoke_static_6/test()V
- return-void
-.end method
-
-
diff --git a/tools/vm-tests-tf/src/dot/junit/opcodes/invoke_static_range/d/T_invoke_static_range_13.d.done b/tools/vm-tests-tf/src/dot/junit/opcodes/invoke_static_range/d/T_invoke_static_range_13.d.done
deleted file mode 100644
index dca327b..0000000
--- a/tools/vm-tests-tf/src/dot/junit/opcodes/invoke_static_range/d/T_invoke_static_range_13.d.done
+++ /dev/null
@@ -1,36 +0,0 @@
-; 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.
-
-.source T_invoke_static_range_13.java
-.class public dot.junit.opcodes.invoke_static_range.d.T_invoke_static_range_13
-.super java/lang/Object
-
-
-.method public <init>()V
-.limit regs 2
-
- invoke-direct {v1}, java/lang/Object/<init>()V
- return-void
-.end method
-
-.method public run()V
-.limit regs 3
-
- const v1, 3.14
-
- invoke-static/range {v1}, dot/junit/opcodes/invoke_static_range/TestClass/test1(F)I
- return-void
-.end method
-
-
diff --git a/tools/vm-tests-tf/src/dot/junit/opcodes/invoke_static_range/d/T_invoke_static_range_14.d.done b/tools/vm-tests-tf/src/dot/junit/opcodes/invoke_static_range/d/T_invoke_static_range_14.d.done
deleted file mode 100644
index 08c04ff..0000000
--- a/tools/vm-tests-tf/src/dot/junit/opcodes/invoke_static_range/d/T_invoke_static_range_14.d.done
+++ /dev/null
@@ -1,51 +0,0 @@
-; 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.
-
-.source TestClassInitError.java
-.class public dot.junit.opcodes.invoke_static_range.d.TestClassInitError
-.super java/lang/Object
-
-.method static public <clinit>()V
-.limit regs 2
-
- const v0, 1
- const v1, 0
- div-int v0, v0, v1
- return-void
-.end method
-
-.method static public test()V
- return-void
-.end method
-
-.source T_invoke_static_range_14.java
-.class public dot.junit.opcodes.invoke_static_range.d.T_invoke_static_range_14
-.super java/lang/Object
-
-
-.method public <init>()V
-.limit regs 2
-
- invoke-direct {v1}, java/lang/Object/<init>()V
- return-void
-.end method
-
-.method public run()V
-.limit regs 1
-
- invoke-static/range {}, dot/junit/opcodes/invoke_static_range/d/TestClassInitError/test()V
- return-void
-.end method
-
-
diff --git a/tools/vm-tests-tf/src/dot/junit/opcodes/invoke_static_range/d/T_invoke_static_range_18.d.done b/tools/vm-tests-tf/src/dot/junit/opcodes/invoke_static_range/d/T_invoke_static_range_18.d.done
deleted file mode 100644
index 19fec09..0000000
--- a/tools/vm-tests-tf/src/dot/junit/opcodes/invoke_static_range/d/T_invoke_static_range_18.d.done
+++ /dev/null
@@ -1,53 +0,0 @@
-; 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.
-
-.source TestProtected.java
-.class public dot.junit.opcodes.invoke_static_range.d.TestProtected
-.super java/lang/Object
-
-
-.method public <init>()V
-.limit regs 2
- invoke-direct {v1}, java/lang/Object/<init>()V
- return-void
-.end method
-
-.method protected static testP()I
-.limit regs 2
- const v0, 888
- return v0
-.end method
-
-
-.source T_invoke_static_range_18.java
-.class public dot.junit.opcodes.invoke_static_range.d.T_invoke_static_range_18
-.super java/lang/Object
-
-
-.method public <init>()V
-.limit regs 2
-
- invoke-direct {v1}, java/lang/Object/<init>()V
- return-void
-.end method
-
-.method public run()I
-.limit regs 3
-
- invoke-static/range {}, dot/junit/opcodes/invoke_static_range/d/TestProtected/testP()I
- move-result v0
- return v0
-.end method
-
-
diff --git a/tools/vm-tests-tf/src/dot/junit/opcodes/invoke_static_range/d/T_invoke_static_range_24.d.done b/tools/vm-tests-tf/src/dot/junit/opcodes/invoke_static_range/d/T_invoke_static_range_24.d.done
deleted file mode 100644
index 6ee8671..0000000
--- a/tools/vm-tests-tf/src/dot/junit/opcodes/invoke_static_range/d/T_invoke_static_range_24.d.done
+++ /dev/null
@@ -1,58 +0,0 @@
-; 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.
-
-.source TTestInterface.java
-.interface public dot.junit.opcodes.invoke_static_range.d.TTestInterface
-
-.method public abstract test()V
-.end method
-
-; =====================================
-
-.source TTestInterfaceImpl.java
-.class public dot.junit.opcodes.invoke_static_range.d.TTestInterfaceImpl
-.super java/lang/Object
-.implements dot.junit.opcodes.invoke_static_range.d.TTestInterface
-
-.method public <init>()V
-.limit regs 2
-
- invoke-direct {v1}, java/lang/Object/<init>()V
- return-void
-.end method
-
-.method public test()V
- return-void
-.end method
-
-; =====================================
-
-.source T_invoke_static_range_24.java
-.class public dot.junit.opcodes.invoke_static_range.d.T_invoke_static_range_24
-.super dot/junit/opcodes/invoke_static_range/d/TTestInterfaceImpl
-
-
-.method public <init>()V
-.limit regs 2
-
- invoke-direct {v1}, dot/junit/opcodes/invoke_static_range/d/TTestInterfaceImpl/<init>()V
- return-void
-.end method
-
-.method public run()V
-.limit regs 8
-
- invoke-static/range {v7}, dot/junit/opcodes/invoke_static_range/d/TTestInterface/test()V
- return-void
-.end method
diff --git a/tools/vm-tests-tf/src/dot/junit/opcodes/invoke_static_range/d/T_invoke_static_range_6.d.done b/tools/vm-tests-tf/src/dot/junit/opcodes/invoke_static_range/d/T_invoke_static_range_6.d.done
deleted file mode 100644
index a739336..0000000
--- a/tools/vm-tests-tf/src/dot/junit/opcodes/invoke_static_range/d/T_invoke_static_range_6.d.done
+++ /dev/null
@@ -1,37 +0,0 @@
-; 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.
-
-.source T_invoke_static_range_6.java
-.class public dot.junit.opcodes.invoke_static_range.d.T_invoke_static_range_6
-.super java/lang/Object
-
-
-.method public <init>()V
-.limit regs 2
-
- invoke-direct {v1}, java/lang/Object/<init>()V
- return-void
-.end method
-
-.method public static native test()V
-.end method
-
-.method public run()V
-.limit regs 1
-
- invoke-static/range {}, dot/junit/opcodes/invoke_static_range/d/T_invoke_static_range_6/test()V
- return-void
-.end method
-
-
diff --git a/tools/vm-tests-tf/src/dot/junit/opcodes/invoke_super/d/TSuper.d.done b/tools/vm-tests-tf/src/dot/junit/opcodes/invoke_super/d/TSuper.d.done
deleted file mode 100644
index 2e4f13f..0000000
--- a/tools/vm-tests-tf/src/dot/junit/opcodes/invoke_super/d/TSuper.d.done
+++ /dev/null
@@ -1,70 +0,0 @@
-; 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.
-
-.source TSuper.java
-.class public dot.junit.opcodes.invoke_super.d.TSuper
-.super java/lang/Object
-
-.method public <init>()V
-.limit regs 2
-
- invoke-direct {v1}, java/lang/Object/<init>()V
- return-void
-.end method
-
-.method public toInt()I
-.limit regs 3
- const v0, 5
- return v0
-.end method
-
-.method public toInt(F)I
-.limit regs 3
- float-to-int v0, v2
- return v0
-.end method
-
-.method public native toIntNative()I
-.end method
-
-.method public static toIntStatic()I
-.limit regs 3
- const v0, 5
- return v0
-.end method
-
-.method protected toIntP()I
-.limit regs 3
- const v0, 5
- return v0
-.end method
-
-.method private toIntPvt()I
-.limit regs 3
- const v0, 5
- return v0
-.end method
-
-.method public testArgsOrder(II)I
-.limit regs 4
- const v0, 349
- const v1, 344656
- div-int v2, v2, v3
- return v2
-.end method
-
-.method public testString(Ljava/lang/String;)V
-.limit regs 2
- return-void
-.end method
diff --git a/tools/vm-tests-tf/src/dot/junit/opcodes/invoke_super/d/T_invoke_super_24.d.done b/tools/vm-tests-tf/src/dot/junit/opcodes/invoke_super/d/T_invoke_super_24.d.done
deleted file mode 100644
index 55303d3..0000000
--- a/tools/vm-tests-tf/src/dot/junit/opcodes/invoke_super/d/T_invoke_super_24.d.done
+++ /dev/null
@@ -1,58 +0,0 @@
-; 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.
-
-.source TTestInterface.java
-.interface public dot.junit.opcodes.invoke_super.d.TTestInterface
-
-.method public abstract test()V
-.end method
-
-; =====================================
-
-.source TTestInterfaceImpl.java
-.class public dot.junit.opcodes.invoke_super.d.TTestInterfaceImpl
-.super java/lang/Object
-.implements dot.junit.opcodes.invoke_super.d.TTestInterface
-
-.method public <init>()V
-.limit regs 2
-
- invoke-direct {v1}, java/lang/Object/<init>()V
- return-void
-.end method
-
-.method public test()V
- return-void
-.end method
-
-; =====================================
-
-.source T_invoke_super_24.java
-.class public dot.junit.opcodes.invoke_super.d.T_invoke_super_24
-.super dot/junit/opcodes/invoke_super/d/TTestInterfaceImpl
-
-
-.method public <init>()V
-.limit regs 2
-
- invoke-direct {v1}, dot/junit/opcodes/invoke_super/d/TTestInterfaceImpl/<init>()V
- return-void
-.end method
-
-.method public run()V
-.limit regs 8
-
- invoke-super {v7}, dot/junit/opcodes/invoke_super/d/TTestInterface/test()V
- return-void
-.end method
diff --git a/tools/vm-tests-tf/src/dot/junit/opcodes/invoke_super/d/T_invoke_super_26.d.done b/tools/vm-tests-tf/src/dot/junit/opcodes/invoke_super/d/T_invoke_super_26.d.done
deleted file mode 100644
index 1e68d5f..0000000
--- a/tools/vm-tests-tf/src/dot/junit/opcodes/invoke_super/d/T_invoke_super_26.d.done
+++ /dev/null
@@ -1,50 +0,0 @@
-; 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.
-
-.source ITestDefault2.java
-.interface public dot.junit.opcodes.invoke_super.d.ITestDefault2
-
-.method public testDefault()V
-.limit regs 2
- return-void
-.end method
-
-.source ITestDefault.java
-.interface public dot.junit.opcodes.invoke_super.d.ITestDefault
-
-.method public testDefault()V
-.limit regs 2
- return-void
-.end method
-
-.source T_invoke_super_26.java
-.class public dot.junit.opcodes.invoke_super.d.T_invoke_super_26
-.super java/lang/Object
-.implements dot.junit.opcodes.invoke_super.d.ITestDefault
-.implements dot.junit.opcodes.invoke_super.d.ITestDefault2
-
-.method public <init>()V
-.limit regs 2
-
- invoke-direct {v1}, java/lang/Object/<init>()V
- return-void
-.end method
-
-.method public run()V
-.limit regs 1
- invoke-super {v0}, dot/junit/opcodes/invoke_super/d/ITestDefault/testDefault()V
- invoke-super {v0}, dot/junit/opcodes/invoke_super/d/ITestDefault2/testDefault()V
- return-void
-.end method
-
diff --git a/tools/vm-tests-tf/src/dot/junit/opcodes/invoke_super/d/T_invoke_super_27.d.done b/tools/vm-tests-tf/src/dot/junit/opcodes/invoke_super/d/T_invoke_super_27.d.done
deleted file mode 100644
index 8bda6a5..0000000
--- a/tools/vm-tests-tf/src/dot/junit/opcodes/invoke_super/d/T_invoke_super_27.d.done
+++ /dev/null
@@ -1,58 +0,0 @@
-; 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.
-
-.source ITestDefault2.java
-.interface public dot.junit.opcodes.invoke_super.d.ITestDefault2
-
-.method public testDefault()V
-.limit regs 2
- return-void
-.end method
-
-.source ITestDefault.java
-.interface public dot.junit.opcodes.invoke_super.d.ITestDefault
-
-.method public testDefault()V
-.limit regs 2
- return-void
-.end method
-
-.source ITestNonDefault.java
-.interface public dot.junit.opcodes.invoke_super.d.ITestNonDefault
-.implements dot.junit.opcodes.invoke_super.d.ITestDefault
-.implements dot.junit.opcodes.invoke_super.d.ITestDefault2
-
-.method public abstract testDefault()V
-.end method
-
-
-.source T_invoke_super_27.java
-.class public dot.junit.opcodes.invoke_super.d.T_invoke_super_27
-.super java/lang/Object
-.implements dot.junit.opcodes.invoke_super.d.ITestNonDefault
-.implements dot.junit.opcodes.invoke_super.d.ITestDefault2
-
-.method public <init>()V
-.limit regs 2
-
- invoke-direct {v1}, java/lang/Object/<init>()V
- return-void
-.end method
-
-.method public run()V
-.limit regs 1
- invoke-super {v0}, dot/junit/opcodes/invoke_super/d/ITestNonDefault/testDefault()V
- return-void
-.end method
-
diff --git a/tools/vm-tests-tf/src/dot/junit/opcodes/invoke_super/d/T_invoke_super_28.d.done b/tools/vm-tests-tf/src/dot/junit/opcodes/invoke_super/d/T_invoke_super_28.d.done
deleted file mode 100644
index 350fdb8..0000000
--- a/tools/vm-tests-tf/src/dot/junit/opcodes/invoke_super/d/T_invoke_super_28.d.done
+++ /dev/null
@@ -1,53 +0,0 @@
-; 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.
-
-.source ITestDefault2.java
-.interface public dot.junit.opcodes.invoke_super.d.ITestDefault2
-
-.method public testDefault()V
-.limit regs 2
- return-void
-.end method
-
-.source ITestDefault.java
-.interface public dot.junit.opcodes.invoke_super.d.ITestDefault
-
-.method public testDefault()V
-.limit regs 2
- return-void
-.end method
-
-.source ITestConflict.java
-.interface public dot.junit.opcodes.invoke_super.d.ITestConflict
-.implements dot.junit.opcodes.invoke_super.d.ITestDefault
-.implements dot.junit.opcodes.invoke_super.d.ITestDefault2
-
-.source T_invoke_super_28.java
-.class public dot.junit.opcodes.invoke_super.d.T_invoke_super_28
-.super java/lang/Object
-.implements dot.junit.opcodes.invoke_super.d.ITestConflict
-
-.method public <init>()V
-.limit regs 2
-
- invoke-direct {v1}, java/lang/Object/<init>()V
- return-void
-.end method
-
-.method public run()V
-.limit regs 1
- invoke-super {v0}, dot/junit/opcodes/invoke_super/d/ITestConflict/testDefault()V
- return-void
-.end method
-
diff --git a/tools/vm-tests-tf/src/dot/junit/opcodes/invoke_super_range/d/TSuper.d.done b/tools/vm-tests-tf/src/dot/junit/opcodes/invoke_super_range/d/TSuper.d.done
deleted file mode 100644
index 88def8a..0000000
--- a/tools/vm-tests-tf/src/dot/junit/opcodes/invoke_super_range/d/TSuper.d.done
+++ /dev/null
@@ -1,70 +0,0 @@
-; 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.
-
-.source TSuper.java
-.class public dot.junit.opcodes.invoke_super_range.d.TSuper
-.super java/lang/Object
-
-.method public <init>()V
-.limit regs 2
-
- invoke-direct {v1}, java/lang/Object/<init>()V
- return-void
-.end method
-
-.method public toInt()I
-.limit regs 3
- const v0, 5
- return v0
-.end method
-
-.method public toInt(F)I
-.limit regs 3
- float-to-int v0, v2
- return v0
-.end method
-
-.method public native toIntNative()I
-.end method
-
-.method public static toIntStatic()I
-.limit regs 3
- const v0, 5
- return v0
-.end method
-
-.method protected toIntP()I
-.limit regs 3
- const v0, 5
- return v0
-.end method
-
-.method private toIntPvt()I
-.limit regs 3
- const v0, 5
- return v0
-.end method
-
-.method public testArgsOrder(II)I
-.limit regs 4
- const v0, 349
- const v1, 344656
- div-int v2, v2, v3
- return v2
-.end method
-
-.method public testString(Ljava/lang/String;)V
-.limit regs 2
- return-void
-.end method
diff --git a/tools/vm-tests-tf/src/dot/junit/opcodes/invoke_super_range/d/T_invoke_super_range_19.d.done b/tools/vm-tests-tf/src/dot/junit/opcodes/invoke_super_range/d/T_invoke_super_range_19.d.done
deleted file mode 100644
index d30cc05..0000000
--- a/tools/vm-tests-tf/src/dot/junit/opcodes/invoke_super_range/d/T_invoke_super_range_19.d.done
+++ /dev/null
@@ -1,37 +0,0 @@
-; 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.
-
-.source T_invoke_super_range_19.java
-.class public dot.junit.opcodes.invoke_super_range.d.T_invoke_super_range_19
-.super dot/junit/opcodes/invoke_super_range/d/TSuper
-
-
-.method public <init>()V
-.limit regs 2
-
- invoke-direct {v1}, dot/junit/opcodes/invoke_super_range/d/TSuper/<init>()V
- return-void
-.end method
-
-.method public run()I
-.limit regs 4
-
- move-object v0, v3
- const/4 v1, 1
- invoke-super/range {v0, v1}, dot/junit/opcodes/invoke_super_range/d/T_invoke_super_range_19/toInt(I)I
- move-result v0
- return v0
-.end method
-
-
diff --git a/tools/vm-tests-tf/src/dot/junit/opcodes/invoke_super_range/d/T_invoke_super_range_24.d.done b/tools/vm-tests-tf/src/dot/junit/opcodes/invoke_super_range/d/T_invoke_super_range_24.d.done
deleted file mode 100644
index dcc399d..0000000
--- a/tools/vm-tests-tf/src/dot/junit/opcodes/invoke_super_range/d/T_invoke_super_range_24.d.done
+++ /dev/null
@@ -1,58 +0,0 @@
-; 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.
-
-.source TTestInterface.java
-.interface public dot.junit.opcodes.invoke_super_range.d.TTestInterface
-
-.method public abstract test()V
-.end method
-
-; =====================================
-
-.source TTestInterfaceImpl.java
-.class public dot.junit.opcodes.invoke_super_range.d.TTestInterfaceImpl
-.super java/lang/Object
-.implements dot.junit.opcodes.invoke_super_range.d.TTestInterface
-
-.method public <init>()V
-.limit regs 2
-
- invoke-direct {v1}, java/lang/Object/<init>()V
- return-void
-.end method
-
-.method public test()V
- return-void
-.end method
-
-; =====================================
-
-.source T_invoke_super_range_24.java
-.class public dot.junit.opcodes.invoke_super_range.d.T_invoke_super_range_24
-.super dot/junit/opcodes/invoke_super_range/d/TTestInterfaceImpl
-
-
-.method public <init>()V
-.limit regs 2
-
- invoke-direct {v1}, dot/junit/opcodes/invoke_super_range/d/TTestInterfaceImpl/<init>()V
- return-void
-.end method
-
-.method public run()V
-.limit regs 8
-
- invoke-super/range {v7}, dot/junit/opcodes/invoke_super_range/d/TTestInterface/test()V
- return-void
-.end method
diff --git a/tools/vm-tests-tf/src/dot/junit/opcodes/invoke_super_range/d/T_invoke_super_range_26.d.done b/tools/vm-tests-tf/src/dot/junit/opcodes/invoke_super_range/d/T_invoke_super_range_26.d.done
deleted file mode 100644
index 8e53186..0000000
--- a/tools/vm-tests-tf/src/dot/junit/opcodes/invoke_super_range/d/T_invoke_super_range_26.d.done
+++ /dev/null
@@ -1,50 +0,0 @@
-; 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.
-
-.source ITestDefault2.java
-.interface public dot.junit.opcodes.invoke_super_range.d.ITestDefault2
-
-.method public testDefault()V
-.limit regs 2
- return-void
-.end method
-
-.source ITestDefault.java
-.interface public dot.junit.opcodes.invoke_super_range.d.ITestDefault
-
-.method public testDefault()V
-.limit regs 2
- return-void
-.end method
-
-.source T_invoke_super_range_26.java
-.class public dot.junit.opcodes.invoke_super_range.d.T_invoke_super_range_26
-.super java/lang/Object
-.implements dot.junit.opcodes.invoke_super_range.d.ITestDefault
-.implements dot.junit.opcodes.invoke_super_range.d.ITestDefault2
-
-.method public <init>()V
-.limit regs 2
-
- invoke-direct {v1}, java/lang/Object/<init>()V
- return-void
-.end method
-
-.method public run()V
-.limit regs 1
- invoke-super/range {v0}, dot/junit/opcodes/invoke_super_range/d/ITestDefault/testDefault()V
- invoke-super/range {v0}, dot/junit/opcodes/invoke_super_range/d/ITestDefault2/testDefault()V
- return-void
-.end method
-
diff --git a/tools/vm-tests-tf/src/dot/junit/opcodes/invoke_super_range/d/T_invoke_super_range_27.d.done b/tools/vm-tests-tf/src/dot/junit/opcodes/invoke_super_range/d/T_invoke_super_range_27.d.done
deleted file mode 100644
index 752182c..0000000
--- a/tools/vm-tests-tf/src/dot/junit/opcodes/invoke_super_range/d/T_invoke_super_range_27.d.done
+++ /dev/null
@@ -1,58 +0,0 @@
-; 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.
-
-.source ITestDefault2.java
-.interface public dot.junit.opcodes.invoke_super_range.d.ITestDefault2
-
-.method public testDefault()V
-.limit regs 2
- return-void
-.end method
-
-.source ITestDefault.java
-.interface public dot.junit.opcodes.invoke_super_range.d.ITestDefault
-
-.method public testDefault()V
-.limit regs 2
- return-void
-.end method
-
-.source ITestNonDefault.java
-.interface public dot.junit.opcodes.invoke_super_range.d.ITestNonDefault
-.implements dot.junit.opcodes.invoke_super_range.d.ITestDefault
-.implements dot.junit.opcodes.invoke_super_range.d.ITestDefault2
-
-.method public abstract testDefault()V
-.end method
-
-
-.source T_invoke_super_range_27.java
-.class public dot.junit.opcodes.invoke_super_range.d.T_invoke_super_range_27
-.super java/lang/Object
-.implements dot.junit.opcodes.invoke_super_range.d.ITestNonDefault
-.implements dot.junit.opcodes.invoke_super_range.d.ITestDefault2
-
-.method public <init>()V
-.limit regs 2
-
- invoke-direct {v1}, java/lang/Object/<init>()V
- return-void
-.end method
-
-.method public run()V
-.limit regs 1
- invoke-super/range {v0}, dot/junit/opcodes/invoke_super_range/d/ITestNonDefault/testDefault()V
- return-void
-.end method
-
diff --git a/tools/vm-tests-tf/src/dot/junit/opcodes/invoke_super_range/d/T_invoke_super_range_28.d.done b/tools/vm-tests-tf/src/dot/junit/opcodes/invoke_super_range/d/T_invoke_super_range_28.d.done
deleted file mode 100644
index df29d4d..0000000
--- a/tools/vm-tests-tf/src/dot/junit/opcodes/invoke_super_range/d/T_invoke_super_range_28.d.done
+++ /dev/null
@@ -1,53 +0,0 @@
-; 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.
-
-.source ITestDefault2.java
-.interface public dot.junit.opcodes.invoke_super_range.d.ITestDefault2
-
-.method public testDefault()V
-.limit regs 2
- return-void
-.end method
-
-.source ITestDefault.java
-.interface public dot.junit.opcodes.invoke_super_range.d.ITestDefault
-
-.method public testDefault()V
-.limit regs 2
- return-void
-.end method
-
-.source ITestConflict.java
-.interface public dot.junit.opcodes.invoke_super_range.d.ITestConflict
-.implements dot.junit.opcodes.invoke_super_range.d.ITestDefault
-.implements dot.junit.opcodes.invoke_super_range.d.ITestDefault2
-
-.source T_invoke_super_range_28.java
-.class public dot.junit.opcodes.invoke_super_range.d.T_invoke_super_range_28
-.super java/lang/Object
-.implements dot.junit.opcodes.invoke_super_range.d.ITestConflict
-
-.method public <init>()V
-.limit regs 2
-
- invoke-direct {v1}, java/lang/Object/<init>()V
- return-void
-.end method
-
-.method public run()V
-.limit regs 1
- invoke-super/range {v0}, dot/junit/opcodes/invoke_super_range/d/ITestConflict/testDefault()V
- return-void
-.end method
-
diff --git a/tools/vm-tests-tf/src/dot/junit/opcodes/invoke_virtual/d/TSuper.d.done b/tools/vm-tests-tf/src/dot/junit/opcodes/invoke_virtual/d/TSuper.d.done
deleted file mode 100644
index 1df3ae2..0000000
--- a/tools/vm-tests-tf/src/dot/junit/opcodes/invoke_virtual/d/TSuper.d.done
+++ /dev/null
@@ -1,67 +0,0 @@
-; 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.
-
-.source TSuper.java
-.class public dot.junit.opcodes.invoke_virtual.d.TSuper
-.super java/lang/Object
-
-.method public <init>()V
-.limit regs 2
-
- invoke-direct {v1}, java/lang/Object/<init>()V
- return-void
-.end method
-
-
-
-.method public toInt()I
-.limit regs 3
- const v0, 5
- return v0
-.end method
-
-.method public toInt(F)I
-.limit regs 3
- float-to-int v0, v2
- return v0
-.end method
-
-.method public native toIntNative()I
-.end method
-
-.method public static toIntStatic()I
-.limit regs 3
- const v0, 5
- return v0
-.end method
-
-.method protected toIntP()I
-.limit regs 3
- const v0, 5
- return v0
-.end method
-
-.method private toIntPvt()I
-.limit regs 3
- const v0, 5
- return v0
-.end method
-
-.method public testArgsOrder(II)I
-.limit regs 4
- const v0, 349
- const v1, 344656
- div-int v2, v2, v3
- return v2
-.end method
diff --git a/tools/vm-tests-tf/src/dot/junit/opcodes/invoke_virtual/d/T_invoke_virtual_24.d.done b/tools/vm-tests-tf/src/dot/junit/opcodes/invoke_virtual/d/T_invoke_virtual_24.d.done
deleted file mode 100644
index 1804cce..0000000
--- a/tools/vm-tests-tf/src/dot/junit/opcodes/invoke_virtual/d/T_invoke_virtual_24.d.done
+++ /dev/null
@@ -1,45 +0,0 @@
-; 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.
-
-.source TTestInterface.java
-.interface public dot.junit.opcodes.invoke_virtual.d.TTestInterface
-
-.method public abstract test()V
-.end method
-
-.source T_invoke_virtual_24.java
-.class public dot.junit.opcodes.invoke_virtual.d.T_invoke_virtual_24
-.super java/lang/Object
-.implements dot.junit.opcodes.invoke_virtual.d.TTestInterface
-
-
-.method public <init>()V
-.limit regs 2
-
- invoke-direct {v1}, java/lang/Object/<init>()V
- return-void
-.end method
-
-.method public test()V
- return-void
-.end method
-
-.method public run()V
-.limit regs 4
-
- invoke-virtual {v3}, dot/junit/opcodes/invoke_virtual/d/TTestInterface/test()V
- return-void
-.end method
-
-
diff --git a/tools/vm-tests-tf/src/dot/junit/opcodes/invoke_virtual/d/T_invoke_virtual_26.d.done b/tools/vm-tests-tf/src/dot/junit/opcodes/invoke_virtual/d/T_invoke_virtual_26.d.done
deleted file mode 100644
index 0e87969..0000000
--- a/tools/vm-tests-tf/src/dot/junit/opcodes/invoke_virtual/d/T_invoke_virtual_26.d.done
+++ /dev/null
@@ -1,49 +0,0 @@
-; 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.
-
-.source ITestDefault2.java
-.interface public dot.junit.opcodes.invoke_virtual.d.ITestDefault2
-
-.method public testDefault()V
-.limit regs 2
- return-void
-.end method
-
-.source ITestDefault.java
-.interface public dot.junit.opcodes.invoke_virtual.d.ITestDefault
-
-.method public testDefault()V
-.limit regs 2
- return-void
-.end method
-
-.source T_invoke_virtual_26.java
-.class public dot.junit.opcodes.invoke_virtual.d.T_invoke_virtual_26
-.super java/lang/Object
-.implements dot.junit.opcodes.invoke_virtual.d.ITestDefault
-.implements dot.junit.opcodes.invoke_virtual.d.ITestDefault2
-
-.method public <init>()V
-.limit regs 2
-
- invoke-direct {v1}, java/lang/Object/<init>()V
- return-void
-.end method
-
-.method public run()V
-.limit regs 1
- invoke-virtual {v0}, dot/junit/opcodes/invoke_virtual/d/T_invoke_virtual_26/testDefault()V
- return-void
-.end method
-
diff --git a/tools/vm-tests-tf/src/dot/junit/opcodes/invoke_virtual/d/T_invoke_virtual_27.d.done b/tools/vm-tests-tf/src/dot/junit/opcodes/invoke_virtual/d/T_invoke_virtual_27.d.done
deleted file mode 100644
index d34045b..0000000
--- a/tools/vm-tests-tf/src/dot/junit/opcodes/invoke_virtual/d/T_invoke_virtual_27.d.done
+++ /dev/null
@@ -1,58 +0,0 @@
-; 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.
-
-.source ITestDefault2.java
-.interface public dot.junit.opcodes.invoke_virtual.d.ITestDefault2
-
-.method public testDefault()V
-.limit regs 2
- return-void
-.end method
-
-.source ITestDefault.java
-.interface public dot.junit.opcodes.invoke_virtual.d.ITestDefault
-
-.method public testDefault()V
-.limit regs 2
- return-void
-.end method
-
-.source ITestNonDefault.java
-.interface public dot.junit.opcodes.invoke_virtual.d.ITestNonDefault
-.implements dot.junit.opcodes.invoke_virtual.d.ITestDefault
-.implements dot.junit.opcodes.invoke_virtual.d.ITestDefault2
-
-.method public abstract testDefault()V
-.end method
-
-
-.source T_invoke_virtual_27.java
-.class public dot.junit.opcodes.invoke_virtual.d.T_invoke_virtual_27
-.super java/lang/Object
-.implements dot.junit.opcodes.invoke_virtual.d.ITestNonDefault
-.implements dot.junit.opcodes.invoke_virtual.d.ITestDefault2
-
-.method public <init>()V
-.limit regs 2
-
- invoke-direct {v1}, java/lang/Object/<init>()V
- return-void
-.end method
-
-.method public run()V
-.limit regs 1
- invoke-virtual {v0}, dot/junit/opcodes/invoke_virtual/d/T_invoke_virtual_27/testDefault()V
- return-void
-.end method
-
diff --git a/tools/vm-tests-tf/src/dot/junit/opcodes/invoke_virtual/d/T_invoke_virtual_28.d.done b/tools/vm-tests-tf/src/dot/junit/opcodes/invoke_virtual/d/T_invoke_virtual_28.d.done
deleted file mode 100644
index 8d3cf9e..0000000
--- a/tools/vm-tests-tf/src/dot/junit/opcodes/invoke_virtual/d/T_invoke_virtual_28.d.done
+++ /dev/null
@@ -1,40 +0,0 @@
-; 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.
-
-.source ITestDefault.java
-.interface public dot.junit.opcodes.invoke_virtual.d.ITestDefault
-
-.method public testDefault()V
-.limit regs 2
- return-void
-.end method
-
-.source T_invoke_virtual_28.java
-.class public dot.junit.opcodes.invoke_virtual.d.T_invoke_virtual_28
-.super java/lang/Object
-.implements dot.junit.opcodes.invoke_virtual.d.ITestDefault
-
-.method public <init>()V
-.limit regs 2
-
- invoke-direct {v1}, java/lang/Object/<init>()V
- return-void
-.end method
-
-.method public run()V
-.limit regs 1
- invoke-virtual {v0}, dot/junit/opcodes/invoke_virtual/d/T_invoke_virtual_28/testDefault()V
- return-void
-.end method
-
diff --git a/tools/vm-tests-tf/src/dot/junit/opcodes/invoke_virtual/d/T_invoke_virtual_4.d.done b/tools/vm-tests-tf/src/dot/junit/opcodes/invoke_virtual/d/T_invoke_virtual_4.d.done
deleted file mode 100644
index 5de2f49..0000000
--- a/tools/vm-tests-tf/src/dot/junit/opcodes/invoke_virtual/d/T_invoke_virtual_4.d.done
+++ /dev/null
@@ -1,35 +0,0 @@
-; 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.
-
-.source T_invoke_virtual_4.java
-.class public dot.junit.opcodes.invoke_virtual.d.T_invoke_virtual_4
-.super java/lang/Object
-
-
-.method public <init>()V
-.limit regs 2
- invoke-direct {v1}, java/lang/Object/<init>()V
- return-void
-.end method
-
-.method public run()V
-.limit regs 3
- invoke-virtual {v2}, dot/junit/opcodes/invoke_virtual/d/T_invoke_virtual_4/test()V
- return-void
-.end method
-
-.method public native test()V
-.end method
-
-
diff --git a/tools/vm-tests-tf/src/dot/junit/opcodes/invoke_virtual_range/d/TSuper.d.done b/tools/vm-tests-tf/src/dot/junit/opcodes/invoke_virtual_range/d/TSuper.d.done
deleted file mode 100644
index b375fc5..0000000
--- a/tools/vm-tests-tf/src/dot/junit/opcodes/invoke_virtual_range/d/TSuper.d.done
+++ /dev/null
@@ -1,67 +0,0 @@
-; 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.
-
-.source TSuper.java
-.class public dot.junit.opcodes.invoke_virtual_range.d.TSuper
-.super java/lang/Object
-
-.method public <init>()V
-.limit regs 2
-
- invoke-direct {v1}, java/lang/Object/<init>()V
- return-void
-.end method
-
-
-
-.method public toInt()I
-.limit regs 3
- const v0, 5
- return v0
-.end method
-
-.method public toInt(F)I
-.limit regs 3
- float-to-int v0, v2
- return v0
-.end method
-
-.method public native toIntNative()I
-.end method
-
-.method public static toIntStatic()I
-.limit regs 3
- const v0, 5
- return v0
-.end method
-
-.method protected toIntP()I
-.limit regs 3
- const v0, 5
- return v0
-.end method
-
-.method private toIntPvt()I
-.limit regs 3
- const v0, 5
- return v0
-.end method
-
-.method public testArgsOrder(II)I
-.limit regs 4
- const v0, 349
- const v1, 344656
- div-int v2, v2, v3
- return v2
-.end method
diff --git a/tools/vm-tests-tf/src/dot/junit/opcodes/invoke_virtual_range/d/T_invoke_virtual_range_24.d.done b/tools/vm-tests-tf/src/dot/junit/opcodes/invoke_virtual_range/d/T_invoke_virtual_range_24.d.done
deleted file mode 100644
index 9e2022f..0000000
--- a/tools/vm-tests-tf/src/dot/junit/opcodes/invoke_virtual_range/d/T_invoke_virtual_range_24.d.done
+++ /dev/null
@@ -1,45 +0,0 @@
-; 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.
-
-.source TTestInterface.java
-.interface public dot.junit.opcodes.invoke_virtual_range.d.TTestInterface
-
-.method public abstract test()V
-.end method
-
-.source T_invoke_virtual_range_24.java
-.class public dot.junit.opcodes.invoke_virtual_range.d.T_invoke_virtual_range_24
-.super java/lang/Object
-.implements dot.junit.opcodes.invoke_virtual_range.d.TTestInterface
-
-
-.method public <init>()V
-.limit regs 2
-
- invoke-direct {v1}, java/lang/Object/<init>()V
- return-void
-.end method
-
-.method public test()V
- return-void
-.end method
-
-.method public run()V
-.limit regs 4
-
- invoke-virtual/range {v3}, dot/junit/opcodes/invoke_virtual_range/d/TTestInterface/test()V
- return-void
-.end method
-
-
diff --git a/tools/vm-tests-tf/src/dot/junit/opcodes/invoke_virtual_range/d/T_invoke_virtual_range_25.d.done b/tools/vm-tests-tf/src/dot/junit/opcodes/invoke_virtual_range/d/T_invoke_virtual_range_25.d.done
deleted file mode 100644
index 1d39236..0000000
--- a/tools/vm-tests-tf/src/dot/junit/opcodes/invoke_virtual_range/d/T_invoke_virtual_range_25.d.done
+++ /dev/null
@@ -1,36 +0,0 @@
-; 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.
-
-.source T_invoke_virtual_range_25.java
-.class public dot.junit.opcodes.invoke_virtual_range.d.T_invoke_virtual_range_25
-.super java/lang/Object
-
-
-.method public <init>()V
-.limit regs 2
-
- invoke-direct {v1}, java/lang/Object/<init>()V
- return-void
-.end method
-
-.method public run()V
-.limit regs 8
-
- new-instance v6, java/lang/Object
- invoke-virtual/range {v6, v7}, java/lang/Object/equals(Ljava/lang/Object;)Z
-
- return-void
-.end method
-
-
diff --git a/tools/vm-tests-tf/src/dot/junit/opcodes/invoke_virtual_range/d/T_invoke_virtual_range_26.d.done b/tools/vm-tests-tf/src/dot/junit/opcodes/invoke_virtual_range/d/T_invoke_virtual_range_26.d.done
deleted file mode 100644
index 31ea1ee..0000000
--- a/tools/vm-tests-tf/src/dot/junit/opcodes/invoke_virtual_range/d/T_invoke_virtual_range_26.d.done
+++ /dev/null
@@ -1,49 +0,0 @@
-; 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.
-
-.source ITestDefault2.java
-.interface public dot.junit.opcodes.invoke_virtual_range.d.ITestDefault2
-
-.method public testDefault()V
-.limit regs 2
- return-void
-.end method
-
-.source ITestDefault.java
-.interface public dot.junit.opcodes.invoke_virtual_range.d.ITestDefault
-
-.method public testDefault()V
-.limit regs 2
- return-void
-.end method
-
-.source T_invoke_virtual_range_26.java
-.class public dot.junit.opcodes.invoke_virtual_range.d.T_invoke_virtual_range_26
-.super java/lang/Object
-.implements dot.junit.opcodes.invoke_virtual_range.d.ITestDefault
-.implements dot.junit.opcodes.invoke_virtual_range.d.ITestDefault2
-
-.method public <init>()V
-.limit regs 2
-
- invoke-direct {v1}, java/lang/Object/<init>()V
- return-void
-.end method
-
-.method public run()V
-.limit regs 1
- invoke-virtual/range {v0}, dot/junit/opcodes/invoke_virtual_range/d/T_invoke_virtual_range_26/testDefault()V
- return-void
-.end method
-
diff --git a/tools/vm-tests-tf/src/dot/junit/opcodes/invoke_virtual_range/d/T_invoke_virtual_range_27.d.done b/tools/vm-tests-tf/src/dot/junit/opcodes/invoke_virtual_range/d/T_invoke_virtual_range_27.d.done
deleted file mode 100644
index ce470e3..0000000
--- a/tools/vm-tests-tf/src/dot/junit/opcodes/invoke_virtual_range/d/T_invoke_virtual_range_27.d.done
+++ /dev/null
@@ -1,58 +0,0 @@
-; 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.
-
-.source ITestDefault2.java
-.interface public dot.junit.opcodes.invoke_virtual_range.d.ITestDefault2
-
-.method public testDefault()V
-.limit regs 2
- return-void
-.end method
-
-.source ITestDefault.java
-.interface public dot.junit.opcodes.invoke_virtual_range.d.ITestDefault
-
-.method public testDefault()V
-.limit regs 2
- return-void
-.end method
-
-.source ITestNonDefault.java
-.interface public dot.junit.opcodes.invoke_virtual_range.d.ITestNonDefault
-.implements dot.junit.opcodes.invoke_virtual_range.d.ITestDefault
-.implements dot.junit.opcodes.invoke_virtual_range.d.ITestDefault2
-
-.method public abstract testDefault()V
-.end method
-
-
-.source T_invoke_virtual_range_27.java
-.class public dot.junit.opcodes.invoke_virtual_range.d.T_invoke_virtual_range_27
-.super java/lang/Object
-.implements dot.junit.opcodes.invoke_virtual_range.d.ITestNonDefault
-.implements dot.junit.opcodes.invoke_virtual_range.d.ITestDefault2
-
-.method public <init>()V
-.limit regs 2
-
- invoke-direct {v1}, java/lang/Object/<init>()V
- return-void
-.end method
-
-.method public run()V
-.limit regs 1
- invoke-virtual/range {v0}, dot/junit/opcodes/invoke_virtual_range/d/T_invoke_virtual_range_27/testDefault()V
- return-void
-.end method
-
diff --git a/tools/vm-tests-tf/src/dot/junit/opcodes/invoke_virtual_range/d/T_invoke_virtual_range_28.d.done b/tools/vm-tests-tf/src/dot/junit/opcodes/invoke_virtual_range/d/T_invoke_virtual_range_28.d.done
deleted file mode 100644
index 5617cbd..0000000
--- a/tools/vm-tests-tf/src/dot/junit/opcodes/invoke_virtual_range/d/T_invoke_virtual_range_28.d.done
+++ /dev/null
@@ -1,40 +0,0 @@
-; 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.
-
-.source ITestDefault.java
-.interface public dot.junit.opcodes.invoke_virtual_range.d.ITestDefault
-
-.method public testDefault()V
-.limit regs 2
- return-void
-.end method
-
-.source T_invoke_virtual_range_28.java
-.class public dot.junit.opcodes.invoke_virtual_range.d.T_invoke_virtual_range_28
-.super java/lang/Object
-.implements dot.junit.opcodes.invoke_virtual_range.d.ITestDefault
-
-.method public <init>()V
-.limit regs 2
-
- invoke-direct {v1}, java/lang/Object/<init>()V
- return-void
-.end method
-
-.method public run()V
-.limit regs 1
- invoke-virtual/range {v0}, dot/junit/opcodes/invoke_virtual_range/d/T_invoke_virtual_range_28/testDefault()V
- return-void
-.end method
-
diff --git a/tools/vm-tests-tf/src/dot/junit/opcodes/invoke_virtual_range/d/T_invoke_virtual_range_4.d.done b/tools/vm-tests-tf/src/dot/junit/opcodes/invoke_virtual_range/d/T_invoke_virtual_range_4.d.done
deleted file mode 100644
index f68a194..0000000
--- a/tools/vm-tests-tf/src/dot/junit/opcodes/invoke_virtual_range/d/T_invoke_virtual_range_4.d.done
+++ /dev/null
@@ -1,35 +0,0 @@
-; 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.
-
-.source T_invoke_virtual_range_4.java
-.class public dot.junit.opcodes.invoke_virtual_range.d.T_invoke_virtual_range_4
-.super java/lang/Object
-
-
-.method public <init>()V
-.limit regs 2
- invoke-direct {v1}, java/lang/Object/<init>()V
- return-void
-.end method
-
-.method public run()V
-.limit regs 3
- invoke-virtual/range {v2}, dot/junit/opcodes/invoke_virtual_range/d/T_invoke_virtual_range_4/test()V
- return-void
-.end method
-
-.method public native test()V
-.end method
-
-
diff --git a/tools/vm-tests-tf/src/dot/junit/opcodes/iput/d/T_iput_19.d.done b/tools/vm-tests-tf/src/dot/junit/opcodes/iput/d/T_iput_19.d.done
deleted file mode 100644
index f7f8997..0000000
--- a/tools/vm-tests-tf/src/dot/junit/opcodes/iput/d/T_iput_19.d.done
+++ /dev/null
@@ -1,38 +0,0 @@
-; 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.
-
-.source T_iput_19.java
-.class public dot.junit.opcodes.iput.d.T_iput_19
-.super java/lang/Object
-
-.field public st_f1 F
-
-
-.method public <init>()V
-.limit regs 1
-
- invoke-direct {v0}, java/lang/Object/<init>()V
- return-void
-.end method
-
-.method public run()V
-.limit regs 3
-
- const v1, 3.14
- iput v1, v2, dot.junit.opcodes.iput.d.T_iput_19.st_f1 F
-
- return-void
-.end method
-
-
diff --git a/tools/vm-tests-tf/src/dot/junit/opcodes/iput/d/T_iput_20.d.done b/tools/vm-tests-tf/src/dot/junit/opcodes/iput/d/T_iput_20.d.done
deleted file mode 100644
index 0161449..0000000
--- a/tools/vm-tests-tf/src/dot/junit/opcodes/iput/d/T_iput_20.d.done
+++ /dev/null
@@ -1,36 +0,0 @@
-; 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.
-
-.source T_iput_20.java
-.class public dot.junit.opcodes.iput.d.T_iput_20
-.super java/lang/Object
-
-.field public st_o Ljava/lang/Object;
-
-.method public <init>()V
-.limit regs 1
-
- invoke-direct {v0}, java/lang/Object/<init>()V
- return-void
-.end method
-
-.method public run()V
-.limit regs 4
-
- const v0, 0
- iput v0, v3, dot.junit.opcodes.iput.d.T_iput_20.st_o Ljava/lang/Object;
- return-void
-.end method
-
-
diff --git a/tools/vm-tests-tf/src/dot/junit/opcodes/iput_boolean/d/T_iput_boolean_19.d.done b/tools/vm-tests-tf/src/dot/junit/opcodes/iput_boolean/d/T_iput_boolean_19.d.done
deleted file mode 100644
index aed12db..0000000
--- a/tools/vm-tests-tf/src/dot/junit/opcodes/iput_boolean/d/T_iput_boolean_19.d.done
+++ /dev/null
@@ -1,38 +0,0 @@
-; 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.
-
-.source T_iput_boolean_19.java
-.class public dot.junit.opcodes.iput_boolean.d.T_iput_boolean_19
-.super java/lang/Object
-
-.field public st_f1 F
-
-
-.method public <init>()V
-.limit regs 1
-
- invoke-direct {v0}, java/lang/Object/<init>()V
- return-void
-.end method
-
-.method public run()V
-.limit regs 3
-
- const v1, 3.14
- iput-boolean v1, v2, dot.junit.opcodes.iput_boolean.d.T_iput_boolean_19.st_f1 F
-
- return-void
-.end method
-
-
diff --git a/tools/vm-tests-tf/src/dot/junit/opcodes/iput_boolean/d/T_iput_boolean_20.d.done b/tools/vm-tests-tf/src/dot/junit/opcodes/iput_boolean/d/T_iput_boolean_20.d.done
deleted file mode 100644
index b7bb68c..0000000
--- a/tools/vm-tests-tf/src/dot/junit/opcodes/iput_boolean/d/T_iput_boolean_20.d.done
+++ /dev/null
@@ -1,36 +0,0 @@
-; 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.
-
-.source T_iput_boolean_20.java
-.class public dot.junit.opcodes.iput_boolean.d.T_iput_boolean_20
-.super java/lang/Object
-
-.field public st_o Ljava/lang/Object;
-
-.method public <init>()V
-.limit regs 1
-
- invoke-direct {v0}, java/lang/Object/<init>()V
- return-void
-.end method
-
-.method public run()V
-.limit regs 4
-
- const v0, 0
- iput-boolean v0, v3, dot.junit.opcodes.iput_boolean.d.T_iput_boolean_20.st_o Ljava/lang/Object;
- return-void
-.end method
-
-
diff --git a/tools/vm-tests-tf/src/dot/junit/opcodes/iput_byte/d/T_iput_byte_20.d.done b/tools/vm-tests-tf/src/dot/junit/opcodes/iput_byte/d/T_iput_byte_20.d.done
deleted file mode 100644
index 2452e5e..0000000
--- a/tools/vm-tests-tf/src/dot/junit/opcodes/iput_byte/d/T_iput_byte_20.d.done
+++ /dev/null
@@ -1,35 +0,0 @@
-; 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.
-
-.source T_iput_byte_20.java
-.class public dot.junit.opcodes.iput_byte.d.T_iput_byte_20
-.super java/lang/Object
-
-.field public st_o Ljava/lang/Object;
-
-.method public <init>()V
-.limit regs 1
-
- invoke-direct {v0}, java/lang/Object/<init>()V
- return-void
-.end method
-
-.method public run()V
-.limit regs 4
-
- iput-byte v3, v3, dot.junit.opcodes.iput_byte.d.T_iput_byte_20.st_o Ljava/lang/Object;
- return-void
-.end method
-
-
diff --git a/tools/vm-tests-tf/src/dot/junit/opcodes/iput_char/d/T_iput_char_20.d.done b/tools/vm-tests-tf/src/dot/junit/opcodes/iput_char/d/T_iput_char_20.d.done
deleted file mode 100644
index 5aa31b2..0000000
--- a/tools/vm-tests-tf/src/dot/junit/opcodes/iput_char/d/T_iput_char_20.d.done
+++ /dev/null
@@ -1,35 +0,0 @@
-; 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.
-
-.source T_iput_char_20.java
-.class public dot.junit.opcodes.iput_char.d.T_iput_char_20
-.super java/lang/Object
-
-.field public st_o Ljava/lang/Object;
-
-.method public <init>()V
-.limit regs 1
-
- invoke-direct {v0}, java/lang/Object/<init>()V
- return-void
-.end method
-
-.method public run()V
-.limit regs 4
-
- iput-char v3, v3, dot.junit.opcodes.iput_char.d.T_iput_char_20.st_o Ljava/lang/Object;
- return-void
-.end method
-
-
diff --git a/tools/vm-tests-tf/src/dot/junit/opcodes/iput_object/d/T_iput_object_1.d.done b/tools/vm-tests-tf/src/dot/junit/opcodes/iput_object/d/T_iput_object_1.d.done
deleted file mode 100644
index 6a9215e..0000000
--- a/tools/vm-tests-tf/src/dot/junit/opcodes/iput_object/d/T_iput_object_1.d.done
+++ /dev/null
@@ -1,45 +0,0 @@
-; 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.
-
-.source T_iput_object_1.java
-.class public dot.junit.opcodes.iput_object.d.T_iput_object_1
-.super java/lang/Object
-
-.field public st_i1 Ljava/lang/Object;
-.field protected st_p1 Ljava/lang/Object;
-.field private st_pvt1 Ljava/lang/Object;
-
-.method public <init>()V
-.limit regs 1
-
- invoke-direct {v0}, java/lang/Object/<init>()V
- return-void
-.end method
-
-.method public getPvtField()Ljava/lang/Object;
-.limit regs 2
-
- iget-object v0, v1, dot.junit.opcodes.iput_object.d.T_iput_object_1.st_pvt1 Ljava/lang/Object;
- return-object v0
-.end method
-
-.method public run()V
-.limit regs 3
-
- iput-object v2, v2, dot.junit.opcodes.iput_object.d.T_iput_object_1.st_i1 Ljava/lang/Object;
-
- return-void
-.end method
-
-
diff --git a/tools/vm-tests-tf/src/dot/junit/opcodes/iput_object/d/T_iput_object_10.d.done b/tools/vm-tests-tf/src/dot/junit/opcodes/iput_object/d/T_iput_object_10.d.done
deleted file mode 100644
index 92f9cff..0000000
--- a/tools/vm-tests-tf/src/dot/junit/opcodes/iput_object/d/T_iput_object_10.d.done
+++ /dev/null
@@ -1,35 +0,0 @@
-; 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.
-
-.source T_iput_object_10.java
-.class public dot.junit.opcodes.iput_object.d.T_iput_object_10
-.super java/lang/Object
-
-.field public st_i1 Ljava/lang/Object;
-
-.method public <init>()V
-.limit regs 1
-
- invoke-direct {v0}, java/lang/Object/<init>()V
- return-void
-.end method
-
-.method public run()V
-.limit regs 3
-
- iput-object v2, v2, dot.junit.opcodes.iput_object.d.T_iput_object_10.st_i1N Ljava/lang/Object;
- return-void
-.end method
-
-
diff --git a/tools/vm-tests-tf/src/dot/junit/opcodes/iput_object/d/T_iput_object_12.d.done b/tools/vm-tests-tf/src/dot/junit/opcodes/iput_object/d/T_iput_object_12.d.done
deleted file mode 100644
index 69f1309..0000000
--- a/tools/vm-tests-tf/src/dot/junit/opcodes/iput_object/d/T_iput_object_12.d.done
+++ /dev/null
@@ -1,35 +0,0 @@
-; 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.
-
-.source T_iput_object_12.java
-.class public dot.junit.opcodes.iput_object.d.T_iput_object_12
-.super java/lang/Object
-
-.field public final st_i1 Ljava/lang/Object;
-
-.method public <init>()V
-.limit regs 1
-
- invoke-direct {v0}, java/lang/Object/<init>()V
- return-void
-.end method
-
-.method public run()V
-.limit regs 3
-
- iput-object v2, v2, dot.junit.opcodes.iput_object.d.T_iput_object_12.st_i1 Ljava/lang/Object;
- return-void
-.end method
-
-
diff --git a/tools/vm-tests-tf/src/dot/junit/opcodes/iput_object/d/T_iput_object_13.d.done b/tools/vm-tests-tf/src/dot/junit/opcodes/iput_object/d/T_iput_object_13.d.done
deleted file mode 100644
index f282745..0000000
--- a/tools/vm-tests-tf/src/dot/junit/opcodes/iput_object/d/T_iput_object_13.d.done
+++ /dev/null
@@ -1,37 +0,0 @@
-; 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.
-
-.source T_iput_object_13.java
-.class public dot.junit.opcodes.iput_object.d.T_iput_object_13
-.super java/lang/Object
-
-.field public st_i1 Ljava/lang/Object;
-
-.method public <init>()V
-.limit regs 1
-
- invoke-direct {v0}, java/lang/Object/<init>()V
- return-void
-.end method
-
-.method public run()V
-.limit regs 3
-
- const v0, 0
- iput-object v2, v0, dot.junit.opcodes.iput_object.d.T_iput_object_13.st_i1 Ljava/lang/Object;
-
- return-void
-.end method
-
-
diff --git a/tools/vm-tests-tf/src/dot/junit/opcodes/iput_object/d/T_iput_object_2.d.done b/tools/vm-tests-tf/src/dot/junit/opcodes/iput_object/d/T_iput_object_2.d.done
deleted file mode 100644
index 805388f..0000000
--- a/tools/vm-tests-tf/src/dot/junit/opcodes/iput_object/d/T_iput_object_2.d.done
+++ /dev/null
@@ -1,36 +0,0 @@
-; 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.
-
-.source T_iput_object_2.java
-.class public dot.junit.opcodes.iput_object.d.T_iput_object_2
-.super java/lang/Object
-
-.field public st_i1 Ljava/lang/Object;
-
-.method public <init>()V
-.limit regs 1
-
- invoke-direct {v0}, java/lang/Object/<init>()V
- return-void
-.end method
-
-.method public run()V
-.limit regs 3
-
- const-wide v0, 1234
- iput-object v0, v2, dot.junit.opcodes.iput_object.d.T_iput_object_2.st_i1 Ljava/lang/Object;
- return-void
-.end method
-
-
diff --git a/tools/vm-tests-tf/src/dot/junit/opcodes/iput_object/d/T_iput_object_20.d.done b/tools/vm-tests-tf/src/dot/junit/opcodes/iput_object/d/T_iput_object_20.d.done
deleted file mode 100644
index a9b90be..0000000
--- a/tools/vm-tests-tf/src/dot/junit/opcodes/iput_object/d/T_iput_object_20.d.done
+++ /dev/null
@@ -1,35 +0,0 @@
-; 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.
-
-.source T_iput_object_20.java
-.class public dot.junit.opcodes.iput_object.d.T_iput_object_20
-.super java/lang/Object
-
-.field public st_o Ljava/lang/String;
-
-.method public <init>()V
-.limit regs 1
-
- invoke-direct {v0}, java/lang/Object/<init>()V
- return-void
-.end method
-
-.method public run()V
-.limit regs 4
-
- iput-object v3, v3, dot.junit.opcodes.iput_object.d.T_iput_object_20.st_o Ljava/lang/String;
- return-void
-.end method
-
-
diff --git a/tools/vm-tests-tf/src/dot/junit/opcodes/iput_object/d/T_iput_object_3.d.done b/tools/vm-tests-tf/src/dot/junit/opcodes/iput_object/d/T_iput_object_3.d.done
deleted file mode 100644
index fa05a78..0000000
--- a/tools/vm-tests-tf/src/dot/junit/opcodes/iput_object/d/T_iput_object_3.d.done
+++ /dev/null
@@ -1,35 +0,0 @@
-; 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.
-
-.source T_iput_object_3.java
-.class public dot.junit.opcodes.iput_object.d.T_iput_object_3
-.super java/lang/Object
-
-.field public st_i1 Ljava/lang/Object;
-
-.method public <init>()V
-.limit regs 1
-
- invoke-direct {v0}, java/lang/Object/<init>()V
- return-void
-.end method
-
-.method public run()V
-.limit regs 3
-
- iput-object v2, v2, dot.junit.opcodes.iput_object.d.T_iput_object_3.st_i1 Ljava/lang/Object;
- return-void
-.end method
-
-
diff --git a/tools/vm-tests-tf/src/dot/junit/opcodes/iput_object/d/T_iput_object_30.d.done b/tools/vm-tests-tf/src/dot/junit/opcodes/iput_object/d/T_iput_object_30.d.done
deleted file mode 100644
index ace5b2c..0000000
--- a/tools/vm-tests-tf/src/dot/junit/opcodes/iput_object/d/T_iput_object_30.d.done
+++ /dev/null
@@ -1,33 +0,0 @@
-; 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.
-
-.source T_iput_object_30.java
-.class public dot.junit.opcodes.iput_object.d.T_iput_object_30
-.super java/lang/Object
-
-.field public st_i1 Ljava/lang/Object;
-
-.method public <init>()V
-.limit regs 1
- invoke-direct {v0}, java/lang/Object/<init>()V
- return-void
-.end method
-
-.method public run()V
-.limit regs 3
- new-instance v0, dot/junit/opcodes/iput_object/d/T_iput_object_30
- const v1, 0
- iput-object v1, v0, dot.junit.opcodes.iput_object.d.T_iput_object_30.st_i1 Ljava/lang/Object;
-.end method
-
diff --git a/tools/vm-tests-tf/src/dot/junit/opcodes/iput_object/d/T_iput_object_31.d.done b/tools/vm-tests-tf/src/dot/junit/opcodes/iput_object/d/T_iput_object_31.d.done
deleted file mode 100644
index 7b1b507..0000000
--- a/tools/vm-tests-tf/src/dot/junit/opcodes/iput_object/d/T_iput_object_31.d.done
+++ /dev/null
@@ -1,32 +0,0 @@
-; 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.
-
-.source T_iput_object_31.java
-.class public dot.junit.opcodes.iput_object.d.T_iput_object_31
-.super java/lang/Object
-
-.field public st_i1 Ljava/lang/Object;
-
-.method public <init>()V
-.limit regs 1
- invoke-direct {v0}, java/lang/Object/<init>()V
- return-void
-.end method
-
-.method public run()V
-.limit regs 3
- const v1, 0
- iput-object v1, v0, dot.junit.opcodes.iput_object.d.T_iput_object_31.st_i1 Ljava/lang/Object;
-.end method
-
diff --git a/tools/vm-tests-tf/src/dot/junit/opcodes/iput_object/d/T_iput_object_4.d.done b/tools/vm-tests-tf/src/dot/junit/opcodes/iput_object/d/T_iput_object_4.d.done
deleted file mode 100644
index 8906abe..0000000
--- a/tools/vm-tests-tf/src/dot/junit/opcodes/iput_object/d/T_iput_object_4.d.done
+++ /dev/null
@@ -1,35 +0,0 @@
-; 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.
-
-.source T_iput_object_4.java
-.class public dot.junit.opcodes.iput_object.d.T_iput_object_4
-.super java/lang/Object
-
-.field public st_i1 Ljava/lang/Object;
-
-.method public <init>()V
-.limit regs 1
-
- invoke-direct {v0}, java/lang/Object/<init>()V
- return-void
-.end method
-
-.method public run()V
-.limit regs 3
-
- iput-object v3, v2, dot.junit.opcodes.iput_object.d.T_iput_object_4.st_i1 Ljava/lang/Object;
- return-void
-.end method
-
-
diff --git a/tools/vm-tests-tf/src/dot/junit/opcodes/iput_object/d/T_iput_object_7.d.done b/tools/vm-tests-tf/src/dot/junit/opcodes/iput_object/d/T_iput_object_7.d.done
deleted file mode 100644
index 25768ff..0000000
--- a/tools/vm-tests-tf/src/dot/junit/opcodes/iput_object/d/T_iput_object_7.d.done
+++ /dev/null
@@ -1,35 +0,0 @@
-; 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.
-
-.source T_iput_object_7.java
-.class public dot.junit.opcodes.iput_object.d.T_iput_object_7
-.super java/lang/Object
-
-.field public static st_i1 Ljava/lang/Object;
-
-.method public <init>()V
-.limit regs 1
-
- invoke-direct {v0}, java/lang/Object/<init>()V
- return-void
-.end method
-
-.method public run()V
-.limit regs 3
-
- iput-object v2, v2, dot.junit.opcodes.iput_object.d.T_iput_object_7.st_i1 Ljava/lang/Object;
- return-void
-.end method
-
-
diff --git a/tools/vm-tests-tf/src/dot/junit/opcodes/iput_object/d/T_iput_object_9.d.done b/tools/vm-tests-tf/src/dot/junit/opcodes/iput_object/d/T_iput_object_9.d.done
deleted file mode 100644
index 3fd712b..0000000
--- a/tools/vm-tests-tf/src/dot/junit/opcodes/iput_object/d/T_iput_object_9.d.done
+++ /dev/null
@@ -1,35 +0,0 @@
-; 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.
-
-.source T_iput_object_9.java
-.class public dot.junit.opcodes.iput_object.d.T_iput_object_9
-.super java/lang/Object
-
-.field public st_i1 Ljava/lang/Object;
-
-.method public <init>()V
-.limit regs 1
-
- invoke-direct {v0}, java/lang/Object/<init>()V
- return-void
-.end method
-
-.method public run()V
-.limit regs 3
-
- iput-object v2, v2, dot.junit.opcodes.iput_object.d.T_iput_object_9noclass.st_i1 Ljava/lang/Object;
- return-void
-.end method
-
-
diff --git a/tools/vm-tests-tf/src/dot/junit/opcodes/iput_short/d/T_iput_short_20.d.done b/tools/vm-tests-tf/src/dot/junit/opcodes/iput_short/d/T_iput_short_20.d.done
deleted file mode 100644
index b7524dc..0000000
--- a/tools/vm-tests-tf/src/dot/junit/opcodes/iput_short/d/T_iput_short_20.d.done
+++ /dev/null
@@ -1,35 +0,0 @@
-; 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.
-
-.source T_iput_short_20.java
-.class public dot.junit.opcodes.iput_short.d.T_iput_short_20
-.super java/lang/Object
-
-.field public st_o Ljava/lang/Object;
-
-.method public <init>()V
-.limit regs 1
-
- invoke-direct {v0}, java/lang/Object/<init>()V
- return-void
-.end method
-
-.method public run()V
-.limit regs 4
-
- iput-short v3, v3, dot.junit.opcodes.iput_short.d.T_iput_short_20.st_o Ljava/lang/Object;
- return-void
-.end method
-
-
diff --git a/tools/vm-tests-tf/src/dot/junit/opcodes/iput_wide/d/T_iput_wide_1.d.done b/tools/vm-tests-tf/src/dot/junit/opcodes/iput_wide/d/T_iput_wide_1.d.done
deleted file mode 100644
index cae692f..0000000
--- a/tools/vm-tests-tf/src/dot/junit/opcodes/iput_wide/d/T_iput_wide_1.d.done
+++ /dev/null
@@ -1,46 +0,0 @@
-; 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.
-
-.source T_iput_wide_1.java
-.class public dot.junit.opcodes.iput_wide.d.T_iput_wide_1
-.super java/lang/Object
-
-.field public st_i1 J
-.field protected st_p1 J
-.field private st_pvt1 J
-
-.method public <init>()V
-.limit regs 1
-
- invoke-direct {v0}, java/lang/Object/<init>()V
- return-void
-.end method
-
-.method public getPvtField()J
-.limit regs 3
-
- iget-wide v0, v2, dot.junit.opcodes.iput_wide.d.T_iput_wide_1.st_pvt1 J
- return-wide v0
-.end method
-
-.method public run()V
-.limit regs 3
-
- const-wide v0, 778899112233
- iput-wide v0, v2, dot.junit.opcodes.iput_wide.d.T_iput_wide_1.st_i1 J
-
- return-void
-.end method
-
-
diff --git a/tools/vm-tests-tf/src/dot/junit/opcodes/iput_wide/d/T_iput_wide_13.d.done b/tools/vm-tests-tf/src/dot/junit/opcodes/iput_wide/d/T_iput_wide_13.d.done
deleted file mode 100644
index cdf7fe6..0000000
--- a/tools/vm-tests-tf/src/dot/junit/opcodes/iput_wide/d/T_iput_wide_13.d.done
+++ /dev/null
@@ -1,38 +0,0 @@
-; 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.
-
-.source T_iput_wide_13.java
-.class public dot.junit.opcodes.iput_wide.d.T_iput_wide_13
-.super java/lang/Object
-
-.field public st_i1 J
-
-.method public <init>()V
-.limit regs 1
-
- invoke-direct {v0}, java/lang/Object/<init>()V
- return-void
-.end method
-
-.method public run()V
-.limit regs 3
-
- const v2, 0
- const-wide v0, 778899112233
- iput-wide v0, v2, dot.junit.opcodes.iput_wide.d.T_iput_wide_13.st_i1 J
-
- return-void
-.end method
-
-
diff --git a/tools/vm-tests-tf/src/dot/junit/opcodes/iput_wide/d/T_iput_wide_18.d.done b/tools/vm-tests-tf/src/dot/junit/opcodes/iput_wide/d/T_iput_wide_18.d.done
deleted file mode 100644
index 1818bed..0000000
--- a/tools/vm-tests-tf/src/dot/junit/opcodes/iput_wide/d/T_iput_wide_18.d.done
+++ /dev/null
@@ -1,37 +0,0 @@
-; 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.
-
-.source T_iput_wide_18.java
-.class public dot.junit.opcodes.iput_wide.d.T_iput_wide_18
-.super java/lang/Object
-
-.field public st_i1 F
-
-.method public <init>()V
-.limit regs 1
-
- invoke-direct {v0}, java/lang/Object/<init>()V
- return-void
-.end method
-
-.method public run()V
-.limit regs 3
-
- const v1, 1.0
- iput-wide v1, v2, dot.junit.opcodes.iput_wide.d.T_iput_wide_18.st_i1 F
-
- return-void
-.end method
-
-
diff --git a/tools/vm-tests-tf/src/dot/junit/opcodes/iput_wide/d/T_iput_wide_20.d.done b/tools/vm-tests-tf/src/dot/junit/opcodes/iput_wide/d/T_iput_wide_20.d.done
deleted file mode 100644
index e0efb25..0000000
--- a/tools/vm-tests-tf/src/dot/junit/opcodes/iput_wide/d/T_iput_wide_20.d.done
+++ /dev/null
@@ -1,37 +0,0 @@
-; 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.
-
-.source T_iput_wide_20.java
-.class public dot.junit.opcodes.iput_wide.d.T_iput_wide_20
-.super java/lang/Object
-
-.field public st_o Ljava/lang/Object;
-
-.method public <init>()V
-.limit regs 1
-
- invoke-direct {v0}, java/lang/Object/<init>()V
- return-void
-.end method
-
-.method public run()V
-.limit regs 4
-
- const-wide v0, 0
-
- iput-wide v0, v3, dot.junit.opcodes.iput_wide.d.T_iput_wide_20.st_o Ljava/lang/Object;
- return-void
-.end method
-
-
diff --git a/tools/vm-tests-tf/src/dot/junit/opcodes/long_to_double/d/T_long_to_double_2.d.done b/tools/vm-tests-tf/src/dot/junit/opcodes/long_to_double/d/T_long_to_double_2.d.done
deleted file mode 100644
index 3201a77..0000000
--- a/tools/vm-tests-tf/src/dot/junit/opcodes/long_to_double/d/T_long_to_double_2.d.done
+++ /dev/null
@@ -1,35 +0,0 @@
-; 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.
-
-.source T_long_to_double_2.java
-.class public dot.junit.opcodes.long_to_double.d.T_long_to_double_2
-.super java/lang/Object
-
-
-.method public <init>()V
-.limit regs 1
-
- invoke-direct {v0}, java/lang/Object/<init>()V
- return-void
-.end method
-
-.method public run(J)D
-.limit regs 8
-
- const v6, 3.1415
- long-to-double v0, v6
- return-wide v0
-.end method
-
-
diff --git a/tools/vm-tests-tf/src/dot/junit/opcodes/long_to_int/d/T_long_to_int_3.d.done b/tools/vm-tests-tf/src/dot/junit/opcodes/long_to_int/d/T_long_to_int_3.d.done
deleted file mode 100644
index 1d4665b..0000000
--- a/tools/vm-tests-tf/src/dot/junit/opcodes/long_to_int/d/T_long_to_int_3.d.done
+++ /dev/null
@@ -1,35 +0,0 @@
-; 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.
-
-.source T_long_to_int_3.java
-.class public dot.junit.opcodes.long_to_int.d.T_long_to_int_3
-.super java/lang/Object
-
-
-.method public <init>()V
-.limit regs 1
-
- invoke-direct {v0}, java/lang/Object/<init>()V
- return-void
-.end method
-
-.method public run(J)I
-.limit regs 8
-
- const v6, 1234.0
- long-to-int v0, v6
- return v0
-.end method
-
-
diff --git a/tools/vm-tests-tf/src/dot/junit/opcodes/monitor_enter/d/T_monitor_enter_6.d.done b/tools/vm-tests-tf/src/dot/junit/opcodes/monitor_enter/d/T_monitor_enter_6.d.done
deleted file mode 100644
index 754a9e3..0000000
--- a/tools/vm-tests-tf/src/dot/junit/opcodes/monitor_enter/d/T_monitor_enter_6.d.done
+++ /dev/null
@@ -1,33 +0,0 @@
-; 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.
-
-.source T_monitor_enter_6.java
-.class public dot.junit.opcodes.monitor_enter.d.T_monitor_enter_6
-.super java/lang/Object
-
-
-.method public <init>()V
-.limit regs 1
-
- invoke-direct {v0}, java/lang/Object/<init>()V
- return-void
-.end method
-
-.method public run()V
-.limit regs 6
-
- const v5, 1.23
- monitor-enter v5
- return-void
-.end method
diff --git a/tools/vm-tests-tf/src/dot/junit/opcodes/monitor_enter/d/T_monitor_enter_7.d.done b/tools/vm-tests-tf/src/dot/junit/opcodes/monitor_enter/d/T_monitor_enter_7.d.done
deleted file mode 100644
index 8fb7791..0000000
--- a/tools/vm-tests-tf/src/dot/junit/opcodes/monitor_enter/d/T_monitor_enter_7.d.done
+++ /dev/null
@@ -1,33 +0,0 @@
-; 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.
-
-.source T_monitor_enter_7.java
-.class public dot.junit.opcodes.monitor_enter.d.T_monitor_enter_7
-.super java/lang/Object
-
-
-.method public <init>()V
-.limit regs 1
-
- invoke-direct {v0}, java/lang/Object/<init>()V
- return-void
-.end method
-
-.method public run()V
-.limit regs 6
-
- const-wide v4, 123456789321
- monitor-enter v4
- return-void
-.end method
diff --git a/tools/vm-tests-tf/src/dot/junit/opcodes/monitor_exit/d/T_monitor_exit_6.d.done b/tools/vm-tests-tf/src/dot/junit/opcodes/monitor_exit/d/T_monitor_exit_6.d.done
deleted file mode 100644
index 9635212..0000000
--- a/tools/vm-tests-tf/src/dot/junit/opcodes/monitor_exit/d/T_monitor_exit_6.d.done
+++ /dev/null
@@ -1,34 +0,0 @@
-; 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.
-
-.source T_monitor_exit_6.java
-.class public dot.junit.opcodes.monitor_exit.d.T_monitor_exit_6
-.super java/lang/Object
-
-
-.method public <init>()V
-.limit regs 1
-
- invoke-direct {v0}, java/lang/Object/<init>()V
- return-void
-.end method
-
-.method public run()V
-.limit regs 4
-
- monitor-enter v3
- const v3, 1.123
- monitor-exit v3
- return-void
-.end method
diff --git a/tools/vm-tests-tf/src/dot/junit/opcodes/monitor_exit/d/T_monitor_exit_7.d.done b/tools/vm-tests-tf/src/dot/junit/opcodes/monitor_exit/d/T_monitor_exit_7.d.done
deleted file mode 100644
index c65ae56..0000000
--- a/tools/vm-tests-tf/src/dot/junit/opcodes/monitor_exit/d/T_monitor_exit_7.d.done
+++ /dev/null
@@ -1,34 +0,0 @@
-; 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.
-
-.source T_monitor_exit_7.java
-.class public dot.junit.opcodes.monitor_exit.d.T_monitor_exit_7
-.super java/lang/Object
-
-
-.method public <init>()V
-.limit regs 1
-
- invoke-direct {v0}, java/lang/Object/<init>()V
- return-void
-.end method
-
-.method public run()V
-.limit regs 4
-
- monitor-enter v3
- const-wide v0, 123456789321
- monitor-exit v0
- return-void
-.end method
diff --git a/tools/vm-tests-tf/src/dot/junit/opcodes/move_16/d/T_move_16_1.d.done b/tools/vm-tests-tf/src/dot/junit/opcodes/move_16/d/T_move_16_1.d.done
deleted file mode 100644
index bb5335f..0000000
--- a/tools/vm-tests-tf/src/dot/junit/opcodes/move_16/d/T_move_16_1.d.done
+++ /dev/null
@@ -1,53 +0,0 @@
-; 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.
-
-.source T_move_16_1.java
-.class public dot.junit.opcodes.move_16.d.T_move_16_1
-.super java/lang/Object
-
-
-.method public <init>()V
-.limit regs 1
-
- invoke-direct {v0}, java/lang/Object/<init>()V
- return-void
-.end method
-
-.method public static run()Z
-.limit regs 5000
- const v0, 123
- const v1, 5678
-
- move/16 v4000, v0
- move/16 v4001, v1
-
- move/16 v4000, v4001
-
- const/4 v4, 5678
-
- move/16 v0, v4000
- move/16 v1, v4001
-
- if-ne v0, v4, Label0
- if-ne v1, v4, Label0
-
- const v1, 1
- return v1
-
-Label0:
- const v1, 0
- return v1
-.end method
-
-
diff --git a/tools/vm-tests-tf/src/dot/junit/opcodes/move_16/d/T_move_16_2.d.done b/tools/vm-tests-tf/src/dot/junit/opcodes/move_16/d/T_move_16_2.d.done
deleted file mode 100644
index 52454ae..0000000
--- a/tools/vm-tests-tf/src/dot/junit/opcodes/move_16/d/T_move_16_2.d.done
+++ /dev/null
@@ -1,47 +0,0 @@
-; 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.
-
-.source T_move_16_2.java
-.class public dot.junit.opcodes.move_16.d.T_move_16_2
-.super java/lang/Object
-
-
-.method public <init>()V
-.limit regs 1
-
- invoke-direct {v0}, java/lang/Object/<init>()V
- return-void
-.end method
-
-.method public static run()Z
-.limit regs 5000
- const v1, 5678
-
- move/16 v4001, v1
- move/16 v0, v4001
-
- const/4 v4, 5678
-
- if-ne v0, v4, Label0
- if-ne v1, v4, Label0
-
- const v1, 1
- return v1
-
-Label0:
- const v1, 0
- return v1
-.end method
-
-
diff --git a/tools/vm-tests-tf/src/dot/junit/opcodes/move_exception/d/T_move_exception_2.d.done b/tools/vm-tests-tf/src/dot/junit/opcodes/move_exception/d/T_move_exception_2.d.done
deleted file mode 100644
index 8713f3a..0000000
--- a/tools/vm-tests-tf/src/dot/junit/opcodes/move_exception/d/T_move_exception_2.d.done
+++ /dev/null
@@ -1,48 +0,0 @@
-; 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.
-
-.source T_move_exception_2.java
-.class public dot.junit.opcodes.move_exception.d.T_move_exception_2
-.super java/lang/Object
-
-
-.method public <init>()V
-.limit regs 1
-
- invoke-direct {v0}, java/lang/Object/<init>()V
- return-void
-.end method
-
-.method public run()Z
-.limit regs 6
-
-Label1:
- const v1, 1
- const v2, 0
- div-int v0, v1, v2
-
-Label2:
- goto Label4
-
-Label3:
- move-exception v3
- const v4, 1
- return v4
-
-Label4:
- const v4, 0
- return v4
-
-.catch java/lang/RuntimeException from Label1 to Label2 using Label3
-.end method
diff --git a/tools/vm-tests-tf/src/dot/junit/opcodes/move_from16/d/T_move_from16_1.d.done b/tools/vm-tests-tf/src/dot/junit/opcodes/move_from16/d/T_move_from16_1.d.done
deleted file mode 100644
index e445cea..0000000
--- a/tools/vm-tests-tf/src/dot/junit/opcodes/move_from16/d/T_move_from16_1.d.done
+++ /dev/null
@@ -1,48 +0,0 @@
-; 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.
-
-.source T_move_from16_1.java
-.class public dot.junit.opcodes.move_from16.d.T_move_from16_1
-.super java/lang/Object
-
-
-.method public <init>()V
-.limit regs 1
-
- invoke-direct {v0}, java/lang/Object/<init>()V
- return-void
-.end method
-
-.method public static run()Z
-.limit regs 5000
- const v10, 5678
-
- move/16 v4001, v10
-
- move/from16 v255, v4001
- move/from16 v1, v255
-
- const/4 v4, 5678
-
- if-ne v1, v4, Label0
-
- const v1, 1
- return v1
-
-Label0:
- const v1, 0
- return v1
-.end method
-
-
diff --git a/tools/vm-tests-tf/src/dot/junit/opcodes/move_from16/d/T_move_from16_6.d.done b/tools/vm-tests-tf/src/dot/junit/opcodes/move_from16/d/T_move_from16_6.d.done
deleted file mode 100644
index 662e314..0000000
--- a/tools/vm-tests-tf/src/dot/junit/opcodes/move_from16/d/T_move_from16_6.d.done
+++ /dev/null
@@ -1,34 +0,0 @@
-; 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.
-
-.source T_move_from16_6.java
-.class public dot.junit.opcodes.move_from16.d.T_move_from16_6
-.super java/lang/Object
-
-
-.method public <init>()V
-.limit regs 1
-
- invoke-direct {v0}, java/lang/Object/<init>()V
- return-void
-.end method
-
-.method public static run()V
-.limit regs 5000
- const-wide v4500, 123
- move/from16 v0, v4500
- return-void
-.end method
-
-
diff --git a/tools/vm-tests-tf/src/dot/junit/opcodes/move_from16/d/T_move_from16_7.d.done b/tools/vm-tests-tf/src/dot/junit/opcodes/move_from16/d/T_move_from16_7.d.done
deleted file mode 100644
index 7d2f26c..0000000
--- a/tools/vm-tests-tf/src/dot/junit/opcodes/move_from16/d/T_move_from16_7.d.done
+++ /dev/null
@@ -1,35 +0,0 @@
-; 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.
-
-.source T_move_from16_7.java
-.class public dot.junit.opcodes.move_from16.d.T_move_from16_7
-.super java/lang/Object
-
-
-.method public <init>()V
-.limit regs 1
-
- invoke-direct {v0}, java/lang/Object/<init>()V
- return-void
-.end method
-
-.method public static run()V
-.limit regs 5000
-
- const-wide v1234, 123
- move/from16 v255, v1235
- return-void
-.end method
-
-
diff --git a/tools/vm-tests-tf/src/dot/junit/opcodes/move_object_from16/d/T_move_object_from16_6.d.done b/tools/vm-tests-tf/src/dot/junit/opcodes/move_object_from16/d/T_move_object_from16_6.d.done
deleted file mode 100644
index d41f1f7..0000000
--- a/tools/vm-tests-tf/src/dot/junit/opcodes/move_object_from16/d/T_move_object_from16_6.d.done
+++ /dev/null
@@ -1,34 +0,0 @@
-; 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.
-
-.source T_move_object_from16_6.java
-.class public dot.junit.opcodes.move_object_from16.d.T_move_object_from16_6
-.super java/lang/Object
-
-
-.method public <init>()V
-.limit regs 1
-
- invoke-direct {v0}, java/lang/Object/<init>()V
- return-void
-.end method
-
-.method public static run()V
-.limit regs 5000
- const-wide v4500, 123
- move-object/from16 v0, v4500
- return-void
-.end method
-
-
diff --git a/tools/vm-tests-tf/src/dot/junit/opcodes/move_object_from16/d/T_move_object_from16_7.d.done b/tools/vm-tests-tf/src/dot/junit/opcodes/move_object_from16/d/T_move_object_from16_7.d.done
deleted file mode 100644
index 09abc65..0000000
--- a/tools/vm-tests-tf/src/dot/junit/opcodes/move_object_from16/d/T_move_object_from16_7.d.done
+++ /dev/null
@@ -1,35 +0,0 @@
-; 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.
-
-.source T_move_object_from16_7.java
-.class public dot.junit.opcodes.move_object_from16.d.T_move_object_from16_7
-.super java/lang/Object
-
-
-.method public <init>()V
-.limit regs 1
-
- invoke-direct {v0}, java/lang/Object/<init>()V
- return-void
-.end method
-
-.method public static run()V
-.limit regs 5000
-
- const-wide v1234, 123
- move-object/from16 v255, v1235
- return-void
-.end method
-
-
diff --git a/tools/vm-tests-tf/src/dot/junit/opcodes/move_result/d/T_move_result_1.d.done b/tools/vm-tests-tf/src/dot/junit/opcodes/move_result/d/T_move_result_1.d.done
deleted file mode 100644
index 50c2eb2..0000000
--- a/tools/vm-tests-tf/src/dot/junit/opcodes/move_result/d/T_move_result_1.d.done
+++ /dev/null
@@ -1,55 +0,0 @@
-; 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.
-
-.source T_move_result_1.java
-.class public dot.junit.opcodes.move_result.d.T_move_result_1
-.super java/lang/Object
-
-
-.method public <init>()V
-.limit regs 1
-
- invoke-direct {v0}, java/lang/Object/<init>()V
- return-void
-.end method
-
-.method public static run()Z
-.limit regs 16
-
- const v0, 0
-
- invoke-static {} dot/junit/opcodes/move_result/d/T_move_result_1/foo()I
-
- move-result v0
- const v1, 12345
-
- if-eq v0, v1 Label1
-
- const v0, 0
- return v0
-
-Label1:
- const v0, 1
- return v0
-
-.end method
-
-.method private static foo()I
-.limit regs 1
-
- const v0, 12345
- return v0
-.end method
-
-
diff --git a/tools/vm-tests-tf/src/dot/junit/opcodes/move_wide/d/T_move_wide_6.d.done b/tools/vm-tests-tf/src/dot/junit/opcodes/move_wide/d/T_move_wide_6.d.done
deleted file mode 100644
index 4fecf88..0000000
--- a/tools/vm-tests-tf/src/dot/junit/opcodes/move_wide/d/T_move_wide_6.d.done
+++ /dev/null
@@ -1,39 +0,0 @@
-; 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.
-
-.source T_move_wide_6.java
-.class public dot.junit.opcodes.move_wide.d.T_move_wide_6
-.super java/lang/Object
-
-
-.method public <init>()V
-.limit regs 1
-
- invoke-direct {v0}, java/lang/Object/<init>()V
- return-void
-.end method
-
-.method public static run()I
-.limit regs 9
- const-wide v0, 1233746384323
-
- move-wide v1, v0
-
- const-wide v4, 1233746384323
- cmp-long v8, v1, v4
-
- return v8
-.end method
-
-
diff --git a/tools/vm-tests-tf/src/dot/junit/opcodes/move_wide_16/d/T_move_wide_16_9.d.done b/tools/vm-tests-tf/src/dot/junit/opcodes/move_wide_16/d/T_move_wide_16_9.d.done
deleted file mode 100644
index aa8cdce..0000000
--- a/tools/vm-tests-tf/src/dot/junit/opcodes/move_wide_16/d/T_move_wide_16_9.d.done
+++ /dev/null
@@ -1,38 +0,0 @@
-; 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.
-
-.source T_move_wide_16_9.java
-.class public dot.junit.opcodes.move_wide_16.d.T_move_wide_16_9
-.super java/lang/Object
-
-
-.method public <init>()V
-.limit regs 1
-
- invoke-direct {v0}, java/lang/Object/<init>()V
- return-void
-.end method
-
-.method public static run()I
-.limit regs 5000
- const-wide v1, 1233746384323
- move-wide/16 v2, v1
-
- const-wide v10, 1233746384323
- cmp-long v4, v2, v10
-
- return v4
-.end method
-
-
diff --git a/tools/vm-tests-tf/src/dot/junit/opcodes/move_wide_from16/d/T_move_wide_from16_1.d.done b/tools/vm-tests-tf/src/dot/junit/opcodes/move_wide_from16/d/T_move_wide_from16_1.d.done
deleted file mode 100644
index 21aaca8..0000000
--- a/tools/vm-tests-tf/src/dot/junit/opcodes/move_wide_from16/d/T_move_wide_from16_1.d.done
+++ /dev/null
@@ -1,49 +0,0 @@
-; 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.
-
-.source T_move_wide_from16_1.java
-.class public dot.junit.opcodes.move_wide_from16.d.T_move_wide_from16_1
-.super java/lang/Object
-
-
-.method public <init>()V
-.limit regs 1
-
- invoke-direct {v0}, java/lang/Object/<init>()V
- return-void
-.end method
-
-.method public static run()Z
-.limit regs 5000
- const-wide v10, 5678233453
-
- move-wide/16 v4001, v10
-
- move-wide/from16 v255, v4001
- move-wide/from16 v1, v255
-
- const-wide v4, 5678233453
-
- cmp-long v0, v1, v4
- if-nez v0, Label0
-
- const v1, 1
- return v1
-
-Label0:
- const v1, 0
- return v1
-.end method
-
-
diff --git a/tools/vm-tests-tf/src/dot/junit/opcodes/move_wide_from16/d/T_move_wide_from16_2.d.done b/tools/vm-tests-tf/src/dot/junit/opcodes/move_wide_from16/d/T_move_wide_from16_2.d.done
deleted file mode 100644
index d2e6700..0000000
--- a/tools/vm-tests-tf/src/dot/junit/opcodes/move_wide_from16/d/T_move_wide_from16_2.d.done
+++ /dev/null
@@ -1,39 +0,0 @@
-; 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.
-
-.source T_move_wide_from16_2.java
-.class public dot.junit.opcodes.move_wide_from16.d.T_move_wide_from16_2
-.super java/lang/Object
-
-
-.method public <init>()V
-.limit regs 1
-
- invoke-direct {v0}, java/lang/Object/<init>()V
- return-void
-.end method
-
-.method public static run()I
-.limit regs 5000
- const-wide v100, 5678233453
- move-wide/from16 v101, v100
-
- const-wide v4, 5678233453
-
- cmp-long v0, v101, v4
-
- return v0
-.end method
-
-
diff --git a/tools/vm-tests-tf/src/dot/junit/opcodes/move_wide_from16/d/T_move_wide_from16_6.d.done b/tools/vm-tests-tf/src/dot/junit/opcodes/move_wide_from16/d/T_move_wide_from16_6.d.done
deleted file mode 100644
index 784e31a..0000000
--- a/tools/vm-tests-tf/src/dot/junit/opcodes/move_wide_from16/d/T_move_wide_from16_6.d.done
+++ /dev/null
@@ -1,34 +0,0 @@
-; 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.
-
-.source T_move_wide_from16_6.java
-.class public dot.junit.opcodes.move_wide_from16.d.T_move_wide_from16_6
-.super java/lang/Object
-
-
-.method public <init>()V
-.limit regs 1
-
- invoke-direct {v0}, java/lang/Object/<init>()V
- return-void
-.end method
-
-.method public static run()V
-.limit regs 5000
- const v4500, 123
- move-wide/from16 v0, v4500
- return-void
-.end method
-
-
diff --git a/tools/vm-tests-tf/src/dot/junit/opcodes/move_wide_from16/d/T_move_wide_from16_7.d.done b/tools/vm-tests-tf/src/dot/junit/opcodes/move_wide_from16/d/T_move_wide_from16_7.d.done
deleted file mode 100644
index 1790fe5..0000000
--- a/tools/vm-tests-tf/src/dot/junit/opcodes/move_wide_from16/d/T_move_wide_from16_7.d.done
+++ /dev/null
@@ -1,35 +0,0 @@
-; 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.
-
-.source T_move_wide_from16_7.java
-.class public dot.junit.opcodes.move_wide_from16.d.T_move_wide_from16_7
-.super java/lang/Object
-
-
-.method public <init>()V
-.limit regs 1
-
- invoke-direct {v0}, java/lang/Object/<init>()V
- return-void
-.end method
-
-.method public static run()V
-.limit regs 5000
-
- const-wide v1234, 123
- move-wide/from16 v255, v1235
- return-void
-.end method
-
-
diff --git a/tools/vm-tests-tf/src/dot/junit/opcodes/new_array/d/T_new_array_7.d.done b/tools/vm-tests-tf/src/dot/junit/opcodes/new_array/d/T_new_array_7.d.done
deleted file mode 100644
index f6f2588..0000000
--- a/tools/vm-tests-tf/src/dot/junit/opcodes/new_array/d/T_new_array_7.d.done
+++ /dev/null
@@ -1,34 +0,0 @@
-; 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.
-
-.source T_new_array_7.java
-.class public dot.junit.opcodes.new_array.d.T_new_array_7
-.super java/lang/Object
-
-
-.method public <init>()V
-.limit regs 1
-
- invoke-direct {v0}, java/lang/Object/<init>()V
- return-void
-.end method
-
-.method public run(I)[Ljava/lang/Object;
-.limit regs 5
-
- new-array v0, v4, java/lang/Object
- return-object v0
-.end method
-
-
diff --git a/tools/vm-tests-tf/src/dot/junit/opcodes/new_instance/d/T_new_instance_2.d.done b/tools/vm-tests-tf/src/dot/junit/opcodes/new_instance/d/T_new_instance_2.d.done
deleted file mode 100644
index 2a8eefb..0000000
--- a/tools/vm-tests-tf/src/dot/junit/opcodes/new_instance/d/T_new_instance_2.d.done
+++ /dev/null
@@ -1,40 +0,0 @@
-; 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.
-
-.source T_new_instance_2.java
-.class public dot.junit.opcodes.new_instance.d.T_new_instance_2
-.super java/lang/Object
-
-.field i I
-
-.method public <init>()V
-.limit regs 1
-
- invoke-direct {v0}, java/lang/Object/<init>()V
- return-void
-.end method
-
-.method public static run()I
-.limit regs 5
-
- new-instance v0, dot/junit/opcodes/new_instance/d/T_new_instance_2
-; invoke-direct {v0}, dot/junit/opcodes/new_instance/d/T_new_instance_2/<init>()V
-
- iget v1, v0, dot.junit.opcodes.new_instance.d.T_new_instance_2.i I
-
- return v1
-
-.end method
-
-
diff --git a/tools/vm-tests-tf/src/dot/junit/opcodes/new_instance/d/TestAbstractClass.d.done b/tools/vm-tests-tf/src/dot/junit/opcodes/new_instance/d/TestAbstractClass.d.done
deleted file mode 100644
index ea321c4..0000000
--- a/tools/vm-tests-tf/src/dot/junit/opcodes/new_instance/d/TestAbstractClass.d.done
+++ /dev/null
@@ -1,22 +0,0 @@
-; 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.
-
-.source TestAbstractClass.java
-.interface public dot.junit.opcodes.new_instance.d.TestInterface
-
-
-.source TestAbstractClass.java
-.class abstract public dot.junit.opcodes.new_instance.d.TestAbstractClass
-.super java/lang/Object
-
diff --git a/tools/vm-tests-tf/src/dot/junit/opcodes/opc_const/d/T_opc_const_1.d.done b/tools/vm-tests-tf/src/dot/junit/opcodes/opc_const/d/T_opc_const_1.d.done
deleted file mode 100644
index 8246f1b..0000000
--- a/tools/vm-tests-tf/src/dot/junit/opcodes/opc_const/d/T_opc_const_1.d.done
+++ /dev/null
@@ -1,34 +0,0 @@
-; 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.
-
-.source T_opc_const_1.java
-.class public dot.junit.opcodes.opc_const.d.T_opc_const_1
-.super java/lang/Object
-
-
-.method public <init>()V
-.limit regs 1
-
- invoke-direct {v0}, java/lang/Object/<init>()V
- return-void
-.end method
-
-.method public run()F
-.limit regs 3
-
- const v1, 1.54
- return v1
-.end method
-
-
diff --git a/tools/vm-tests-tf/src/dot/junit/opcodes/opc_return/d/T_opc_return_3.d.done b/tools/vm-tests-tf/src/dot/junit/opcodes/opc_return/d/T_opc_return_3.d.done
deleted file mode 100644
index 1ab9dc1..0000000
--- a/tools/vm-tests-tf/src/dot/junit/opcodes/opc_return/d/T_opc_return_3.d.done
+++ /dev/null
@@ -1,48 +0,0 @@
-; 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.
-
-.source T_opc_return_3.java
-.class public dot.junit.opcodes.opc_return.d.T_opc_return_3
-.super java/lang/Object
-
-
-.method public <init>()V
-.limit regs 1
-
- invoke-direct {v0}, java/lang/Object/<init>()V
- return-void
-.end method
-
-.method private declared_synchronized test()F
-.limit regs 4
-
- new-instance v2, java/lang/Object
- invoke-direct {v2}, java/lang/Object/<init>()V
- monitor-enter v2
- monitor-exit v3
- const v0, 1.0
- return v0
-.end method
-
-
-
-.method public run()Z
-.limit regs 1
-
- invoke-direct {v0}, dot/junit/opcodes/opc_return/d/T_opc_return_3/test()F
-
- const v0, 1
- return v0
-.end method
-
diff --git a/tools/vm-tests-tf/src/dot/junit/opcodes/opc_throw/d/T_opc_throw_12.d.done b/tools/vm-tests-tf/src/dot/junit/opcodes/opc_throw/d/T_opc_throw_12.d.done
deleted file mode 100644
index 67366f6..0000000
--- a/tools/vm-tests-tf/src/dot/junit/opcodes/opc_throw/d/T_opc_throw_12.d.done
+++ /dev/null
@@ -1,53 +0,0 @@
-; 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.
-
-.source T_opc_throw_12.java
-.class public dot.junit.opcodes.opc_throw.d.T_opc_throw_12
-.super java/lang/Object
-
-
-.method public <init>()V
-.limit regs 1
-
- invoke-direct {v0}, java/lang/Object/<init>()V
- return-void
-.end method
-
-.method public run()Z
-.limit regs 2
-
-Label0:
- invoke-direct {v1}, dot/junit/opcodes/opc_throw/d/T_opc_throw_12/test()Z
- move-result v0
- return v0
-Label1:
- const v0, 0
- return v0
-
-.catch java/lang/RuntimeException from Label0 to Label1 using Label1
-.end method
-
-
-.method private test()Z
-.limit regs 2
-Label0:
- new-instance v0, java/lang/RuntimeException
- invoke-direct {v0}, java/lang/RuntimeException/<init>()V
- throw v0
-Label1:
- const v1, 1
- return v1
-
-.catch java/lang/RuntimeException from Label0 to Label1 using Label1
-.end method
diff --git a/tools/vm-tests-tf/src/dot/junit/opcodes/opc_throw/d/T_opc_throw_5.d.done b/tools/vm-tests-tf/src/dot/junit/opcodes/opc_throw/d/T_opc_throw_5.d.done
deleted file mode 100644
index f37a447..0000000
--- a/tools/vm-tests-tf/src/dot/junit/opcodes/opc_throw/d/T_opc_throw_5.d.done
+++ /dev/null
@@ -1,40 +0,0 @@
-; 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.
-
-.source T_opc_throw_5.java
-.class public dot.junit.opcodes.opc_throw.d.T_opc_throw_5
-.super java/lang/Object
-
-
-.method public <init>()V
-.limit regs 1
-
- invoke-direct {v0}, java/lang/Object/<init>()V
- return-void
-.end method
-
-.method public declared_synchronized run()V
-.limit regs 6
-
- new-instance v2, java/lang/Object
- invoke-direct {v2}, java/lang/Object/<init>()V
- monitor-enter v2
- monitor-exit v5
-
- new-instance v1, java/lang/NullPointerException
- invoke-direct {v1}, java/lang/NullPointerException/<init>()V
- throw v1
-.end method
-
-
diff --git a/tools/vm-tests-tf/src/dot/junit/opcodes/opc_throw/d/T_opc_throw_7.d.done b/tools/vm-tests-tf/src/dot/junit/opcodes/opc_throw/d/T_opc_throw_7.d.done
deleted file mode 100644
index bf85401..0000000
--- a/tools/vm-tests-tf/src/dot/junit/opcodes/opc_throw/d/T_opc_throw_7.d.done
+++ /dev/null
@@ -1,34 +0,0 @@
-; 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.
-
-.source T_opc_throw_7.java
-.class public dot.junit.opcodes.opc_throw.d.T_opc_throw_7
-.super java/lang/Object
-
-
-.method public <init>()V
-.limit regs 1
-
- invoke-direct {v0}, java/lang/Object/<init>()V
- return-void
-.end method
-
-.method public run()V
-.limit regs 5
-
- const v1, 3.14
- throw v1
-.end method
-
-
diff --git a/tools/vm-tests-tf/src/dot/junit/opcodes/packed_switch/d/T_packed_switch_1.d.done b/tools/vm-tests-tf/src/dot/junit/opcodes/packed_switch/d/T_packed_switch_1.d.done
deleted file mode 100644
index bd692e7..0000000
--- a/tools/vm-tests-tf/src/dot/junit/opcodes/packed_switch/d/T_packed_switch_1.d.done
+++ /dev/null
@@ -1,46 +0,0 @@
-; 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.
-
-.source T_packed_switch_1.java
-.class public dot.junit.opcodes.packed_switch.d.T_packed_switch_1
-.super java/lang/Object
-
-
-.method public <init>()V
-.limit regs 1
-
- invoke-direct {v0}, java/lang/Object/<init>()V
- return-void
-.end method
-
-.method public run(I)I
-.limit regs 5
- packed-switch v4, -1
- Label9 ; -1
- Label6 ; 0
- Label6 ; 1
- Label12 ; 2
- Label12 ; 3
- packed-switch-end
-Label6:
- const/4 v2, -1
- return v2
-Label9:
- const/4 v2, 2
- return v2
-Label12:
- const/16 v2, 20
- return v2
-
-.end method
diff --git a/tools/vm-tests-tf/src/dot/junit/opcodes/packed_switch/d/T_packed_switch_11.d.done b/tools/vm-tests-tf/src/dot/junit/opcodes/packed_switch/d/T_packed_switch_11.d.done
deleted file mode 100644
index d1d2d03..0000000
--- a/tools/vm-tests-tf/src/dot/junit/opcodes/packed_switch/d/T_packed_switch_11.d.done
+++ /dev/null
@@ -1,46 +0,0 @@
-; 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.
-
-.source T_packed_switch_11.java
-.class public dot.junit.opcodes.packed_switch.d.T_packed_switch_11
-.super java/lang/Object
-
-
-.method public <init>()V
-.limit regs 1
-
- invoke-direct {v0}, java/lang/Object/<init>()V
- return-void
-.end method
-
-.method public run(I)I
-.limit regs 5
- packed-switch v4, -1
- Label9 ; -1
- Label6 ; 0
- Label6 ; 1
- Label12 ; 2
- Label12 ; 3
- packed-switch-end
-Label6:
- const/4 v2, -1
- return v2
-Label9:
- const/4 v2, 2
- return v2
-Label12:
- const/16 v2, 20
- return v2
-
-.end method
diff --git a/tools/vm-tests-tf/src/dot/junit/opcodes/packed_switch/d/T_packed_switch_12.d.done b/tools/vm-tests-tf/src/dot/junit/opcodes/packed_switch/d/T_packed_switch_12.d.done
deleted file mode 100644
index 58afb0b6..0000000
--- a/tools/vm-tests-tf/src/dot/junit/opcodes/packed_switch/d/T_packed_switch_12.d.done
+++ /dev/null
@@ -1,48 +0,0 @@
-; 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.
-
-.source T_packed_switch_12.java
-.class public dot.junit.opcodes.packed_switch.d.T_packed_switch_12
-.super java/lang/Object
-
-
-.method public <init>()V
-.limit regs 1
-
- invoke-direct {v0}, java/lang/Object/<init>()V
- return-void
-.end method
-
-.method public run(I)I
-.limit regs 5
- goto Label0
-
- packed-switch v4, -1
- Label9 ; -1
- Label6 ; 0
- Label6 ; 1
- Label12 ; 2
- Label12 ; 3
- packed-switch-end
-Label6:
- const/4 v2, -1
- return v2
-Label9:
- const/4 v2, 2
- return v2
-Label12:
- const/16 v2, 20
- return v2
-Label0:
-.end method
diff --git a/tools/vm-tests-tf/src/dot/junit/opcodes/packed_switch/d/T_packed_switch_13.d.done b/tools/vm-tests-tf/src/dot/junit/opcodes/packed_switch/d/T_packed_switch_13.d.done
deleted file mode 100644
index 2e7471b..0000000
--- a/tools/vm-tests-tf/src/dot/junit/opcodes/packed_switch/d/T_packed_switch_13.d.done
+++ /dev/null
@@ -1,47 +0,0 @@
-; 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.
-
-.source T_packed_switch_13.java
-.class public dot.junit.opcodes.packed_switch.d.T_packed_switch_13
-.super java/lang/Object
-
-
-.method public <init>()V
-.limit regs 1
-
- invoke-direct {v0}, java/lang/Object/<init>()V
- return-void
-.end method
-
-.method public run(I)I
-.limit regs 5
- goto Label0
-Label0:
- packed-switch v4, 0
- Label6 ; 0
- Label6 ; 1
- Label12 ; 2
- Label12 ; 3
- packed-switch-end
-Label6:
- const/4 v2, -1
- return v2
-Label9:
- const/4 v2, 2
- return v2
-Label12:
- const/16 v2, 20
- return v2
-
-.end method
diff --git a/tools/vm-tests-tf/src/dot/junit/opcodes/packed_switch/d/T_packed_switch_2.d.done b/tools/vm-tests-tf/src/dot/junit/opcodes/packed_switch/d/T_packed_switch_2.d.done
deleted file mode 100644
index a356eb3..0000000
--- a/tools/vm-tests-tf/src/dot/junit/opcodes/packed_switch/d/T_packed_switch_2.d.done
+++ /dev/null
@@ -1,46 +0,0 @@
-; 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.
-
-.source T_packed_switch_2.java
-.class public dot.junit.opcodes.packed_switch.d.T_packed_switch_2
-.super java/lang/Object
-
-
-.method public <init>()V
-.limit regs 1
-
- invoke-direct {v0}, java/lang/Object/<init>()V
- return-void
-.end method
-
-.method public run(F)I
-.limit regs 5
- packed-switch v4, -1
- Label9 ; -1
- Label6 ; 0
- Label6 ; 1
- Label12 ; 2
- Label12 ; 3
- packed-switch-end
-Label6:
- const/4 v2, -1
- return v2
-Label9:
- const/4 v2, 2
- return v2
-Label12:
- const/16 v2, 20
- return v2
-
-.end method
diff --git a/tools/vm-tests-tf/src/dot/junit/opcodes/packed_switch/d/T_packed_switch_3.d.done b/tools/vm-tests-tf/src/dot/junit/opcodes/packed_switch/d/T_packed_switch_3.d.done
deleted file mode 100644
index 79e9e8d..0000000
--- a/tools/vm-tests-tf/src/dot/junit/opcodes/packed_switch/d/T_packed_switch_3.d.done
+++ /dev/null
@@ -1,46 +0,0 @@
-; 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.
-
-.source T_packed_switch_3.java
-.class public dot.junit.opcodes.packed_switch.d.T_packed_switch_3
-.super java/lang/Object
-
-
-.method public <init>()V
-.limit regs 1
-
- invoke-direct {v0}, java/lang/Object/<init>()V
- return-void
-.end method
-
-.method public run(I)I
-.limit regs 5
- packed-switch v5, -1
- Label9 ; -1
- Label6 ; 0
- Label6 ; 1
- Label12 ; 2
- Label12 ; 3
- packed-switch-end
-Label6:
- const/4 v2, -1
- return v2
-Label9:
- const/4 v2, 2
- return v2
-Label12:
- const/16 v2, 20
- return v2
-
-.end method
diff --git a/tools/vm-tests-tf/src/dot/junit/opcodes/packed_switch/d/T_packed_switch_4.d.done b/tools/vm-tests-tf/src/dot/junit/opcodes/packed_switch/d/T_packed_switch_4.d.done
deleted file mode 100644
index 1c3d42b..0000000
--- a/tools/vm-tests-tf/src/dot/junit/opcodes/packed_switch/d/T_packed_switch_4.d.done
+++ /dev/null
@@ -1,46 +0,0 @@
-; 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.
-
-.source T_packed_switch_4.java
-.class public dot.junit.opcodes.packed_switch.d.T_packed_switch_4
-.super java/lang/Object
-
-
-.method public <init>()V
-.limit regs 1
-
- invoke-direct {v0}, java/lang/Object/<init>()V
- return-void
-.end method
-
-.method public run(D)I
-.limit regs 5
- packed-switch v3, -1
- Label9 ; -1
- Label6 ; 0
- Label6 ; 1
- Label12 ; 2
- Label12 ; 3
- packed-switch-end
-Label6:
- const/4 v2, -1
- return v2
-Label9:
- const/4 v2, 2
- return v2
-Label12:
- const/16 v2, 20
- return v2
-
-.end method
diff --git a/tools/vm-tests-tf/src/dot/junit/opcodes/packed_switch/d/T_packed_switch_5.d.done b/tools/vm-tests-tf/src/dot/junit/opcodes/packed_switch/d/T_packed_switch_5.d.done
deleted file mode 100644
index c648fbb..0000000
--- a/tools/vm-tests-tf/src/dot/junit/opcodes/packed_switch/d/T_packed_switch_5.d.done
+++ /dev/null
@@ -1,46 +0,0 @@
-; 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.
-
-.source T_packed_switch_5.java
-.class public dot.junit.opcodes.packed_switch.d.T_packed_switch_5
-.super java/lang/Object
-
-
-.method public <init>()V
-.limit regs 1
-
- invoke-direct {v0}, java/lang/Object/<init>()V
- return-void
-.end method
-
-.method public run(J)I
-.limit regs 5
- packed-switch v3, -1
- Label9 ; -1
- Label6 ; 0
- Label6 ; 1
- Label12 ; 2
- Label12 ; 3
- packed-switch-end
-Label6:
- const/4 v2, -1
- return v2
-Label9:
- const/4 v2, 2
- return v2
-Label12:
- const/16 v2, 20
- return v2
-
-.end method
diff --git a/tools/vm-tests-tf/src/dot/junit/opcodes/packed_switch/d/T_packed_switch_6.d.done b/tools/vm-tests-tf/src/dot/junit/opcodes/packed_switch/d/T_packed_switch_6.d.done
deleted file mode 100644
index 9a18602..0000000
--- a/tools/vm-tests-tf/src/dot/junit/opcodes/packed_switch/d/T_packed_switch_6.d.done
+++ /dev/null
@@ -1,46 +0,0 @@
-; 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.
-
-.source T_packed_switch_6.java
-.class public dot.junit.opcodes.packed_switch.d.T_packed_switch_6
-.super java/lang/Object
-
-
-.method public <init>()V
-.limit regs 1
-
- invoke-direct {v0}, java/lang/Object/<init>()V
- return-void
-.end method
-
-.method public run(I)I
-.limit regs 5
- packed-switch v3, -1
- Label9 ; -1
- Label6 ; 0
- Label6 ; 1
- Label12 ; 2
- Label12 ; 3
- packed-switch-end
-Label6:
- const/4 v2, -1
- return v2
-Label9:
- const/4 v2, 2
- return v2
-Label12:
- const/16 v2, 20
- return v2
-
-.end method
diff --git a/tools/vm-tests-tf/src/dot/junit/opcodes/packed_switch/d/T_packed_switch_7.d.done b/tools/vm-tests-tf/src/dot/junit/opcodes/packed_switch/d/T_packed_switch_7.d.done
deleted file mode 100644
index ebf9766..0000000
--- a/tools/vm-tests-tf/src/dot/junit/opcodes/packed_switch/d/T_packed_switch_7.d.done
+++ /dev/null
@@ -1,46 +0,0 @@
-; 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.
-
-.source T_packed_switch_7.java
-.class public dot.junit.opcodes.packed_switch.d.T_packed_switch_7
-.super java/lang/Object
-
-
-.method public <init>()V
-.limit regs 1
-
- invoke-direct {v0}, java/lang/Object/<init>()V
- return-void
-.end method
-
-.method public run(I)I
-.limit regs 5
- packed-switch v4, -1
- Label9 ; -1
- Label6 ; 0
- Label6 ; 1
- Label12 ; 2
- Label12 ; 3
- packed-switch-end
-Label6:
- const/4 v2, -1
- return v2
-Label9:
- const/4 v2, 2
- return v2
-Label12:
- const/16 v2, 20
- return v2
-
-.end method
diff --git a/tools/vm-tests-tf/src/dot/junit/opcodes/packed_switch/d/T_packed_switch_8.d.done b/tools/vm-tests-tf/src/dot/junit/opcodes/packed_switch/d/T_packed_switch_8.d.done
deleted file mode 100644
index b22771c..0000000
--- a/tools/vm-tests-tf/src/dot/junit/opcodes/packed_switch/d/T_packed_switch_8.d.done
+++ /dev/null
@@ -1,46 +0,0 @@
-; 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.
-
-.source T_packed_switch_8.java
-.class public dot.junit.opcodes.packed_switch.d.T_packed_switch_8
-.super java/lang/Object
-
-
-.method public <init>()V
-.limit regs 1
-
- invoke-direct {v0}, java/lang/Object/<init>()V
- return-void
-.end method
-
-.method public run(I)I
-.limit regs 5
- packed-switch v4, -1
- Label9 ; -1
- Label6 ; 0
- Label6 ; 1
- Label12 ; 2
- Label12 ; 3
- packed-switch-end
-Label6:
- const v2, -1
- return v2
-Label9:
- const v2, 2
- return v2
-Label12:
- const v2, 20
- return v2
-
-.end method
diff --git a/tools/vm-tests-tf/src/dot/junit/opcodes/packed_switch/d/T_packed_switch_9.d.done b/tools/vm-tests-tf/src/dot/junit/opcodes/packed_switch/d/T_packed_switch_9.d.done
deleted file mode 100644
index 217a917..0000000
--- a/tools/vm-tests-tf/src/dot/junit/opcodes/packed_switch/d/T_packed_switch_9.d.done
+++ /dev/null
@@ -1,46 +0,0 @@
-; 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.
-
-.source T_packed_switch_9.java
-.class public dot.junit.opcodes.packed_switch.d.T_packed_switch_9
-.super java/lang/Object
-
-
-.method public <init>()V
-.limit regs 1
-
- invoke-direct {v0}, java/lang/Object/<init>()V
- return-void
-.end method
-
-.method public run(I)I
-.limit regs 5
- packed-switch v4, -1
- Label9 ; -1
- Label6 ; 0
- Label6 ; 1
- Label12 ; 2
- Label12 ; 3
- packed-switch-end
-Label6:
- const/4 v2, -1
- return v2
-Label9:
- const/4 v2, 2
- return v2
-Label12:
- const/16 v2, 20
- return v2
-
-.end method
diff --git a/tools/vm-tests-tf/src/dot/junit/opcodes/return_object/d/T_return_object_12.d.done b/tools/vm-tests-tf/src/dot/junit/opcodes/return_object/d/T_return_object_12.d.done
deleted file mode 100644
index ea4c11a..0000000
--- a/tools/vm-tests-tf/src/dot/junit/opcodes/return_object/d/T_return_object_12.d.done
+++ /dev/null
@@ -1,43 +0,0 @@
-; 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.
-
-.source T_return_object_12.java
-.class public dot.junit.opcodes.return_object.d.T_return_object_12
-.super java/lang/Object
-
-
-.method public <init>()V
-.limit regs 1
- invoke-direct {v0}, java/lang/Object/<init>()V
- return-void
-.end method
-
-.method private test()Ldot/junit/opcodes/return_object/d/TSuper;
-.limit regs 5
-
- new-instance v1, dot/junit/opcodes/return_object/d/TChild
- invoke-direct {v1}, dot/junit/opcodes/return_object/d/TChild/<init>()V
- return-object v1
-.end method
-
-.method public run()Z
-.limit regs 4
-
- invoke-direct {v3}, dot/junit/opcodes/return_object/d/T_return_object_12/test()Ldot/junit/opcodes/return_object/d/TSuper;
- move-result-object v2
- instance-of v0, v2, dot/junit/opcodes/return_object/d/TChild
- return v0
-.end method
-
-
diff --git a/tools/vm-tests-tf/src/dot/junit/opcodes/return_object/d/T_return_object_13.d.done b/tools/vm-tests-tf/src/dot/junit/opcodes/return_object/d/T_return_object_13.d.done
deleted file mode 100644
index 4cae4ce..0000000
--- a/tools/vm-tests-tf/src/dot/junit/opcodes/return_object/d/T_return_object_13.d.done
+++ /dev/null
@@ -1,45 +0,0 @@
-; 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.
-
-.source T_return_object_13.java
-.class public dot.junit.opcodes.return_object.d.T_return_object_13
-.super java/lang/Object
-
-
-.method public <init>()V
-.limit regs 1
-
- invoke-direct {v0}, java/lang/Object/<init>()V
- return-void
-.end method
-
-.method private test()Ldot/junit/opcodes/return_object/d/TInterface;
-.limit regs 5
-
- new-instance v1, dot/junit/opcodes/return_object/d/TChild
- invoke-direct {v1}, dot/junit/opcodes/return_object/d/TChild/<init>()V
- return-object v1
-.end method
-
-.method public run()Z
-.limit regs 4
-Label0:
-
- invoke-direct {v3}, dot/junit/opcodes/return_object/d/T_return_object_13/test()Ldot/junit/opcodes/return_object/d/TInterface;
- move-result-object v2
- instance-of v2, v2, dot/junit/opcodes/return_object/d/TChild
- return v2
-.end method
-
-
diff --git a/tools/vm-tests-tf/src/dot/junit/opcodes/return_object/d/T_return_object_14.d.done b/tools/vm-tests-tf/src/dot/junit/opcodes/return_object/d/T_return_object_14.d.done
deleted file mode 100644
index cff2b12..0000000
--- a/tools/vm-tests-tf/src/dot/junit/opcodes/return_object/d/T_return_object_14.d.done
+++ /dev/null
@@ -1,49 +0,0 @@
-; 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.
-
-.source T_return_object_14.java
-.class public dot.junit.opcodes.return_object.d.T_return_object_14
-.super java/lang/Object
-
-
-.method public <init>()V
-.limit regs 1
-
- invoke-direct {v0}, java/lang/Object/<init>()V
- return-void
-.end method
-
-.method private test()Ldot/junit/opcodes/return_object/d/TChild;
-.limit regs 6
-
- new-instance v0, dot/junit/opcodes/return_object/d/TSuper
- invoke-direct {v0}, dot/junit/opcodes/return_object/d/TSuper/<init>()V
-
- return-object v0
-.end method
-
-
-.method public run()Z
-.limit regs 6
-
- invoke-direct {v5}, dot/junit/opcodes/return_object/d/T_return_object_14/test()Ldot/junit/opcodes/return_object/d/TChild;
- move-result-object v1
-
- instance-of v0, v1, dot/junit/opcodes/return_object/d/TChild
-
- return v0
-
-.end method
-
-
diff --git a/tools/vm-tests-tf/src/dot/junit/opcodes/return_object/d/T_return_object_4.d.done b/tools/vm-tests-tf/src/dot/junit/opcodes/return_object/d/T_return_object_4.d.done
deleted file mode 100644
index 9b30169..0000000
--- a/tools/vm-tests-tf/src/dot/junit/opcodes/return_object/d/T_return_object_4.d.done
+++ /dev/null
@@ -1,34 +0,0 @@
-; 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.
-
-.source T_return_object_4.java
-.class public dot.junit.opcodes.return_object.d.T_return_object_4
-.super java/lang/Object
-
-
-.method public <init>()V
-.limit regs 1
-
- invoke-direct {v0}, java/lang/Object/<init>()V
- return-void
-.end method
-
-.method public run()F
-.limit regs 3
-
- const v2, 3.14
- return-object v2
-.end method
-
-
diff --git a/tools/vm-tests-tf/src/dot/junit/opcodes/return_object/d/T_return_object_8.d.done b/tools/vm-tests-tf/src/dot/junit/opcodes/return_object/d/T_return_object_8.d.done
deleted file mode 100644
index e82e7d6..0000000
--- a/tools/vm-tests-tf/src/dot/junit/opcodes/return_object/d/T_return_object_8.d.done
+++ /dev/null
@@ -1,47 +0,0 @@
-; 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.
-
-.source T_return_object_8.java
-.class public dot.junit.opcodes.return_object.d.T_return_object_8
-.super java/lang/Object
-
-
-.method public <init>()V
-.limit regs 1
-
- invoke-direct {v0}, java/lang/Object/<init>()V
- return-void
-.end method
-
-.method private declared_synchronized test()Ljava/lang/String;
-.limit regs 4
-
- new-instance v2, java/lang/Object
- invoke-direct {v2}, java/lang/Object/<init>()V
- monitor-enter v2
- monitor-exit v3
- const-string v0, "abc"
- return-object v0
-.end method
-
-.method public run()Z
-.limit regs 3
-
- invoke-direct {v2}, dot/junit/opcodes/return_object/d/T_return_object_8/test()Ljava/lang/String;
-
- const v0, 1
- return v0
-.end method
-
-
diff --git a/tools/vm-tests-tf/src/dot/junit/opcodes/return_object/d/TestStubs.d.done b/tools/vm-tests-tf/src/dot/junit/opcodes/return_object/d/TestStubs.d.done
deleted file mode 100644
index 44f819f..0000000
--- a/tools/vm-tests-tf/src/dot/junit/opcodes/return_object/d/TestStubs.d.done
+++ /dev/null
@@ -1,51 +0,0 @@
-; 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.
-
-.source TestStubs.java
-.interface dot.junit.opcodes.return_object.d.TInterface
-
-.source TestStubs.java
-.class dot.junit.opcodes.return_object.d.TSuper
-.super java/lang/Object
-.implements dot.junit.opcodes.return_object.d.TInterface
-
-.method public <init>()V
-.limit regs 1
- invoke-direct {v0}, java/lang/Object/<init>()V
- return-void
-.end method
-
-.source TestStubs.java
-.class dot.junit.opcodes.return_object.d.TChild
-.super dot.junit.opcodes.return_object.d.TSuper
-
-.method public <init>()V
-.limit regs 1
- invoke-direct {v0}, dot/junit/opcodes/return_object/d/TSuper/<init>()V
- return-void
-.end method
-
-.source TestStubs.java
-.class dot.junit.opcodes.return_object.d.TSuper2
-.super java/lang/Object
-
-
-.method public <init>()V
-.limit regs 1
- invoke-direct {v0}, java/lang/Object/<init>()V
- return-void
-.end method
-
-.source TestStubs.java
-.class dot.junit.opcodes.return_object.d.TestStubs
diff --git a/tools/vm-tests-tf/src/dot/junit/opcodes/return_void/d/T_return_void_3.d.done b/tools/vm-tests-tf/src/dot/junit/opcodes/return_void/d/T_return_void_3.d.done
deleted file mode 100644
index b6bad32..0000000
--- a/tools/vm-tests-tf/src/dot/junit/opcodes/return_void/d/T_return_void_3.d.done
+++ /dev/null
@@ -1,47 +0,0 @@
-; 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.
-
-.source T_return_void_3.java
-.class public dot.junit.opcodes.return_void.d.T_return_void_3
-.super java/lang/Object
-
-
-.method public <init>()V
-.limit regs 1
-
- invoke-direct {v0}, java/lang/Object/<init>()V
- return-void
-.end method
-
-.method private declared_synchronized test()V
-.limit regs 2
-
- new-instance v0, java/lang/Object
- invoke-direct {v0}, java/lang/Object/<init>()V
- monitor-enter v0
- monitor-exit v1
- return-void
-.end method
-
-
-
-.method public run()Z
-.limit regs 1
-
- invoke-direct {v0}, dot/junit/opcodes/return_void/d/T_return_void_3/test()V
-
- const v0, 1
- return v0
-.end method
-
diff --git a/tools/vm-tests-tf/src/dot/junit/opcodes/return_wide/d/T_return_wide_3.d.done b/tools/vm-tests-tf/src/dot/junit/opcodes/return_wide/d/T_return_wide_3.d.done
deleted file mode 100644
index 479e777..0000000
--- a/tools/vm-tests-tf/src/dot/junit/opcodes/return_wide/d/T_return_wide_3.d.done
+++ /dev/null
@@ -1,48 +0,0 @@
-; 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.
-
-.source T_return_wide_3.java
-.class public dot.junit.opcodes.return_wide.d.T_return_wide_3
-.super java/lang/Object
-
-
-.method public <init>()V
-.limit regs 1
-
- invoke-direct {v0}, java/lang/Object/<init>()V
- return-void
-.end method
-
-.method private declared_synchronized test()D
-.limit regs 4
-
- new-instance v2, java/lang/Object
- invoke-direct {v2}, java/lang/Object/<init>()V
- monitor-enter v2
- monitor-exit v3
- const-wide v0, 1.0
- return-wide v0
-.end method
-
-
-
-.method public run()Z
-.limit regs 1
-
- invoke-direct {v0}, dot/junit/opcodes/return_wide/d/T_return_wide_3/test()D
-
- const v0, 1
- return v0
-.end method
-
diff --git a/tools/vm-tests-tf/src/dot/junit/opcodes/sget/d/T_sget_14.d.done b/tools/vm-tests-tf/src/dot/junit/opcodes/sget/d/T_sget_14.d.done
deleted file mode 100644
index 43ed17b..0000000
--- a/tools/vm-tests-tf/src/dot/junit/opcodes/sget/d/T_sget_14.d.done
+++ /dev/null
@@ -1,35 +0,0 @@
-; 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.
-
-.source T_sget_14.java
-.class public dot.junit.opcodes.sget.d.T_sget_14
-.super java/lang/Object
-
-.field public static i1 Ljava/lang/Object;
-
-.method public <init>()V
-.limit regs 1
-
- invoke-direct {v0}, java/lang/Object/<init>()V
- return-void
-.end method
-
-.method public run()V
-.limit regs 3
-
- sget v0, dot.junit.opcodes.sget.d.T_sget_14.i1 Ljava/lang/Object;
- return-void
-.end method
-
-
diff --git a/tools/vm-tests-tf/src/dot/junit/opcodes/sget/d/T_sget_2.d.done b/tools/vm-tests-tf/src/dot/junit/opcodes/sget/d/T_sget_2.d.done
deleted file mode 100644
index de5c7cb..0000000
--- a/tools/vm-tests-tf/src/dot/junit/opcodes/sget/d/T_sget_2.d.done
+++ /dev/null
@@ -1,42 +0,0 @@
-; 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.
-
-.source T_sget_2.java
-.class public dot.junit.opcodes.sget.d.T_sget_2
-.super java/lang/Object
-
-.field public static val F
-
-.method static <clinit>()V
-.limit regs 2
- const v0, 123.0
- sput v0, dot.junit.opcodes.sget.d.T_sget_2.val F
- return-void
-.end method
-
-.method public <init>()V
-.limit regs 1
-
- invoke-direct {v0}, java/lang/Object/<init>()V
- return-void
-.end method
-
-.method public run()F
-.limit regs 4
-
- sget v1, dot.junit.opcodes.sget.d.T_sget_2.val F
- return v1
-.end method
-
-
diff --git a/tools/vm-tests-tf/src/dot/junit/opcodes/sget/d/T_sget_9.d.done b/tools/vm-tests-tf/src/dot/junit/opcodes/sget/d/T_sget_9.d.done
deleted file mode 100644
index 831c623..0000000
--- a/tools/vm-tests-tf/src/dot/junit/opcodes/sget/d/T_sget_9.d.done
+++ /dev/null
@@ -1,52 +0,0 @@
-; 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.
-
-.source StubInitError.java
-.class public dot.junit.opcodes.sget.d.StubInitError
-.super java/lang/Object
-
-.field public static value I
-
-.method static <clinit>()V
-.limit regs 2
-
- const/4 v0, 0
- const/4 v1, 5
- div-int/2addr v1, v0
-
- sput v1, dot.junit.opcodes.sget.d.StubInitError.value I
- return-void
-.end method
-
-
-.source T_sget_9.java
-.class public dot.junit.opcodes.sget.d.T_sget_9
-.super java/lang/Object
-
-
-.method public <init>()V
-.limit regs 1
-
- invoke-direct {v0}, java/lang/Object/<init>()V
- return-void
-.end method
-
-.method public run()I
-.limit regs 3
-
- sget v1, dot.junit.opcodes.sget.d.StubInitError.value I
- return v1
-.end method
-
-
diff --git a/tools/vm-tests-tf/src/dot/junit/opcodes/sget_boolean/d/T_sget_boolean_14.d.done b/tools/vm-tests-tf/src/dot/junit/opcodes/sget_boolean/d/T_sget_boolean_14.d.done
deleted file mode 100644
index 90de215..0000000
--- a/tools/vm-tests-tf/src/dot/junit/opcodes/sget_boolean/d/T_sget_boolean_14.d.done
+++ /dev/null
@@ -1,35 +0,0 @@
-; 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.
-
-.source T_sget_boolean_14.java
-.class public dot.junit.opcodes.sget_boolean.d.T_sget_boolean_14
-.super java/lang/Object
-
-.field public static i1 Ljava/lang/Object;
-
-.method public <init>()V
-.limit regs 1
-
- invoke-direct {v0}, java/lang/Object/<init>()V
- return-void
-.end method
-
-.method public run()V
-.limit regs 3
-
- sget-boolean v0, dot.junit.opcodes.sget_boolean.d.T_sget_boolean_14.i1 Ljava/lang/Object;
- return-void
-.end method
-
-
diff --git a/tools/vm-tests-tf/src/dot/junit/opcodes/sget_boolean/d/T_sget_boolean_9.d.done b/tools/vm-tests-tf/src/dot/junit/opcodes/sget_boolean/d/T_sget_boolean_9.d.done
deleted file mode 100644
index 0cf9a87..0000000
--- a/tools/vm-tests-tf/src/dot/junit/opcodes/sget_boolean/d/T_sget_boolean_9.d.done
+++ /dev/null
@@ -1,53 +0,0 @@
-; 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.
-
-.source StubInitError.java
-.class public dot.junit.opcodes.sget_boolean.d.StubInitError
-.super java/lang/Object
-
-.field public static value Z
-
-.method static <clinit>()V
-.limit regs 2
-
- const/4 v0, 0
- const/4 v1, 1
- div-int/2addr v1, v0
-
- const v1, 1
- sput-boolean v1, dot.junit.opcodes.sget_boolean.d.StubInitError.value Z
- return-void
-.end method
-
-
-.source T_sget_boolean_9.java
-.class public dot.junit.opcodes.sget_boolean.d.T_sget_boolean_9
-.super java/lang/Object
-
-
-.method public <init>()V
-.limit regs 1
-
- invoke-direct {v0}, java/lang/Object/<init>()V
- return-void
-.end method
-
-.method public run()Z
-.limit regs 3
-
- sget-boolean v1, dot.junit.opcodes.sget_boolean.d.StubInitError.value Z
- return v1
-.end method
-
-
diff --git a/tools/vm-tests-tf/src/dot/junit/opcodes/sget_byte/d/T_sget_byte_14.d.done b/tools/vm-tests-tf/src/dot/junit/opcodes/sget_byte/d/T_sget_byte_14.d.done
deleted file mode 100644
index d64eedc..0000000
--- a/tools/vm-tests-tf/src/dot/junit/opcodes/sget_byte/d/T_sget_byte_14.d.done
+++ /dev/null
@@ -1,35 +0,0 @@
-; 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.
-
-.source T_sget_byte_14.java
-.class public dot.junit.opcodes.sget_byte.d.T_sget_byte_14
-.super java/lang/Object
-
-.field public static i1 Ljava/lang/Object;
-
-.method public <init>()V
-.limit regs 1
-
- invoke-direct {v0}, java/lang/Object/<init>()V
- return-void
-.end method
-
-.method public run()V
-.limit regs 3
-
- sget-byte v0, dot.junit.opcodes.sget_byte.d.T_sget_byte_14.i1 Ljava/lang/Object;
- return-void
-.end method
-
-
diff --git a/tools/vm-tests-tf/src/dot/junit/opcodes/sget_byte/d/T_sget_byte_9.d.done b/tools/vm-tests-tf/src/dot/junit/opcodes/sget_byte/d/T_sget_byte_9.d.done
deleted file mode 100644
index aee1a37..0000000
--- a/tools/vm-tests-tf/src/dot/junit/opcodes/sget_byte/d/T_sget_byte_9.d.done
+++ /dev/null
@@ -1,53 +0,0 @@
-; 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.
-
-.source StubInitError.java
-.class public dot.junit.opcodes.sget_byte.d.StubInitError
-.super java/lang/Object
-
-.field public static value B
-
-.method static <clinit>()V
-.limit regs 2
-
- const/4 v0, 0
- const/4 v1, 1
- div-int/2addr v1, v0
-
- const v1, 1
- sput-byte v1, dot.junit.opcodes.sget_byte.d.StubInitError.value B
- return-void
-.end method
-
-
-.source T_sget_byte_9.java
-.class public dot.junit.opcodes.sget_byte.d.T_sget_byte_9
-.super java/lang/Object
-
-
-.method public <init>()V
-.limit regs 1
-
- invoke-direct {v0}, java/lang/Object/<init>()V
- return-void
-.end method
-
-.method public run()B
-.limit regs 3
-
- sget-byte v1, dot.junit.opcodes.sget_byte.d.StubInitError.value B
- return v1
-.end method
-
-
diff --git a/tools/vm-tests-tf/src/dot/junit/opcodes/sget_char/d/T_sget_char_14.d.done b/tools/vm-tests-tf/src/dot/junit/opcodes/sget_char/d/T_sget_char_14.d.done
deleted file mode 100644
index c1b8040..0000000
--- a/tools/vm-tests-tf/src/dot/junit/opcodes/sget_char/d/T_sget_char_14.d.done
+++ /dev/null
@@ -1,35 +0,0 @@
-; 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.
-
-.source T_sget_char_14.java
-.class public dot.junit.opcodes.sget_char.d.T_sget_char_14
-.super java/lang/Object
-
-.field public static i1 Ljava/lang/Object;
-
-.method public <init>()V
-.limit regs 1
-
- invoke-direct {v0}, java/lang/Object/<init>()V
- return-void
-.end method
-
-.method public run()V
-.limit regs 3
-
- sget-char v0, dot.junit.opcodes.sget_char.d.T_sget_char_14.i1 Ljava/lang/Object;
- return-void
-.end method
-
-
diff --git a/tools/vm-tests-tf/src/dot/junit/opcodes/sget_char/d/T_sget_char_9.d.done b/tools/vm-tests-tf/src/dot/junit/opcodes/sget_char/d/T_sget_char_9.d.done
deleted file mode 100644
index cbb4a54..0000000
--- a/tools/vm-tests-tf/src/dot/junit/opcodes/sget_char/d/T_sget_char_9.d.done
+++ /dev/null
@@ -1,53 +0,0 @@
-; 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.
-
-.source StubInitError.java
-.class public dot.junit.opcodes.sget_char.d.StubInitError
-.super java/lang/Object
-
-.field public static value C
-
-.method static <clinit>()V
-.limit regs 2
-
- const/4 v0, 0
- const/4 v1, 1
- div-int/2addr v1, v0
-
- const v1, 1
- sput-char v1, dot.junit.opcodes.sget_char.d.StubInitError.value C
- return-void
-.end method
-
-
-.source T_sget_char_9.java
-.class public dot.junit.opcodes.sget_char.d.T_sget_char_9
-.super java/lang/Object
-
-
-.method public <init>()V
-.limit regs 1
-
- invoke-direct {v0}, java/lang/Object/<init>()V
- return-void
-.end method
-
-.method public run()C
-.limit regs 3
-
- sget-char v1, dot.junit.opcodes.sget_char.d.StubInitError.value C
- return v1
-.end method
-
-
diff --git a/tools/vm-tests-tf/src/dot/junit/opcodes/sget_object/d/T_sget_object_1.d.done b/tools/vm-tests-tf/src/dot/junit/opcodes/sget_object/d/T_sget_object_1.d.done
deleted file mode 100644
index e77f532..0000000
--- a/tools/vm-tests-tf/src/dot/junit/opcodes/sget_object/d/T_sget_object_1.d.done
+++ /dev/null
@@ -1,51 +0,0 @@
-; 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.
-
-.source T_sget_object_1.java
-.class public dot.junit.opcodes.sget_object.d.T_sget_object_1
-.super java/lang/Object
-
-.field public static i1 Ljava/lang/Object;
-.field protected static p1 Ljava/lang/Object;
-.field private static pvt1 Ljava/lang/Object;
-
-.method static <clinit>()V
-.limit regs 1
- const v0, 0
- sput-object v0, dot.junit.opcodes.sget_object.d.T_sget_object_1.i1 Ljava/lang/Object;
-
- const v0, 0
- sput-object v0, dot.junit.opcodes.sget_object.d.T_sget_object_1.p1 Ljava/lang/Object;
-
- const v0, 0
- sput-object v0, dot.junit.opcodes.sget_object.d.T_sget_object_1.pvt1 Ljava/lang/Object;
-
- return-void
-.end method
-
-.method public <init>()V
-.limit regs 1
-
- invoke-direct {v0}, java/lang/Object/<init>()V
- return-void
-.end method
-
-.method public run()Ljava/lang/Object;
-.limit regs 3
-
- sget-object v1, dot.junit.opcodes.sget_object.d.T_sget_object_1.i1 Ljava/lang/Object;
- return-object v1
-.end method
-
-
diff --git a/tools/vm-tests-tf/src/dot/junit/opcodes/sget_object/d/T_sget_object_21.d.done b/tools/vm-tests-tf/src/dot/junit/opcodes/sget_object/d/T_sget_object_21.d.done
deleted file mode 100644
index ddb0713..0000000
--- a/tools/vm-tests-tf/src/dot/junit/opcodes/sget_object/d/T_sget_object_21.d.done
+++ /dev/null
@@ -1,45 +0,0 @@
-; 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.
-
-.source T_sget_object_21.java
-.class public dot.junit.opcodes.sget_object.d.T_sget_object_21
-.super java/lang/Object
-
-.field public static i1 Ljava/lang/Object;
-
-.method static <clinit>()V
-.limit regs 1
- new-instance v0, java/lang/Object
- invoke-direct {v0}, java/lang/Object/<init>()V
-
- sput-object v0, dot.junit.opcodes.sget_object.d.T_sget_object_21.i1 Ljava/lang/Object;
-
- return-void
-.end method
-
-.method public <init>()V
-.limit regs 1
-
- invoke-direct {v0}, java/lang/Object/<init>()V
- return-void
-.end method
-
-.method public run()Ljava/lang/String;
-.limit regs 3
-
- sget-object v1, dot.junit.opcodes.sget_object.d.T_sget_object_21.i1 Ljava/lang/String;
- return-object v1
-.end method
-
-
diff --git a/tools/vm-tests-tf/src/dot/junit/opcodes/sget_object/d/T_sget_object_3.d.done b/tools/vm-tests-tf/src/dot/junit/opcodes/sget_object/d/T_sget_object_3.d.done
deleted file mode 100644
index 498a01a..0000000
--- a/tools/vm-tests-tf/src/dot/junit/opcodes/sget_object/d/T_sget_object_3.d.done
+++ /dev/null
@@ -1,35 +0,0 @@
-; 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.
-
-.source T_sget_object_3.java
-.class public dot.junit.opcodes.sget_object.d.T_sget_object_3
-.super java/lang/Object
-
-.field public static i1 Ljava/lang/Object;
-
-.method public <init>()V
-.limit regs 1
-
- invoke-direct {v0}, java/lang/Object/<init>()V
- return-void
-.end method
-
-.method public run()V
-.limit regs 3
-
- sget-object v3, dot.junit.opcodes.sget_object.d.T_sget_object_3.i1 Ljava/lang/Object;
- return-void
-.end method
-
-
diff --git a/tools/vm-tests-tf/src/dot/junit/opcodes/sget_object/d/T_sget_object_4.d.done b/tools/vm-tests-tf/src/dot/junit/opcodes/sget_object/d/T_sget_object_4.d.done
deleted file mode 100644
index d00c4a0..0000000
--- a/tools/vm-tests-tf/src/dot/junit/opcodes/sget_object/d/T_sget_object_4.d.done
+++ /dev/null
@@ -1,35 +0,0 @@
-; 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.
-
-.source T_sget_object_4.java
-.class public dot.junit.opcodes.sget_object.d.T_sget_object_4
-.super java/lang/Object
-
-.field public static i1 Ljava/lang/Object;
-
-.method public <init>()V
-.limit regs 1
-
- invoke-direct {v0}, java/lang/Object/<init>()V
- return-void
-.end method
-
-.method public run()Ljava/lang/Object;
-.limit regs 3
-
- sget-object v1, dot.junit.opcodes.sget_object.d.T_sget_object_4.i1 Ljava/lang/Object;
- return-object v1
-.end method
-
-
diff --git a/tools/vm-tests-tf/src/dot/junit/opcodes/sget_object/d/T_sget_object_5.d.done b/tools/vm-tests-tf/src/dot/junit/opcodes/sget_object/d/T_sget_object_5.d.done
deleted file mode 100644
index 35687ab..0000000
--- a/tools/vm-tests-tf/src/dot/junit/opcodes/sget_object/d/T_sget_object_5.d.done
+++ /dev/null
@@ -1,38 +0,0 @@
-; 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.
-
-.source T_sget_object_5.java
-.class public dot.junit.opcodes.sget_object.d.T_sget_object_5
-.super java/lang/Object
-
-.field public i1 Ljava/lang/Object;
-
-.method public <init>()V
-.limit regs 4
-
- invoke-direct {v3}, java/lang/Object/<init>()V
-
- const v2, 0
- iput-object v2, v3, dot.junit.opcodes.sget_object.d.T_sget_object_5.i1 Ljava/lang/Object;
- return-void
-.end method
-
-.method public run()Ljava/lang/Object;
-.limit regs 3
-
- sget-object v1, dot.junit.opcodes.sget_object.d.T_sget_object_5.i1 Ljava/lang/Object;
- return-object v1
-.end method
-
-
diff --git a/tools/vm-tests-tf/src/dot/junit/opcodes/sget_object/d/T_sget_object_9.d.done b/tools/vm-tests-tf/src/dot/junit/opcodes/sget_object/d/T_sget_object_9.d.done
deleted file mode 100644
index efd184b..0000000
--- a/tools/vm-tests-tf/src/dot/junit/opcodes/sget_object/d/T_sget_object_9.d.done
+++ /dev/null
@@ -1,53 +0,0 @@
-; 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.
-
-.source StubInitError.java
-.class public dot.junit.opcodes.sget_object.d.StubInitError
-.super java/lang/Object
-
-.field public static value Ljava/lang/Object;
-
-.method static <clinit>()V
-.limit regs 2
-
- const/4 v0, 0
- const/4 v1, 1
- div-int/2addr v1, v0
-
- const v1, 0
- sput-object v1, dot.junit.opcodes.sget_object.d.StubInitError.value Ljava/lang/Object;
- return-void
-.end method
-
-
-.source T_sget_object_9.java
-.class public dot.junit.opcodes.sget_object.d.T_sget_object_9
-.super java/lang/Object
-
-
-.method public <init>()V
-.limit regs 1
-
- invoke-direct {v0}, java/lang/Object/<init>()V
- return-void
-.end method
-
-.method public run()Ljava/lang/Object;
-.limit regs 3
-
- sget-object v1, dot.junit.opcodes.sget_object.d.StubInitError.value Ljava/lang/Object;
- return-object v1
-.end method
-
-
diff --git a/tools/vm-tests-tf/src/dot/junit/opcodes/sget_short/d/T_sget_short_14.d.done b/tools/vm-tests-tf/src/dot/junit/opcodes/sget_short/d/T_sget_short_14.d.done
deleted file mode 100644
index 3d79cd1..0000000
--- a/tools/vm-tests-tf/src/dot/junit/opcodes/sget_short/d/T_sget_short_14.d.done
+++ /dev/null
@@ -1,35 +0,0 @@
-; 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.
-
-.source T_sget_short_14.java
-.class public dot.junit.opcodes.sget_short.d.T_sget_short_14
-.super java/lang/Object
-
-.field public static i1 Ljava/lang/Object;
-
-.method public <init>()V
-.limit regs 1
-
- invoke-direct {v0}, java/lang/Object/<init>()V
- return-void
-.end method
-
-.method public run()V
-.limit regs 3
-
- sget-short v0, dot.junit.opcodes.sget_short.d.T_sget_short_14.i1 Ljava/lang/Object;
- return-void
-.end method
-
-
diff --git a/tools/vm-tests-tf/src/dot/junit/opcodes/sget_short/d/T_sget_short_9.d.done b/tools/vm-tests-tf/src/dot/junit/opcodes/sget_short/d/T_sget_short_9.d.done
deleted file mode 100644
index 85d6755..0000000
--- a/tools/vm-tests-tf/src/dot/junit/opcodes/sget_short/d/T_sget_short_9.d.done
+++ /dev/null
@@ -1,53 +0,0 @@
-; 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.
-
-.source StubInitError.java
-.class public dot.junit.opcodes.sget_short.d.StubInitError
-.super java/lang/Object
-
-.field public static value S
-
-.method static <clinit>()V
-.limit regs 2
-
- const/4 v0, 0
- const/4 v1, 1
- div-int/2addr v1, v0
-
- const v1, 1
- sput-short v1, dot.junit.opcodes.sget_short.d.StubInitError.value S
- return-void
-.end method
-
-
-.source T_sget_short_9.java
-.class public dot.junit.opcodes.sget_short.d.T_sget_short_9
-.super java/lang/Object
-
-
-.method public <init>()V
-.limit regs 1
-
- invoke-direct {v0}, java/lang/Object/<init>()V
- return-void
-.end method
-
-.method public run()S
-.limit regs 3
-
- sget-short v1, dot.junit.opcodes.sget_short.d.StubInitError.value S
- return v1
-.end method
-
-
diff --git a/tools/vm-tests-tf/src/dot/junit/opcodes/sget_wide/d/T_sget_wide_1.d.done b/tools/vm-tests-tf/src/dot/junit/opcodes/sget_wide/d/T_sget_wide_1.d.done
deleted file mode 100644
index ffd5cb4..0000000
--- a/tools/vm-tests-tf/src/dot/junit/opcodes/sget_wide/d/T_sget_wide_1.d.done
+++ /dev/null
@@ -1,51 +0,0 @@
-; 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.
-
-.source T_sget_wide_1.java
-.class public dot.junit.opcodes.sget_wide.d.T_sget_wide_1
-.super java/lang/Object
-
-.field public static i1 J
-.field protected static p1 J
-.field private static pvt1 J
-
-.method static <clinit>()V
-.limit regs 2
- const-wide v0, 12345679890123
- sput-wide v0, dot.junit.opcodes.sget_wide.d.T_sget_wide_1.i1 J
-
- const-wide v0, 10
- sput-wide v0, dot.junit.opcodes.sget_wide.d.T_sget_wide_1.p1 J
-
- const-wide v0, 20
- sput-wide v0, dot.junit.opcodes.sget_wide.d.T_sget_wide_1.pvt1 J
-
- return-void
-.end method
-
-.method public <init>()V
-.limit regs 1
-
- invoke-direct {v0}, java/lang/Object/<init>()V
- return-void
-.end method
-
-.method public run()J
-.limit regs 3
-
- sget-wide v1, dot.junit.opcodes.sget_wide.d.T_sget_wide_1.i1 J
- return-wide v1
-.end method
-
-
diff --git a/tools/vm-tests-tf/src/dot/junit/opcodes/sget_wide/d/T_sget_wide_14.d.done b/tools/vm-tests-tf/src/dot/junit/opcodes/sget_wide/d/T_sget_wide_14.d.done
deleted file mode 100644
index 6e32d54..0000000
--- a/tools/vm-tests-tf/src/dot/junit/opcodes/sget_wide/d/T_sget_wide_14.d.done
+++ /dev/null
@@ -1,35 +0,0 @@
-; 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.
-
-.source T_sget_wide_14.java
-.class public dot.junit.opcodes.sget_wide.d.T_sget_wide_14
-.super java/lang/Object
-
-.field public static i1 Ljava/lang/Object;
-
-.method public <init>()V
-.limit regs 1
-
- invoke-direct {v0}, java/lang/Object/<init>()V
- return-void
-.end method
-
-.method public run()V
-.limit regs 3
-
- sget-wide v0, dot.junit.opcodes.sget_wide.d.T_sget_wide_14.i1 Ljava/lang/Object;
- return-void
-.end method
-
-
diff --git a/tools/vm-tests-tf/src/dot/junit/opcodes/sget_wide/d/T_sget_wide_9.d.done b/tools/vm-tests-tf/src/dot/junit/opcodes/sget_wide/d/T_sget_wide_9.d.done
deleted file mode 100644
index e223578..0000000
--- a/tools/vm-tests-tf/src/dot/junit/opcodes/sget_wide/d/T_sget_wide_9.d.done
+++ /dev/null
@@ -1,53 +0,0 @@
-; 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.
-
-.source StubInitError.java
-.class public dot.junit.opcodes.sget_wide.d.StubInitError
-.super java/lang/Object
-
-.field public static value J
-
-.method static <clinit>()V
-.limit regs 2
-
- const/4 v0, 0
- const/4 v1, 5
- div-int/2addr v1, v0
-
- const-wide v0, 1
- sput-wide v0, dot.junit.opcodes.sget_wide.d.StubInitError.value J
- return-void
-.end method
-
-
-.source T_sget_wide_9.java
-.class public dot.junit.opcodes.sget_wide.d.T_sget_wide_9
-.super java/lang/Object
-
-
-.method public <init>()V
-.limit regs 1
-
- invoke-direct {v0}, java/lang/Object/<init>()V
- return-void
-.end method
-
-.method public run()J
-.limit regs 3
-
- sget-wide v1, dot.junit.opcodes.sget_wide.d.StubInitError.value J
- return-wide v1
-.end method
-
-
diff --git a/tools/vm-tests-tf/src/dot/junit/opcodes/sparse_switch/d/T_sparse_switch_1.d.done b/tools/vm-tests-tf/src/dot/junit/opcodes/sparse_switch/d/T_sparse_switch_1.d.done
deleted file mode 100644
index bd3aaa5..0000000
--- a/tools/vm-tests-tf/src/dot/junit/opcodes/sparse_switch/d/T_sparse_switch_1.d.done
+++ /dev/null
@@ -1,47 +0,0 @@
-; 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.
-
-.source T_sparse_switch_1.java
-.class public dot.junit.opcodes.sparse_switch.d.T_sparse_switch_1
-.super java/lang/Object
-
-
-.method public <init>()V
-.limit regs 1
-
- invoke-direct {v0}, java/lang/Object/<init>()V
- return-void
-.end method
-
-.method public run(I)I
-.limit regs 5
-
- sparse-switch v4
- -1 : Label9
- 10 : Label12
- 15 : Label12
- sparse-switch-end
-Label6:
- const v4, -1
- return v4
-
-Label9:
- const v4, 2
- return v4
-
-Label12:
- const v4, 20
- return v4
-
-.end method
diff --git a/tools/vm-tests-tf/src/dot/junit/opcodes/sparse_switch/d/T_sparse_switch_11.d.done b/tools/vm-tests-tf/src/dot/junit/opcodes/sparse_switch/d/T_sparse_switch_11.d.done
deleted file mode 100644
index 5853adb..0000000
--- a/tools/vm-tests-tf/src/dot/junit/opcodes/sparse_switch/d/T_sparse_switch_11.d.done
+++ /dev/null
@@ -1,47 +0,0 @@
-; 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.
-
-.source T_sparse_switch_11.java
-.class public dot.junit.opcodes.sparse_switch.d.T_sparse_switch_11
-.super java/lang/Object
-
-
-.method public <init>()V
-.limit regs 1
-
- invoke-direct {v0}, java/lang/Object/<init>()V
- return-void
-.end method
-
-.method public run(I)I
-.limit regs 5
-
- sparse-switch v4
- -1 : Label9
- 10 : Label12
- 15 : Label12
- sparse-switch-end
-Label6:
- const v4, -1
- return v4
-
-Label9:
- const v4, 2
- return v4
-
-Label12:
- const v4, 20
- return v4
-
-.end method
diff --git a/tools/vm-tests-tf/src/dot/junit/opcodes/sparse_switch/d/T_sparse_switch_12.d.done b/tools/vm-tests-tf/src/dot/junit/opcodes/sparse_switch/d/T_sparse_switch_12.d.done
deleted file mode 100644
index feff623..0000000
--- a/tools/vm-tests-tf/src/dot/junit/opcodes/sparse_switch/d/T_sparse_switch_12.d.done
+++ /dev/null
@@ -1,46 +0,0 @@
-; 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.
-
-.source T_sparse_switch_12.java
-.class public dot.junit.opcodes.sparse_switch.d.T_sparse_switch_12
-.super java/lang/Object
-
-.method public <init>()V
-.limit regs 1
-
- invoke-direct {v0}, java/lang/Object/<init>()V
- return-void
-.end method
-
-.method public run(I)I
-.limit regs 5
-
- sparse-switch v4
- -1 : Label9
- 10 : Label12
- 15 : Label12
- sparse-switch-end
-Label6:
- const v4, -1
- return v4
-
-Label9:
- const v4, 2
- return v4
-
-Label12:
- const v4, 20
- return v4
-
-.end method
diff --git a/tools/vm-tests-tf/src/dot/junit/opcodes/sparse_switch/d/T_sparse_switch_13.d.done b/tools/vm-tests-tf/src/dot/junit/opcodes/sparse_switch/d/T_sparse_switch_13.d.done
deleted file mode 100644
index 8c7814d..0000000
--- a/tools/vm-tests-tf/src/dot/junit/opcodes/sparse_switch/d/T_sparse_switch_13.d.done
+++ /dev/null
@@ -1,47 +0,0 @@
-; 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.
-
-.source T_sparse_switch_13.java
-.class public dot.junit.opcodes.sparse_switch.d.T_sparse_switch_13
-.super java/lang/Object
-
-.method public <init>()V
-.limit regs 1
-
- invoke-direct {v0}, java/lang/Object/<init>()V
- return-void
-.end method
-
-.method public run(I)I
-.limit regs 5
-
- goto Label0
- sparse-switch v4
- -1 : Label9
- 10 : Label12
- 15 : Label12
- sparse-switch-end
-Label6:
- const v4, -1
- return v4
-
-Label9:
- const v4, 2
- return v4
-
-Label12:
- const v4, 20
- return v4
-Label0:
-.end method
diff --git a/tools/vm-tests-tf/src/dot/junit/opcodes/sparse_switch/d/T_sparse_switch_14.d.done b/tools/vm-tests-tf/src/dot/junit/opcodes/sparse_switch/d/T_sparse_switch_14.d.done
deleted file mode 100644
index 074c119..0000000
--- a/tools/vm-tests-tf/src/dot/junit/opcodes/sparse_switch/d/T_sparse_switch_14.d.done
+++ /dev/null
@@ -1,48 +0,0 @@
-; 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.
-
-.source T_sparse_switch_14.java
-.class public dot.junit.opcodes.sparse_switch.d.T_sparse_switch_14
-.super java/lang/Object
-
-.method public <init>()V
-.limit regs 1
-
- invoke-direct {v0}, java/lang/Object/<init>()V
- return-void
-.end method
-
-.method public run(I)I
-.limit regs 5
-
- goto Label0
-Label0:
- sparse-switch v4
- -1 : Label9
- 10 : Label12
- 15 : Label12
- sparse-switch-end
-Label6:
- const v4, -1
- return v4
-
-Label9:
- const v4, 2
- return v4
-
-Label12:
- const v4, 20
- return v4
-
-.end method
diff --git a/tools/vm-tests-tf/src/dot/junit/opcodes/sparse_switch/d/T_sparse_switch_2.d.done b/tools/vm-tests-tf/src/dot/junit/opcodes/sparse_switch/d/T_sparse_switch_2.d.done
deleted file mode 100644
index 0f8b90b..0000000
--- a/tools/vm-tests-tf/src/dot/junit/opcodes/sparse_switch/d/T_sparse_switch_2.d.done
+++ /dev/null
@@ -1,50 +0,0 @@
-; 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.
-
-.source T_sparse_switch_2.java
-.class public dot.junit.opcodes.sparse_switch.d.T_sparse_switch_2
-.super java/lang/Object
-
-
-.method public <init>()V
-.limit regs 1
-
- invoke-direct {v0}, java/lang/Object/<init>()V
- return-void
-.end method
-
-.method public run(F)I
-.limit regs 5
-
-Label3:
- sparse-switch v4
- -1 : Label9
- 10 : Label12
- 15 : Label12
- sparse-switch-end
-Label6:
- const v4, -1
- return v4
-
-Label9:
- const v4, 2
- return v4
-
-Label12:
- const v4, 20
- return v4
-
-.end method
-
-
diff --git a/tools/vm-tests-tf/src/dot/junit/opcodes/sparse_switch/d/T_sparse_switch_3.d.done b/tools/vm-tests-tf/src/dot/junit/opcodes/sparse_switch/d/T_sparse_switch_3.d.done
deleted file mode 100644
index ce82bc9..0000000
--- a/tools/vm-tests-tf/src/dot/junit/opcodes/sparse_switch/d/T_sparse_switch_3.d.done
+++ /dev/null
@@ -1,48 +0,0 @@
-; 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.
-
-.source T_sparse_switch_3.java
-.class public dot.junit.opcodes.sparse_switch.d.T_sparse_switch_3
-.super java/lang/Object
-
-
-.method public <init>()V
-.limit regs 1
-
- invoke-direct {v0}, java/lang/Object/<init>()V
- return-void
-.end method
-
-.method public run(I)I
-.limit regs 5
-
-Label3:
- sparse-switch v5
- -1 : Label9
- 10 : Label12
- 15 : Label12
- sparse-switch-end
-Label6:
- const v4, -1
- return v4
-
-Label9:
- const v4, 2
- return v4
-
-Label12:
- const v4, 20
- return v4
-
-.end method
diff --git a/tools/vm-tests-tf/src/dot/junit/opcodes/sparse_switch/d/T_sparse_switch_4.d.done b/tools/vm-tests-tf/src/dot/junit/opcodes/sparse_switch/d/T_sparse_switch_4.d.done
deleted file mode 100644
index 36f8c8b..0000000
--- a/tools/vm-tests-tf/src/dot/junit/opcodes/sparse_switch/d/T_sparse_switch_4.d.done
+++ /dev/null
@@ -1,48 +0,0 @@
-; 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.
-
-.source T_sparse_switch_4.java
-.class public dot.junit.opcodes.sparse_switch.d.T_sparse_switch_4
-.super java/lang/Object
-
-
-.method public <init>()V
-.limit regs 1
-
- invoke-direct {v0}, java/lang/Object/<init>()V
- return-void
-.end method
-
-.method public run(D)I
-.limit regs 5
-
-Label3:
- sparse-switch v3
- -1 : Label9
- 10 : Label12
- 15 : Label12
- sparse-switch-end
-Label6:
- const v4, -1
- return v4
-
-Label9:
- const v4, 2
- return v4
-
-Label12:
- const v4, 20
- return v4
-
-.end method
diff --git a/tools/vm-tests-tf/src/dot/junit/opcodes/sparse_switch/d/T_sparse_switch_5.d.done b/tools/vm-tests-tf/src/dot/junit/opcodes/sparse_switch/d/T_sparse_switch_5.d.done
deleted file mode 100644
index dc72c30..0000000
--- a/tools/vm-tests-tf/src/dot/junit/opcodes/sparse_switch/d/T_sparse_switch_5.d.done
+++ /dev/null
@@ -1,48 +0,0 @@
-; 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.
-
-.source T_sparse_switch_5.java
-.class public dot.junit.opcodes.sparse_switch.d.T_sparse_switch_5
-.super java/lang/Object
-
-
-.method public <init>()V
-.limit regs 1
-
- invoke-direct {v0}, java/lang/Object/<init>()V
- return-void
-.end method
-
-.method public run(J)I
-.limit regs 5
-
-Label3:
- sparse-switch v3
- -1 : Label9
- 10 : Label12
- 15 : Label12
- sparse-switch-end
-Label6:
- const v4, -1
- return v4
-
-Label9:
- const v4, 2
- return v4
-
-Label12:
- const v4, 20
- return v4
-
-.end method
diff --git a/tools/vm-tests-tf/src/dot/junit/opcodes/sparse_switch/d/T_sparse_switch_6.d.done b/tools/vm-tests-tf/src/dot/junit/opcodes/sparse_switch/d/T_sparse_switch_6.d.done
deleted file mode 100644
index 25e418f..0000000
--- a/tools/vm-tests-tf/src/dot/junit/opcodes/sparse_switch/d/T_sparse_switch_6.d.done
+++ /dev/null
@@ -1,48 +0,0 @@
-; 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.
-
-.source T_sparse_switch_6.java
-.class public dot.junit.opcodes.sparse_switch.d.T_sparse_switch_6
-.super java/lang/Object
-
-
-.method public <init>()V
-.limit regs 1
-
- invoke-direct {v0}, java/lang/Object/<init>()V
- return-void
-.end method
-
-.method public run(I)I
-.limit regs 5
-
-Label3:
- sparse-switch v3
- -1 : Label9
- 10 : Label12
- 15 : Label12
- sparse-switch-end
-Label6:
- const v4, -1
- return v4
-
-Label9:
- const v4, 2
- return v4
-
-Label12:
- const v4, 20
- return v4
-
-.end method
diff --git a/tools/vm-tests-tf/src/dot/junit/opcodes/sparse_switch/d/T_sparse_switch_7.d.done b/tools/vm-tests-tf/src/dot/junit/opcodes/sparse_switch/d/T_sparse_switch_7.d.done
deleted file mode 100644
index 67f3328..0000000
--- a/tools/vm-tests-tf/src/dot/junit/opcodes/sparse_switch/d/T_sparse_switch_7.d.done
+++ /dev/null
@@ -1,47 +0,0 @@
-; 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.
-
-.source T_sparse_switch_7.java
-.class public dot.junit.opcodes.sparse_switch.d.T_sparse_switch_7
-.super java/lang/Object
-
-
-.method public <init>()V
-.limit regs 1
-
- invoke-direct {v0}, java/lang/Object/<init>()V
- return-void
-.end method
-
-.method public run(I)I
-.limit regs 5
-
- sparse-switch v4
- -1 : Label9
- 10 : Label12
- 15 : Label12
- sparse-switch-end
-Label6:
- const v4, -1
- return v4
-
-Label9:
- const v4, 2
- return v4
-
-Label12:
- const v4, 20
- return v4
-
-.end method
diff --git a/tools/vm-tests-tf/src/dot/junit/opcodes/sparse_switch/d/T_sparse_switch_8.d.done b/tools/vm-tests-tf/src/dot/junit/opcodes/sparse_switch/d/T_sparse_switch_8.d.done
deleted file mode 100644
index ba0dae3..0000000
--- a/tools/vm-tests-tf/src/dot/junit/opcodes/sparse_switch/d/T_sparse_switch_8.d.done
+++ /dev/null
@@ -1,47 +0,0 @@
-; 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.
-
-.source T_sparse_switch_8.java
-.class public dot.junit.opcodes.sparse_switch.d.T_sparse_switch_8
-.super java/lang/Object
-
-
-.method public <init>()V
-.limit regs 1
-
- invoke-direct {v0}, java/lang/Object/<init>()V
- return-void
-.end method
-
-.method public run(I)I
-.limit regs 5
-
- sparse-switch v4
- -1 : Label9
- 10 : Label12
- 15 : Label12
- sparse-switch-end
-Label6:
- const v4, -1
- return v4
-
-Label9:
- const v4, 2
- return v4
-
-Label12:
- const v4, 20
- return v4
-
-.end method
diff --git a/tools/vm-tests-tf/src/dot/junit/opcodes/sparse_switch/d/T_sparse_switch_9.d.done b/tools/vm-tests-tf/src/dot/junit/opcodes/sparse_switch/d/T_sparse_switch_9.d.done
deleted file mode 100644
index 2566813..0000000
--- a/tools/vm-tests-tf/src/dot/junit/opcodes/sparse_switch/d/T_sparse_switch_9.d.done
+++ /dev/null
@@ -1,47 +0,0 @@
-; 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.
-
-.source T_sparse_switch_9.java
-.class public dot.junit.opcodes.sparse_switch.d.T_sparse_switch_9
-.super java/lang/Object
-
-
-.method public <init>()V
-.limit regs 1
-
- invoke-direct {v0}, java/lang/Object/<init>()V
- return-void
-.end method
-
-.method public run(I)I
-.limit regs 5
-
- sparse-switch v4
- -1 : Label9
- 10 : Label12
- 15 : Label12
- sparse-switch-end
-Label6:
- const v4, -1
- return v4
-
-Label9:
- const v4, 2
- return v4
-
-Label12:
- const v4, 20
- return v4
-
-.end method
diff --git a/tools/vm-tests-tf/src/dot/junit/opcodes/sput/d/T_sput_13.d.done b/tools/vm-tests-tf/src/dot/junit/opcodes/sput/d/T_sput_13.d.done
deleted file mode 100644
index f6c9d9f..0000000
--- a/tools/vm-tests-tf/src/dot/junit/opcodes/sput/d/T_sput_13.d.done
+++ /dev/null
@@ -1,53 +0,0 @@
-; 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.
-
-.source StubInitError.java
-.class public dot.junit.opcodes.sput.d.StubInitError
-.super java/lang/Object
-
-.field public static value I
-
-.method static <clinit>()V
-.limit regs 2
-
- const/4 v0, 0
- const/4 v1, 5
- div-int/2addr v1, v0
-
- sput v1, dot.junit.opcodes.sput.d.StubInitError.value I
- return-void
-.end method
-
-
-.source T_sput_13.java
-.class public dot.junit.opcodes.sput.d.T_sput_13
-.super java/lang/Object
-
-
-.method public <init>()V
-.limit regs 1
-
- invoke-direct {v0}, java/lang/Object/<init>()V
- return-void
-.end method
-
-.method public run()V
-.limit regs 3
-
- const v1, 1000000
- sput v1, dot.junit.opcodes.sput.d.StubInitError.value I
- return-void
-.end method
-
-
diff --git a/tools/vm-tests-tf/src/dot/junit/opcodes/sput/d/T_sput_19.d.done b/tools/vm-tests-tf/src/dot/junit/opcodes/sput/d/T_sput_19.d.done
deleted file mode 100644
index d0f53cf..0000000
--- a/tools/vm-tests-tf/src/dot/junit/opcodes/sput/d/T_sput_19.d.done
+++ /dev/null
@@ -1,38 +0,0 @@
-; 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.
-
-.source T_sput_19.java
-.class public dot.junit.opcodes.sput.d.T_sput_19
-.super java/lang/Object
-
-.field public static st_f1 F
-
-
-.method public <init>()V
-.limit regs 1
-
- invoke-direct {v0}, java/lang/Object/<init>()V
- return-void
-.end method
-
-.method public run()V
-.limit regs 3
-
- const v1, 3.14
- sput v1, dot.junit.opcodes.sput.d.T_sput_19.st_f1 F
-
- return-void
-.end method
-
-
diff --git a/tools/vm-tests-tf/src/dot/junit/opcodes/sput/d/T_sput_20.d.done b/tools/vm-tests-tf/src/dot/junit/opcodes/sput/d/T_sput_20.d.done
deleted file mode 100644
index 9229d34..0000000
--- a/tools/vm-tests-tf/src/dot/junit/opcodes/sput/d/T_sput_20.d.done
+++ /dev/null
@@ -1,36 +0,0 @@
-; 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.
-
-.source T_sput_20.java
-.class public dot.junit.opcodes.sput.d.T_sput_20
-.super java/lang/Object
-
-.field public static st_o Ljava/lang/Object;
-
-.method public <init>()V
-.limit regs 1
-
- invoke-direct {v0}, java/lang/Object/<init>()V
- return-void
-.end method
-
-.method public run()V
-.limit regs 4
-
- const v3, 0
- sput v3, dot.junit.opcodes.sput.d.T_sput_20.st_o Ljava/lang/Object;
- return-void
-.end method
-
-
diff --git a/tools/vm-tests-tf/src/dot/junit/opcodes/sput_boolean/d/T_sput_boolean_13.d.done b/tools/vm-tests-tf/src/dot/junit/opcodes/sput_boolean/d/T_sput_boolean_13.d.done
deleted file mode 100644
index 0f89bc2..0000000
--- a/tools/vm-tests-tf/src/dot/junit/opcodes/sput_boolean/d/T_sput_boolean_13.d.done
+++ /dev/null
@@ -1,53 +0,0 @@
-; 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.
-
-.source StubInitError.java
-.class public dot.junit.opcodes.sput_boolean.d.StubInitError
-.super java/lang/Object
-
-.field public static value Z
-
-.method static <clinit>()V
-.limit regs 2
-
- const/4 v0, 0
- const/4 v1, 5
- div-int/2addr v1, v0
-
- sput-boolean v1, dot.junit.opcodes.sput_boolean.d.StubInitError.value Z
- return-void
-.end method
-
-
-.source T_sput_boolean_13.java
-.class public dot.junit.opcodes.sput_boolean.d.T_sput_boolean_13
-.super java/lang/Object
-
-
-.method public <init>()V
-.limit regs 1
-
- invoke-direct {v0}, java/lang/Object/<init>()V
- return-void
-.end method
-
-.method public run()V
-.limit regs 3
-
- const v1, 1
- sput-boolean v1, dot.junit.opcodes.sput_boolean.d.StubInitError.value Z
- return-void
-.end method
-
-
diff --git a/tools/vm-tests-tf/src/dot/junit/opcodes/sput_boolean/d/T_sput_boolean_19.d.done b/tools/vm-tests-tf/src/dot/junit/opcodes/sput_boolean/d/T_sput_boolean_19.d.done
deleted file mode 100644
index f7922afb..0000000
--- a/tools/vm-tests-tf/src/dot/junit/opcodes/sput_boolean/d/T_sput_boolean_19.d.done
+++ /dev/null
@@ -1,38 +0,0 @@
-; 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.
-
-.source T_sput_boolean_19.java
-.class public dot.junit.opcodes.sput_boolean.d.T_sput_boolean_19
-.super java/lang/Object
-
-.field public static st_f1 F
-
-
-.method public <init>()V
-.limit regs 1
-
- invoke-direct {v0}, java/lang/Object/<init>()V
- return-void
-.end method
-
-.method public run()V
-.limit regs 3
-
- const v1, 3.14
- sput-boolean v1, dot.junit.opcodes.sput_boolean.d.T_sput_boolean_19.st_f1 F
-
- return-void
-.end method
-
-
diff --git a/tools/vm-tests-tf/src/dot/junit/opcodes/sput_boolean/d/T_sput_boolean_20.d.done b/tools/vm-tests-tf/src/dot/junit/opcodes/sput_boolean/d/T_sput_boolean_20.d.done
deleted file mode 100644
index abc0227..0000000
--- a/tools/vm-tests-tf/src/dot/junit/opcodes/sput_boolean/d/T_sput_boolean_20.d.done
+++ /dev/null
@@ -1,36 +0,0 @@
-; 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.
-
-.source T_sput_boolean_20.java
-.class public dot.junit.opcodes.sput_boolean.d.T_sput_boolean_20
-.super java/lang/Object
-
-.field public static st_o Ljava/lang/Object;
-
-.method public <init>()V
-.limit regs 1
-
- invoke-direct {v0}, java/lang/Object/<init>()V
- return-void
-.end method
-
-.method public run()V
-.limit regs 4
-
- const v3, 0
- sput-boolean v3, dot.junit.opcodes.sput_boolean.d.T_sput_boolean_20.st_o Ljava/lang/Object;
- return-void
-.end method
-
-
diff --git a/tools/vm-tests-tf/src/dot/junit/opcodes/sput_byte/d/T_sput_byte_13.d.done b/tools/vm-tests-tf/src/dot/junit/opcodes/sput_byte/d/T_sput_byte_13.d.done
deleted file mode 100644
index 2271ca2..0000000
--- a/tools/vm-tests-tf/src/dot/junit/opcodes/sput_byte/d/T_sput_byte_13.d.done
+++ /dev/null
@@ -1,53 +0,0 @@
-; 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.
-
-.source StubInitError.java
-.class public dot.junit.opcodes.sput_byte.d.StubInitError
-.super java/lang/Object
-
-.field public static value B
-
-.method static <clinit>()V
-.limit regs 2
-
- const/4 v0, 0
- const/4 v1, 5
- div-int/2addr v1, v0
-
- sput-byte v1, dot.junit.opcodes.sput_byte.d.StubInitError.value B
- return-void
-.end method
-
-
-.source T_sput_byte_13.java
-.class public dot.junit.opcodes.sput_byte.d.T_sput_byte_13
-.super java/lang/Object
-
-
-.method public <init>()V
-.limit regs 1
-
- invoke-direct {v0}, java/lang/Object/<init>()V
- return-void
-.end method
-
-.method public run()V
-.limit regs 3
-
- const v1, 1
- sput-byte v1, dot.junit.opcodes.sput_byte.d.StubInitError.value B
- return-void
-.end method
-
-
diff --git a/tools/vm-tests-tf/src/dot/junit/opcodes/sput_byte/d/T_sput_byte_20.d.done b/tools/vm-tests-tf/src/dot/junit/opcodes/sput_byte/d/T_sput_byte_20.d.done
deleted file mode 100644
index 9a77ec6..0000000
--- a/tools/vm-tests-tf/src/dot/junit/opcodes/sput_byte/d/T_sput_byte_20.d.done
+++ /dev/null
@@ -1,35 +0,0 @@
-; 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.
-
-.source T_sput_byte_20.java
-.class public dot.junit.opcodes.sput_byte.d.T_sput_byte_20
-.super java/lang/Object
-
-.field public static st_o Ljava/lang/Object;
-
-.method public <init>()V
-.limit regs 1
-
- invoke-direct {v0}, java/lang/Object/<init>()V
- return-void
-.end method
-
-.method public run()V
-.limit regs 4
-
- sput-byte v3, dot.junit.opcodes.sput_byte.d.T_sput_byte_20.st_o Ljava/lang/Object;
- return-void
-.end method
-
-
diff --git a/tools/vm-tests-tf/src/dot/junit/opcodes/sput_char/d/T_sput_char_13.d.done b/tools/vm-tests-tf/src/dot/junit/opcodes/sput_char/d/T_sput_char_13.d.done
deleted file mode 100644
index 5b97bc4..0000000
--- a/tools/vm-tests-tf/src/dot/junit/opcodes/sput_char/d/T_sput_char_13.d.done
+++ /dev/null
@@ -1,53 +0,0 @@
-; 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.
-
-.source StubInitError.java
-.class public dot.junit.opcodes.sput_char.d.StubInitError
-.super java/lang/Object
-
-.field public static value C
-
-.method static <clinit>()V
-.limit regs 2
-
- const/4 v0, 0
- const/4 v1, 5
- div-int/2addr v1, v0
-
- sput-char v1, dot.junit.opcodes.sput_char.d.StubInitError.value C
- return-void
-.end method
-
-
-.source T_sput_char_13.java
-.class public dot.junit.opcodes.sput_char.d.T_sput_char_13
-.super java/lang/Object
-
-
-.method public <init>()V
-.limit regs 1
-
- invoke-direct {v0}, java/lang/Object/<init>()V
- return-void
-.end method
-
-.method public run()V
-.limit regs 3
-
- const v1, 1
- sput-char v1, dot.junit.opcodes.sput_char.d.StubInitError.value C
- return-void
-.end method
-
-
diff --git a/tools/vm-tests-tf/src/dot/junit/opcodes/sput_char/d/T_sput_char_20.d.done b/tools/vm-tests-tf/src/dot/junit/opcodes/sput_char/d/T_sput_char_20.d.done
deleted file mode 100644
index 92d2e6e..0000000
--- a/tools/vm-tests-tf/src/dot/junit/opcodes/sput_char/d/T_sput_char_20.d.done
+++ /dev/null
@@ -1,35 +0,0 @@
-; 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.
-
-.source T_sput_char_20.java
-.class public dot.junit.opcodes.sput_char.d.T_sput_char_20
-.super java/lang/Object
-
-.field public static st_o Ljava/lang/Object;
-
-.method public <init>()V
-.limit regs 1
-
- invoke-direct {v0}, java/lang/Object/<init>()V
- return-void
-.end method
-
-.method public run()V
-.limit regs 4
-
- sput-char v3, dot.junit.opcodes.sput_char.d.T_sput_char_20.st_o Ljava/lang/Object;
- return-void
-.end method
-
-
diff --git a/tools/vm-tests-tf/src/dot/junit/opcodes/sput_object/d/T_sput_object_1.d.done b/tools/vm-tests-tf/src/dot/junit/opcodes/sput_object/d/T_sput_object_1.d.done
deleted file mode 100644
index acb4903..0000000
--- a/tools/vm-tests-tf/src/dot/junit/opcodes/sput_object/d/T_sput_object_1.d.done
+++ /dev/null
@@ -1,45 +0,0 @@
-; 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.
-
-.source T_sput_object_1.java
-.class public dot.junit.opcodes.sput_object.d.T_sput_object_1
-.super java/lang/Object
-
-.field public static st_i1 Ljava/lang/Object;
-.field protected static st_p1 Ljava/lang/Object;
-.field private static st_pvt1 Ljava/lang/Object;
-
-.method public <init>()V
-.limit regs 1
-
- invoke-direct {v0}, java/lang/Object/<init>()V
- return-void
-.end method
-
-.method public static getPvtField()Ljava/lang/Object;
-.limit regs 2
-
- sget-object v0, dot.junit.opcodes.sput_object.d.T_sput_object_1.st_pvt1 Ljava/lang/Object;
- return-object v0
-.end method
-
-.method public run()V
-.limit regs 3
-
- sput-object v2, dot.junit.opcodes.sput_object.d.T_sput_object_1.st_i1 Ljava/lang/Object;
-
- return-void
-.end method
-
-
diff --git a/tools/vm-tests-tf/src/dot/junit/opcodes/sput_object/d/T_sput_object_10.d.done b/tools/vm-tests-tf/src/dot/junit/opcodes/sput_object/d/T_sput_object_10.d.done
deleted file mode 100644
index 7f12b99..0000000
--- a/tools/vm-tests-tf/src/dot/junit/opcodes/sput_object/d/T_sput_object_10.d.done
+++ /dev/null
@@ -1,35 +0,0 @@
-; 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.
-
-.source T_sput_object_10.java
-.class public dot.junit.opcodes.sput_object.d.T_sput_object_10
-.super java/lang/Object
-
-.field public st_i1 Ljava/lang/Object;
-
-.method public <init>()V
-.limit regs 1
-
- invoke-direct {v0}, java/lang/Object/<init>()V
- return-void
-.end method
-
-.method public run()V
-.limit regs 3
-
- sput-object v2, dot.junit.opcodes.sput_object.d.T_sput_object_10.st_i1N Ljava/lang/Object;
- return-void
-.end method
-
-
diff --git a/tools/vm-tests-tf/src/dot/junit/opcodes/sput_object/d/T_sput_object_12.d.done b/tools/vm-tests-tf/src/dot/junit/opcodes/sput_object/d/T_sput_object_12.d.done
deleted file mode 100644
index 562d8edb..0000000
--- a/tools/vm-tests-tf/src/dot/junit/opcodes/sput_object/d/T_sput_object_12.d.done
+++ /dev/null
@@ -1,35 +0,0 @@
-; 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.
-
-.source T_sput_object_12.java
-.class public dot.junit.opcodes.sput_object.d.T_sput_object_12
-.super java/lang/Object
-
-.field public static final st_i1 Ljava/lang/Object;
-
-.method public <init>()V
-.limit regs 1
-
- invoke-direct {v0}, java/lang/Object/<init>()V
- return-void
-.end method
-
-.method public run()V
-.limit regs 3
-
- sput-object v2, dot.junit.opcodes.sput_object.d.T_sput_object_12.st_i1 Ljava/lang/Object;
- return-void
-.end method
-
-
diff --git a/tools/vm-tests-tf/src/dot/junit/opcodes/sput_object/d/T_sput_object_13.d.done b/tools/vm-tests-tf/src/dot/junit/opcodes/sput_object/d/T_sput_object_13.d.done
deleted file mode 100644
index d2d59da..0000000
--- a/tools/vm-tests-tf/src/dot/junit/opcodes/sput_object/d/T_sput_object_13.d.done
+++ /dev/null
@@ -1,53 +0,0 @@
-; 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.
-
-.source StubInitError.java
-.class public dot.junit.opcodes.sput_object.d.StubInitError
-.super java/lang/Object
-
-.field public static t I
-.field public static value Ljava/lang/Object;
-
-.method static <clinit>()V
-.limit regs 2
-
- const/4 v0, 0
- const/4 v1, 5
- div-int/2addr v1, v0
-
- sput v1, dot.junit.opcodes.sput_object.d.StubInitError.t I
- return-void
-.end method
-
-
-.source T_sput_object_13.java
-.class public dot.junit.opcodes.sput_object.d.T_sput_object_13
-.super java/lang/Object
-
-
-.method public <init>()V
-.limit regs 1
-
- invoke-direct {v0}, java/lang/Object/<init>()V
- return-void
-.end method
-
-.method public run()V
-.limit regs 3
-
- sput-object v2, dot.junit.opcodes.sput_object.d.StubInitError.value Ljava/lang/Object;
- return-void
-.end method
-
-
diff --git a/tools/vm-tests-tf/src/dot/junit/opcodes/sput_object/d/T_sput_object_2.d.done b/tools/vm-tests-tf/src/dot/junit/opcodes/sput_object/d/T_sput_object_2.d.done
deleted file mode 100644
index 5b6c088..0000000
--- a/tools/vm-tests-tf/src/dot/junit/opcodes/sput_object/d/T_sput_object_2.d.done
+++ /dev/null
@@ -1,36 +0,0 @@
-; 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.
-
-.source T_sput_object_2.java
-.class public dot.junit.opcodes.sput_object.d.T_sput_object_2
-.super java/lang/Object
-
-.field public static st_i1 Ljava/lang/Object;
-
-.method public <init>()V
-.limit regs 1
-
- invoke-direct {v0}, java/lang/Object/<init>()V
- return-void
-.end method
-
-.method public run()V
-.limit regs 3
-
- const-wide v0, 1234
- sput-object v0, dot.junit.opcodes.sput_object.d.T_sput_object_2.st_i1 Ljava/lang/Object;
- return-void
-.end method
-
-
diff --git a/tools/vm-tests-tf/src/dot/junit/opcodes/sput_object/d/T_sput_object_20.d.done b/tools/vm-tests-tf/src/dot/junit/opcodes/sput_object/d/T_sput_object_20.d.done
deleted file mode 100644
index 8d6c9df..0000000
--- a/tools/vm-tests-tf/src/dot/junit/opcodes/sput_object/d/T_sput_object_20.d.done
+++ /dev/null
@@ -1,35 +0,0 @@
-; 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.
-
-.source T_sput_object_20.java
-.class public dot.junit.opcodes.sput_object.d.T_sput_object_20
-.super java/lang/Object
-
-.field public static st_o Ljava/lang/String;
-
-.method public <init>()V
-.limit regs 1
-
- invoke-direct {v0}, java/lang/Object/<init>()V
- return-void
-.end method
-
-.method public run()V
-.limit regs 4
-
- sput-object v3, dot.junit.opcodes.sput_object.d.T_sput_object_20.st_o Ljava/lang/String;
- return-void
-.end method
-
-
diff --git a/tools/vm-tests-tf/src/dot/junit/opcodes/sput_object/d/T_sput_object_3.d.done b/tools/vm-tests-tf/src/dot/junit/opcodes/sput_object/d/T_sput_object_3.d.done
deleted file mode 100644
index 080efbc..0000000
--- a/tools/vm-tests-tf/src/dot/junit/opcodes/sput_object/d/T_sput_object_3.d.done
+++ /dev/null
@@ -1,35 +0,0 @@
-; 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.
-
-.source T_sput_object_3.java
-.class public dot.junit.opcodes.sput_object.d.T_sput_object_3
-.super java/lang/Object
-
-.field public static st_i1 Ljava/lang/Object;
-
-.method public <init>()V
-.limit regs 1
-
- invoke-direct {v0}, java/lang/Object/<init>()V
- return-void
-.end method
-
-.method public run()V
-.limit regs 3
-
- sput-object v2, dot.junit.opcodes.sput_object.d.T_sput_object_3.st_i1 Ljava/lang/Object;
- return-void
-.end method
-
-
diff --git a/tools/vm-tests-tf/src/dot/junit/opcodes/sput_object/d/T_sput_object_4.d.done b/tools/vm-tests-tf/src/dot/junit/opcodes/sput_object/d/T_sput_object_4.d.done
deleted file mode 100644
index 3a3bccd..0000000
--- a/tools/vm-tests-tf/src/dot/junit/opcodes/sput_object/d/T_sput_object_4.d.done
+++ /dev/null
@@ -1,35 +0,0 @@
-; 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.
-
-.source T_sput_object_4.java
-.class public dot.junit.opcodes.sput_object.d.T_sput_object_4
-.super java/lang/Object
-
-.field public static st_i1 Ljava/lang/Object;
-
-.method public <init>()V
-.limit regs 1
-
- invoke-direct {v0}, java/lang/Object/<init>()V
- return-void
-.end method
-
-.method public run()V
-.limit regs 3
-
- sput-object v3, dot.junit.opcodes.sput_object.d.T_sput_object_4.st_i1 Ljava/lang/Object;
- return-void
-.end method
-
-
diff --git a/tools/vm-tests-tf/src/dot/junit/opcodes/sput_object/d/T_sput_object_7.d.done b/tools/vm-tests-tf/src/dot/junit/opcodes/sput_object/d/T_sput_object_7.d.done
deleted file mode 100644
index 84988f9..0000000
--- a/tools/vm-tests-tf/src/dot/junit/opcodes/sput_object/d/T_sput_object_7.d.done
+++ /dev/null
@@ -1,35 +0,0 @@
-; 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.
-
-.source T_sput_object_7.java
-.class public dot.junit.opcodes.sput_object.d.T_sput_object_7
-.super java/lang/Object
-
-.field public st_i1 Ljava/lang/Object;
-
-.method public <init>()V
-.limit regs 1
-
- invoke-direct {v0}, java/lang/Object/<init>()V
- return-void
-.end method
-
-.method public run()V
-.limit regs 3
-
- sput-object v2, dot.junit.opcodes.sput_object.d.T_sput_object_7.st_i1 Ljava/lang/Object;
- return-void
-.end method
-
-
diff --git a/tools/vm-tests-tf/src/dot/junit/opcodes/sput_object/d/T_sput_object_9.d.done b/tools/vm-tests-tf/src/dot/junit/opcodes/sput_object/d/T_sput_object_9.d.done
deleted file mode 100644
index 2d35cf1..0000000
--- a/tools/vm-tests-tf/src/dot/junit/opcodes/sput_object/d/T_sput_object_9.d.done
+++ /dev/null
@@ -1,35 +0,0 @@
-; 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.
-
-.source T_sput_object_9.java
-.class public dot.junit.opcodes.sput_object.d.T_sput_object_9
-.super java/lang/Object
-
-.field public st_i1 Ljava/lang/Object;
-
-.method public <init>()V
-.limit regs 1
-
- invoke-direct {v0}, java/lang/Object/<init>()V
- return-void
-.end method
-
-.method public run()V
-.limit regs 3
-
- sput-object v2, dot.junit.opcodes.sput_object.d.T_sput_object_9noclass.st_i1 Ljava/lang/Object;
- return-void
-.end method
-
-
diff --git a/tools/vm-tests-tf/src/dot/junit/opcodes/sput_short/d/T_sput_short_13.d.done b/tools/vm-tests-tf/src/dot/junit/opcodes/sput_short/d/T_sput_short_13.d.done
deleted file mode 100644
index 55d0bf5..0000000
--- a/tools/vm-tests-tf/src/dot/junit/opcodes/sput_short/d/T_sput_short_13.d.done
+++ /dev/null
@@ -1,53 +0,0 @@
-; 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.
-
-.source StubInitError.java
-.class public dot.junit.opcodes.sput_short.d.StubInitError
-.super java/lang/Object
-
-.field public static value S
-
-.method static <clinit>()V
-.limit regs 2
-
- const/4 v0, 0
- const/4 v1, 5
- div-int/2addr v1, v0
-
- sput-short v1, dot.junit.opcodes.sput_short.d.StubInitError.value S
- return-void
-.end method
-
-
-.source T_sput_short_13.java
-.class public dot.junit.opcodes.sput_short.d.T_sput_short_13
-.super java/lang/Object
-
-
-.method public <init>()V
-.limit regs 1
-
- invoke-direct {v0}, java/lang/Object/<init>()V
- return-void
-.end method
-
-.method public run()V
-.limit regs 3
-
- const v1, 1
- sput-short v1, dot.junit.opcodes.sput_short.d.StubInitError.value S
- return-void
-.end method
-
-
diff --git a/tools/vm-tests-tf/src/dot/junit/opcodes/sput_short/d/T_sput_short_20.d.done b/tools/vm-tests-tf/src/dot/junit/opcodes/sput_short/d/T_sput_short_20.d.done
deleted file mode 100644
index dc42d54..0000000
--- a/tools/vm-tests-tf/src/dot/junit/opcodes/sput_short/d/T_sput_short_20.d.done
+++ /dev/null
@@ -1,35 +0,0 @@
-; 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.
-
-.source T_sput_short_20.java
-.class public dot.junit.opcodes.sput_short.d.T_sput_short_20
-.super java/lang/Object
-
-.field public static st_o Ljava/lang/Object;
-
-.method public <init>()V
-.limit regs 1
-
- invoke-direct {v0}, java/lang/Object/<init>()V
- return-void
-.end method
-
-.method public run()V
-.limit regs 4
-
- sput-short v3, dot.junit.opcodes.sput_short.d.T_sput_short_20.st_o Ljava/lang/Object;
- return-void
-.end method
-
-
diff --git a/tools/vm-tests-tf/src/dot/junit/opcodes/sput_wide/d/T_sput_wide_1.d.done b/tools/vm-tests-tf/src/dot/junit/opcodes/sput_wide/d/T_sput_wide_1.d.done
deleted file mode 100644
index 94e2898..0000000
--- a/tools/vm-tests-tf/src/dot/junit/opcodes/sput_wide/d/T_sput_wide_1.d.done
+++ /dev/null
@@ -1,46 +0,0 @@
-; 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.
-
-.source T_sput_wide_1.java
-.class public dot.junit.opcodes.sput_wide.d.T_sput_wide_1
-.super java/lang/Object
-
-.field public static st_i1 J
-.field protected static st_p1 J
-.field private static st_pvt1 J
-
-.method public <init>()V
-.limit regs 1
-
- invoke-direct {v0}, java/lang/Object/<init>()V
- return-void
-.end method
-
-.method public static getPvtField()J
-.limit regs 2
-
- sget-wide v0, dot.junit.opcodes.sput_wide.d.T_sput_wide_1.st_pvt1 J
- return-wide v0
-.end method
-
-.method public run()V
-.limit regs 3
-
- const-wide v1, 778899112233
- sput-wide v1, dot.junit.opcodes.sput_wide.d.T_sput_wide_1.st_i1 J
-
- return-void
-.end method
-
-
diff --git a/tools/vm-tests-tf/src/dot/junit/opcodes/sput_wide/d/T_sput_wide_13.d.done b/tools/vm-tests-tf/src/dot/junit/opcodes/sput_wide/d/T_sput_wide_13.d.done
deleted file mode 100644
index ae7d1df..0000000
--- a/tools/vm-tests-tf/src/dot/junit/opcodes/sput_wide/d/T_sput_wide_13.d.done
+++ /dev/null
@@ -1,54 +0,0 @@
-; 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.
-
-.source JtubInitError.java
-.class public dot.junit.opcodes.sput_wide.d.JtubInitError
-.super java/lang/Object
-
-.field public static value J
-
-.method static <clinit>()V
-.limit regs 2
-
- const/4 v0, 0
- const/4 v1, 5
- div-int/2addr v1, v0
-
- int-to-long v0, v0
- sput-wide v0, dot.junit.opcodes.sput_wide.d.JtubInitError.value J
- return-void
-.end method
-
-
-.source T_sput_wide_13.java
-.class public dot.junit.opcodes.sput_wide.d.T_sput_wide_13
-.super java/lang/Object
-
-
-.method public <init>()V
-.limit regs 1
-
- invoke-direct {v0}, java/lang/Object/<init>()V
- return-void
-.end method
-
-.method public run()V
-.limit regs 3
-
- const-wide v1, 1
- sput-wide v1, dot.junit.opcodes.sput_wide.d.JtubInitError.value J
- return-void
-.end method
-
-
diff --git a/tools/vm-tests-tf/src/dot/junit/opcodes/sput_wide/d/T_sput_wide_18.d.done b/tools/vm-tests-tf/src/dot/junit/opcodes/sput_wide/d/T_sput_wide_18.d.done
deleted file mode 100644
index 463bdbd..0000000
--- a/tools/vm-tests-tf/src/dot/junit/opcodes/sput_wide/d/T_sput_wide_18.d.done
+++ /dev/null
@@ -1,37 +0,0 @@
-; 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.
-
-.source T_sput_wide_18.java
-.class public dot.junit.opcodes.sput_wide.d.T_sput_wide_18
-.super java/lang/Object
-
-.field public static st_i1 F
-
-.method public <init>()V
-.limit regs 1
-
- invoke-direct {v0}, java/lang/Object/<init>()V
- return-void
-.end method
-
-.method public run()V
-.limit regs 3
-
- const v1, 1.0
- sput-wide v1, dot.junit.opcodes.sput_wide.d.T_sput_wide_18.st_i1 F
-
- return-void
-.end method
-
-
diff --git a/tools/vm-tests-tf/src/dot/junit/opcodes/sput_wide/d/T_sput_wide_20.d.done b/tools/vm-tests-tf/src/dot/junit/opcodes/sput_wide/d/T_sput_wide_20.d.done
deleted file mode 100644
index ca43933..0000000
--- a/tools/vm-tests-tf/src/dot/junit/opcodes/sput_wide/d/T_sput_wide_20.d.done
+++ /dev/null
@@ -1,35 +0,0 @@
-; 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.
-
-.source T_sput_wide_20.java
-.class public dot.junit.opcodes.sput_wide.d.T_sput_wide_20
-.super java/lang/Object
-
-.field public static st_o Ljava/lang/Object;
-
-.method public <init>()V
-.limit regs 1
-
- invoke-direct {v0}, java/lang/Object/<init>()V
- return-void
-.end method
-
-.method public run()V
-.limit regs 4
-
- sput-wide v3, dot.junit.opcodes.sput_wide.d.T_sput_wide_20.st_o Ljava/lang/Object;
- return-void
-.end method
-
-
diff --git a/tools/vm-tests-tf/src/dot/junit/opcodes/sub_double/d/T_sub_double_2.d.done b/tools/vm-tests-tf/src/dot/junit/opcodes/sub_double/d/T_sub_double_2.d.done
deleted file mode 100644
index e202f3c..0000000
--- a/tools/vm-tests-tf/src/dot/junit/opcodes/sub_double/d/T_sub_double_2.d.done
+++ /dev/null
@@ -1,35 +0,0 @@
-; 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.
-
-.source T_sub_double_2.java
-.class public dot.junit.opcodes.sub_double.d.T_sub_double_2
-.super java/lang/Object
-
-
-.method public <init>()V
-.limit regs 1
-
- invoke-direct {v0}, java/lang/Object/<init>()V
- return-void
-.end method
-
-.method public run(DD)D
-.limit regs 7
-
- const v3, 3.1415
- sub-double v0, v3, v5
- return-wide v0
-.end method
-
-
diff --git a/tools/vm-tests-tf/src/dot/junit/opcodes/sub_double_2addr/d/T_sub_double_2addr_2.d.done b/tools/vm-tests-tf/src/dot/junit/opcodes/sub_double_2addr/d/T_sub_double_2addr_2.d.done
deleted file mode 100644
index 0b37443c..0000000
--- a/tools/vm-tests-tf/src/dot/junit/opcodes/sub_double_2addr/d/T_sub_double_2addr_2.d.done
+++ /dev/null
@@ -1,35 +0,0 @@
-; 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.
-
-.source T_sub_double_2addr_2.java
-.class public dot.junit.opcodes.sub_double_2addr.d.T_sub_double_2addr_2
-.super java/lang/Object
-
-
-.method public <init>()V
-.limit regs 1
-
- invoke-direct {v0}, java/lang/Object/<init>()V
- return-void
-.end method
-
-.method public run(DD)D
-.limit regs 7
-
- const v3, 3.1415
- sub-double/2addr v3, v5
- return-wide v3
-.end method
-
-
diff --git a/tools/vm-tests-tf/src/dot/junit/opcodes/sub_long/d/T_sub_long_4.d.done b/tools/vm-tests-tf/src/dot/junit/opcodes/sub_long/d/T_sub_long_4.d.done
deleted file mode 100644
index 7ab2d2d..0000000
--- a/tools/vm-tests-tf/src/dot/junit/opcodes/sub_long/d/T_sub_long_4.d.done
+++ /dev/null
@@ -1,34 +0,0 @@
-; 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.
-
-.source T_sub_long_4.java
-.class public dot.junit.opcodes.sub_long.d.T_sub_long_4
-.super java/lang/Object
-
-
-.method public <init>()V
-.limit regs 1
-
- invoke-direct {v0}, java/lang/Object/<init>()V
- return-void
-.end method
-
-.method public run(JJ)J
-.limit regs 7
- const v5, 12346.0
- sub-long v0, v3, v5
- return-wide v3
-.end method
-
-
diff --git a/tools/vm-tests-tf/src/dot/junit/opcodes/sub_long_2addr/d/T_sub_long_2addr_4.d.done b/tools/vm-tests-tf/src/dot/junit/opcodes/sub_long_2addr/d/T_sub_long_2addr_4.d.done
deleted file mode 100644
index 57d6c24..0000000
--- a/tools/vm-tests-tf/src/dot/junit/opcodes/sub_long_2addr/d/T_sub_long_2addr_4.d.done
+++ /dev/null
@@ -1,34 +0,0 @@
-; 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.
-
-.source T_sub_long_2addr_4.java
-.class public dot.junit.opcodes.sub_long_2addr.d.T_sub_long_2addr_4
-.super java/lang/Object
-
-
-.method public <init>()V
-.limit regs 1
-
- invoke-direct {v0}, java/lang/Object/<init>()V
- return-void
-.end method
-
-.method public run(JJ)J
-.limit regs 7
- const v5, 12346.0
- sub-long/2addr v3, v5
- return-wide v3
-.end method
-
-
diff --git a/tools/vm-tests-tf/src/dot/junit/opcodes/ushr_int_lit8/d/T_ushr_int_lit8_11.d.done b/tools/vm-tests-tf/src/dot/junit/opcodes/ushr_int_lit8/d/T_ushr_int_lit8_11.d.done
deleted file mode 100644
index d0b5a53..0000000
--- a/tools/vm-tests-tf/src/dot/junit/opcodes/ushr_int_lit8/d/T_ushr_int_lit8_11.d.done
+++ /dev/null
@@ -1,32 +0,0 @@
-; 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.
-
-.source T_ushr_int_lit8_11.java
-.class public dot.junit.opcodes.ushr_int_lit8.d.T_ushr_int_lit8_11
-.super java/lang/Object
-
-.method public <init>()V
-.limit regs 1
- invoke-direct {v0}, java/lang/Object/<init>()V
- return-void
-.end method
-
-.method public run()I
-.limit regs 4
- const-wide v0, 12345456788
- ushr-int/lit8 v1, v0, 1
- return v1
-.end method
-
-
diff --git a/tools/vm-tests-tf/src/dot/junit/opcodes/ushr_long/d/T_ushr_long_4.d.done b/tools/vm-tests-tf/src/dot/junit/opcodes/ushr_long/d/T_ushr_long_4.d.done
deleted file mode 100644
index 03ae1aa..0000000
--- a/tools/vm-tests-tf/src/dot/junit/opcodes/ushr_long/d/T_ushr_long_4.d.done
+++ /dev/null
@@ -1,35 +0,0 @@
-; 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.
-
-.source T_ushr_long_4.java
-.class public dot.junit.opcodes.ushr_long.d.T_ushr_long_4
-.super java/lang/Object
-
-
-.method public <init>()V
-.limit regs 1
-
- invoke-direct {v0}, java/lang/Object/<init>()V
- return-void
-.end method
-
-.method public run(JI)J
-.limit regs 6
-
- const v0, 12345.0
- ushr-long v0, v0, v5
- return-wide v3
-.end method
-
-
diff --git a/tools/vm-tests-tf/src/dot/junit/opcodes/ushr_long_2addr/d/T_ushr_long_2addr_4.d.done b/tools/vm-tests-tf/src/dot/junit/opcodes/ushr_long_2addr/d/T_ushr_long_2addr_4.d.done
deleted file mode 100644
index 4f03522..0000000
--- a/tools/vm-tests-tf/src/dot/junit/opcodes/ushr_long_2addr/d/T_ushr_long_2addr_4.d.done
+++ /dev/null
@@ -1,35 +0,0 @@
-; 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.
-
-.source T_ushr_long_2addr_4.java
-.class public dot.junit.opcodes.ushr_long_2addr.d.T_ushr_long_2addr_4
-.super java/lang/Object
-
-
-.method public <init>()V
-.limit regs 1
-
- invoke-direct {v0}, java/lang/Object/<init>()V
- return-void
-.end method
-
-.method public run(JI)J
-.limit regs 4
-
- const v1, 12345.0
- ushr-long/2addr v1, v3
- return-wide v1
-.end method
-
-
diff --git a/tools/vm-tests-tf/src/dot/junit/opcodes/xor_long/d/T_xor_long_4.d.done b/tools/vm-tests-tf/src/dot/junit/opcodes/xor_long/d/T_xor_long_4.d.done
deleted file mode 100644
index 28e9fff..0000000
--- a/tools/vm-tests-tf/src/dot/junit/opcodes/xor_long/d/T_xor_long_4.d.done
+++ /dev/null
@@ -1,35 +0,0 @@
-; 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.
-
-.source T_xor_long_4.java
-.class public dot.junit.opcodes.xor_long.d.T_xor_long_4
-.super java/lang/Object
-
-
-.method public <init>()V
-.limit regs 1
-
- invoke-direct {v0}, java/lang/Object/<init>()V
- return-void
-.end method
-
-.method public run(JJ)J
-.limit regs 5
-
- const v3, 1234.0
- xor-long v1, v1, v3
- return-wide v1
-.end method
-
-
diff --git a/tools/vm-tests-tf/src/dot/junit/opcodes/xor_long_2addr/d/T_xor_long_2addr_4.d.done b/tools/vm-tests-tf/src/dot/junit/opcodes/xor_long_2addr/d/T_xor_long_2addr_4.d.done
deleted file mode 100644
index 98c0cd8..0000000
--- a/tools/vm-tests-tf/src/dot/junit/opcodes/xor_long_2addr/d/T_xor_long_2addr_4.d.done
+++ /dev/null
@@ -1,35 +0,0 @@
-; 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.
-
-.source T_xor_long_2addr_4.java
-.class public dot.junit.opcodes.xor_long_2addr.d.T_xor_long_2addr_4
-.super java/lang/Object
-
-
-.method public <init>()V
-.limit regs 1
-
- invoke-direct {v0}, java/lang/Object/<init>()V
- return-void
-.end method
-
-.method public run(JJ)J
-.limit regs 5
-
- const v3, 1234.0
- xor-long/2addr v1, v3
- return-wide v1
-.end method
-
-
diff --git a/tools/vm-tests-tf/src/dot/junit/verify/b2/d/T_b2_1.d.done b/tools/vm-tests-tf/src/dot/junit/verify/b2/d/T_b2_1.d.done
deleted file mode 100644
index 1fe908a..0000000
--- a/tools/vm-tests-tf/src/dot/junit/verify/b2/d/T_b2_1.d.done
+++ /dev/null
@@ -1,32 +0,0 @@
-; 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.
-
-.source T_b2_1.java
-.class public dot.junit.verify.b2.d.T_b2_1
-.super java/lang/Object
-
-.method public <init>()V
-.limit regs 1
-
- invoke-direct {v0}, java/lang/Object/<init>()V
- return-void
-.end method
-
-.method public run()V
-.limit regs 3
-
- const-wide v0, 123
- move v1, v0 ; illegal read access to v1
- return-void
-.end method
diff --git a/tools/vm-tests-tf/src/dot/junit/verify/b2/d/T_b2_2.d.done b/tools/vm-tests-tf/src/dot/junit/verify/b2/d/T_b2_2.d.done
deleted file mode 100644
index a885c41..0000000
--- a/tools/vm-tests-tf/src/dot/junit/verify/b2/d/T_b2_2.d.done
+++ /dev/null
@@ -1,33 +0,0 @@
-; 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.
-
-.source T_b2_2.java
-.class public dot.junit.verify.b2.d.T_b2_2
-.super java/lang/Object
-
-.method public <init>()V
-.limit regs 1
-
- invoke-direct {v0}, java/lang/Object/<init>()V
- return-void
-.end method
-
-.method public run()V
-.limit regs 3
-
- const-wide v0, 123
- move v0, v1 ; // illegal read access to v0
- return-void
-.end method
-
diff --git a/tools/vm-tests-tf/src/dot/junit/verify/b2/d/T_b2_3.d.done b/tools/vm-tests-tf/src/dot/junit/verify/b2/d/T_b2_3.d.done
deleted file mode 100644
index bf8d6e0..0000000
--- a/tools/vm-tests-tf/src/dot/junit/verify/b2/d/T_b2_3.d.done
+++ /dev/null
@@ -1,34 +0,0 @@
-; 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.
-
-.source T_b2_3.java
-.class public dot.junit.verify.b2.d.T_b2_3
-.super java/lang/Object
-
-.method public <init>()V
-.limit regs 1
-
- invoke-direct {v0}, java/lang/Object/<init>()V
- return-void
-.end method
-
-.method public run()V
-.limit regs 5
-
- const v0, 123
- const v1, 123
- move-wide v2, v0 ; // illegal read access to v0/1
- return-void
-.end method
-
diff --git a/tools/vm-tests-tf/src/dot/junit/verify/b2/d/T_b2_4.d.done b/tools/vm-tests-tf/src/dot/junit/verify/b2/d/T_b2_4.d.done
deleted file mode 100644
index bb158ce..0000000
--- a/tools/vm-tests-tf/src/dot/junit/verify/b2/d/T_b2_4.d.done
+++ /dev/null
@@ -1,33 +0,0 @@
-; 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.
-
-.source T_b2_4.java
-.class public dot.junit.verify.b2.d.T_b2_4
-.super java/lang/Object
-
-.method public <init>()V
-.limit regs 1
-
- invoke-direct {v0}, java/lang/Object/<init>()V
- return-void
-.end method
-
-.method public run()V
-.limit regs 4
-
- const-wide v0, 123
- move v2, v0 ; // illegal read access to v0
- return-void
-.end method
-
diff --git a/tools/vm-tests-tf/src/dot/junit/verify/b2/d/T_b2_5.d.done b/tools/vm-tests-tf/src/dot/junit/verify/b2/d/T_b2_5.d.done
deleted file mode 100644
index 483066d..0000000
--- a/tools/vm-tests-tf/src/dot/junit/verify/b2/d/T_b2_5.d.done
+++ /dev/null
@@ -1,34 +0,0 @@
-; 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.
-
-.source T_b2_5.java
-.class public dot.junit.verify.b2.d.T_b2_5
-.super java/lang/Object
-
-.method public <init>()V
-.limit regs 1
-
- invoke-direct {v0}, java/lang/Object/<init>()V
- return-void
-.end method
-
-.method public run()V
-.limit regs 5
-
- const-wide v0, 123
- move-wide v2, v0
- move-wide v2, v1 ; // illegal read access to v1/2
- return-void
-.end method
-