summaryrefslogtreecommitdiff
path: root/core/tests
diff options
context:
space:
mode:
Diffstat (limited to 'core/tests')
-rw-r--r--core/tests/ConnectivityManagerTest/AndroidManifest.xml20
-rw-r--r--core/tests/ConnectivityManagerTest/res/values/strings.xml4
-rw-r--r--core/tests/ConnectivityManagerTest/src/com/android/connectivitymanagertest/ConnectivityManagerUnitTestRunner.java47
-rw-r--r--core/tests/ConnectivityManagerTest/src/com/android/connectivitymanagertest/functional/ConnectivityManagerMobileTest.java76
-rw-r--r--core/tests/ConnectivityManagerTest/src/com/android/connectivitymanagertest/unit/WifiSoftAPTest.java86
-rw-r--r--core/tests/coretests/Android.mk4
-rw-r--r--core/tests/coretests/AndroidManifest.xml4
-rw-r--r--core/tests/coretests/res/raw/v21_im.vcf5
-rw-r--r--core/tests/coretests/res/raw/v21_invalid_multiple_line.vcf7
-rw-r--r--core/tests/coretests/res/raw/v30_comma_separated.vcf4
-rw-r--r--core/tests/coretests/res/raw/v30_multibyte_param.vcf5
-rw-r--r--core/tests/coretests/res/raw/v30_pager.vcf5
-rw-r--r--core/tests/coretests/res/raw/v40_sort_as.vcf6
-rw-r--r--core/tests/coretests/src/android/app/activity/LifecycleTest.java5
-rw-r--r--core/tests/coretests/src/android/app/activity/MetaDataTest.java3
-rw-r--r--core/tests/coretests/src/android/bluetooth/BluetoothStressTest.java46
-rw-r--r--core/tests/coretests/src/android/bluetooth/BluetoothTestRunner.java33
-rw-r--r--core/tests/coretests/src/android/bluetooth/BluetoothTestUtils.java498
-rw-r--r--core/tests/coretests/src/android/content/BrickDeniedTest.java5
-rw-r--r--core/tests/coretests/src/android/content/MemoryFileProviderTest.java7
-rw-r--r--core/tests/coretests/src/android/content/SyncStorageEngineTest.java20
-rwxr-xr-xcore/tests/coretests/src/android/content/pm/AppCacheTest.java28
-rw-r--r--core/tests/coretests/src/android/content/pm/ComponentTest.java53
-rwxr-xr-xcore/tests/coretests/src/android/content/pm/PackageManagerTests.java343
-rw-r--r--core/tests/coretests/src/android/database/sqlite/AbstractJDBCDriverTest.java211
-rw-r--r--core/tests/coretests/src/android/database/sqlite/SQLiteJDBCDriverTest.java137
-rw-r--r--core/tests/coretests/src/android/net/DownloadManagerBaseTest.java888
-rw-r--r--core/tests/coretests/src/android/net/DownloadManagerIntegrationTest.java381
-rw-r--r--core/tests/coretests/src/android/net/DownloadManagerStressTest.java156
-rw-r--r--core/tests/coretests/src/android/net/http/HttpsThroughHttpProxyTest.java142
-rw-r--r--core/tests/coretests/src/android/os/FileObserverTest.java5
-rw-r--r--core/tests/coretests/src/android/os/HierarchicalStateMachineTest.java110
-rw-r--r--core/tests/coretests/src/android/os/PerformanceCollectorTest.java15
-rw-r--r--core/tests/coretests/src/android/os/PowerManagerTest.java9
-rw-r--r--core/tests/coretests/src/android/os/storage/StorageListener.java21
-rw-r--r--core/tests/coretests/src/android/pim/vcard/ContentValuesVerifier.java101
-rw-r--r--core/tests/coretests/src/android/pim/vcard/VCardExporterTests.java428
-rw-r--r--core/tests/coretests/src/android/pim/vcard/VCardImporterTests.java173
-rw-r--r--core/tests/coretests/src/android/pim/vcard/VCardJapanizationTests.java79
-rw-r--r--core/tests/coretests/src/android/pim/vcard/VCardTestRunner.java42
-rw-r--r--core/tests/coretests/src/android/pim/vcard/VCardTestUtilsTests.java98
-rw-r--r--core/tests/coretests/src/android/pim/vcard/VCardTestsBase.java169
-rw-r--r--core/tests/coretests/src/android/pim/vcard/VCardUtilsTests.java37
-rw-r--r--core/tests/coretests/src/android/pim/vcard/VCardVerifier.java306
-rw-r--r--core/tests/coretests/src/android/pim/vcard/test_utils/ContactEntry.java43
-rw-r--r--core/tests/coretests/src/android/pim/vcard/test_utils/ContentValuesBuilder.java (renamed from core/tests/coretests/src/android/pim/vcard/ContentValuesBuilder.java)11
-rw-r--r--core/tests/coretests/src/android/pim/vcard/test_utils/ContentValuesVerifier.java54
-rw-r--r--core/tests/coretests/src/android/pim/vcard/test_utils/ContentValuesVerifierElem.java (renamed from core/tests/coretests/src/android/pim/vcard/ContentValuesVerifierElem.java)24
-rw-r--r--core/tests/coretests/src/android/pim/vcard/test_utils/ExportTestProvider.java (renamed from core/tests/coretests/src/android/pim/vcard/ExportTestResolver.java)136
-rw-r--r--core/tests/coretests/src/android/pim/vcard/test_utils/ExportTestResolver.java38
-rw-r--r--core/tests/coretests/src/android/pim/vcard/test_utils/ImportTestProvider.java (renamed from core/tests/coretests/src/android/pim/vcard/ImportTestResolver.java)93
-rw-r--r--core/tests/coretests/src/android/pim/vcard/test_utils/ImportTestResolver.java56
-rw-r--r--core/tests/coretests/src/android/pim/vcard/test_utils/LineVerifier.java (renamed from core/tests/coretests/src/android/pim/vcard/LineVerifier.java)17
-rw-r--r--core/tests/coretests/src/android/pim/vcard/test_utils/LineVerifierElem.java (renamed from core/tests/coretests/src/android/pim/vcard/LineVerifierElem.java)33
-rw-r--r--core/tests/coretests/src/android/pim/vcard/test_utils/PropertyNode.java (renamed from core/tests/coretests/src/android/pim/vcard/PropertyNode.java)16
-rw-r--r--core/tests/coretests/src/android/pim/vcard/test_utils/PropertyNodesVerifier.java82
-rw-r--r--core/tests/coretests/src/android/pim/vcard/test_utils/PropertyNodesVerifierElem.java (renamed from core/tests/coretests/src/android/pim/vcard/PropertyNodesVerifier.java)110
-rw-r--r--core/tests/coretests/src/android/pim/vcard/test_utils/VCardTestsBase.java84
-rw-r--r--core/tests/coretests/src/android/pim/vcard/test_utils/VCardVerifier.java370
-rw-r--r--core/tests/coretests/src/android/pim/vcard/test_utils/VNode.java (renamed from core/tests/coretests/src/android/pim/vcard/VNode.java)2
-rw-r--r--core/tests/coretests/src/android/pim/vcard/test_utils/VNodeBuilder.java (renamed from core/tests/coretests/src/android/pim/vcard/VNodeBuilder.java)128
-rw-r--r--core/tests/coretests/src/android/text/HtmlTest.java13
-rw-r--r--core/tests/coretests/src/android/text/PackedIntVectorTest.java158
-rw-r--r--core/tests/coretests/src/android/text/TextUtilsTest.java40
-rw-r--r--core/tests/coretests/src/android/text/util/LinkifyTest.java4
-rw-r--r--core/tests/coretests/src/android/util/MonthDisplayHelperTest.java10
-rw-r--r--core/tests/coretests/src/android/view/FocusFinderTest.java3
-rw-r--r--core/tests/coretests/src/android/view/VelocityTest.java285
-rw-r--r--core/tests/coretests/src/android/view/accessibility/RecycleAccessibilityEventTest.java5
-rw-r--r--core/tests/coretests/src/android/widget/RadioGroupPreCheckedTest.java9
-rw-r--r--core/tests/coretests/src/android/widget/expandablelistview/ExpandableListWithHeadersTest.java6
-rw-r--r--core/tests/coretests/src/android/widget/gridview/touch/GridTouchStackFromBottomManyTest.java2
-rw-r--r--core/tests/coretests/src/android/widget/listview/arrowscroll/ListInterleaveFocusablesTest.java14
-rw-r--r--core/tests/coretests/src/android/widget/listview/arrowscroll/ListOfItemsTallerThanScreenTest.java13
-rw-r--r--core/tests/coretests/src/android/widget/listview/arrowscroll/ListOfShortShortTallShortShortTest.java15
-rw-r--r--core/tests/coretests/src/android/widget/listview/arrowscroll/ListWithScreenOfNoSelectablesTest.java14
-rw-r--r--core/tests/coretests/src/com/android/internal/http/multipart/MultipartTest.java118
-rw-r--r--core/tests/coretests/src/com/android/internal/os/LoggingPrintStreamTest.java184
-rw-r--r--core/tests/hosttests/src/android/content/pm/PackageManagerHostTestUtils.java51
-rw-r--r--core/tests/hosttests/src/android/net/DownloadManagerHostTests.java201
-rw-r--r--core/tests/hosttests/test-apps/DownloadManagerTestApp/Android.mk29
-rw-r--r--core/tests/hosttests/test-apps/DownloadManagerTestApp/AndroidManifest.xml35
-rw-r--r--core/tests/hosttests/test-apps/DownloadManagerTestApp/src/com/android/frameworks/DownloadManagerTestApp.java463
-rw-r--r--core/tests/hosttests/test-apps/DownloadManagerTestApp/src/com/android/frameworks/DownloadManagerTestRunner.java63
-rw-r--r--core/tests/utillib/Android.mk27
-rw-r--r--core/tests/utillib/src/coretestutils/http/MockResponse.java239
-rw-r--r--core/tests/utillib/src/coretestutils/http/MockWebServer.java426
-rw-r--r--core/tests/utillib/src/coretestutils/http/RecordedRequest.java93
88 files changed, 6748 insertions, 1891 deletions
diff --git a/core/tests/ConnectivityManagerTest/AndroidManifest.xml b/core/tests/ConnectivityManagerTest/AndroidManifest.xml
index c318577ff91a..d298d40cafde 100644
--- a/core/tests/ConnectivityManagerTest/AndroidManifest.xml
+++ b/core/tests/ConnectivityManagerTest/AndroidManifest.xml
@@ -24,23 +24,35 @@
<application>
<uses-library android:name="android.test.runner" />
<activity android:name="ConnectivityManagerTestActivity"
- android:label="CMTest">
+ android:label="@string/app_name">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
- <category android:name="android.intent.category.TEST" />
+ <category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
<!--
This declares that this app uses the instrumentation test runner targeting
- the package of browserpowertest. To run the tests use the command:
- "adb shell am instrument -w com.android.connectivitymanagertest/.ConnectivityManagerTestRunner"
+ the package of connectivitymanagertest. To run the tests use the command:
+ "adb shell am instrument -e ssid <SSID> -w
+ com.android.connectivitymanagertest/.ConnectivityManagerTestRunner",
+ the access point <SSID> should be an open AP.
-->
<instrumentation android:name=".ConnectivityManagerTestRunner"
android:targetPackage="com.android.connectivitymanagertest"
android:label="Test runner for Connectivity Manager Tests"
/>
+ <!--
+ To run the unit tests use the command:
+ "adb shell am instrument -w
+ com.android.connectivitymanagertest/.ConnectivityManagerUnitTestRunner"
+ -->
+ <instrumentation android:name=".ConnectivityManagerUnitTestRunner"
+ android:targetPackage="com.android.connectivitymanagertest"
+ android.label="Test runner for unit tests"
+ />
+
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
diff --git a/core/tests/ConnectivityManagerTest/res/values/strings.xml b/core/tests/ConnectivityManagerTest/res/values/strings.xml
new file mode 100644
index 000000000000..fb6e82f83af8
--- /dev/null
+++ b/core/tests/ConnectivityManagerTest/res/values/strings.xml
@@ -0,0 +1,4 @@
+<?xml version="1.0" encoding="utf-8"?>
+<resources>
+ <string name="app_name">ConnectivityManagerTest</string>
+</resources>
diff --git a/core/tests/ConnectivityManagerTest/src/com/android/connectivitymanagertest/ConnectivityManagerUnitTestRunner.java b/core/tests/ConnectivityManagerTest/src/com/android/connectivitymanagertest/ConnectivityManagerUnitTestRunner.java
new file mode 100644
index 000000000000..6adfc7489910
--- /dev/null
+++ b/core/tests/ConnectivityManagerTest/src/com/android/connectivitymanagertest/ConnectivityManagerUnitTestRunner.java
@@ -0,0 +1,47 @@
+/*
+ * Copyright (C) 2010, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.connectivitymanagertest;
+
+import android.os.Bundle;
+import android.test.InstrumentationTestRunner;
+import android.test.InstrumentationTestSuite;
+import android.util.Log;
+import com.android.connectivitymanagertest.unit.WifiSoftAPTest;
+
+import junit.framework.TestSuite;
+
+/**
+ * Instrumentation Test Runner for all unit tests
+ *
+ * adb shell am instrument \
+ * -w com.android.connectivitymanagertest/.ConnectivityManagerUnitTestRunner
+ */
+
+public class ConnectivityManagerUnitTestRunner extends InstrumentationTestRunner {
+ @Override
+ public TestSuite getAllTests() {
+ TestSuite suite = new InstrumentationTestSuite(this);
+ suite.addTestSuite(WifiSoftAPTest.class);
+ return suite;
+ }
+
+
+ @Override
+ public ClassLoader getLoader() {
+ return ConnectivityManagerUnitTestRunner.class.getClassLoader();
+ }
+}
diff --git a/core/tests/ConnectivityManagerTest/src/com/android/connectivitymanagertest/functional/ConnectivityManagerMobileTest.java b/core/tests/ConnectivityManagerTest/src/com/android/connectivitymanagertest/functional/ConnectivityManagerMobileTest.java
index cdaefc853079..ad8d444114d7 100644
--- a/core/tests/ConnectivityManagerTest/src/com/android/connectivitymanagertest/functional/ConnectivityManagerMobileTest.java
+++ b/core/tests/ConnectivityManagerTest/src/com/android/connectivitymanagertest/functional/ConnectivityManagerMobileTest.java
@@ -91,30 +91,30 @@ public class ConnectivityManagerMobileTest
// DISCONNECTING, DISCONNECTED, UNKNOWN
private void waitForNetworkState(int networkType, State expectedState, long timeout) {
long startTime = System.currentTimeMillis();
- // In case the broadcast is already sent out, no need to wait
- if (cmActivity.mCM.getNetworkInfo(networkType).getState() == expectedState) {
- return;
- } else {
- while (true) {
- if ((System.currentTimeMillis() - startTime) > timeout) {
+ while (true) {
+ if ((System.currentTimeMillis() - startTime) > timeout) {
+ if (cmActivity.mCM.getNetworkInfo(networkType).getState() != expectedState) {
assertFalse("Wait for network state timeout", true);
+ } else {
+ // the broadcast has been sent out. the state has been changed.
+ return;
+ }
+ }
+ Log.v(LOG_TAG, "Wait for the connectivity state for network: " + networkType +
+ " to be " + expectedState.toString());
+ synchronized (cmActivity.connectivityObject) {
+ try {
+ cmActivity.connectivityObject.wait(STATE_TRANSITION_SHORT_TIMEOUT);
+ } catch (InterruptedException e) {
+ e.printStackTrace();
}
- Log.v(LOG_TAG, "Wait for the connectivity state for network: " + networkType +
- " to be " + expectedState.toString());
- synchronized (cmActivity.connectivityObject) {
- try {
- cmActivity.connectivityObject.wait(STATE_TRANSITION_SHORT_TIMEOUT);
- } catch (InterruptedException e) {
- e.printStackTrace();
- }
- if ((cmActivity.mNetworkInfo.getType() != networkType) ||
- (cmActivity.mNetworkInfo.getState() != expectedState)) {
- Log.v(LOG_TAG, "network state for " + cmActivity.mNetworkInfo.getType() +
- "is: " + cmActivity.mNetworkInfo.getState());
- continue;
- }
- break;
+ if ((cmActivity.mNetworkInfo.getType() != networkType) ||
+ (cmActivity.mNetworkInfo.getState() != expectedState)) {
+ Log.v(LOG_TAG, "network state for " + cmActivity.mNetworkInfo.getType() +
+ "is: " + cmActivity.mNetworkInfo.getState());
+ continue;
}
+ break;
}
}
}
@@ -123,26 +123,26 @@ public class ConnectivityManagerMobileTest
// WIFI_STATE_ENALBING, WIFI_STATE_UNKNOWN
private void waitForWifiState(int expectedState, long timeout) {
long startTime = System.currentTimeMillis();
- if (cmActivity.mWifiState == expectedState) {
- return;
- } else {
- while (true) {
- if ((System.currentTimeMillis() - startTime) > timeout) {
+ while (true) {
+ if ((System.currentTimeMillis() - startTime) > timeout) {
+ if (cmActivity.mWifiState != expectedState) {
assertFalse("Wait for Wifi state timeout", true);
+ } else {
+ return;
+ }
+ }
+ Log.v(LOG_TAG, "Wait for wifi state to be: " + expectedState);
+ synchronized (cmActivity.wifiObject) {
+ try {
+ cmActivity.wifiObject.wait(5*1000);
+ } catch (InterruptedException e) {
+ e.printStackTrace();
}
- Log.v(LOG_TAG, "Wait for wifi state to be: " + expectedState);
- synchronized (cmActivity.wifiObject) {
- try {
- cmActivity.wifiObject.wait(5*1000);
- } catch (InterruptedException e) {
- e.printStackTrace();
- }
- if (cmActivity.mWifiState != expectedState) {
- Log.v(LOG_TAG, "Wifi state is: " + cmActivity.mWifiNetworkInfo.getState());
- continue;
- }
- break;
+ if (cmActivity.mWifiState != expectedState) {
+ Log.v(LOG_TAG, "Wifi state is: " + cmActivity.mWifiNetworkInfo.getState());
+ continue;
}
+ break;
}
}
}
diff --git a/core/tests/ConnectivityManagerTest/src/com/android/connectivitymanagertest/unit/WifiSoftAPTest.java b/core/tests/ConnectivityManagerTest/src/com/android/connectivitymanagertest/unit/WifiSoftAPTest.java
new file mode 100644
index 000000000000..3f43e4851c4f
--- /dev/null
+++ b/core/tests/ConnectivityManagerTest/src/com/android/connectivitymanagertest/unit/WifiSoftAPTest.java
@@ -0,0 +1,86 @@
+/*
+ * Copyright (C) 2010 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.connectivitymanagertest.unit;
+
+import android.content.BroadcastReceiver;
+import android.content.Intent;
+import android.content.Context;
+import android.app.Instrumentation;
+import android.os.Handler;
+import android.os.Message;
+import android.net.ConnectivityManager;
+import android.net.wifi.WifiManager;
+import android.net.wifi.WifiConfiguration;
+import android.net.wifi.WifiConfiguration.KeyMgmt;
+
+import android.test.suitebuilder.annotation.LargeTest;
+import android.test.AndroidTestCase;
+
+import java.util.ArrayList;
+
+import android.util.Log;
+
+/**
+ * Test Wifi soft AP configuration
+ */
+public class WifiSoftAPTest extends AndroidTestCase {
+
+ private WifiManager mWifiManager;
+ private WifiConfiguration mWifiConfig = null;
+ private final String TAG = "WifiSoftAPTest";
+ private final int DURATION = 10000;
+
+ @Override
+ protected void setUp() throws Exception {
+ super.setUp();
+ mWifiManager = (WifiManager) getContext().getSystemService(Context.WIFI_SERVICE);
+ assertNotNull(mWifiManager);
+ assertTrue(mWifiManager.setWifiApEnabled(null, true));
+ mWifiConfig = mWifiManager.getWifiApConfiguration();
+ if (mWifiConfig != null) {
+ Log.v(TAG, "mWifiConfig is " + mWifiConfig.toString());
+ } else {
+ Log.v(TAG, "mWifiConfig is null.");
+ }
+ }
+
+ @Override
+ protected void tearDown() throws Exception {
+ Log.v(TAG, "turn off wifi tethering");
+ mWifiManager.setWifiApEnabled(null, false);
+ super.tearDown();
+ }
+
+ // Test case 1: Test the soft AP SSID with letters
+ @LargeTest
+ public void testApSsidWithAlphabet() {
+ WifiConfiguration config = new WifiConfiguration();
+ config.SSID = "abcdefghijklmnopqrstuvwxyz";
+ config.allowedKeyManagement.set(KeyMgmt.NONE);
+ mWifiConfig = config;
+ assertTrue(mWifiManager.setWifiApEnabled(mWifiConfig, true));
+ try {
+ Thread.sleep(DURATION);
+ } catch (InterruptedException e) {
+ Log.v(TAG, "exception " + e.getStackTrace());
+ assertFalse(true);
+ }
+ assertNotNull(mWifiManager.getWifiApConfiguration());
+ assertEquals("wifi AP state is not enabled", WifiManager.WIFI_AP_STATE_ENABLED,
+ mWifiManager.getWifiApState());
+ }
+}
diff --git a/core/tests/coretests/Android.mk b/core/tests/coretests/Android.mk
index 245c67cf4002..b49680506802 100644
--- a/core/tests/coretests/Android.mk
+++ b/core/tests/coretests/Android.mk
@@ -11,8 +11,8 @@ LOCAL_SRC_FILES := \
$(call all-java-files-under, DisabledTestApp/src) \
$(call all-java-files-under, EnabledTestApp/src)
-LOCAL_STATIC_JAVA_LIBRARIES += android-common
-
+LOCAL_DX_FLAGS := --core-library
+LOCAL_STATIC_JAVA_LIBRARIES := core-tests-supportlib android-common frameworks-core-util-lib
LOCAL_JAVA_LIBRARIES := android.test.runner
LOCAL_PACKAGE_NAME := FrameworksCoreTests
diff --git a/core/tests/coretests/AndroidManifest.xml b/core/tests/coretests/AndroidManifest.xml
index ce73ae1eb433..f09421bca74f 100644
--- a/core/tests/coretests/AndroidManifest.xml
+++ b/core/tests/coretests/AndroidManifest.xml
@@ -36,12 +36,16 @@
android:description="@string/permdesc_testDenied" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
+ <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
+ <uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
<uses-permission android:name="android.permission.BLUETOOTH" />
<uses-permission android:name="android.permission.BLUETOOTH_ADMIN" />
<uses-permission android:name="android.permission.BROADCAST_STICKY" />
+ <uses-permission android:name="android.permission.CHANGE_WIFI_STATE" />
<uses-permission android:name="android.permission.CLEAR_APP_CACHE" />
<uses-permission android:name="android.permission.CLEAR_APP_USER_DATA" />
<uses-permission android:name="android.permission.DELETE_CACHE_FILES" />
+ <uses-permission android:name="android.permission.DOWNLOAD_CACHE_NON_PURGEABLE" />
<uses-permission android:name="android.permission.GET_PACKAGE_SIZE" />
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.READ_CONTACTS" />
diff --git a/core/tests/coretests/res/raw/v21_im.vcf b/core/tests/coretests/res/raw/v21_im.vcf
new file mode 100644
index 000000000000..cc1aabb74941
--- /dev/null
+++ b/core/tests/coretests/res/raw/v21_im.vcf
@@ -0,0 +1,5 @@
+BEGIN:VCARD
+VERSION:2.1
+X-ANDROID-CUSTOM:vnd.android.cursor.item/nickname;Nick;1;;;;;;;;;;;;;
+X-GOOGLE-TALK:hhh@gmail.com
+END:VCARD
diff --git a/core/tests/coretests/res/raw/v21_invalid_multiple_line.vcf b/core/tests/coretests/res/raw/v21_invalid_multiple_line.vcf
new file mode 100644
index 000000000000..9c81fd52a14b
--- /dev/null
+++ b/core/tests/coretests/res/raw/v21_invalid_multiple_line.vcf
@@ -0,0 +1,7 @@
+BEGIN:VCARD
+VERSION:2.1
+N:;Omega;;;
+EMAIL;INTERNET:"Omega"
+ <omega@example.com>
+FN:Omega
+END:VCARD
diff --git a/core/tests/coretests/res/raw/v30_comma_separated.vcf b/core/tests/coretests/res/raw/v30_comma_separated.vcf
index 98a7f20588a1..f1baf880972f 100644
--- a/core/tests/coretests/res/raw/v30_comma_separated.vcf
+++ b/core/tests/coretests/res/raw/v30_comma_separated.vcf
@@ -1,5 +1,5 @@
BEGIN:VCARD
VERSION:3.0
-N:F;G;M;;
-TEL;TYPE=PAGER,WORK,MSG:6101231234@pagersample.com
+N;TYPE=PREF,HOME:F;G;M;;
+TEL;TYPE="COMMA,SEPARATED:INSIDE.DQUOTE",PREF:1
END:VCARD
diff --git a/core/tests/coretests/res/raw/v30_multibyte_param.vcf b/core/tests/coretests/res/raw/v30_multibyte_param.vcf
new file mode 100644
index 000000000000..cd200e563d11
--- /dev/null
+++ b/core/tests/coretests/res/raw/v30_multibyte_param.vcf
@@ -0,0 +1,5 @@
+BEGIN:VCARD
+VERSION:3.0
+N:F;G;M;;
+TEL;TYPE="费":1
+END:VCARD
diff --git a/core/tests/coretests/res/raw/v30_pager.vcf b/core/tests/coretests/res/raw/v30_pager.vcf
new file mode 100644
index 000000000000..98a7f20588a1
--- /dev/null
+++ b/core/tests/coretests/res/raw/v30_pager.vcf
@@ -0,0 +1,5 @@
+BEGIN:VCARD
+VERSION:3.0
+N:F;G;M;;
+TEL;TYPE=PAGER,WORK,MSG:6101231234@pagersample.com
+END:VCARD
diff --git a/core/tests/coretests/res/raw/v40_sort_as.vcf b/core/tests/coretests/res/raw/v40_sort_as.vcf
new file mode 100644
index 000000000000..6f6bc3b15662
--- /dev/null
+++ b/core/tests/coretests/res/raw/v40_sort_as.vcf
@@ -0,0 +1,6 @@
+BEGIN:VCARD
+VERSION:4.0
+FN:安藤 ロイド
+N;SORT-AS="あんどう;ろいど":安藤;ロイド;;;
+ORG;TYPE=WORK;SORT-AS="ぐーぐる;けんさくぶもん":グーグル;検索部門
+END:VCARD
diff --git a/core/tests/coretests/src/android/app/activity/LifecycleTest.java b/core/tests/coretests/src/android/app/activity/LifecycleTest.java
index 768a9a446e08..ed01fac5e0a9 100644
--- a/core/tests/coretests/src/android/app/activity/LifecycleTest.java
+++ b/core/tests/coretests/src/android/app/activity/LifecycleTest.java
@@ -18,10 +18,7 @@ package android.app.activity;
import android.content.ComponentName;
import android.content.Intent;
-import android.test.FlakyTest;
-import android.test.suitebuilder.annotation.LargeTest;
import android.test.suitebuilder.annotation.MediumTest;
-import android.test.suitebuilder.annotation.SmallTest;
import android.test.suitebuilder.annotation.Suppress;
public class LifecycleTest extends ActivityTestsBase {
@@ -37,7 +34,7 @@ public class LifecycleTest extends ActivityTestsBase {
LaunchpadActivity.class));
}
- @LargeTest
+ @MediumTest
public void testBasic() throws Exception {
mIntent = mTopIntent;
runLaunchpad(LaunchpadActivity.LIFECYCLE_BASIC);
diff --git a/core/tests/coretests/src/android/app/activity/MetaDataTest.java b/core/tests/coretests/src/android/app/activity/MetaDataTest.java
index 214bc9106cdc..5b9c0e903135 100644
--- a/core/tests/coretests/src/android/app/activity/MetaDataTest.java
+++ b/core/tests/coretests/src/android/app/activity/MetaDataTest.java
@@ -27,7 +27,6 @@ import android.content.res.TypedArray;
import android.content.res.XmlResourceParser;
import android.os.Bundle;
import android.test.AndroidTestCase;
-import android.test.suitebuilder.annotation.MediumTest;
import android.test.suitebuilder.annotation.SmallTest;
import com.android.frameworks.coretests.R;
import org.xmlpull.v1.XmlPullParser;
@@ -134,7 +133,7 @@ public class MetaDataTest extends AndroidTestCase {
assertNull("Meta data returned when not requested", si.metaData);
}
- @MediumTest
+ @SmallTest
public void testProviderWithData() throws Exception {
ComponentName cn = new ComponentName(mContext, LocalProvider.class);
ProviderInfo pi = mContext.getPackageManager().resolveContentProvider(
diff --git a/core/tests/coretests/src/android/bluetooth/BluetoothStressTest.java b/core/tests/coretests/src/android/bluetooth/BluetoothStressTest.java
index d8d9eba14dc3..149685c2a6fa 100644
--- a/core/tests/coretests/src/android/bluetooth/BluetoothStressTest.java
+++ b/core/tests/coretests/src/android/bluetooth/BluetoothStressTest.java
@@ -78,4 +78,50 @@ public class BluetoothStressTest extends InstrumentationTestCase {
mTestUtils.disable(adapter);
}
+
+ public void testPair() {
+ BluetoothAdapter adapter = BluetoothAdapter.getDefaultAdapter();
+ BluetoothDevice device = adapter.getRemoteDevice(BluetoothTestRunner.sHeadsetAddress);
+
+ mTestUtils.enable(adapter);
+ mTestUtils.pair(adapter, device);
+ mTestUtils.unpair(adapter, device);
+ mTestUtils.disable(adapter);
+ }
+
+ public void testConnectA2dp() {
+ int iterations = BluetoothTestRunner.sConnectA2dpIterations;
+ BluetoothAdapter adapter = BluetoothAdapter.getDefaultAdapter();
+ BluetoothDevice device = adapter.getRemoteDevice(BluetoothTestRunner.sA2dpAddress);
+
+ mTestUtils.enable(adapter);
+ mTestUtils.pair(adapter, device);
+
+ for (int i = 0; i < iterations; i++) {
+ mTestUtils.writeOutput("connectA2dp iteration " + (i + 1) + " of " + iterations);
+ mTestUtils.connectA2dp(adapter, device);
+ mTestUtils.disconnectA2dp(adapter, device);
+ }
+
+ // TODO: Unpair from device if device can accept pairing after unpairing
+ mTestUtils.disable(adapter);
+ }
+
+ public void testConnectHeadset() {
+ int iterations = BluetoothTestRunner.sConnectHeadsetIterations;
+ BluetoothAdapter adapter = BluetoothAdapter.getDefaultAdapter();
+ BluetoothDevice device = adapter.getRemoteDevice(BluetoothTestRunner.sHeadsetAddress);
+
+ mTestUtils.enable(adapter);
+ mTestUtils.pair(adapter, device);
+
+ for (int i = 0; i < iterations; i++) {
+ mTestUtils.writeOutput("connectHeadset iteration " + (i + 1) + " of " + iterations);
+ mTestUtils.connectHeadset(adapter, device);
+ mTestUtils.disconnectHeadset(adapter, device);
+ }
+
+ // TODO: Unpair from device if device can accept pairing after unpairing
+ mTestUtils.disable(adapter);
+ }
}
diff --git a/core/tests/coretests/src/android/bluetooth/BluetoothTestRunner.java b/core/tests/coretests/src/android/bluetooth/BluetoothTestRunner.java
index cf0ff99d1283..2e6daa33f6e0 100644
--- a/core/tests/coretests/src/android/bluetooth/BluetoothTestRunner.java
+++ b/core/tests/coretests/src/android/bluetooth/BluetoothTestRunner.java
@@ -26,6 +26,11 @@ public class BluetoothTestRunner extends InstrumentationTestRunner {
public static int sEnableIterations = 100;
public static int sDiscoverableIterations = 1000;
public static int sScanIterations = 1000;
+ public static int sConnectHeadsetIterations = 100;
+ public static int sConnectA2dpIterations = 100;
+
+ public static String sHeadsetAddress = "";
+ public static String sA2dpAddress = "";
@Override
public TestSuite getAllTests() {
@@ -69,5 +74,33 @@ public class BluetoothTestRunner extends InstrumentationTestRunner {
// Invalid argument, fall back to default value
}
}
+
+ val = arguments.getString("connect_a2dp_iterations");
+ if (val != null) {
+ try {
+ sConnectA2dpIterations = Integer.parseInt(val);
+ } catch (NumberFormatException e) {
+ // Invalid argument, fall back to default value
+ }
+ }
+
+ val = arguments.getString("connect_headset_iterations");
+ if (val != null) {
+ try {
+ sConnectHeadsetIterations = Integer.parseInt(val);
+ } catch (NumberFormatException e) {
+ // Invalid argument, fall back to default value
+ }
+ }
+
+ val = arguments.getString("headset_address");
+ if (val != null) {
+ sHeadsetAddress = val;
+ }
+
+ val = arguments.getString("a2dp_address");
+ if (val != null) {
+ sA2dpAddress = val;
+ }
}
}
diff --git a/core/tests/coretests/src/android/bluetooth/BluetoothTestUtils.java b/core/tests/coretests/src/android/bluetooth/BluetoothTestUtils.java
index 82de5098e66b..e9311e08f2ea 100644
--- a/core/tests/coretests/src/android/bluetooth/BluetoothTestUtils.java
+++ b/core/tests/coretests/src/android/bluetooth/BluetoothTestUtils.java
@@ -16,6 +16,7 @@
package android.bluetooth;
+import android.bluetooth.BluetoothHeadset.ServiceListener;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
@@ -57,6 +58,36 @@ public class BluetoothTestUtils extends Assert {
*/
private static final int CANCEL_DISCOVERY_TIMEOUT = 5000;
+ /**
+ * Timeout for {@link BluetoothDevice#createBond()} in ms.
+ */
+ private static final int PAIR_TIMEOUT = 20000;
+
+ /**
+ * Timeout for {@link BluetoothDevice#removeBond()} in ms.
+ */
+ private static final int UNPAIR_TIMEOUT = 20000;
+
+ /**
+ * Timeout for {@link BluetoothA2dp#connectSink(BluetoothDevice)} in ms.
+ */
+ private static final int CONNECT_A2DP_TIMEOUT = 20000;
+
+ /**
+ * Timeout for {@link BluetoothA2dp#disconnectSink(BluetoothDevice)} in ms.
+ */
+ private static final int DISCONNECT_A2DP_TIMEOUT = 20000;
+
+ /**
+ * Timeout for {@link BluetoothHeadset#connectHeadset(BluetoothDevice)} in ms.
+ */
+ private static final int CONNECT_HEADSET_TIMEOUT = 20000;
+
+ /**
+ * Timeout for {@link BluetoothHeadset#disconnectHeadset(BluetoothDevice)} in ms.
+ */
+ private static final int DISCONNECT_HEADSET_TIMEOUT = 20000;
+
private static final int DISCOVERY_STARTED_FLAG = 1;
private static final int DISCOVERY_FINISHED_FLAG = 1 << 1;
private static final int SCAN_MODE_NONE_FLAG = 1 << 2;
@@ -66,6 +97,23 @@ public class BluetoothTestUtils extends Assert {
private static final int STATE_TURNING_ON_FLAG = 1 << 6;
private static final int STATE_ON_FLAG = 1 << 7;
private static final int STATE_TURNING_OFF_FLAG = 1 << 8;
+ private static final int PAIR_STATE_FLAG = 1 << 9;
+ private static final int PROFILE_A2DP_FLAG = 1 << 10;
+ private static final int PROFILE_HEADSET_FLAG = 1 << 11;
+
+ private static final int PAIR_STATE_BONDED = 1;
+ private static final int PAIR_STATE_BONDING = 1 << 1;
+ private static final int PAIR_STATE_NONE = 1 << 2;
+
+ private static final int A2DP_STATE_DISCONNECTED = 1;
+ private static final int A2DP_STATE_CONNECTING = 1 << 1;
+ private static final int A2DP_STATE_CONNECTED = 1 << 2;
+ private static final int A2DP_STATE_DISCONNECTING = 1 << 3;
+ private static final int A2DP_STATE_PLAYING = 1 << 4;
+
+ private static final int HEADSET_STATE_DISCONNECTED = 1;
+ private static final int HEADSET_STATE_CONNECTING = 1 << 1;
+ private static final int HEADSET_STATE_CONNECTED = 1 << 2;
/**
* Time between polls in ms.
@@ -76,11 +124,43 @@ public class BluetoothTestUtils extends Assert {
private BufferedWriter mOutputWriter;
+ private BluetoothA2dp mA2dp;
+
+ private BluetoothHeadset mHeadset;
+
private String mOutputFile;
private String mTag;
+ private class HeadsetServiceListener implements ServiceListener {
+ private boolean mConnected = false;
+
+ @Override
+ public void onServiceConnected() {
+ synchronized (this) {
+ mConnected = true;
+ }
+ }
+
+ @Override
+ public void onServiceDisconnected() {
+ synchronized (this) {
+ mConnected = false;
+ }
+ }
+
+ public boolean isConnected() {
+ synchronized (this) {
+ return mConnected;
+ }
+ }
+ }
+
+ private HeadsetServiceListener mHeadsetServiceListener = new HeadsetServiceListener();
private class BluetoothReceiver extends BroadcastReceiver {
private int mFiredFlags = 0;
+ private int mPairFiredFlags = 0;
+ private int mA2dpFiredFlags = 0;
+ private int mHeadsetFiredFlags = 0;
@Override
public void onReceive(Context context, Intent intent) {
@@ -122,6 +202,58 @@ public class BluetoothTestUtils extends Assert {
mFiredFlags |= STATE_TURNING_OFF_FLAG;
break;
}
+ } else if (BluetoothDevice.ACTION_BOND_STATE_CHANGED.equals(intent.getAction())) {
+ mFiredFlags |= PAIR_STATE_FLAG;
+ int state = intent.getIntExtra(BluetoothDevice.EXTRA_BOND_STATE, -1);
+ assertNotSame(state, -1);
+ switch (state) {
+ case BluetoothDevice.BOND_BONDED:
+ mPairFiredFlags |= PAIR_STATE_BONDED;
+ break;
+ case BluetoothDevice.BOND_BONDING:
+ mPairFiredFlags |= PAIR_STATE_BONDING;
+ break;
+ case BluetoothDevice.BOND_NONE:
+ mPairFiredFlags |= PAIR_STATE_NONE;
+ break;
+ }
+ } else if (BluetoothA2dp.ACTION_SINK_STATE_CHANGED.equals(intent.getAction())) {
+ mFiredFlags |= PROFILE_A2DP_FLAG;
+ int state = intent.getIntExtra(BluetoothA2dp.EXTRA_SINK_STATE, -1);
+ assertNotSame(state, -1);
+ switch (state) {
+ case BluetoothA2dp.STATE_DISCONNECTED:
+ mA2dpFiredFlags |= A2DP_STATE_DISCONNECTED;
+ break;
+ case BluetoothA2dp.STATE_CONNECTING:
+ mA2dpFiredFlags |= A2DP_STATE_CONNECTING;
+ break;
+ case BluetoothA2dp.STATE_CONNECTED:
+ mA2dpFiredFlags |= A2DP_STATE_CONNECTED;
+ break;
+ case BluetoothA2dp.STATE_DISCONNECTING:
+ mA2dpFiredFlags |= A2DP_STATE_DISCONNECTING;
+ break;
+ case BluetoothA2dp.STATE_PLAYING:
+ mA2dpFiredFlags |= A2DP_STATE_PLAYING;
+ break;
+ }
+ } else if (BluetoothHeadset.ACTION_STATE_CHANGED.equals(intent.getAction())) {
+ mFiredFlags |= PROFILE_HEADSET_FLAG;
+ int state = intent.getIntExtra(BluetoothHeadset.EXTRA_STATE,
+ BluetoothHeadset.STATE_ERROR);
+ assertNotSame(state, BluetoothHeadset.STATE_ERROR);
+ switch (state) {
+ case BluetoothHeadset.STATE_DISCONNECTED:
+ mHeadsetFiredFlags |= HEADSET_STATE_DISCONNECTED;
+ break;
+ case BluetoothHeadset.STATE_CONNECTING:
+ mHeadsetFiredFlags |= HEADSET_STATE_CONNECTING;
+ break;
+ case BluetoothHeadset.STATE_CONNECTED:
+ mHeadsetFiredFlags |= HEADSET_STATE_CONNECTED;
+ break;
+ }
}
}
}
@@ -132,9 +264,30 @@ public class BluetoothTestUtils extends Assert {
}
}
+ public int getPairFiredFlags() {
+ synchronized (this) {
+ return mPairFiredFlags;
+ }
+ }
+
+ public int getA2dpFiredFlags() {
+ synchronized (this) {
+ return mA2dpFiredFlags;
+ }
+ }
+
+ public int getHeadsetFiredFlags() {
+ synchronized (this) {
+ return mHeadsetFiredFlags;
+ }
+ }
+
public void resetFiredFlags() {
synchronized (this) {
mFiredFlags = 0;
+ mPairFiredFlags = 0;
+ mA2dpFiredFlags = 0;
+ mHeadsetFiredFlags = 0;
}
}
}
@@ -419,6 +572,351 @@ public class BluetoothTestUtils extends Assert {
}
+ public void pair(BluetoothAdapter adapter, BluetoothDevice device) {
+ int mask = PAIR_STATE_FLAG;
+ int pairMask = PAIR_STATE_BONDING | PAIR_STATE_BONDED;
+ mReceiver.resetFiredFlags();
+
+ if (!adapter.isEnabled()) {
+ fail("pair() bluetooth not enabled");
+ }
+
+ int state = device.getBondState();
+ switch (state) {
+ case BluetoothDevice.BOND_BONDED:
+ assertTrue(adapter.getBondedDevices().contains(device));
+ return;
+ case BluetoothDevice.BOND_BONDING:
+ // Don't check for received intents since we might have missed them.
+ mask = pairMask = 0;
+ break;
+ case BluetoothDevice.BOND_NONE:
+ assertFalse(adapter.getBondedDevices().contains(device));
+ assertTrue(device.createBond());
+ break;
+ default:
+ fail("pair() invalide state: state=" + state);
+ }
+
+ long s = System.currentTimeMillis();
+ while (System.currentTimeMillis() - s < PAIR_TIMEOUT) {
+ state = device.getBondState();
+ if (state == BluetoothDevice.BOND_BONDED) {
+ assertTrue(adapter.getBondedDevices().contains(device));
+ if ((mReceiver.getFiredFlags() & mask) == mask
+ && (mReceiver.getPairFiredFlags() & pairMask) == pairMask) {
+ writeOutput(String.format("pair() completed in %d ms: device=%s",
+ (System.currentTimeMillis() - s), device));
+ return;
+ }
+ }
+ sleep(POLL_TIME);
+ }
+
+ int firedFlags = mReceiver.getFiredFlags();
+ int pairFiredFlags = mReceiver.getPairFiredFlags();
+ mReceiver.resetFiredFlags();
+ fail(String.format("pair() timeout: state=%d (expected %d), flags=0x%x (expected 0x%x), "
+ + "pairFlags=0x%x (expected 0x%x)", state, BluetoothDevice.BOND_BONDED, firedFlags,
+ mask, pairFiredFlags, pairMask));
+ }
+
+ public void unpair(BluetoothAdapter adapter, BluetoothDevice device) {
+ int mask = PAIR_STATE_FLAG;
+ int pairMask = PAIR_STATE_NONE;
+ mReceiver.resetFiredFlags();
+
+ if (!adapter.isEnabled()) {
+ fail("unpair() bluetooth not enabled");
+ }
+
+ int state = device.getBondState();
+ switch (state) {
+ case BluetoothDevice.BOND_BONDED:
+ assertTrue(adapter.getBondedDevices().contains(device));
+ assertTrue(device.removeBond());
+ break;
+ case BluetoothDevice.BOND_BONDING:
+ assertTrue(device.removeBond());
+ break;
+ case BluetoothDevice.BOND_NONE:
+ assertFalse(adapter.getBondedDevices().contains(device));
+ return;
+ default:
+ fail("unpair() invalid state: state=" + state);
+ }
+
+ assertTrue(device.removeBond());
+
+ long s = System.currentTimeMillis();
+ while (System.currentTimeMillis() - s < UNPAIR_TIMEOUT) {
+ if (device.getBondState() == BluetoothDevice.BOND_NONE) {
+ assertFalse(adapter.getBondedDevices().contains(device));
+ if ((mReceiver.getFiredFlags() & mask) == mask
+ && (mReceiver.getPairFiredFlags() & pairMask) == pairMask) {
+ writeOutput(String.format("unpair() completed in %d ms: device=%s",
+ (System.currentTimeMillis() - s), device));
+ return;
+ }
+ }
+ }
+
+ int firedFlags = mReceiver.getFiredFlags();
+ int pairFiredFlags = mReceiver.getPairFiredFlags();
+ mReceiver.resetFiredFlags();
+ fail(String.format("unpair() timeout: state=%d (expected %d), flags=0x%x (expected 0x%x), "
+ + "pairFlags=0x%x (expected 0x%x)", state, BluetoothDevice.BOND_BONDED, firedFlags,
+ mask, pairFiredFlags, pairMask));
+ }
+
+ public void connectA2dp(BluetoothAdapter adapter, BluetoothDevice device) {
+ int mask = PROFILE_A2DP_FLAG;
+ int a2dpMask1 = A2DP_STATE_CONNECTING | A2DP_STATE_CONNECTED | A2DP_STATE_PLAYING;
+ int a2dpMask2 = a2dpMask1 ^ A2DP_STATE_CONNECTED;
+ int a2dpMask3 = a2dpMask1 ^ A2DP_STATE_PLAYING;
+ mReceiver.resetFiredFlags();
+
+ if (!adapter.isEnabled()) {
+ fail("connectA2dp() bluetooth not enabled");
+ }
+
+ if (!adapter.getBondedDevices().contains(device)) {
+ fail("connectA2dp() device not paired: device=" + device);
+ }
+
+ int state = mA2dp.getSinkState(device);
+ switch (state) {
+ case BluetoothA2dp.STATE_CONNECTED:
+ case BluetoothA2dp.STATE_PLAYING:
+ assertTrue(mA2dp.isSinkConnected(device));
+ return;
+ case BluetoothA2dp.STATE_DISCONNECTING:
+ case BluetoothA2dp.STATE_DISCONNECTED:
+ assertFalse(mA2dp.isSinkConnected(device));
+ assertTrue(mA2dp.connectSink(device));
+ break;
+ case BluetoothA2dp.STATE_CONNECTING:
+ assertFalse(mA2dp.isSinkConnected(device));
+ // Don't check for received intents since we might have missed them.
+ mask = a2dpMask1 = a2dpMask2 = a2dpMask3 = 0;
+ break;
+ default:
+ fail("connectA2dp() invalid state: state=" + state);
+ }
+
+ long s = System.currentTimeMillis();
+ while (System.currentTimeMillis() - s < CONNECT_A2DP_TIMEOUT) {
+ state = mA2dp.getSinkState(device);
+ if (state == BluetoothA2dp.STATE_CONNECTED || state == BluetoothA2dp.STATE_PLAYING) {
+ assertTrue(mA2dp.isSinkConnected(device));
+ // Check whether STATE_CONNECTING and (STATE_CONNECTED or STATE_PLAYING) intents
+ // have fired if we are checking if intents should be fired.
+ int firedFlags = mReceiver.getFiredFlags();
+ int a2dpFiredFlags = mReceiver.getA2dpFiredFlags();
+ if ((mReceiver.getFiredFlags() & mask) == mask
+ && ((a2dpFiredFlags & a2dpMask1) == a2dpMask1
+ || (a2dpFiredFlags & a2dpMask2) == a2dpMask2
+ || (a2dpFiredFlags & a2dpMask3) == a2dpMask3)) {
+ mReceiver.resetFiredFlags();
+ writeOutput(String.format("connectA2dp() completed in %d ms: device=%s",
+ (System.currentTimeMillis() - s), device));
+ return;
+ }
+ }
+ sleep(POLL_TIME);
+ }
+
+ int firedFlags = mReceiver.getFiredFlags();
+ int a2dpFiredFlags = mReceiver.getA2dpFiredFlags();
+ mReceiver.resetFiredFlags();
+ fail(String.format("connectA2dp() timeout: state=%d (expected %d or %d), "
+ + "flags=0x%x (expected 0x%x), a2dpFlags=0x%x (expected 0x%x or 0x%x or 0x%x)",
+ state, BluetoothHeadset.STATE_CONNECTED, BluetoothA2dp.STATE_PLAYING, firedFlags,
+ mask, a2dpFiredFlags, a2dpMask1, a2dpMask2, a2dpMask3));
+ }
+
+ public void disconnectA2dp(BluetoothAdapter adapter, BluetoothDevice device) {
+ int mask = PROFILE_A2DP_FLAG;
+ int a2dpMask = A2DP_STATE_DISCONNECTING | A2DP_STATE_DISCONNECTED;
+ mReceiver.resetFiredFlags();
+
+ if (!adapter.isEnabled()) {
+ fail("disconnectA2dp() bluetooth not enabled");
+ }
+
+ if (!adapter.getBondedDevices().contains(device)) {
+ fail("disconnectA2dp() device not paired: device=" + device);
+ }
+
+ int state = mA2dp.getSinkState(device);
+ switch (state) {
+ case BluetoothA2dp.STATE_DISCONNECTED:
+ assertFalse(mA2dp.isSinkConnected(device));
+ return;
+ case BluetoothA2dp.STATE_CONNECTED:
+ case BluetoothA2dp.STATE_PLAYING:
+ assertTrue(mA2dp.isSinkConnected(device));
+ assertTrue(mA2dp.disconnectSink(device));
+ break;
+ case BluetoothA2dp.STATE_CONNECTING:
+ assertFalse(mA2dp.isSinkConnected(device));
+ assertTrue(mA2dp.disconnectSink(device));
+ break;
+ case BluetoothA2dp.STATE_DISCONNECTING:
+ assertFalse(mA2dp.isSinkConnected(device));
+ // Don't check for received intents since we might have missed them.
+ mask = a2dpMask = 0;
+ break;
+ default:
+ fail("disconnectA2dp() invalid state: state=" + state);
+ }
+
+ long s = System.currentTimeMillis();
+ while (System.currentTimeMillis() - s < DISCONNECT_A2DP_TIMEOUT) {
+ state = mA2dp.getSinkState(device);
+ if (state == BluetoothA2dp.STATE_DISCONNECTED) {
+ assertFalse(mA2dp.isSinkConnected(device));
+ if ((mReceiver.getFiredFlags() & mask) == mask
+ && (mReceiver.getA2dpFiredFlags() & a2dpMask) == a2dpMask) {
+ mReceiver.resetFiredFlags();
+ writeOutput(String.format("disconnectA2dp() completed in %d ms: device=%s",
+ (System.currentTimeMillis() - s), device));
+ return;
+ }
+ }
+ sleep(POLL_TIME);
+ }
+
+ int firedFlags = mReceiver.getFiredFlags();
+ int a2dpFiredFlags = mReceiver.getA2dpFiredFlags();
+ mReceiver.resetFiredFlags();
+ fail(String.format("disconnectA2dp() timeout: state=%d (expected %d), "
+ + "flags=0x%x (expected 0x%x), a2dpFlags=0x%x (expected 0x%x)", state,
+ BluetoothA2dp.STATE_DISCONNECTED, firedFlags, mask, a2dpFiredFlags, a2dpMask));
+ }
+
+ public void connectHeadset(BluetoothAdapter adapter, BluetoothDevice device) {
+ int mask = PROFILE_HEADSET_FLAG;
+ int headsetMask = HEADSET_STATE_CONNECTING | HEADSET_STATE_CONNECTED;
+ mReceiver.resetFiredFlags();
+
+ if (!adapter.isEnabled()) {
+ fail("connectHeadset() bluetooth not enabled");
+ }
+
+ if (!adapter.getBondedDevices().contains(device)) {
+ fail("connectHeadset() device not paired: device=" + device);
+ }
+
+ while (!mHeadsetServiceListener.isConnected()) {
+ sleep(POLL_TIME);
+ }
+
+ int state = mHeadset.getState(device);
+ switch (state) {
+ case BluetoothHeadset.STATE_CONNECTED:
+ assertTrue(mHeadset.isConnected(device));
+ return;
+ case BluetoothHeadset.STATE_DISCONNECTED:
+ assertFalse(mHeadset.isConnected(device));
+ mHeadset.connectHeadset(device);
+ break;
+ case BluetoothHeadset.STATE_CONNECTING:
+ assertFalse(mHeadset.isConnected(device));
+ // Don't check for received intents since we might have missed them.
+ mask = headsetMask = 0;
+ break;
+ case BluetoothHeadset.STATE_ERROR:
+ fail("connectHeadset() error state");
+ break;
+ default:
+ fail("connectHeadset() invalid state: state=" + state);
+ }
+
+ long s = System.currentTimeMillis();
+ while (System.currentTimeMillis() - s < CONNECT_HEADSET_TIMEOUT) {
+ state = mHeadset.getState(device);
+ if (state == BluetoothHeadset.STATE_CONNECTED) {
+ assertTrue(mHeadset.isConnected(device));
+ if ((mReceiver.getFiredFlags() & mask) == mask
+ && (mReceiver.getHeadsetFiredFlags() & headsetMask) == headsetMask) {
+ mReceiver.resetFiredFlags();
+ writeOutput(String.format("connectHeadset() completed in %d ms: device=%s",
+ (System.currentTimeMillis() - s), device));
+ return;
+ }
+ }
+ sleep(POLL_TIME);
+ }
+
+ int firedFlags = mReceiver.getFiredFlags();
+ int headsetFiredFlags = mReceiver.getHeadsetFiredFlags();
+ mReceiver.resetFiredFlags();
+ fail(String.format("connectHeadset() timeout: state=%d (expected %d), "
+ + "flags=0x%x (expected 0x%x), headsetFlags=0x%s (expected 0x%x)", state,
+ BluetoothHeadset.STATE_CONNECTED, firedFlags, mask, headsetFiredFlags,
+ headsetMask));
+ }
+
+ public void disconnectHeadset(BluetoothAdapter adapter, BluetoothDevice device) {
+ int mask = PROFILE_HEADSET_FLAG;
+ int headsetMask = HEADSET_STATE_DISCONNECTED;
+ mReceiver.resetFiredFlags();
+
+ if (!adapter.isEnabled()) {
+ fail("disconnectHeadset() bluetooth not enabled");
+ }
+
+ if (!adapter.getBondedDevices().contains(device)) {
+ fail("disconnectHeadset() device not paired: device=" + device);
+ }
+
+ while (!mHeadsetServiceListener.isConnected()) {
+ sleep(POLL_TIME);
+ }
+
+ int state = mHeadset.getState(device);
+ switch (state) {
+ case BluetoothHeadset.STATE_CONNECTED:
+ mHeadset.disconnectHeadset(device);
+ break;
+ case BluetoothHeadset.STATE_CONNECTING:
+ mHeadset.disconnectHeadset(device);
+ break;
+ case BluetoothHeadset.STATE_DISCONNECTED:
+ return;
+ case BluetoothHeadset.STATE_ERROR:
+ fail("disconnectHeadset() error state");
+ break;
+ default:
+ fail("disconnectHeadset() invalid state: state=" + state);
+ }
+
+ long s = System.currentTimeMillis();
+ while (System.currentTimeMillis() - s < DISCONNECT_HEADSET_TIMEOUT) {
+ state = mHeadset.getState(device);
+ if (state == BluetoothHeadset.STATE_DISCONNECTED) {
+ assertFalse(mHeadset.isConnected(device));
+ if ((mReceiver.getFiredFlags() & mask) == mask
+ && (mReceiver.getHeadsetFiredFlags() & headsetMask) == headsetMask) {
+ mReceiver.resetFiredFlags();
+ writeOutput(String.format("disconnectHeadset() completed in %d ms: device=%s",
+ (System.currentTimeMillis() - s), device));
+ return;
+ }
+ }
+ sleep(POLL_TIME);
+ }
+
+ int firedFlags = mReceiver.getFiredFlags();
+ int headsetFiredFlags = mReceiver.getHeadsetFiredFlags();
+ mReceiver.resetFiredFlags();
+ fail(String.format("disconnectHeadset() timeout: state=%d (expected %d), "
+ + "flags=0x%x (expected 0x%x), headsetFlags=0x%s (expected 0x%x)", state,
+ BluetoothHeadset.STATE_DISCONNECTED, firedFlags, mask, headsetFiredFlags,
+ headsetMask));
+ }
+
public void writeOutput(String s) {
Log.i(mTag, s);
if (mOutputWriter == null) {
diff --git a/core/tests/coretests/src/android/content/BrickDeniedTest.java b/core/tests/coretests/src/android/content/BrickDeniedTest.java
index c7d0b7acab66..3d246b457ed5 100644
--- a/core/tests/coretests/src/android/content/BrickDeniedTest.java
+++ b/core/tests/coretests/src/android/content/BrickDeniedTest.java
@@ -16,13 +16,12 @@
package android.content;
-import android.content.Intent;
import android.test.AndroidTestCase;
-import android.test.suitebuilder.annotation.MediumTest;
+import android.test.suitebuilder.annotation.SmallTest;
/** Test to make sure brick intents <b>don't</b> work without permission. */
public class BrickDeniedTest extends AndroidTestCase {
- @MediumTest
+ @SmallTest
public void testBrick() {
// Try both the old and new brick intent names. Neither should work,
// since this test application doesn't have the required permission.
diff --git a/core/tests/coretests/src/android/content/MemoryFileProviderTest.java b/core/tests/coretests/src/android/content/MemoryFileProviderTest.java
index 6708af6e83d8..62b4e7e1ce96 100644
--- a/core/tests/coretests/src/android/content/MemoryFileProviderTest.java
+++ b/core/tests/coretests/src/android/content/MemoryFileProviderTest.java
@@ -16,10 +16,11 @@
package android.content;
-import android.content.ContentResolver;
import android.net.Uri;
import android.test.AndroidTestCase;
+import android.test.suitebuilder.annotation.LargeTest;
import android.test.suitebuilder.annotation.MediumTest;
+import android.test.suitebuilder.annotation.SmallTest;
import java.io.InputStream;
import java.util.Arrays;
@@ -46,7 +47,7 @@ public class MemoryFileProviderTest extends AndroidTestCase {
}
// tests that we don't leak file descriptors or virtual address space
- @MediumTest
+ @LargeTest
public void testClose() throws Exception {
ContentResolver resolver = getContext().getContentResolver();
// open enough file descriptors that we will crash something if we leak FDs
@@ -65,7 +66,7 @@ public class MemoryFileProviderTest extends AndroidTestCase {
}
// tests that we haven't broken AssestFileDescriptors for normal files.
- @MediumTest
+ @SmallTest
public void testFile() throws Exception {
ContentResolver resolver = getContext().getContentResolver();
Uri uri = Uri.parse("content://android.content.MemoryFileProvider/file");
diff --git a/core/tests/coretests/src/android/content/SyncStorageEngineTest.java b/core/tests/coretests/src/android/content/SyncStorageEngineTest.java
index f84051276bc0..0b494a768552 100644
--- a/core/tests/coretests/src/android/content/SyncStorageEngineTest.java
+++ b/core/tests/coretests/src/android/content/SyncStorageEngineTest.java
@@ -18,17 +18,19 @@ package android.content;
import com.android.internal.os.AtomicFile;
+import android.accounts.Account;
+import android.os.Bundle;
import android.test.AndroidTestCase;
import android.test.RenamingDelegatingContext;
-import android.test.suitebuilder.annotation.SmallTest;
-import android.test.mock.MockContext;
import android.test.mock.MockContentResolver;
-import android.accounts.Account;
-import android.os.Bundle;
+import android.test.mock.MockContext;
+import android.test.suitebuilder.annotation.LargeTest;
+import android.test.suitebuilder.annotation.MediumTest;
+import android.test.suitebuilder.annotation.SmallTest;
-import java.util.List;
import java.io.File;
import java.io.FileOutputStream;
+import java.util.List;
public class SyncStorageEngineTest extends AndroidTestCase {
@@ -57,7 +59,7 @@ public class SyncStorageEngineTest extends AndroidTestCase {
/**
* Test that we can create, remove and retrieve periodic syncs
*/
- @SmallTest
+ @MediumTest
public void testPeriodics() throws Exception {
final Account account1 = new Account("a@example.com", "example.type");
final Account account2 = new Account("b@example.com", "example.type.2");
@@ -114,7 +116,7 @@ public class SyncStorageEngineTest extends AndroidTestCase {
}
}
- @SmallTest
+ @LargeTest
public void testAuthorityPersistence() throws Exception {
final Account account1 = new Account("a@example.com", "example.type");
final Account account2 = new Account("b@example.com", "example.type.2");
@@ -197,7 +199,7 @@ public class SyncStorageEngineTest extends AndroidTestCase {
assertEquals(0, engine.getIsSyncable(account2, authority2));
}
- @SmallTest
+ @MediumTest
public void testAuthorityParsing() throws Exception {
final Account account = new Account("account1", "type1");
final String authority1 = "auth1";
@@ -299,7 +301,7 @@ public class SyncStorageEngineTest extends AndroidTestCase {
assertEquals(sync3s, syncs.get(0));
}
- @SmallTest
+ @MediumTest
public void testAuthorityRenaming() throws Exception {
final Account account1 = new Account("acc1", "type1");
final Account account2 = new Account("acc2", "type2");
diff --git a/core/tests/coretests/src/android/content/pm/AppCacheTest.java b/core/tests/coretests/src/android/content/pm/AppCacheTest.java
index dbb10b1ba36d..dd252203b808 100755
--- a/core/tests/coretests/src/android/content/pm/AppCacheTest.java
+++ b/core/tests/coretests/src/android/content/pm/AppCacheTest.java
@@ -16,32 +16,25 @@
package android.content.pm;
-import java.io.File;
-import java.io.FileInputStream;
-import java.io.FileNotFoundException;
-import java.io.FileOutputStream;
-import java.io.IOException;
-
import android.app.PendingIntent;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
-import android.content.pm.ApplicationInfo;
-import android.content.pm.IPackageDataObserver;
-import android.content.pm.IPackageStatsObserver;
-import android.content.pm.PackageStats;
-import android.content.pm.IPackageManager;
+import android.os.RemoteException;
+import android.os.ServiceManager;
+import android.os.StatFs;
import android.test.AndroidTestCase;
import android.test.suitebuilder.annotation.LargeTest;
import android.test.suitebuilder.annotation.MediumTest;
import android.test.suitebuilder.annotation.SmallTest;
-import android.test.suitebuilder.annotation.Suppress;
import android.util.Log;
-import android.os.Handler;
-import android.os.RemoteException;
-import android.os.ServiceManager;
-import android.os.StatFs;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileNotFoundException;
+import java.io.FileOutputStream;
+import java.io.IOException;
public class AppCacheTest extends AndroidTestCase {
private static final boolean localLOGV = false;
@@ -627,7 +620,8 @@ public class AppCacheTest extends AndroidTestCase {
}
}
- @SmallTest
+ // TODO: flaky test, omit from LargeTest for now
+ //@LargeTest
public void testFreeStorage() throws Exception {
boolean TRACKING = true;
StatFs st = new StatFs("/data");
diff --git a/core/tests/coretests/src/android/content/pm/ComponentTest.java b/core/tests/coretests/src/android/content/pm/ComponentTest.java
index ebfbd683fcfb..f1a2a9bd172e 100644
--- a/core/tests/coretests/src/android/content/pm/ComponentTest.java
+++ b/core/tests/coretests/src/android/content/pm/ComponentTest.java
@@ -16,6 +16,11 @@
package android.content.pm;
+import static android.content.pm.PackageManager.COMPONENT_ENABLED_STATE_DEFAULT;
+import static android.content.pm.PackageManager.COMPONENT_ENABLED_STATE_DISABLED;
+import static android.content.pm.PackageManager.COMPONENT_ENABLED_STATE_ENABLED;
+import static android.content.pm.PackageManager.GET_DISABLED_COMPONENTS;
+
import com.android.frameworks.coretests.enabled_app.DisabledActivity;
import com.android.frameworks.coretests.enabled_app.DisabledProvider;
import com.android.frameworks.coretests.enabled_app.DisabledReceiver;
@@ -27,21 +32,9 @@ import com.android.frameworks.coretests.enabled_app.EnabledService;
import android.content.ComponentName;
import android.content.Intent;
-import android.content.pm.ActivityInfo;
-import android.content.pm.ComponentInfo;
-import android.content.pm.PackageInfo;
-import android.content.pm.PackageManager;
-import android.test.suitebuilder.annotation.LargeTest;
+import android.test.AndroidTestCase;
import android.test.suitebuilder.annotation.MediumTest;
import android.test.suitebuilder.annotation.SmallTest;
-import static android.content.pm.PackageManager.COMPONENT_ENABLED_STATE_DEFAULT;
-import static android.content.pm.PackageManager.COMPONENT_ENABLED_STATE_DISABLED;
-import static android.content.pm.PackageManager.COMPONENT_ENABLED_STATE_ENABLED;
-import static android.content.pm.PackageManager.GET_DISABLED_COMPONENTS;
-import android.content.pm.ProviderInfo;
-import android.content.pm.ResolveInfo;
-import android.content.pm.ServiceInfo;
-import android.test.AndroidTestCase;
import java.util.List;
@@ -134,7 +127,7 @@ public class ComponentTest extends AndroidTestCase {
assertNotNull(mContext);
}
- @MediumTest
+ @SmallTest
public void testResolveDisabledActivity() throws Exception {
mPackageManager.setComponentEnabledSetting(DISABLED_ACTIVITY_COMPONENTNAME,
COMPONENT_ENABLED_STATE_DEFAULT,
@@ -150,7 +143,7 @@ public class ComponentTest extends AndroidTestCase {
assertFalse(info2.activityInfo.enabled);
}
- @MediumTest
+ @SmallTest
public void testResolveEnabledActivity() throws Exception {
mPackageManager.setComponentEnabledSetting(ENABLED_ACTIVITY_COMPONENTNAME,
COMPONENT_ENABLED_STATE_DEFAULT,
@@ -183,7 +176,7 @@ public class ComponentTest extends AndroidTestCase {
assertFalse(info.activityInfo.enabled);
}
- @MediumTest
+ @SmallTest
public void testQueryEnabledActivity() throws Exception {
mPackageManager.setComponentEnabledSetting(ENABLED_ACTIVITY_COMPONENTNAME,
COMPONENT_ENABLED_STATE_DEFAULT,
@@ -218,7 +211,7 @@ public class ComponentTest extends AndroidTestCase {
assertFalse(activityInfo.enabled);
}
- @MediumTest
+ @SmallTest
public void testGetEnabledActivityInfo() throws Exception {
mPackageManager.setComponentEnabledSetting(ENABLED_ACTIVITY_COMPONENTNAME,
COMPONENT_ENABLED_STATE_DEFAULT,
@@ -253,7 +246,7 @@ public class ComponentTest extends AndroidTestCase {
assertEquals(1, infoList.size());
}
- @LargeTest
+ @MediumTest
public void testDisableActivity() throws Exception {
mPackageManager.setComponentEnabledSetting(ENABLED_ACTIVITY_COMPONENTNAME,
COMPONENT_ENABLED_STATE_DEFAULT,
@@ -281,7 +274,7 @@ public class ComponentTest extends AndroidTestCase {
assertEquals(0, infoList.size());
}
- @MediumTest
+ @SmallTest
public void testResolveDisabledService() throws Exception {
mPackageManager.setComponentEnabledSetting(DISABLED_SERVICE_COMPONENTNAME,
COMPONENT_ENABLED_STATE_DEFAULT,
@@ -297,7 +290,7 @@ public class ComponentTest extends AndroidTestCase {
assertFalse(info2.serviceInfo.enabled);
}
- @MediumTest
+ @SmallTest
public void testResolveEnabledService() throws Exception {
mPackageManager.setComponentEnabledSetting(ENABLED_SERVICE_COMPONENTNAME,
COMPONENT_ENABLED_STATE_DEFAULT,
@@ -310,7 +303,7 @@ public class ComponentTest extends AndroidTestCase {
assertTrue(info.serviceInfo.enabled);
}
- @MediumTest
+ @SmallTest
public void testQueryDisabledService() throws Exception {
mPackageManager.setComponentEnabledSetting(DISABLED_SERVICE_COMPONENTNAME,
COMPONENT_ENABLED_STATE_DEFAULT,
@@ -330,7 +323,7 @@ public class ComponentTest extends AndroidTestCase {
assertFalse(info.serviceInfo.enabled);
}
- @MediumTest
+ @SmallTest
public void testQueryEnabledService() throws Exception {
mPackageManager.setComponentEnabledSetting(ENABLED_SERVICE_COMPONENTNAME,
COMPONENT_ENABLED_STATE_DEFAULT,
@@ -365,7 +358,7 @@ public class ComponentTest extends AndroidTestCase {
assertFalse(serviceInfo.enabled);
}
- @MediumTest
+ @SmallTest
public void testGetEnabledServiceInfo() throws Exception {
mPackageManager.setComponentEnabledSetting(ENABLED_SERVICE_COMPONENTNAME,
COMPONENT_ENABLED_STATE_DEFAULT,
@@ -396,7 +389,7 @@ public class ComponentTest extends AndroidTestCase {
assertFalse(info2.serviceInfo.enabled);
}
- @LargeTest
+ @MediumTest
public void testDisableService() throws Exception {
mPackageManager.setComponentEnabledSetting(ENABLED_SERVICE_COMPONENTNAME,
COMPONENT_ENABLED_STATE_DEFAULT,
@@ -420,7 +413,7 @@ public class ComponentTest extends AndroidTestCase {
assertTrue(info3.serviceInfo.enabled);
}
- @MediumTest
+ @SmallTest
public void testQueryDisabledReceiver() throws Exception {
mPackageManager.setComponentEnabledSetting(DISABLED_RECEIVER_COMPONENTNAME,
COMPONENT_ENABLED_STATE_DEFAULT,
@@ -440,7 +433,7 @@ public class ComponentTest extends AndroidTestCase {
assertFalse(info.activityInfo.enabled);
}
- @MediumTest
+ @SmallTest
public void testQueryEnabledReceiver() throws Exception {
mPackageManager.setComponentEnabledSetting(ENABLED_RECEIVER_COMPONENTNAME,
COMPONENT_ENABLED_STATE_DEFAULT,
@@ -475,7 +468,7 @@ public class ComponentTest extends AndroidTestCase {
assertFalse(activityInfo.enabled);
}
- @MediumTest
+ @SmallTest
public void testGetEnabledReceiverInfo() throws Exception {
mPackageManager.setComponentEnabledSetting(ENABLED_RECEIVER_COMPONENTNAME,
COMPONENT_ENABLED_STATE_DEFAULT,
@@ -530,7 +523,7 @@ public class ComponentTest extends AndroidTestCase {
}
}
- @MediumTest
+ @SmallTest
public void testResolveEnabledProvider() throws Exception {
mPackageManager.setComponentEnabledSetting(ENABLED_PROVIDER_COMPONENTNAME,
COMPONENT_ENABLED_STATE_DEFAULT,
@@ -542,7 +535,7 @@ public class ComponentTest extends AndroidTestCase {
assertTrue(providerInfo.enabled);
}
- @MediumTest
+ @SmallTest
public void testResolveDisabledProvider() throws Exception {
mPackageManager.setComponentEnabledSetting(DISABLED_PROVIDER_COMPONENTNAME,
COMPONENT_ENABLED_STATE_DEFAULT,
@@ -594,7 +587,7 @@ public class ComponentTest extends AndroidTestCase {
assertNull(providerInfo2);
}
- @MediumTest
+ @SmallTest
public void testQueryEnabledProvider() throws Exception {
mPackageManager.setComponentEnabledSetting(ENABLED_PROVIDER_COMPONENTNAME,
COMPONENT_ENABLED_STATE_DEFAULT,
diff --git a/core/tests/coretests/src/android/content/pm/PackageManagerTests.java b/core/tests/coretests/src/android/content/pm/PackageManagerTests.java
index 1f2e97c738c2..975a4c2ddc7b 100755
--- a/core/tests/coretests/src/android/content/pm/PackageManagerTests.java
+++ b/core/tests/coretests/src/android/content/pm/PackageManagerTests.java
@@ -23,22 +23,10 @@ import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
-import android.content.pm.ApplicationInfo;
-import android.content.pm.IPackageMoveObserver;
-import android.content.pm.PackageInfo;
-import android.content.pm.PackageManager;
-import android.content.pm.PackageParser;
import android.content.pm.PackageManager.NameNotFoundException;
import android.content.res.Resources;
import android.content.res.Resources.NotFoundException;
import android.net.Uri;
-import android.test.AndroidTestCase;
-import android.test.suitebuilder.annotation.SmallTest;
-import android.test.suitebuilder.annotation.MediumTest;
-import android.test.suitebuilder.annotation.LargeTest;
-import android.test.suitebuilder.annotation.Suppress;
-import android.util.DisplayMetrics;
-import android.util.Log;
import android.os.Environment;
import android.os.FileUtils;
import android.os.IBinder;
@@ -52,6 +40,7 @@ import android.os.storage.StorageResultCode;
import android.provider.Settings;
import android.provider.Settings.SettingNotFoundException;
import android.test.AndroidTestCase;
+import android.test.suitebuilder.annotation.LargeTest;
import android.util.DisplayMetrics;
import android.util.Log;
@@ -80,7 +69,7 @@ public class PackageManagerTests extends AndroidTestCase {
@Override
protected void setUp() throws Exception {
super.setUp();
- mOrigState = getMediaState();
+ mOrigState = checkMediaState(Environment.MEDIA_MOUNTED);
if (!mountMedia()) {
Log.i(TAG, "sdcard not mounted? Some of these tests might fail");
}
@@ -89,12 +78,12 @@ public class PackageManagerTests extends AndroidTestCase {
@Override
protected void tearDown() throws Exception {
// Restore media state.
- boolean newState = getMediaState();
+ boolean newState = checkMediaState(Environment.MEDIA_MOUNTED);
if (newState != mOrigState) {
if (mOrigState) {
- getMs().mountVolume(Environment.getExternalStorageDirectory().getPath());
+ mountMedia();
} else {
- getMs().unmountVolume(Environment.getExternalStorageDirectory().getPath(), true);
+ unmountMedia();
}
}
super.tearDown();
@@ -369,6 +358,7 @@ public class PackageManagerTests extends AndroidTestCase {
assertTrue((info.flags & ApplicationInfo.FLAG_FORWARD_LOCK) != 0);
assertEquals(srcPath, drmInstallPath);
assertEquals(publicSrcPath, appInstallPath);
+ assertTrue(info.nativeLibraryDir.startsWith(dataDir.getPath()));
} else {
assertFalse((info.flags & ApplicationInfo.FLAG_FORWARD_LOCK) != 0);
int rLoc = getInstallLoc(flags, expInstallLocation, pkgLen);
@@ -376,10 +366,12 @@ public class PackageManagerTests extends AndroidTestCase {
assertEquals(srcPath, appInstallPath);
assertEquals(publicSrcPath, appInstallPath);
assertFalse((info.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0);
+ assertTrue(info.nativeLibraryDir.startsWith(dataDir.getPath()));
} else if (rLoc == INSTALL_LOC_SD){
assertTrue((info.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0);
assertTrue(srcPath.startsWith(SECURE_CONTAINERS_PREFIX));
assertTrue(publicSrcPath.startsWith(SECURE_CONTAINERS_PREFIX));
+ assertTrue(info.nativeLibraryDir.startsWith(SECURE_CONTAINERS_PREFIX));
} else {
// TODO handle error. Install should have failed.
}
@@ -575,18 +567,19 @@ public class PackageManagerTests extends AndroidTestCase {
return ip;
}
- @MediumTest
+ @LargeTest
public void testInstallNormalInternal() {
sampleInstallFromRawResource(0, true);
}
- @MediumTest
+ @LargeTest
public void testInstallFwdLockedInternal() {
sampleInstallFromRawResource(PackageManager.INSTALL_FORWARD_LOCK, true);
}
- @MediumTest
+ @LargeTest
public void testInstallSdcard() {
+ mountMedia();
sampleInstallFromRawResource(PackageManager.INSTALL_EXTERNAL, true);
}
@@ -675,33 +668,33 @@ public class PackageManagerTests extends AndroidTestCase {
}
}
- @MediumTest
+ @LargeTest
public void testReplaceFailNormalInternal() {
sampleReplaceFromRawResource(0);
}
- @MediumTest
+ @LargeTest
public void testReplaceFailFwdLockedInternal() {
sampleReplaceFromRawResource(PackageManager.INSTALL_FORWARD_LOCK);
}
- @MediumTest
+ @LargeTest
public void testReplaceFailSdcard() {
sampleReplaceFromRawResource(PackageManager.INSTALL_EXTERNAL);
}
- @MediumTest
+ @LargeTest
public void testReplaceNormalInternal() {
sampleReplaceFromRawResource(PackageManager.INSTALL_REPLACE_EXISTING);
}
- @MediumTest
+ @LargeTest
public void testReplaceFwdLockedInternal() {
sampleReplaceFromRawResource(PackageManager.INSTALL_REPLACE_EXISTING |
PackageManager.INSTALL_FORWARD_LOCK);
}
- @MediumTest
+ @LargeTest
public void testReplaceSdcard() {
sampleReplaceFromRawResource(PackageManager.INSTALL_REPLACE_EXISTING |
PackageManager.INSTALL_EXTERNAL);
@@ -815,32 +808,32 @@ public class PackageManagerTests extends AndroidTestCase {
}
}
- @MediumTest
+ @LargeTest
public void testDeleteNormalInternal() {
deleteFromRawResource(0, 0);
}
- @MediumTest
+ @LargeTest
public void testDeleteFwdLockedInternal() {
deleteFromRawResource(PackageManager.INSTALL_FORWARD_LOCK, 0);
}
- @MediumTest
+ @LargeTest
public void testDeleteSdcard() {
deleteFromRawResource(PackageManager.INSTALL_EXTERNAL, 0);
}
- @MediumTest
+ @LargeTest
public void testDeleteNormalInternalRetainData() {
deleteFromRawResource(0, PackageManager.DONT_DELETE_DATA);
}
- @MediumTest
+ @LargeTest
public void testDeleteFwdLockedInternalRetainData() {
deleteFromRawResource(PackageManager.INSTALL_FORWARD_LOCK, PackageManager.DONT_DELETE_DATA);
}
- @MediumTest
+ @LargeTest
public void testDeleteSdcardRetainData() {
deleteFromRawResource(PackageManager.INSTALL_EXTERNAL, PackageManager.DONT_DELETE_DATA);
}
@@ -924,41 +917,62 @@ public class PackageManagerTests extends AndroidTestCase {
return null;
}
- boolean getMediaState() {
+ boolean checkMediaState(String desired) {
try {
- String mPath = Environment.getExternalStorageDirectory().getPath();
- String state = getMs().getVolumeState(mPath);
- return Environment.MEDIA_MOUNTED.equals(state);
+ String mPath = Environment.getExternalStorageDirectory().getPath();
+ String actual = getMs().getVolumeState(mPath);
+ if (desired.equals(actual)) {
+ return true;
+ } else {
+ return false;
+ }
} catch (RemoteException e) {
+ Log.e(TAG, "Exception while checking media state", e);
return false;
}
}
boolean mountMedia() {
- if (getMediaState()) {
+ if (checkMediaState(Environment.MEDIA_MOUNTED)) {
return true;
}
+
+ final String path = Environment.getExternalStorageDirectory().toString();
+ StorageListener observer = new StorageListener(Environment.MEDIA_MOUNTED);
+ StorageManager sm = (StorageManager) mContext.getSystemService(Context.STORAGE_SERVICE);
+ sm.registerListener(observer);
try {
- String mPath = Environment.getExternalStorageDirectory().toString();
- int ret = getMs().mountVolume(mPath);
- return ret == StorageResultCode.OperationSucceeded;
- } catch (RemoteException e) {
+ // Wait on observer
+ synchronized (observer) {
+ int ret = getMs().mountVolume(path);
+ if (ret != StorageResultCode.OperationSucceeded) {
+ throw new Exception("Could not mount the media");
+ }
+ long waitTime = 0;
+ while ((!observer.isDone()) && (waitTime < MAX_WAIT_TIME)) {
+ observer.wait(WAIT_TIME_INCR);
+ waitTime += WAIT_TIME_INCR;
+ }
+ if (!observer.isDone()) {
+ throw new Exception("Timed out waiting for unmount media notification");
+ }
+ return true;
+ }
+ } catch (Exception e) {
+ Log.e(TAG, "Exception : " + e);
return false;
+ } finally {
+ sm.unregisterListener(observer);
}
}
private boolean unmountMedia() {
- String path = Environment.getExternalStorageDirectory().getPath();
- try {
- String state = getMs().getVolumeState(path);
- if (Environment.MEDIA_UNMOUNTED.equals(state)) {
- return true;
- }
- } catch (RemoteException e) {
- failStr(e);
+ if (checkMediaState(Environment.MEDIA_UNMOUNTED)) {
+ return true;
}
- StorageListener observer = new StorageListener();
+ final String path = Environment.getExternalStorageDirectory().getPath();
+ StorageListener observer = new StorageListener(Environment.MEDIA_UNMOUNTED);
StorageManager sm = (StorageManager) mContext.getSystemService(Context.STORAGE_SERVICE);
sm.registerListener(observer);
try {
@@ -987,7 +1001,7 @@ public class PackageManagerTests extends AndroidTestCase {
// Install pkg on sdcard
InstallParams ip = sampleInstallFromRawResource(PackageManager.INSTALL_EXTERNAL, false);
if (localLOGV) Log.i(TAG, "Installed pkg on sdcard");
- boolean origState = getMediaState();
+ boolean origState = checkMediaState(Environment.MEDIA_MOUNTED);
boolean registeredReceiver = false;
SdMountReceiver receiver = new SdMountReceiver(new String[]{ip.pkg.packageName});
try {
@@ -1040,7 +1054,7 @@ public class PackageManagerTests extends AndroidTestCase {
* (Use PackageManagerService private api for now)
* Make sure the installed package is available.
*/
- @MediumTest
+ @LargeTest
public void testMountSdNormalInternal() {
assertTrue(mountFromRawResource());
}
@@ -1071,31 +1085,31 @@ public class PackageManagerTests extends AndroidTestCase {
} catch (NameNotFoundException e) {}
}
- @MediumTest
+ @LargeTest
public void testManifestInstallLocationInternal() {
installFromRawResource("install.apk", R.raw.install_loc_internal,
0, true, false, -1, PackageInfo.INSTALL_LOCATION_INTERNAL_ONLY);
}
- @MediumTest
+ @LargeTest
public void testManifestInstallLocationSdcard() {
installFromRawResource("install.apk", R.raw.install_loc_sdcard,
0, true, false, -1, PackageInfo.INSTALL_LOCATION_PREFER_EXTERNAL);
}
- @MediumTest
+ @LargeTest
public void testManifestInstallLocationAuto() {
installFromRawResource("install.apk", R.raw.install_loc_auto,
0, true, false, -1, PackageInfo.INSTALL_LOCATION_AUTO);
}
- @MediumTest
+ @LargeTest
public void testManifestInstallLocationUnspecified() {
installFromRawResource("install.apk", R.raw.install_loc_unspecified,
0, true, false, -1, PackageInfo.INSTALL_LOCATION_UNSPECIFIED);
}
- @MediumTest
+ @LargeTest
public void testManifestInstallLocationFwdLockedFlagSdcard() {
installFromRawResource("install.apk", R.raw.install_loc_unspecified,
PackageManager.INSTALL_FORWARD_LOCK |
@@ -1104,7 +1118,7 @@ public class PackageManagerTests extends AndroidTestCase {
PackageInfo.INSTALL_LOCATION_UNSPECIFIED);
}
- @MediumTest
+ @LargeTest
public void testManifestInstallLocationFwdLockedSdcard() {
installFromRawResource("install.apk", R.raw.install_loc_sdcard,
PackageManager.INSTALL_FORWARD_LOCK, true, false,
@@ -1117,7 +1131,7 @@ public class PackageManagerTests extends AndroidTestCase {
* the package via flag to install on sdcard. Make sure the new flag overrides
* the old install location.
*/
- @MediumTest
+ @LargeTest
public void testReplaceFlagInternalSdcard() {
int iFlags = 0;
int rFlags = PackageManager.INSTALL_EXTERNAL;
@@ -1139,7 +1153,7 @@ public class PackageManagerTests extends AndroidTestCase {
* the package with no flags or manifest option and make sure the old
* install location is retained.
*/
- @MediumTest
+ @LargeTest
public void testReplaceFlagSdcardInternal() {
int iFlags = PackageManager.INSTALL_EXTERNAL;
int rFlags = 0;
@@ -1156,7 +1170,7 @@ public class PackageManagerTests extends AndroidTestCase {
}
}
- @MediumTest
+ @LargeTest
public void testManifestInstallLocationReplaceInternalSdcard() {
int iFlags = 0;
int iApk = R.raw.install_loc_internal;
@@ -1179,7 +1193,7 @@ public class PackageManagerTests extends AndroidTestCase {
}
}
- @MediumTest
+ @LargeTest
public void testManifestInstallLocationReplaceSdcardInternal() {
int iFlags = 0;
int iApk = R.raw.install_loc_sdcard;
@@ -1378,8 +1392,10 @@ public class PackageManagerTests extends AndroidTestCase {
assertNotNull(info);
if ((moveFlags & PackageManager.MOVE_INTERNAL) != 0) {
assertTrue((info.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) == 0);
+ assertTrue(info.nativeLibraryDir.startsWith(info.dataDir));
} else if ((moveFlags & PackageManager.MOVE_EXTERNAL_MEDIA) != 0){
assertTrue((info.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0);
+ assertTrue(info.nativeLibraryDir.startsWith(SECURE_CONTAINERS_PREFIX));
}
}
} catch (NameNotFoundException e) {
@@ -1401,7 +1417,7 @@ public class PackageManagerTests extends AndroidTestCase {
fail, result);
}
- @MediumTest
+ @LargeTest
public void testMoveAppInternalToExternal() {
int installFlags = PackageManager.INSTALL_INTERNAL;
int moveFlags = PackageManager.MOVE_EXTERNAL_MEDIA;
@@ -1410,7 +1426,7 @@ public class PackageManagerTests extends AndroidTestCase {
sampleMoveFromRawResource(installFlags, moveFlags, fail, result);
}
- @MediumTest
+ @LargeTest
public void testMoveAppInternalToInternal() {
int installFlags = PackageManager.INSTALL_INTERNAL;
int moveFlags = PackageManager.MOVE_INTERNAL;
@@ -1419,7 +1435,7 @@ public class PackageManagerTests extends AndroidTestCase {
sampleMoveFromRawResource(installFlags, moveFlags, fail, result);
}
- @MediumTest
+ @LargeTest
public void testMoveAppExternalToExternal() {
int installFlags = PackageManager.INSTALL_EXTERNAL;
int moveFlags = PackageManager.MOVE_EXTERNAL_MEDIA;
@@ -1427,7 +1443,7 @@ public class PackageManagerTests extends AndroidTestCase {
int result = PackageManager.MOVE_FAILED_INVALID_LOCATION;
sampleMoveFromRawResource(installFlags, moveFlags, fail, result);
}
- @MediumTest
+ @LargeTest
public void testMoveAppExternalToInternal() {
int installFlags = PackageManager.INSTALL_EXTERNAL;
int moveFlags = PackageManager.MOVE_INTERNAL;
@@ -1435,7 +1451,7 @@ public class PackageManagerTests extends AndroidTestCase {
int result = PackageManager.MOVE_SUCCEEDED;
sampleMoveFromRawResource(installFlags, moveFlags, fail, result);
}
- @MediumTest
+ @LargeTest
public void testMoveAppForwardLocked() {
int installFlags = PackageManager.INSTALL_FORWARD_LOCK;
int moveFlags = PackageManager.MOVE_EXTERNAL_MEDIA;
@@ -1443,7 +1459,7 @@ public class PackageManagerTests extends AndroidTestCase {
int result = PackageManager.MOVE_FAILED_FORWARD_LOCKED;
sampleMoveFromRawResource(installFlags, moveFlags, fail, result);
}
- @MediumTest
+ @LargeTest
public void testMoveAppFailInternalToExternalDelete() {
int installFlags = 0;
int moveFlags = PackageManager.MOVE_EXTERNAL_MEDIA;
@@ -1477,9 +1493,9 @@ public class PackageManagerTests extends AndroidTestCase {
* Test that an install error code is returned when media is unmounted
* and package installed on sdcard via package manager flag.
*/
- @MediumTest
+ @LargeTest
public void testInstallSdcardUnmount() {
- boolean origState = getMediaState();
+ boolean origState = checkMediaState(Environment.MEDIA_MOUNTED);
try {
// Unmount sdcard
assertTrue(unmountMedia());
@@ -1502,24 +1518,24 @@ public class PackageManagerTests extends AndroidTestCase {
* Unmount sdcard. Try installing an app with manifest option to install
* on sdcard. Make sure it gets installed on internal flash.
*/
- @MediumTest
+ @LargeTest
public void testInstallManifestSdcardUnmount() {
- boolean origState = getMediaState();
- try {
- // Unmount sdcard
- assertTrue(unmountMedia());
- InstallParams ip = new InstallParams("install.apk", R.raw.install_loc_sdcard);
- installFromRawResource(ip, 0, true, false, -1,
- PackageInfo.INSTALL_LOCATION_INTERNAL_ONLY);
- } finally {
- // Restore original media state
- if (origState) {
- mountMedia();
- } else {
- unmountMedia();
- }
- }
- }
+ boolean origState = checkMediaState(Environment.MEDIA_MOUNTED);
+ try {
+ // Unmount sdcard
+ assertTrue(unmountMedia());
+ InstallParams ip = new InstallParams("install.apk", R.raw.install_loc_sdcard);
+ installFromRawResource(ip, 0, true, false, -1,
+ PackageInfo.INSTALL_LOCATION_INTERNAL_ONLY);
+ } finally {
+ // Restore original media state
+ if (origState) {
+ mountMedia();
+ } else {
+ unmountMedia();
+ }
+ }
+ }
/*---------- Recommended install location tests ----*/
/* Precedence: FlagManifestExistingUser
@@ -1534,14 +1550,14 @@ public class PackageManagerTests extends AndroidTestCase {
/*
* Install an app on internal flash
*/
- @MediumTest
+ @LargeTest
public void testFlagI() {
sampleInstallFromRawResource(PackageManager.INSTALL_INTERNAL, true);
}
/*
* Install an app on sdcard.
*/
- @MediumTest
+ @LargeTest
public void testFlagE() {
sampleInstallFromRawResource(PackageManager.INSTALL_EXTERNAL, true);
}
@@ -1549,14 +1565,14 @@ public class PackageManagerTests extends AndroidTestCase {
/*
* Install an app on sdcard.
*/
- @MediumTest
+ @LargeTest
public void testFlagF() {
sampleInstallFromRawResource(PackageManager.INSTALL_FORWARD_LOCK, true);
}
/*
* Install an app with both internal and external flags set. should fail
*/
- @MediumTest
+ @LargeTest
public void testFlagIE() {
installFromRawResource("install.apk", R.raw.install,
PackageManager.INSTALL_EXTERNAL | PackageManager.INSTALL_INTERNAL,
@@ -1568,7 +1584,7 @@ public class PackageManagerTests extends AndroidTestCase {
/*
* Install an app with both internal and external flags set. should fail
*/
- @MediumTest
+ @LargeTest
public void testFlagIF() {
sampleInstallFromRawResource(PackageManager.INSTALL_FORWARD_LOCK |
PackageManager.INSTALL_INTERNAL, true);
@@ -1576,7 +1592,7 @@ public class PackageManagerTests extends AndroidTestCase {
/*
* Install an app with both internal and external flags set. should fail
*/
- @MediumTest
+ @LargeTest
public void testFlagEF() {
installFromRawResource("install.apk", R.raw.install,
PackageManager.INSTALL_FORWARD_LOCK | PackageManager.INSTALL_EXTERNAL,
@@ -1587,7 +1603,7 @@ public class PackageManagerTests extends AndroidTestCase {
/*
* Install an app with both internal and external flags set. should fail
*/
- @MediumTest
+ @LargeTest
public void testFlagIEF() {
installFromRawResource("install.apk", R.raw.install,
PackageManager.INSTALL_FORWARD_LOCK | PackageManager.INSTALL_INTERNAL |
@@ -1600,7 +1616,7 @@ public class PackageManagerTests extends AndroidTestCase {
* Install an app with both internal and manifest option set.
* should install on internal.
*/
- @MediumTest
+ @LargeTest
public void testFlagIManifestI() {
installFromRawResource("install.apk", R.raw.install_loc_internal,
PackageManager.INSTALL_INTERNAL,
@@ -1612,7 +1628,7 @@ public class PackageManagerTests extends AndroidTestCase {
* Install an app with both internal and manifest preference for
* preferExternal. Should install on internal.
*/
- @MediumTest
+ @LargeTest
public void testFlagIManifestE() {
installFromRawResource("install.apk", R.raw.install_loc_sdcard,
PackageManager.INSTALL_INTERNAL,
@@ -1624,7 +1640,7 @@ public class PackageManagerTests extends AndroidTestCase {
* Install an app with both internal and manifest preference for
* auto. should install internal.
*/
- @MediumTest
+ @LargeTest
public void testFlagIManifestA() {
installFromRawResource("install.apk", R.raw.install_loc_auto,
PackageManager.INSTALL_INTERNAL,
@@ -1636,7 +1652,7 @@ public class PackageManagerTests extends AndroidTestCase {
* Install an app with both external and manifest option set.
* should install externally.
*/
- @MediumTest
+ @LargeTest
public void testFlagEManifestI() {
installFromRawResource("install.apk", R.raw.install_loc_internal,
PackageManager.INSTALL_EXTERNAL,
@@ -1648,7 +1664,7 @@ public class PackageManagerTests extends AndroidTestCase {
* Install an app with both external and manifest preference for
* preferExternal. Should install externally.
*/
- @MediumTest
+ @LargeTest
public void testFlagEManifestE() {
installFromRawResource("install.apk", R.raw.install_loc_sdcard,
PackageManager.INSTALL_EXTERNAL,
@@ -1660,7 +1676,7 @@ public class PackageManagerTests extends AndroidTestCase {
* Install an app with both external and manifest preference for
* auto. should install on external media.
*/
- @MediumTest
+ @LargeTest
public void testFlagEManifestA() {
installFromRawResource("install.apk", R.raw.install_loc_auto,
PackageManager.INSTALL_EXTERNAL,
@@ -1672,7 +1688,7 @@ public class PackageManagerTests extends AndroidTestCase {
* Install an app with fwd locked flag set and install location set to
* internal. should install internally.
*/
- @MediumTest
+ @LargeTest
public void testFlagFManifestI() {
installFromRawResource("install.apk", R.raw.install_loc_internal,
PackageManager.INSTALL_EXTERNAL,
@@ -1684,7 +1700,7 @@ public class PackageManagerTests extends AndroidTestCase {
* Install an app with fwd locked flag set and install location set to
* preferExternal. should install internally.
*/
- @MediumTest
+ @LargeTest
public void testFlagFManifestE() {
installFromRawResource("install.apk", R.raw.install_loc_sdcard,
PackageManager.INSTALL_EXTERNAL,
@@ -1696,7 +1712,7 @@ public class PackageManagerTests extends AndroidTestCase {
* Install an app with fwd locked flag set and install location set to
* auto. should install internally.
*/
- @MediumTest
+ @LargeTest
public void testFlagFManifestA() {
installFromRawResource("install.apk", R.raw.install_loc_auto,
PackageManager.INSTALL_EXTERNAL,
@@ -1711,7 +1727,7 @@ public class PackageManagerTests extends AndroidTestCase {
* location should be honoured.
* testFlagI/E/F/ExistingI/E -
*/
- @MediumTest
+ @LargeTest
public void testFlagIExistingI() {
int iFlags = PackageManager.INSTALL_INTERNAL;
int rFlags = PackageManager.INSTALL_INTERNAL | PackageManager.INSTALL_REPLACE_EXISTING;
@@ -1728,7 +1744,7 @@ public class PackageManagerTests extends AndroidTestCase {
false, -1,
-1);
}
- @MediumTest
+ @LargeTest
public void testFlagIExistingE() {
int iFlags = PackageManager.INSTALL_EXTERNAL;
int rFlags = PackageManager.INSTALL_INTERNAL | PackageManager.INSTALL_REPLACE_EXISTING;
@@ -1745,7 +1761,7 @@ public class PackageManagerTests extends AndroidTestCase {
false, -1,
-1);
}
- @MediumTest
+ @LargeTest
public void testFlagEExistingI() {
int iFlags = PackageManager.INSTALL_INTERNAL;
int rFlags = PackageManager.INSTALL_EXTERNAL | PackageManager.INSTALL_REPLACE_EXISTING;
@@ -1762,7 +1778,7 @@ public class PackageManagerTests extends AndroidTestCase {
false, -1,
-1);
}
- @MediumTest
+ @LargeTest
public void testFlagEExistingE() {
int iFlags = PackageManager.INSTALL_EXTERNAL;
int rFlags = PackageManager.INSTALL_EXTERNAL | PackageManager.INSTALL_REPLACE_EXISTING;
@@ -1779,7 +1795,7 @@ public class PackageManagerTests extends AndroidTestCase {
false, -1,
-1);
}
- @MediumTest
+ @LargeTest
public void testFlagFExistingI() {
int iFlags = PackageManager.INSTALL_INTERNAL;
int rFlags = PackageManager.INSTALL_FORWARD_LOCK | PackageManager.INSTALL_REPLACE_EXISTING;
@@ -1796,7 +1812,7 @@ public class PackageManagerTests extends AndroidTestCase {
false, -1,
-1);
}
- @MediumTest
+ @LargeTest
public void testFlagFExistingE() {
int iFlags = PackageManager.INSTALL_EXTERNAL;
int rFlags = PackageManager.INSTALL_FORWARD_LOCK | PackageManager.INSTALL_REPLACE_EXISTING;
@@ -1820,7 +1836,7 @@ public class PackageManagerTests extends AndroidTestCase {
* public void testManifestI/E/A
* TODO out of memory fall back behaviour.
*/
- @MediumTest
+ @LargeTest
public void testManifestI() {
installFromRawResource("install.apk", R.raw.install_loc_internal,
0,
@@ -1828,7 +1844,7 @@ public class PackageManagerTests extends AndroidTestCase {
false, -1,
PackageInfo.INSTALL_LOCATION_INTERNAL_ONLY);
}
- @MediumTest
+ @LargeTest
public void testManifestE() {
installFromRawResource("install.apk", R.raw.install_loc_sdcard,
0,
@@ -1836,7 +1852,7 @@ public class PackageManagerTests extends AndroidTestCase {
false, -1,
PackageInfo.INSTALL_LOCATION_PREFER_EXTERNAL);
}
- @MediumTest
+ @LargeTest
public void testManifestA() {
installFromRawResource("install.apk", R.raw.install_loc_auto,
0,
@@ -1851,7 +1867,7 @@ public class PackageManagerTests extends AndroidTestCase {
* TODO add out of memory fall back behaviour.
* testManifestI/E/AExistingI/E
*/
- @MediumTest
+ @LargeTest
public void testManifestIExistingI() {
int iFlags = PackageManager.INSTALL_INTERNAL;
int rFlags = PackageManager.INSTALL_REPLACE_EXISTING;
@@ -1868,7 +1884,7 @@ public class PackageManagerTests extends AndroidTestCase {
false, -1,
PackageInfo.INSTALL_LOCATION_INTERNAL_ONLY);
}
- @MediumTest
+ @LargeTest
public void testManifestIExistingE() {
int iFlags = PackageManager.INSTALL_EXTERNAL;
int rFlags = PackageManager.INSTALL_REPLACE_EXISTING;
@@ -1885,7 +1901,7 @@ public class PackageManagerTests extends AndroidTestCase {
false, -1,
PackageInfo.INSTALL_LOCATION_INTERNAL_ONLY);
}
- @MediumTest
+ @LargeTest
public void testManifestEExistingI() {
int iFlags = PackageManager.INSTALL_INTERNAL;
int rFlags = PackageManager.INSTALL_REPLACE_EXISTING;
@@ -1902,7 +1918,7 @@ public class PackageManagerTests extends AndroidTestCase {
false, -1,
PackageInfo.INSTALL_LOCATION_PREFER_EXTERNAL);
}
- @MediumTest
+ @LargeTest
public void testManifestEExistingE() {
int iFlags = PackageManager.INSTALL_EXTERNAL;
int rFlags = PackageManager.INSTALL_REPLACE_EXISTING;
@@ -1919,7 +1935,7 @@ public class PackageManagerTests extends AndroidTestCase {
false, -1,
PackageInfo.INSTALL_LOCATION_PREFER_EXTERNAL);
}
- @MediumTest
+ @LargeTest
public void testManifestAExistingI() {
int iFlags = PackageManager.INSTALL_INTERNAL;
int rFlags = PackageManager.INSTALL_REPLACE_EXISTING;
@@ -1936,7 +1952,7 @@ public class PackageManagerTests extends AndroidTestCase {
false, -1,
PackageInfo.INSTALL_LOCATION_AUTO);
}
- @MediumTest
+ @LargeTest
public void testManifestAExistingE() {
int iFlags = PackageManager.INSTALL_EXTERNAL;
int rFlags = PackageManager.INSTALL_REPLACE_EXISTING;
@@ -1993,37 +2009,37 @@ public class PackageManagerTests extends AndroidTestCase {
setInstallLoc(origSetting);
}
}
- @MediumTest
+ @LargeTest
public void testExistingIUserI() {
int userSetting = PackageHelper.APP_INSTALL_INTERNAL;
int iFlags = PackageManager.INSTALL_INTERNAL;
setExistingXUserX(userSetting, iFlags, PackageInfo.INSTALL_LOCATION_INTERNAL_ONLY);
}
- @MediumTest
+ @LargeTest
public void testExistingIUserE() {
int userSetting = PackageHelper.APP_INSTALL_EXTERNAL;
int iFlags = PackageManager.INSTALL_INTERNAL;
setExistingXUserX(userSetting, iFlags, PackageInfo.INSTALL_LOCATION_INTERNAL_ONLY);
}
- @MediumTest
+ @LargeTest
public void testExistingIUserA() {
int userSetting = PackageHelper.APP_INSTALL_AUTO;
int iFlags = PackageManager.INSTALL_INTERNAL;
setExistingXUserX(userSetting, iFlags, PackageInfo.INSTALL_LOCATION_INTERNAL_ONLY);
}
- @MediumTest
+ @LargeTest
public void testExistingEUserI() {
int userSetting = PackageHelper.APP_INSTALL_INTERNAL;
int iFlags = PackageManager.INSTALL_EXTERNAL;
setExistingXUserX(userSetting, iFlags, PackageInfo.INSTALL_LOCATION_PREFER_EXTERNAL);
}
- @MediumTest
+ @LargeTest
public void testExistingEUserE() {
int userSetting = PackageHelper.APP_INSTALL_EXTERNAL;
int iFlags = PackageManager.INSTALL_EXTERNAL;
setExistingXUserX(userSetting, iFlags, PackageInfo.INSTALL_LOCATION_PREFER_EXTERNAL);
}
- @MediumTest
+ @LargeTest
public void testExistingEUserA() {
int userSetting = PackageHelper.APP_INSTALL_AUTO;
int iFlags = PackageManager.INSTALL_EXTERNAL;
@@ -2066,19 +2082,19 @@ public class PackageManagerTests extends AndroidTestCase {
setInstallLoc(origSetting);
}
}
- @MediumTest
+ @LargeTest
public void testUserI() {
int userSetting = PackageHelper.APP_INSTALL_INTERNAL;
int iloc = getExpectedInstallLocation(userSetting);
setUserX(true, userSetting, iloc);
}
- @MediumTest
+ @LargeTest
public void testUserE() {
int userSetting = PackageHelper.APP_INSTALL_EXTERNAL;
int iloc = getExpectedInstallLocation(userSetting);
setUserX(true, userSetting, iloc);
}
- @MediumTest
+ @LargeTest
public void testUserA() {
int userSetting = PackageHelper.APP_INSTALL_AUTO;
int iloc = getExpectedInstallLocation(userSetting);
@@ -2088,19 +2104,19 @@ public class PackageManagerTests extends AndroidTestCase {
* The following set of tests turn on/off the basic
* user setting for turning on install location.
*/
- @MediumTest
+ @LargeTest
public void testUserPrefOffUserI() {
int userSetting = PackageHelper.APP_INSTALL_INTERNAL;
int iloc = PackageInfo.INSTALL_LOCATION_UNSPECIFIED;
setUserX(false, userSetting, iloc);
}
- @MediumTest
+ @LargeTest
public void testUserPrefOffUserE() {
int userSetting = PackageHelper.APP_INSTALL_EXTERNAL;
int iloc = PackageInfo.INSTALL_LOCATION_UNSPECIFIED;
setUserX(false, userSetting, iloc);
}
- @MediumTest
+ @LargeTest
public void testUserPrefOffA() {
int userSetting = PackageHelper.APP_INSTALL_AUTO;
int iloc = PackageInfo.INSTALL_LOCATION_UNSPECIFIED;
@@ -2277,10 +2293,10 @@ public class PackageManagerTests extends AndroidTestCase {
/*
* Ensure that permissions are properly declared.
*/
- @MediumTest
+ @LargeTest
public void testInstallOnSdPermissionsUnmount() {
InstallParams ip = null;
- boolean origMediaState = getMediaState();
+ boolean origMediaState = checkMediaState(Environment.MEDIA_MOUNTED);
try {
// **: Upon installing a package, are its declared permissions published?
int iFlags = PackageManager.INSTALL_INTERNAL;
@@ -2309,10 +2325,12 @@ public class PackageManagerTests extends AndroidTestCase {
* Please note that this test is very closely tied to the framework's
* naming convention for secure containers.
*/
- @MediumTest
+ @LargeTest
public void testInstallSdcardStaleContainer() {
- boolean origMediaState = getMediaState();
+ boolean origMediaState = checkMediaState(Environment.MEDIA_MOUNTED);
try {
+ // Mount media first
+ mountMedia();
String outFileName = "install.apk";
int rawResId = R.raw.install;
PackageManager pm = mContext.getPackageManager();
@@ -2351,9 +2369,9 @@ public class PackageManagerTests extends AndroidTestCase {
* The app is then re-installed on internal storage. The sdcard is mounted
* and verified that the re-installation on internal storage takes precedence.
*/
- @MediumTest
+ @LargeTest
public void testInstallSdcardStaleContainerReinstall() {
- boolean origMediaState = getMediaState();
+ boolean origMediaState = checkMediaState(Environment.MEDIA_MOUNTED);
try {
// Mount media first
mountMedia();
@@ -2386,7 +2404,6 @@ public class PackageManagerTests extends AndroidTestCase {
} else {
unmountMedia();
}
-
}
}
/*
@@ -2429,7 +2446,7 @@ public class PackageManagerTests extends AndroidTestCase {
* Test that an app signed with two certificates can be upgraded by the
* same app signed with two certificates.
*/
- @MediumTest
+ @LargeTest
public void testReplaceMatchAllCerts() {
replaceCerts(APP1_CERT1_CERT2, APP1_CERT1_CERT2, true, false, -1);
}
@@ -2438,7 +2455,7 @@ public class PackageManagerTests extends AndroidTestCase {
* Test that an app signed with two certificates cannot be upgraded
* by an app signed with a different certificate.
*/
- @MediumTest
+ @LargeTest
public void testReplaceMatchNoCerts1() {
replaceCerts(APP1_CERT1_CERT2, APP1_CERT3, true, true,
PackageManager.INSTALL_PARSE_FAILED_INCONSISTENT_CERTIFICATES);
@@ -2447,7 +2464,7 @@ public class PackageManagerTests extends AndroidTestCase {
* Test that an app signed with two certificates cannot be upgraded
* by an app signed with a different certificate.
*/
- @MediumTest
+ @LargeTest
public void testReplaceMatchNoCerts2() {
replaceCerts(APP1_CERT1_CERT2, APP1_CERT3_CERT4, true, true,
PackageManager.INSTALL_PARSE_FAILED_INCONSISTENT_CERTIFICATES);
@@ -2456,7 +2473,7 @@ public class PackageManagerTests extends AndroidTestCase {
* Test that an app signed with two certificates cannot be upgraded by
* an app signed with a subset of initial certificates.
*/
- @MediumTest
+ @LargeTest
public void testReplaceMatchSomeCerts1() {
replaceCerts(APP1_CERT1_CERT2, APP1_CERT1, true, true,
PackageManager.INSTALL_PARSE_FAILED_INCONSISTENT_CERTIFICATES);
@@ -2465,7 +2482,7 @@ public class PackageManagerTests extends AndroidTestCase {
* Test that an app signed with two certificates cannot be upgraded by
* an app signed with the last certificate.
*/
- @MediumTest
+ @LargeTest
public void testReplaceMatchSomeCerts2() {
replaceCerts(APP1_CERT1_CERT2, APP1_CERT2, true, true,
PackageManager.INSTALL_PARSE_FAILED_INCONSISTENT_CERTIFICATES);
@@ -2474,7 +2491,7 @@ public class PackageManagerTests extends AndroidTestCase {
* Test that an app signed with a certificate can be upgraded by app
* signed with a superset of certificates.
*/
- @MediumTest
+ @LargeTest
public void testReplaceMatchMoreCerts() {
replaceCerts(APP1_CERT1, APP1_CERT1_CERT2, true, true,
PackageManager.INSTALL_PARSE_FAILED_INCONSISTENT_CERTIFICATES);
@@ -2484,7 +2501,7 @@ public class PackageManagerTests extends AndroidTestCase {
* signed with a superset of certificates. Then verify that the an app
* signed with the original set of certs cannot upgrade the new one.
*/
- @MediumTest
+ @LargeTest
public void testReplaceMatchMoreCertsReplaceSomeCerts() {
InstallParams ip = replaceCerts(APP1_CERT1, APP1_CERT1_CERT2, false, true,
PackageManager.INSTALL_PARSE_FAILED_INCONSISTENT_CERTIFICATES);
@@ -2508,37 +2525,37 @@ public class PackageManagerTests extends AndroidTestCase {
private void checkSignatures(int apk1, int apk2, int expMatchResult) {
checkSharedSignatures(apk1, apk2, true, false, -1, expMatchResult);
}
- @MediumTest
+ @LargeTest
public void testCheckSignaturesAllMatch() {
int apk1 = APP1_CERT1_CERT2;
int apk2 = APP2_CERT1_CERT2;
checkSignatures(apk1, apk2, PackageManager.SIGNATURE_MATCH);
}
- @MediumTest
+ @LargeTest
public void testCheckSignaturesNoMatch() {
int apk1 = APP1_CERT1;
int apk2 = APP2_CERT2;
checkSignatures(apk1, apk2, PackageManager.SIGNATURE_NO_MATCH);
}
- @MediumTest
+ @LargeTest
public void testCheckSignaturesSomeMatch1() {
int apk1 = APP1_CERT1_CERT2;
int apk2 = APP2_CERT1;
checkSignatures(apk1, apk2, PackageManager.SIGNATURE_NO_MATCH);
}
- @MediumTest
+ @LargeTest
public void testCheckSignaturesSomeMatch2() {
int apk1 = APP1_CERT1_CERT2;
int apk2 = APP2_CERT2;
checkSignatures(apk1, apk2, PackageManager.SIGNATURE_NO_MATCH);
}
- @MediumTest
+ @LargeTest
public void testCheckSignaturesMoreMatch() {
int apk1 = APP1_CERT1;
int apk2 = APP2_CERT1_CERT2;
checkSignatures(apk1, apk2, PackageManager.SIGNATURE_NO_MATCH);
}
- @MediumTest
+ @LargeTest
public void testCheckSignaturesUnknown() {
int apk1 = APP1_CERT1_CERT2;
int apk2 = APP2_CERT1_CERT2;
@@ -2567,7 +2584,7 @@ public class PackageManagerTests extends AndroidTestCase {
}
}
}
- @MediumTest
+ @LargeTest
public void testInstallNoCertificates() {
int apk1 = APP1_UNSIGNED;
String apk1Name = "install1.apk";
@@ -2620,7 +2637,7 @@ public class PackageManagerTests extends AndroidTestCase {
}
}
}
- @MediumTest
+ @LargeTest
public void testCheckSignaturesSharedAllMatch() {
int apk1 = SHARED1_CERT1_CERT2;
int apk2 = SHARED2_CERT1_CERT2;
@@ -2629,7 +2646,7 @@ public class PackageManagerTests extends AndroidTestCase {
int expMatchResult = PackageManager.SIGNATURE_MATCH;
checkSharedSignatures(apk1, apk2, true, fail, retCode, expMatchResult);
}
- @MediumTest
+ @LargeTest
public void testCheckSignaturesSharedNoMatch() {
int apk1 = SHARED1_CERT1;
int apk2 = SHARED2_CERT2;
@@ -2641,7 +2658,7 @@ public class PackageManagerTests extends AndroidTestCase {
/*
* Test that an app signed with cert1 and cert2 cannot be replaced when signed with cert1 alone.
*/
- @MediumTest
+ @LargeTest
public void testCheckSignaturesSharedSomeMatch1() {
int apk1 = SHARED1_CERT1_CERT2;
int apk2 = SHARED2_CERT1;
@@ -2653,7 +2670,7 @@ public class PackageManagerTests extends AndroidTestCase {
/*
* Test that an app signed with cert1 and cert2 cannot be replaced when signed with cert2 alone.
*/
- @MediumTest
+ @LargeTest
public void testCheckSignaturesSharedSomeMatch2() {
int apk1 = SHARED1_CERT1_CERT2;
int apk2 = SHARED2_CERT2;
@@ -2662,7 +2679,7 @@ public class PackageManagerTests extends AndroidTestCase {
int expMatchResult = -1;
checkSharedSignatures(apk1, apk2, true, fail, retCode, expMatchResult);
}
- @MediumTest
+ @LargeTest
public void testCheckSignaturesSharedUnknown() {
int apk1 = SHARED1_CERT1_CERT2;
int apk2 = SHARED2_CERT1_CERT2;
@@ -2688,7 +2705,7 @@ public class PackageManagerTests extends AndroidTestCase {
}
}
- @MediumTest
+ @LargeTest
public void testReplaceFirstSharedMatchAllCerts() {
int apk1 = SHARED1_CERT1;
int apk2 = SHARED2_CERT1;
@@ -2696,7 +2713,7 @@ public class PackageManagerTests extends AndroidTestCase {
checkSignatures(apk1, apk2, PackageManager.SIGNATURE_MATCH);
replaceCerts(apk1, rapk1, true, false, -1);
}
- @MediumTest
+ @LargeTest
public void testReplaceSecondSharedMatchAllCerts() {
int apk1 = SHARED1_CERT1;
int apk2 = SHARED2_CERT1;
@@ -2704,7 +2721,7 @@ public class PackageManagerTests extends AndroidTestCase {
checkSignatures(apk1, apk2, PackageManager.SIGNATURE_MATCH);
replaceCerts(apk2, rapk2, true, false, -1);
}
- @MediumTest
+ @LargeTest
public void testReplaceFirstSharedMatchSomeCerts() {
int apk1 = SHARED1_CERT1_CERT2;
int apk2 = SHARED2_CERT1_CERT2;
@@ -2715,7 +2732,7 @@ public class PackageManagerTests extends AndroidTestCase {
installFromRawResource("install.apk", rapk1, PackageManager.INSTALL_REPLACE_EXISTING, true,
fail, retCode, PackageInfo.INSTALL_LOCATION_UNSPECIFIED);
}
- @MediumTest
+ @LargeTest
public void testReplaceSecondSharedMatchSomeCerts() {
int apk1 = SHARED1_CERT1_CERT2;
int apk2 = SHARED2_CERT1_CERT2;
@@ -2726,7 +2743,7 @@ public class PackageManagerTests extends AndroidTestCase {
installFromRawResource("install.apk", rapk2, PackageManager.INSTALL_REPLACE_EXISTING, true,
fail, retCode, PackageInfo.INSTALL_LOCATION_UNSPECIFIED);
}
- @MediumTest
+ @LargeTest
public void testReplaceFirstSharedMatchNoCerts() {
int apk1 = SHARED1_CERT1;
int apk2 = SHARED2_CERT1;
@@ -2737,7 +2754,7 @@ public class PackageManagerTests extends AndroidTestCase {
installFromRawResource("install.apk", rapk1, PackageManager.INSTALL_REPLACE_EXISTING, true,
fail, retCode, PackageInfo.INSTALL_LOCATION_UNSPECIFIED);
}
- @MediumTest
+ @LargeTest
public void testReplaceSecondSharedMatchNoCerts() {
int apk1 = SHARED1_CERT1;
int apk2 = SHARED2_CERT1;
@@ -2748,7 +2765,7 @@ public class PackageManagerTests extends AndroidTestCase {
installFromRawResource("install.apk", rapk2, PackageManager.INSTALL_REPLACE_EXISTING, true,
fail, retCode, PackageInfo.INSTALL_LOCATION_UNSPECIFIED);
}
- @MediumTest
+ @LargeTest
public void testReplaceFirstSharedMatchMoreCerts() {
int apk1 = SHARED1_CERT1;
int apk2 = SHARED2_CERT1;
@@ -2759,7 +2776,7 @@ public class PackageManagerTests extends AndroidTestCase {
installFromRawResource("install.apk", rapk1, PackageManager.INSTALL_REPLACE_EXISTING, true,
fail, retCode, PackageInfo.INSTALL_LOCATION_UNSPECIFIED);
}
- @MediumTest
+ @LargeTest
public void testReplaceSecondSharedMatchMoreCerts() {
int apk1 = SHARED1_CERT1;
int apk2 = SHARED2_CERT1;
diff --git a/core/tests/coretests/src/android/database/sqlite/AbstractJDBCDriverTest.java b/core/tests/coretests/src/android/database/sqlite/AbstractJDBCDriverTest.java
deleted file mode 100644
index 19c7bcb03cc9..000000000000
--- a/core/tests/coretests/src/android/database/sqlite/AbstractJDBCDriverTest.java
+++ /dev/null
@@ -1,211 +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.
- */
-
-package android.database.sqlite;
-
-import java.io.File;
-import java.sql.Connection;
-import java.sql.DriverManager;
-import java.sql.ResultSet;
-import java.sql.SQLException;
-import java.sql.Statement;
-
-import junit.framework.TestCase;
-import android.test.suitebuilder.annotation.MediumTest;
-
-/**
- * Tests for the most commonly used methods of sql like creating a connection,
- * inserting, selecting, updating.
- */
-public abstract class AbstractJDBCDriverTest extends TestCase {
-
- @MediumTest
- public void testJDBCDriver() throws Exception {
- Connection firstConnection = null;
- Connection secondConnection = null;
- File dbFile = getDbFile();
- String connectionURL = getConnectionURL();
- Statement firstStmt = null;
- Statement secondStmt = null;
- try {
- Class.forName(getJDBCDriverClassName());
- firstConnection = DriverManager.getConnection(connectionURL);
- secondConnection = DriverManager.getConnection(connectionURL);
-
- String[] ones = {"hello!", "goodbye"};
- short[] twos = {10, 20};
- String[] onesUpdated = new String[ones.length];
- for (int i = 0; i < ones.length; i++) {
- onesUpdated[i] = ones[i] + twos[i];
- }
- firstStmt = firstConnection.createStatement();
- firstStmt.execute("create table tbl1(one varchar(10), two smallint)");
- secondStmt = secondConnection.createStatement();
-
- autoCommitInsertSelectTest(firstStmt, ones, twos);
- updateSelectCommitSelectTest(firstStmt, secondStmt, ones, onesUpdated, twos);
- updateSelectRollbackSelectTest(firstStmt, secondStmt, onesUpdated, ones, twos);
- } finally {
- closeConnections(firstConnection, secondConnection, dbFile, firstStmt, secondStmt);
- }
- }
-
- protected abstract String getJDBCDriverClassName();
- protected abstract String getConnectionURL();
- protected abstract File getDbFile();
-
- private void closeConnections(Connection firstConnection, Connection secondConnection,
- File dbFile, Statement firstStmt, Statement secondStmt) {
- String failText = null;
- try {
- if (firstStmt != null) {
- firstStmt.execute("drop table tbl1");
- }
- } catch (SQLException e) {
- failText = e.getLocalizedMessage();
- }
- try {
- if (firstStmt != null) {
- firstStmt.close();
- }
- } catch (SQLException e) {
- failText = e.getLocalizedMessage();
- }
- try {
- if (firstConnection != null) {
- firstConnection.close();
- }
- } catch (SQLException e) {
- failText = e.getLocalizedMessage();
- }
- try {
- if (secondStmt != null) {
- secondStmt.close();
- }
- } catch (SQLException e) {
- failText = e.getLocalizedMessage();
- }
- try {
- if (secondConnection != null) {
- secondConnection.close();
- }
- } catch (SQLException e) {
- failText = e.getLocalizedMessage();
- }
- dbFile.delete();
- assertNull(failText, failText);
- }
-
- /**
- * Inserts the values from 'ones' with the values from 'twos' into 'tbl1'
- * @param stmt the statement to use for the inserts.
- * @param ones the string values to insert into tbl1.
- * @param twos the corresponding numerical values to insert into tbl1.
- * @throws SQLException in case of a problem during insert.
- */
- private void autoCommitInsertSelectTest(Statement stmt, String[] ones,
- short[] twos) throws SQLException {
- for (int i = 0; i < ones.length; i++) {
- stmt.execute("insert into tbl1 values('" + ones[i] + "'," + twos[i]
- + ")");
- }
- assertAllFromTbl1(stmt, ones, twos);
- }
-
- /**
- * Asserts that all values that where added to tbl1 are actually in tbl1.
- * @param stmt the statement to use for the select.
- * @param ones the string values that where added.
- * @param twos the numerical values that where added.
- * @throws SQLException in case of a problem during select.
- */
- private void assertAllFromTbl1(Statement stmt, String[] ones, short[] twos)
- throws SQLException {
- ResultSet rs = stmt.executeQuery("select * from tbl1");
- int i = 0;
- for (; rs.next(); i++) {
- assertTrue(i < ones.length);
- assertEquals(ones[i], rs.getString("one"));
- assertEquals(twos[i], rs.getShort("two"));
- }
- assertEquals(i, ones.length);
- }
-
- /**
- * Tests the results of an update followed bz a select on a diffrent statement.
- * After that the first statement commits its update. and now the second
- * statement should also be able to see the changed values in a select.
- * @param firstStmt the statement to use for the update and commit.
- * @param secondStmt the statement that should be used to check if the commit works
- * @param ones the original string values.
- * @param onesUpdated the updated string values.
- * @param twos the numerical values.
- * @throws SQLException in case of a problem during any of the executed commands.
- */
- private void updateSelectCommitSelectTest(Statement firstStmt,
- Statement secondStmt, String[] ones, String[] onesUpdated,
- short[] twos) throws SQLException {
- firstStmt.getConnection().setAutoCommit(false);
- try {
- updateOnes(firstStmt, onesUpdated, twos);
- assertAllFromTbl1(secondStmt, ones, twos);
- firstStmt.getConnection().commit();
- assertAllFromTbl1(secondStmt, onesUpdated, twos);
- } finally {
- firstStmt.getConnection().setAutoCommit(true);
- }
- }
-
- /**
- * Tests if an update followed by a select works. After that a rollback will
- * be made and again a select should show that the rollback worked.
- * @param firstStmt the statement to use for the update and the rollback
- * @param secondStmt the statement to use for checking if the rollback worked as intended.
- * @param ones the original string values.
- * @param onesUpdated the updated string values.
- * @param twos the nomerical values.
- * @throws SQLException in case of a problem during any command.
- */
- private void updateSelectRollbackSelectTest(Statement firstStmt,
- Statement secondStmt, String[] ones, String[] onesUpdated,
- short[] twos) throws SQLException {
- firstStmt.getConnection().setAutoCommit(false);
- try {
- updateOnes(firstStmt, onesUpdated, twos);
- assertAllFromTbl1(secondStmt, ones, twos);
- firstStmt.getConnection().rollback();
- assertAllFromTbl1(secondStmt, ones, twos);
- } finally {
- firstStmt.getConnection().setAutoCommit(true);
- }
- }
-
- /**
- * updates the sring values. the original values are stored in 'ones'
- * and the updated values in 'ones_updated'
- * @param stmt the statement to use for the update.
- * @param onesUpdated the new string values.
- * @param twos the numerical values.
- * @throws SQLException in case of a problem during update.
- */
- private void updateOnes(Statement stmt, String[] onesUpdated, short[] twos)
- throws SQLException {
- for (int i = 0; i < onesUpdated.length; i++) {
- stmt.execute("UPDATE tbl1 SET one = '" + onesUpdated[i]
- + "' WHERE two = " + twos[i]);
- }
- }
-}
diff --git a/core/tests/coretests/src/android/database/sqlite/SQLiteJDBCDriverTest.java b/core/tests/coretests/src/android/database/sqlite/SQLiteJDBCDriverTest.java
deleted file mode 100644
index 8e677a5b8702..000000000000
--- a/core/tests/coretests/src/android/database/sqlite/SQLiteJDBCDriverTest.java
+++ /dev/null
@@ -1,137 +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.
- */
-
-package android.database.sqlite;
-
-import java.io.File;
-import java.sql.Connection;
-import java.sql.DriverManager;
-import java.sql.PreparedStatement;
-import java.sql.SQLException;
-import java.sql.Statement;
-import android.test.suitebuilder.annotation.MediumTest;
-
-/**
- * Minimal test for JDBC driver
- */
-public class SQLiteJDBCDriverTest extends AbstractJDBCDriverTest {
-
- private File dbFile;
-
- @Override
- protected void setUp() throws Exception {
- super.setUp();
- dbFile = File.createTempFile("sqliteTestDB", null);
- }
-
- @Override
- protected void tearDown() throws Exception {
- if(dbFile != null) {
- dbFile.delete();
- }
- super.tearDown();
- }
-
- @Override
- protected String getConnectionURL() {
- return "jdbc:sqlite:/" + dbFile;
- }
-
- @Override
- protected File getDbFile() {
- return dbFile;
- }
-
- @Override
- protected String getJDBCDriverClassName() {
- return "SQLite.JDBCDriver";
- }
-
- // Regression test for (Noser) #255: PreparedStatement.executeUpdate results
- // in VM crashing with SIGABRT.
- @MediumTest
- public void test_connection3() throws Exception {
- PreparedStatement prst = null;
- Statement st = null;
- Connection conn = null;
- try {
- Class.forName("SQLite.JDBCDriver").newInstance();
- if (dbFile.exists()) {
- dbFile.delete();
- }
- conn = DriverManager.getConnection("jdbc:sqlite:/"
- + dbFile.getPath());
- assertNotNull(conn);
-
- // create table
- st = conn.createStatement();
- String sql = "CREATE TABLE zoo (ZID INTEGER NOT NULL, family VARCHAR (20) NOT NULL, name VARCHAR (20) NOT NULL, PRIMARY KEY(ZID) )";
- st.executeUpdate(sql);
-
- String update = "update zoo set family = ? where name = ?;";
- prst = conn.prepareStatement(update);
- prst.setString(1, "cat");
- prst.setString(2, "Yasha");
- // st = conn.createStatement();
- // st.execute("select * from zoo where family = 'cat'");
- // ResultSet rs = st.getResultSet();
- // assertEquals(0, getCount(rs));
- prst.executeUpdate();
- // st.execute("select * from zoo where family = 'cat'");
- // ResultSet rs1 = st.getResultSet();
- // assertEquals(1, getCount(rs1));
- try {
- prst = conn.prepareStatement("");
- prst.execute();
- fail("SQLException is not thrown");
- } catch (SQLException e) {
- // expected
- }
-
- try {
- conn.prepareStatement(null);
- fail("NPE is not thrown");
- } catch (Exception e) {
- // expected
- }
- try {
- st = conn.createStatement();
- st.execute("drop table if exists zoo");
-
- } catch (SQLException e) {
- fail("Couldn't drop table: " + e.getMessage());
- } finally {
- try {
- st.close();
- conn.close();
- } catch (SQLException ee) {
- }
- }
- } finally {
- try {
- if (prst != null) {
- prst.close();
- }
- if (st != null) {
- st.close();
- }
- } catch (SQLException ee) {
- }
- }
-
- }
-
-}
diff --git a/core/tests/coretests/src/android/net/DownloadManagerBaseTest.java b/core/tests/coretests/src/android/net/DownloadManagerBaseTest.java
new file mode 100644
index 000000000000..ee0f5f14516d
--- /dev/null
+++ b/core/tests/coretests/src/android/net/DownloadManagerBaseTest.java
@@ -0,0 +1,888 @@
+/*
+ * Copyright (C) 2010 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.net;
+
+import android.content.BroadcastReceiver;
+import android.content.Context;
+import android.content.Intent;
+import android.content.IntentFilter;
+import android.database.Cursor;
+import android.net.ConnectivityManager;
+import android.net.DownloadManager;
+import android.net.NetworkInfo;
+import android.net.DownloadManager.Query;
+import android.net.DownloadManager.Request;
+import android.net.wifi.WifiManager;
+import android.os.Environment;
+import android.os.ParcelFileDescriptor;
+import android.os.SystemClock;
+import android.os.ParcelFileDescriptor.AutoCloseInputStream;
+import android.provider.Settings;
+import android.test.InstrumentationTestCase;
+import android.util.Log;
+
+import java.io.DataInputStream;
+import java.io.DataOutputStream;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.net.URL;
+import java.util.concurrent.TimeoutException;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Random;
+import java.util.Vector;
+
+import junit.framework.AssertionFailedError;
+
+import coretestutils.http.MockResponse;
+import coretestutils.http.MockWebServer;
+
+/**
+ * Base class for Instrumented tests for the Download Manager.
+ */
+public class DownloadManagerBaseTest extends InstrumentationTestCase {
+
+ protected DownloadManager mDownloadManager = null;
+ protected MockWebServer mServer = null;
+ protected String mFileType = "text/plain";
+ protected Context mContext = null;
+ protected static final int DEFAULT_FILE_SIZE = 130 * 1024; // 130kb
+ protected static final int FILE_BLOCK_READ_SIZE = 1024 * 1024;
+
+ protected static final String LOG_TAG = "android.net.DownloadManagerBaseTest";
+ protected static final int HTTP_OK = 200;
+ protected static final int HTTP_PARTIAL_CONTENT = 206;
+ protected static final int HTTP_NOT_FOUND = 404;
+ protected static final int HTTP_SERVICE_UNAVAILABLE = 503;
+ protected String DEFAULT_FILENAME = "somefile.txt";
+
+ protected static final int DEFAULT_MAX_WAIT_TIME = 2 * 60 * 1000; // 2 minutes
+ protected static final int DEFAULT_WAIT_POLL_TIME = 5 * 1000; // 5 seconds
+
+ protected static final int WAIT_FOR_DOWNLOAD_POLL_TIME = 1 * 1000; // 1 second
+ protected static final int MAX_WAIT_FOR_DOWNLOAD_TIME = 5 * 60 * 1000; // 5 minutes
+
+ // Just a few popular file types used to return from a download
+ protected enum DownloadFileType {
+ PLAINTEXT,
+ APK,
+ GIF,
+ GARBAGE,
+ UNRECOGNIZED,
+ ZIP
+ }
+
+ protected enum DataType {
+ TEXT,
+ BINARY
+ }
+
+ public static class LoggingRng extends Random {
+
+ /**
+ * Constructor
+ *
+ * Creates RNG with self-generated seed value.
+ */
+ public LoggingRng() {
+ this(SystemClock.uptimeMillis());
+ }
+
+ /**
+ * Constructor
+ *
+ * Creats RNG with given initial seed value
+
+ * @param seed The initial seed value
+ */
+ public LoggingRng(long seed) {
+ super(seed);
+ Log.i(LOG_TAG, "Seeding RNG with value: " + seed);
+ }
+ }
+
+ public static class MultipleDownloadsCompletedReceiver extends BroadcastReceiver {
+ private volatile int mNumDownloadsCompleted = 0;
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public void onReceive(Context context, Intent intent) {
+ if (intent.getAction().equalsIgnoreCase(DownloadManager.ACTION_DOWNLOAD_COMPLETE)) {
+ ++mNumDownloadsCompleted;
+ Log.i(LOG_TAG, "MultipleDownloadsCompletedReceiver got intent: " +
+ intent.getAction() + " --> total count: " + mNumDownloadsCompleted);
+ }
+ }
+
+ /**
+ * Gets the number of times the {@link #onReceive} callback has been called for the
+ * {@link DownloadManager.ACTION_DOWNLOAD_COMPLETED} action, indicating the number of
+ * downloads completed thus far.
+ *
+ * @return the number of downloads completed so far.
+ */
+ public int numDownloadsCompleted() {
+ return mNumDownloadsCompleted;
+ }
+ }
+
+ public static class WiFiChangedReceiver extends BroadcastReceiver {
+ private Context mContext = null;
+
+ /**
+ * Constructor
+ *
+ * Sets the current state of WiFi.
+ *
+ * @param context The current app {@link Context}.
+ */
+ public WiFiChangedReceiver(Context context) {
+ mContext = context;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public void onReceive(Context context, Intent intent) {
+ if (intent.getAction().equalsIgnoreCase(ConnectivityManager.CONNECTIVITY_ACTION)) {
+ Log.i(LOG_TAG, "ConnectivityManager state change: " + intent.getAction());
+ synchronized (this) {
+ this.notify();
+ }
+ }
+ }
+
+ /**
+ * Gets the current state of WiFi.
+ *
+ * @return Returns true if WiFi is on, false otherwise.
+ */
+ public boolean getWiFiIsOn() {
+ ConnectivityManager connManager = (ConnectivityManager)mContext.getSystemService(
+ Context.CONNECTIVITY_SERVICE);
+ NetworkInfo info = connManager.getNetworkInfo(ConnectivityManager.TYPE_WIFI);
+ return info.isConnected();
+ }
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public void setUp() throws Exception {
+ mContext = getInstrumentation().getContext();
+ mDownloadManager = (DownloadManager)mContext.getSystemService(Context.DOWNLOAD_SERVICE);
+ mServer = new MockWebServer();
+ // Note: callers overriding this should call mServer.play() with the desired port #
+ }
+
+ /**
+ * Helper to enqueue a response from the MockWebServer.
+ *
+ * @param status The HTTP status code to return for this response
+ * @param body The body to return in this response
+ * @return Returns the mock web server response that was queued (which can be modified)
+ */
+ protected MockResponse enqueueResponse(int status, byte[] body) {
+ return doEnqueueResponse(status).setBody(body);
+
+ }
+
+ /**
+ * Helper to enqueue a response from the MockWebServer.
+ *
+ * @param status The HTTP status code to return for this response
+ * @param bodyFile The body to return in this response
+ * @return Returns the mock web server response that was queued (which can be modified)
+ */
+ protected MockResponse enqueueResponse(int status, File bodyFile) {
+ return doEnqueueResponse(status).setBody(bodyFile);
+ }
+
+ /**
+ * Helper for enqueue'ing a response from the MockWebServer.
+ *
+ * @param status The HTTP status code to return for this response
+ * @return Returns the mock web server response that was queued (which can be modified)
+ */
+ protected MockResponse doEnqueueResponse(int status) {
+ MockResponse response = new MockResponse().setResponseCode(status);
+ response.addHeader("Content-type", mFileType);
+ mServer.enqueue(response);
+ return response;
+ }
+
+ /**
+ * Helper to generate a random blob of bytes.
+ *
+ * @param size The size of the data to generate
+ * @param type The type of data to generate: currently, one of {@link DataType.TEXT} or
+ * {@link DataType.BINARY}.
+ * @return The random data that is generated.
+ */
+ protected byte[] generateData(int size, DataType type) {
+ return generateData(size, type, null);
+ }
+
+ /**
+ * Helper to generate a random blob of bytes using a given RNG.
+ *
+ * @param size The size of the data to generate
+ * @param type The type of data to generate: currently, one of {@link DataType.TEXT} or
+ * {@link DataType.BINARY}.
+ * @param rng (optional) The RNG to use; pass null to use
+ * @return The random data that is generated.
+ */
+ protected byte[] generateData(int size, DataType type, Random rng) {
+ int min = Byte.MIN_VALUE;
+ int max = Byte.MAX_VALUE;
+
+ // Only use chars in the HTTP ASCII printable character range for Text
+ if (type == DataType.TEXT) {
+ min = 32;
+ max = 126;
+ }
+ byte[] result = new byte[size];
+ Log.i(LOG_TAG, "Generating data of size: " + size);
+
+ if (rng == null) {
+ rng = new LoggingRng();
+ }
+
+ for (int i = 0; i < size; ++i) {
+ result[i] = (byte) (min + rng.nextInt(max - min + 1));
+ }
+ return result;
+ }
+
+ /**
+ * Helper to verify the size of a file.
+ *
+ * @param pfd The input file to compare the size of
+ * @param size The expected size of the file
+ */
+ protected void verifyFileSize(ParcelFileDescriptor pfd, long size) {
+ assertEquals(pfd.getStatSize(), size);
+ }
+
+ /**
+ * Helper to verify the contents of a downloaded file versus a byte[].
+ *
+ * @param actual The file of whose contents to verify
+ * @param expected The data we expect to find in the aforementioned file
+ * @throws IOException if there was a problem reading from the file
+ */
+ protected void verifyFileContents(ParcelFileDescriptor actual, byte[] expected)
+ throws IOException {
+ AutoCloseInputStream input = new ParcelFileDescriptor.AutoCloseInputStream(actual);
+ long fileSize = actual.getStatSize();
+
+ assertTrue(fileSize <= Integer.MAX_VALUE);
+ assertEquals(expected.length, fileSize);
+
+ byte[] actualData = new byte[expected.length];
+ assertEquals(input.read(actualData), fileSize);
+ compareByteArrays(actualData, expected);
+ }
+
+ /**
+ * Helper to compare 2 byte arrays.
+ *
+ * @param actual The array whose data we want to verify
+ * @param expected The array of data we expect to see
+ */
+ protected void compareByteArrays(byte[] actual, byte[] expected) {
+ assertEquals(actual.length, expected.length);
+ int length = actual.length;
+ for (int i = 0; i < length; ++i) {
+ // assert has a bit of overhead, so only do the assert when the values are not the same
+ if (actual[i] != expected[i]) {
+ fail("Byte arrays are not equal.");
+ }
+ }
+ }
+
+ /**
+ * Verifies the contents of a downloaded file versus the contents of a File.
+ *
+ * @param pfd The file whose data we want to verify
+ * @param file The file containing the data we expect to see in the aforementioned file
+ * @throws IOException If there was a problem reading either of the two files
+ */
+ protected void verifyFileContents(ParcelFileDescriptor pfd, File file) throws IOException {
+ byte[] actual = new byte[FILE_BLOCK_READ_SIZE];
+ byte[] expected = new byte[FILE_BLOCK_READ_SIZE];
+
+ AutoCloseInputStream input = new ParcelFileDescriptor.AutoCloseInputStream(pfd);
+
+ assertEquals(file.length(), pfd.getStatSize());
+
+ DataInputStream inFile = new DataInputStream(new FileInputStream(file));
+ int actualRead = 0;
+ int expectedRead = 0;
+
+ while (((actualRead = input.read(actual)) != -1) &&
+ ((expectedRead = inFile.read(expected)) != -1)) {
+ assertEquals(actualRead, expectedRead);
+ compareByteArrays(actual, expected);
+ }
+ }
+
+ /**
+ * Sets the MIME type of file that will be served from the mock server
+ *
+ * @param type The MIME type to return from the server
+ */
+ protected void setServerMimeType(DownloadFileType type) {
+ mFileType = getMimeMapping(type);
+ }
+
+ /**
+ * Gets the MIME content string for a given type
+ *
+ * @param type The MIME type to return
+ * @return the String representation of that MIME content type
+ */
+ protected String getMimeMapping(DownloadFileType type) {
+ switch (type) {
+ case APK:
+ return "application/vnd.android.package-archive";
+ case GIF:
+ return "image/gif";
+ case ZIP:
+ return "application/x-zip-compressed";
+ case GARBAGE:
+ return "zip\\pidy/doo/da";
+ case UNRECOGNIZED:
+ return "application/new.undefined.type.of.app";
+ }
+ return "text/plain";
+ }
+
+ /**
+ * Gets the Uri that should be used to access the mock server
+ *
+ * @param filename The name of the file to try to retrieve from the mock server
+ * @return the Uri to use for access the file on the mock server
+ */
+ protected Uri getServerUri(String filename) throws Exception {
+ URL url = mServer.getUrl("/" + filename);
+ return Uri.parse(url.toString());
+ }
+
+ /**
+ * Gets the Uri that should be used to access the mock server
+ *
+ * @param filename The name of the file to try to retrieve from the mock server
+ * @return the Uri to use for access the file on the mock server
+ */
+ protected void logDBColumnData(Cursor cursor, String column) {
+ int index = cursor.getColumnIndex(column);
+ Log.i(LOG_TAG, "columnName: " + column);
+ Log.i(LOG_TAG, "columnValue: " + cursor.getString(index));
+ }
+
+ /**
+ * Helper to create and register a new MultipleDownloadCompletedReciever
+ *
+ * This is used to track many simultaneous downloads by keeping count of all the downloads
+ * that have completed.
+ *
+ * @return A new receiver that records and can be queried on how many downloads have completed.
+ */
+ protected MultipleDownloadsCompletedReceiver registerNewMultipleDownloadsReceiver() {
+ MultipleDownloadsCompletedReceiver receiver = new MultipleDownloadsCompletedReceiver();
+ mContext.registerReceiver(receiver, new IntentFilter(
+ DownloadManager.ACTION_DOWNLOAD_COMPLETE));
+ return receiver;
+ }
+
+ /**
+ * Helper to verify a standard single-file download from the mock server, and clean up after
+ * verification
+ *
+ * Note that this also calls the Download manager's remove, which cleans up the file from cache.
+ *
+ * @param requestId The id of the download to remove
+ * @param fileData The data to verify the file contains
+ */
+ protected void verifyAndCleanupSingleFileDownload(long requestId, byte[] fileData)
+ throws Exception {
+ int fileSize = fileData.length;
+ ParcelFileDescriptor pfd = mDownloadManager.openDownloadedFile(requestId);
+ Cursor cursor = mDownloadManager.query(new Query().setFilterById(requestId));
+
+ try {
+ assertEquals(1, cursor.getCount());
+ assertTrue(cursor.moveToFirst());
+
+ mServer.checkForExceptions();
+
+ verifyFileSize(pfd, fileSize);
+ verifyFileContents(pfd, fileData);
+ } finally {
+ pfd.close();
+ cursor.close();
+ mDownloadManager.remove(requestId);
+ }
+ }
+
+ /**
+ * Enables or disables WiFi.
+ *
+ * Note: Needs the following permissions:
+ * android.permission.ACCESS_WIFI_STATE
+ * android.permission.CHANGE_WIFI_STATE
+ * @param enable true if it should be enabled, false if it should be disabled
+ */
+ protected void setWiFiStateOn(boolean enable) throws Exception {
+ WifiManager manager = (WifiManager)mContext.getSystemService(Context.WIFI_SERVICE);
+
+ manager.setWifiEnabled(enable);
+
+ String timeoutMessage = "Timed out waiting for Wifi to be "
+ + (enable ? "enabled!" : "disabled!");
+
+ WiFiChangedReceiver receiver = new WiFiChangedReceiver(mContext);
+ mContext.registerReceiver(receiver, new IntentFilter(
+ ConnectivityManager.CONNECTIVITY_ACTION));
+
+ synchronized (receiver) {
+ long timeoutTime = SystemClock.elapsedRealtime() + DEFAULT_MAX_WAIT_TIME;
+ boolean timedOut = false;
+
+ while (receiver.getWiFiIsOn() != enable && !timedOut) {
+ try {
+ receiver.wait(DEFAULT_MAX_WAIT_TIME);
+
+ if (SystemClock.elapsedRealtime() > timeoutTime) {
+ timedOut = true;
+ }
+ }
+ catch (InterruptedException e) {
+ // ignore InterruptedExceptions
+ }
+ }
+ if (timedOut) {
+ fail(timeoutMessage);
+ }
+ }
+ assertEquals(enable, receiver.getWiFiIsOn());
+ }
+
+ /**
+ * Helper to enables or disables airplane mode. If successful, it also broadcasts an intent
+ * indicating that the mode has changed.
+ *
+ * Note: Needs the following permission:
+ * android.permission.WRITE_SETTINGS
+ * @param enable true if airplane mode should be ON, false if it should be OFF
+ */
+ protected void setAirplaneModeOn(boolean enable) throws Exception {
+ int state = enable ? 1 : 0;
+
+ // Change the system setting
+ Settings.System.putInt(mContext.getContentResolver(), Settings.System.AIRPLANE_MODE_ON,
+ state);
+
+ String timeoutMessage = "Timed out waiting for airplane mode to be " +
+ (enable ? "enabled!" : "disabled!");
+
+ // wait for airplane mode to change state
+ int currentWaitTime = 0;
+ while (Settings.System.getInt(mContext.getContentResolver(),
+ Settings.System.AIRPLANE_MODE_ON, -1) != state) {
+ timeoutWait(currentWaitTime, DEFAULT_WAIT_POLL_TIME, DEFAULT_MAX_WAIT_TIME,
+ timeoutMessage);
+ }
+
+ // Post the intent
+ Intent intent = new Intent(Intent.ACTION_AIRPLANE_MODE_CHANGED);
+ intent.putExtra("state", true);
+ mContext.sendBroadcast(intent);
+ }
+
+ /**
+ * Helper to create a large file of random data on the SD card.
+ *
+ * @param filename (optional) The name of the file to create on the SD card; pass in null to
+ * use a default temp filename.
+ * @param type The type of file to create
+ * @param subdirectory If not null, the subdirectory under the SD card where the file should go
+ * @return The File that was created
+ * @throws IOException if there was an error while creating the file.
+ */
+ protected File createFileOnSD(String filename, long fileSize, DataType type,
+ String subdirectory) throws IOException {
+
+ // Build up the file path and name
+ String sdPath = Environment.getExternalStorageDirectory().getPath();
+ StringBuilder fullPath = new StringBuilder(sdPath);
+ if (subdirectory != null) {
+ fullPath.append(File.separatorChar).append(subdirectory);
+ }
+
+ File file = null;
+ if (filename == null) {
+ file = File.createTempFile("DMTEST_", null, new File(fullPath.toString()));
+ }
+ else {
+ fullPath.append(File.separatorChar).append(filename);
+ file = new File(fullPath.toString());
+ file.createNewFile();
+ }
+
+ // Fill the file with random data
+ DataOutputStream output = new DataOutputStream(new FileOutputStream(file));
+ final int CHUNK_SIZE = 1000000; // copy random data in 1000000-char chunks
+ long remaining = fileSize;
+ int nextChunkSize = CHUNK_SIZE;
+ byte[] randomData = null;
+ Random rng = new LoggingRng();
+
+ try {
+ while (remaining > 0) {
+ if (remaining < CHUNK_SIZE) {
+ nextChunkSize = (int)remaining;
+ remaining = 0;
+ }
+ else {
+ remaining -= CHUNK_SIZE;
+ }
+
+ randomData = generateData(nextChunkSize, type, rng);
+ output.write(randomData);
+ }
+ } catch (IOException e) {
+ Log.e(LOG_TAG, "Error writing to file " + file.getAbsolutePath());
+ file.delete();
+ throw e;
+ } finally {
+ output.close();
+ }
+ return file;
+ }
+
+ /**
+ * Helper to wait for a particular download to finish, or else a timeout to occur
+ *
+ * @param id The download id to query on (wait for)
+ */
+ protected void waitForDownloadOrTimeout(long id) throws TimeoutException,
+ InterruptedException {
+ waitForDownloadOrTimeout(id, WAIT_FOR_DOWNLOAD_POLL_TIME, MAX_WAIT_FOR_DOWNLOAD_TIME);
+ }
+
+ /**
+ * Helper to wait for a particular download to finish, or else a timeout to occur
+ *
+ * @param id The download id to query on (wait for)
+ * @param poll The amount of time to wait
+ * @param timeoutMillis The max time (in ms) to wait for the download(s) to complete
+ */
+ protected void waitForDownloadOrTimeout(long id, long poll, long timeoutMillis)
+ throws TimeoutException, InterruptedException {
+ doWaitForDownloadsOrTimeout(new Query().setFilterById(id), poll, timeoutMillis);
+ }
+
+ /**
+ * Helper to wait for all downloads to finish, or else a specified timeout to occur
+ *
+ * @param poll The amount of time to wait
+ * @param timeoutMillis The max time (in ms) to wait for the download(s) to complete
+ */
+ protected void waitForDownloadsOrTimeout(long poll, long timeoutMillis) throws TimeoutException,
+ InterruptedException {
+ doWaitForDownloadsOrTimeout(new Query(), poll, timeoutMillis);
+ }
+
+ /**
+ * Helper to wait for all downloads to finish, or else a timeout to occur, but does not throw
+ *
+ * @param id The id of the download to query against
+ * @param poll The amount of time to wait
+ * @param timeoutMillis The max time (in ms) to wait for the download(s) to complete
+ * @return true if download completed successfully (didn't timeout), false otherwise
+ */
+ protected boolean waitForDownloadOrTimeoutNoThrow(long id, long poll, long timeoutMillis) {
+ try {
+ doWaitForDownloadsOrTimeout(new Query().setFilterById(id), poll, timeoutMillis);
+ } catch (TimeoutException e) {
+ return false;
+ }
+ return true;
+ }
+
+ /**
+ * Helper function to synchronously wait, or timeout if the maximum threshold has been exceeded.
+ *
+ * @param currentTotalWaitTime The total time waited so far
+ * @param poll The amount of time to wait
+ * @param maxTimeoutMillis The total wait time threshold; if we've waited more than this long,
+ * we timeout and fail
+ * @param timedOutMessage The message to display in the failure message if we timeout
+ * @return The new total amount of time we've waited so far
+ * @throws TimeoutException if timed out waiting for SD card to mount
+ */
+ protected int timeoutWait(int currentTotalWaitTime, long poll, long maxTimeoutMillis,
+ String timedOutMessage) throws TimeoutException {
+ long now = SystemClock.elapsedRealtime();
+ long end = now + poll;
+
+ // if we get InterruptedException's, ignore them and just keep sleeping
+ while (now < end) {
+ try {
+ Thread.sleep(end - now);
+ } catch (InterruptedException e) {
+ // ignore interrupted exceptions
+ }
+ now = SystemClock.elapsedRealtime();
+ }
+
+ currentTotalWaitTime += poll;
+ if (currentTotalWaitTime > maxTimeoutMillis) {
+ throw new TimeoutException(timedOutMessage);
+ }
+ return currentTotalWaitTime;
+ }
+
+ /**
+ * Helper to wait for all downloads to finish, or else a timeout to occur
+ *
+ * @param query The query to pass to the download manager
+ * @param poll The poll time to wait between checks
+ * @param timeoutMillis The max amount of time (in ms) to wait for the download(s) to complete
+ */
+ protected void doWaitForDownloadsOrTimeout(Query query, long poll, long timeoutMillis)
+ throws TimeoutException {
+ int currentWaitTime = 0;
+ while (true) {
+ query.setFilterByStatus(DownloadManager.STATUS_PENDING | DownloadManager.STATUS_PAUSED
+ | DownloadManager.STATUS_RUNNING);
+ Cursor cursor = mDownloadManager.query(query);
+
+ try {
+ // If we've finished the downloads then we're done
+ if (cursor.getCount() == 0) {
+ break;
+ }
+ currentWaitTime = timeoutWait(currentWaitTime, poll, timeoutMillis,
+ "Timed out waiting for all downloads to finish");
+ } finally {
+ cursor.close();
+ }
+ }
+ }
+
+ /**
+ * Synchronously waits for external store to be mounted (eg: SD Card).
+ *
+ * @throws InterruptedException if interrupted
+ * @throws Exception if timed out waiting for SD card to mount
+ */
+ protected void waitForExternalStoreMount() throws Exception {
+ String extStorageState = Environment.getExternalStorageState();
+ int currentWaitTime = 0;
+ while (!extStorageState.equals(Environment.MEDIA_MOUNTED)) {
+ Log.i(LOG_TAG, "Waiting for SD card...");
+ currentWaitTime = timeoutWait(currentWaitTime, DEFAULT_WAIT_POLL_TIME,
+ DEFAULT_MAX_WAIT_TIME, "Timed out waiting for SD Card to be ready!");
+ extStorageState = Environment.getExternalStorageState();
+ }
+ }
+
+ /**
+ * Synchronously waits for a download to start.
+ *
+ * @param dlRequest the download request id used by Download Manager to track the download.
+ * @throws Exception if timed out while waiting for SD card to mount
+ */
+ protected void waitForDownloadToStart(long dlRequest) throws Exception {
+ Cursor cursor = getCursor(dlRequest);
+ try {
+ int columnIndex = cursor.getColumnIndex(DownloadManager.COLUMN_STATUS);
+ int value = cursor.getInt(columnIndex);
+ int currentWaitTime = 0;
+
+ while (value != DownloadManager.STATUS_RUNNING &&
+ (value != DownloadManager.STATUS_FAILED) &&
+ (value != DownloadManager.STATUS_SUCCESSFUL)) {
+ Log.i(LOG_TAG, "Waiting for download to start...");
+ currentWaitTime = timeoutWait(currentWaitTime, WAIT_FOR_DOWNLOAD_POLL_TIME,
+ MAX_WAIT_FOR_DOWNLOAD_TIME, "Timed out waiting for download to start!");
+ cursor.requery();
+ assertTrue(cursor.moveToFirst());
+ columnIndex = cursor.getColumnIndex(DownloadManager.COLUMN_STATUS);
+ value = cursor.getInt(columnIndex);
+ }
+ assertFalse("Download failed immediately after start",
+ value == DownloadManager.STATUS_FAILED);
+ } finally {
+ cursor.close();
+ }
+ }
+
+ /**
+ * Synchronously waits for a file to increase in size (such as to monitor that a download is
+ * progressing).
+ *
+ * @param file The file whose size to track.
+ * @throws Exception if timed out while waiting for the file to grow in size.
+ */
+ protected void waitForFileToGrow(File file) throws Exception {
+ int currentWaitTime = 0;
+
+ // File may not even exist yet, so wait until it does (or we timeout)
+ while (!file.exists()) {
+ Log.i(LOG_TAG, "Waiting for file to exist...");
+ currentWaitTime = timeoutWait(currentWaitTime, WAIT_FOR_DOWNLOAD_POLL_TIME,
+ MAX_WAIT_FOR_DOWNLOAD_TIME, "Timed out waiting for file to be created.");
+ }
+
+ // Get original file size...
+ long originalSize = file.length();
+
+ while (file.length() <= originalSize) {
+ Log.i(LOG_TAG, "Waiting for file to be written to...");
+ currentWaitTime = timeoutWait(currentWaitTime, WAIT_FOR_DOWNLOAD_POLL_TIME,
+ MAX_WAIT_FOR_DOWNLOAD_TIME, "Timed out waiting for file to be written to.");
+ }
+ }
+
+ /**
+ * Helper to remove all downloads that are registered with the DL Manager.
+ *
+ * Note: This gives us a clean slate b/c it includes downloads that are pending, running,
+ * paused, or have completed.
+ */
+ protected void removeAllCurrentDownloads() {
+ Log.i(LOG_TAG, "Removing all current registered downloads...");
+ Cursor cursor = mDownloadManager.query(new Query());
+ try {
+ if (cursor.moveToFirst()) {
+ do {
+ int index = cursor.getColumnIndex(DownloadManager.COLUMN_ID);
+ long downloadId = cursor.getLong(index);
+
+ mDownloadManager.remove(downloadId);
+ } while (cursor.moveToNext());
+ }
+ } finally {
+ cursor.close();
+ }
+ }
+
+ /**
+ * Helper to perform a standard enqueue of data to the mock server.
+ *
+ * @param body The body to return in the response from the server
+ */
+ protected long doStandardEnqueue(byte[] body) throws Exception {
+ // Prepare the mock server with a standard response
+ enqueueResponse(HTTP_OK, body);
+ return doCommonStandardEnqueue();
+ }
+
+ /**
+ * Helper to perform a standard enqueue of data to the mock server.
+ *
+ * @param body The body to return in the response from the server, contained in the file
+ */
+ protected long doStandardEnqueue(File body) throws Exception {
+ // Prepare the mock server with a standard response
+ enqueueResponse(HTTP_OK, body);
+ return doCommonStandardEnqueue();
+ }
+
+ /**
+ * Helper to do the additional steps (setting title and Uri of default filename) when
+ * doing a standard enqueue request to the server.
+ */
+ protected long doCommonStandardEnqueue() throws Exception {
+ Uri uri = getServerUri(DEFAULT_FILENAME);
+ Request request = new Request(uri);
+ request.setTitle(DEFAULT_FILENAME);
+
+ long dlRequest = mDownloadManager.enqueue(request);
+ Log.i(LOG_TAG, "request ID: " + dlRequest);
+ return dlRequest;
+ }
+
+ /**
+ * Helper to verify an int value in a Cursor
+ *
+ * @param cursor The cursor containing the query results
+ * @param columnName The name of the column to query
+ * @param expected The expected int value
+ */
+ protected void verifyInt(Cursor cursor, String columnName, int expected) {
+ int index = cursor.getColumnIndex(columnName);
+ int actual = cursor.getInt(index);
+ assertEquals(expected, actual);
+ }
+
+ /**
+ * Helper to verify a String value in a Cursor
+ *
+ * @param cursor The cursor containing the query results
+ * @param columnName The name of the column to query
+ * @param expected The expected String value
+ */
+ protected void verifyString(Cursor cursor, String columnName, String expected) {
+ int index = cursor.getColumnIndex(columnName);
+ String actual = cursor.getString(index);
+ Log.i(LOG_TAG, ": " + actual);
+ assertEquals(expected, actual);
+ }
+
+ /**
+ * Performs a query based on ID and returns a Cursor for the query.
+ *
+ * @param id The id of the download in DL Manager; pass -1 to query all downloads
+ * @return A cursor for the query results
+ */
+ protected Cursor getCursor(long id) throws Exception {
+ Query query = new Query();
+ if (id != -1) {
+ query.setFilterById(id);
+ }
+
+ Cursor cursor = mDownloadManager.query(query);
+ int currentWaitTime = 0;
+
+ try {
+ while (!cursor.moveToFirst()) {
+ Thread.sleep(DEFAULT_WAIT_POLL_TIME);
+ currentWaitTime += DEFAULT_WAIT_POLL_TIME;
+ if (currentWaitTime > DEFAULT_MAX_WAIT_TIME) {
+ fail("timed out waiting for a non-null query result");
+ }
+ cursor.requery();
+ }
+ } catch (Exception e) {
+ cursor.close();
+ throw e;
+ }
+ return cursor;
+ }
+
+} \ No newline at end of file
diff --git a/core/tests/coretests/src/android/net/DownloadManagerIntegrationTest.java b/core/tests/coretests/src/android/net/DownloadManagerIntegrationTest.java
new file mode 100644
index 000000000000..be3cbf729458
--- /dev/null
+++ b/core/tests/coretests/src/android/net/DownloadManagerIntegrationTest.java
@@ -0,0 +1,381 @@
+/*
+ * Copyright (C) 2010 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.net;
+
+import android.content.BroadcastReceiver;
+import android.content.Context;
+import android.content.Intent;
+import android.content.IntentFilter;
+import android.database.Cursor;
+import android.net.DownloadManager.Query;
+import android.net.DownloadManager.Request;
+import android.net.DownloadManagerBaseTest.DataType;
+import android.net.DownloadManagerBaseTest.MultipleDownloadsCompletedReceiver;
+import android.net.wifi.WifiManager;
+import android.os.Environment;
+import android.os.ParcelFileDescriptor;
+import android.os.SystemClock;
+import android.test.InstrumentationTestCase;
+import android.test.suitebuilder.annotation.LargeTest;
+import android.test.suitebuilder.annotation.MediumTest;
+import android.test.suitebuilder.annotation.SmallTest;
+import android.util.Log;
+
+import java.io.File;
+import java.io.FileWriter;
+import java.io.IOException;
+import java.net.URL;
+import java.util.Random;
+
+import junit.framework.AssertionFailedError;
+
+import coretestutils.http.MockResponse;
+import coretestutils.http.MockWebServer;
+
+/**
+ * Integration tests of the DownloadManager API.
+ */
+public class DownloadManagerIntegrationTest extends DownloadManagerBaseTest {
+
+ private static String LOG_TAG = "android.net.DownloadManagerIntegrationTest";
+ private static String PROHIBITED_DIRECTORY = "/system";
+ protected MultipleDownloadsCompletedReceiver mReceiver = null;
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public void setUp() throws Exception {
+ super.setUp();
+ setWiFiStateOn(true);
+ mServer.play();
+ removeAllCurrentDownloads();
+ mReceiver = registerNewMultipleDownloadsReceiver();
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public void tearDown() throws Exception {
+ super.tearDown();
+ setWiFiStateOn(true);
+
+ if (mReceiver != null) {
+ mContext.unregisterReceiver(mReceiver);
+ mReceiver = null;
+ removeAllCurrentDownloads();
+ }
+ }
+
+ /**
+ * Helper that does the actual basic download verification.
+ */
+ protected void doBasicDownload(byte[] blobData) throws Exception {
+ long dlRequest = doStandardEnqueue(blobData);
+
+ // wait for the download to complete
+ waitForDownloadOrTimeout(dlRequest);
+
+ verifyAndCleanupSingleFileDownload(dlRequest, blobData);
+ assertEquals(1, mReceiver.numDownloadsCompleted());
+ }
+
+ /**
+ * Test a basic download of a binary file 500k in size.
+ */
+ @LargeTest
+ public void testBasicBinaryDownload() throws Exception {
+ int fileSize = 500 * 1024; // 500k
+ byte[] blobData = generateData(fileSize, DataType.BINARY);
+
+ doBasicDownload(blobData);
+ }
+
+ /**
+ * Tests the basic downloading of a text file 300000 bytes in size.
+ */
+ @LargeTest
+ public void testBasicTextDownload() throws Exception {
+ int fileSize = 300000;
+ byte[] blobData = generateData(fileSize, DataType.TEXT);
+
+ doBasicDownload(blobData);
+ }
+
+ /**
+ * Tests when the server drops the connection after all headers (but before any data send).
+ */
+ @LargeTest
+ public void testDropConnection_headers() throws Exception {
+ byte[] blobData = generateData(DEFAULT_FILE_SIZE, DataType.TEXT);
+
+ MockResponse response = enqueueResponse(HTTP_OK, blobData);
+ response.setCloseConnectionAfterHeader("content-length");
+ long dlRequest = doCommonStandardEnqueue();
+
+ // Download will never complete when header is dropped
+ boolean success = waitForDownloadOrTimeoutNoThrow(dlRequest, DEFAULT_WAIT_POLL_TIME,
+ DEFAULT_MAX_WAIT_TIME);
+
+ assertFalse(success);
+ }
+
+ /**
+ * Tests that we get an error code when the server drops the connection during a download.
+ */
+ @LargeTest
+ public void testServerDropConnection_body() throws Exception {
+ byte[] blobData = generateData(25000, DataType.TEXT); // file size = 25000 bytes
+
+ MockResponse response = enqueueResponse(HTTP_OK, blobData);
+ response.setCloseConnectionAfterXBytes(15382);
+ long dlRequest = doCommonStandardEnqueue();
+ waitForDownloadOrTimeout(dlRequest);
+
+ Cursor cursor = getCursor(dlRequest);
+ try {
+ verifyInt(cursor, DownloadManager.COLUMN_STATUS, DownloadManager.STATUS_FAILED);
+ verifyInt(cursor, DownloadManager.COLUMN_ERROR_CODE,
+ DownloadManager.ERROR_CANNOT_RESUME);
+ } finally {
+ cursor.close();
+ }
+ // Even tho the server drops the connection, we should still get a completed notification
+ assertEquals(1, mReceiver.numDownloadsCompleted());
+ }
+
+ /**
+ * Attempts to download several files simultaneously
+ */
+ @LargeTest
+ public void testMultipleDownloads() throws Exception {
+ // need to be sure all current downloads have stopped first
+ removeAllCurrentDownloads();
+ int NUM_FILES = 50;
+ int MAX_FILE_SIZE = 500 * 1024; // 500 kb
+
+ Random r = new LoggingRng();
+ for (int i=0; i<NUM_FILES; ++i) {
+ int size = r.nextInt(MAX_FILE_SIZE);
+ byte[] blobData = generateData(size, DataType.TEXT);
+
+ Uri uri = getServerUri(DEFAULT_FILENAME);
+ Request request = new Request(uri);
+ request.setTitle(String.format("%s--%d", DEFAULT_FILENAME, i));
+
+ // Prepare the mock server with a standard response
+ enqueueResponse(HTTP_OK, blobData);
+
+ Log.i(LOG_TAG, "request: " + i);
+ mDownloadManager.enqueue(request);
+ }
+
+ waitForDownloadsOrTimeout(WAIT_FOR_DOWNLOAD_POLL_TIME, MAX_WAIT_FOR_DOWNLOAD_TIME);
+ Cursor cursor = mDownloadManager.query(new Query());
+ try {
+ assertEquals(NUM_FILES, cursor.getCount());
+
+ if (cursor.moveToFirst()) {
+ do {
+ int status = cursor.getInt(cursor.getColumnIndex(
+ DownloadManager.COLUMN_STATUS));
+ String filename = cursor.getString(cursor.getColumnIndex(
+ DownloadManager.COLUMN_URI));
+ String errorString = String.format(
+ "File %s failed to download successfully. Status code: %d",
+ filename, status);
+ assertEquals(errorString, DownloadManager.STATUS_SUCCESSFUL, status);
+ } while (cursor.moveToNext());
+ }
+
+ assertEquals(NUM_FILES, mReceiver.numDownloadsCompleted());
+ } finally {
+ cursor.close();
+ }
+ }
+
+ /**
+ * Tests trying to download to SD card when the file with same name already exists.
+ */
+ @LargeTest
+ public void testDownloadToExternal_fileExists() throws Exception {
+ File existentFile = createFileOnSD(null, 1, DataType.TEXT, null);
+ byte[] blobData = generateData(DEFAULT_FILE_SIZE, DataType.TEXT);
+
+ // Prepare the mock server with a standard response
+ enqueueResponse(HTTP_OK, blobData);
+
+ try {
+ Uri uri = getServerUri(DEFAULT_FILENAME);
+ Request request = new Request(uri);
+
+ Uri localUri = Uri.fromFile(existentFile);
+ Log.i(LOG_TAG, "setting localUri to: " + localUri.getPath());
+ request.setDestinationUri(localUri);
+
+ long dlRequest = mDownloadManager.enqueue(request);
+
+ // wait for the download to complete
+ waitForDownloadOrTimeout(dlRequest);
+ Cursor cursor = getCursor(dlRequest);
+
+ try {
+ verifyInt(cursor, DownloadManager.COLUMN_STATUS, DownloadManager.STATUS_FAILED);
+ verifyInt(cursor, DownloadManager.COLUMN_ERROR_CODE,
+ DownloadManager.ERROR_FILE_ERROR);
+ } finally {
+ cursor.close();
+ }
+ } finally {
+ existentFile.delete();
+ }
+ }
+
+ /**
+ * Tests trying to download a file to SD card.
+ */
+ @LargeTest
+ public void testDownloadToExternal() throws Exception {
+ String localDownloadDirectory = Environment.getExternalStorageDirectory().getPath();
+ File downloadedFile = new File(localDownloadDirectory, DEFAULT_FILENAME);
+ // make sure the file doesn't already exist in the directory
+ downloadedFile.delete();
+
+ try {
+ byte[] blobData = generateData(DEFAULT_FILE_SIZE, DataType.TEXT);
+
+ // Prepare the mock server with a standard response
+ enqueueResponse(HTTP_OK, blobData);
+
+ Uri uri = getServerUri(DEFAULT_FILENAME);
+ Request request = new Request(uri);
+
+ Uri localUri = Uri.fromFile(downloadedFile);
+ Log.i(LOG_TAG, "setting localUri to: " + localUri.getPath());
+ request.setDestinationUri(localUri);
+
+ long dlRequest = mDownloadManager.enqueue(request);
+
+ // wait for the download to complete
+ waitForDownloadOrTimeout(dlRequest);
+
+ verifyAndCleanupSingleFileDownload(dlRequest, blobData);
+
+ assertEquals(1, mReceiver.numDownloadsCompleted());
+ } finally {
+ downloadedFile.delete();
+ }
+ }
+
+ /**
+ * Tests trying to download a file to the system partition.
+ */
+ @LargeTest
+ public void testDownloadToProhibitedDirectory() throws Exception {
+ File downloadedFile = new File(PROHIBITED_DIRECTORY, DEFAULT_FILENAME);
+ try {
+ byte[] blobData = generateData(DEFAULT_FILE_SIZE, DataType.TEXT);
+
+ // Prepare the mock server with a standard response
+ enqueueResponse(HTTP_OK, blobData);
+
+ Uri uri = getServerUri(DEFAULT_FILENAME);
+ Request request = new Request(uri);
+
+ Uri localUri = Uri.fromFile(downloadedFile);
+ Log.i(LOG_TAG, "setting localUri to: " + localUri.getPath());
+ request.setDestinationUri(localUri);
+
+ try {
+ mDownloadManager.enqueue(request);
+ fail("Failed to throw SecurityException when trying to write to /system.");
+ } catch (SecurityException s) {
+ assertFalse(downloadedFile.exists());
+ }
+ } finally {
+ // Just in case file somehow got created, make sure to delete it
+ downloadedFile.delete();
+ }
+ }
+
+ /**
+ * Tests that a download set for Wifi does not progress while Wifi is disabled, but resumes
+ * once Wifi is re-enabled.
+ */
+ @LargeTest
+ public void testDownloadNoWifi() throws Exception {
+ long timeout = 60 * 1000; // wait only 60 seconds before giving up
+ int fileSize = 140 * 1024; // 140k
+ byte[] blobData = generateData(fileSize, DataType.TEXT);
+
+ setWiFiStateOn(false);
+ enqueueResponse(HTTP_OK, blobData);
+
+ try {
+ Uri uri = getServerUri(DEFAULT_FILENAME);
+ Request request = new Request(uri);
+ request.setAllowedNetworkTypes(Request.NETWORK_WIFI);
+
+ long dlRequest = mDownloadManager.enqueue(request);
+
+ // wait for the download to complete
+ boolean success = waitForDownloadOrTimeoutNoThrow(dlRequest,
+ WAIT_FOR_DOWNLOAD_POLL_TIME, timeout);
+ assertFalse("Download proceeded without Wifi connection!", success);
+
+ setWiFiStateOn(true);
+ waitForDownloadOrTimeout(dlRequest);
+
+ assertEquals(1, mReceiver.numDownloadsCompleted());
+ } finally {
+ setWiFiStateOn(true);
+ }
+ }
+
+ /**
+ * Tests trying to download two large files (50M bytes, followed by 60M bytes)
+ */
+ @LargeTest
+ public void testInsufficientSpaceSingleFiles() throws Exception {
+ long fileSize1 = 50000000L;
+ long fileSize2 = 60000000L;
+ File largeFile1 = createFileOnSD(null, fileSize1, DataType.TEXT, null);
+ File largeFile2 = createFileOnSD(null, fileSize2, DataType.TEXT, null);
+
+ try {
+ long dlRequest = doStandardEnqueue(largeFile1);
+ waitForDownloadOrTimeout(dlRequest);
+ ParcelFileDescriptor pfd = mDownloadManager.openDownloadedFile(dlRequest);
+ verifyFileContents(pfd, largeFile1);
+ verifyFileSize(pfd, largeFile1.length());
+
+ dlRequest = doStandardEnqueue(largeFile2);
+ waitForDownloadOrTimeout(dlRequest);
+ Cursor cursor = getCursor(dlRequest);
+ try {
+ verifyInt(cursor, DownloadManager.COLUMN_ERROR_CODE,
+ DownloadManager.ERROR_INSUFFICIENT_SPACE);
+ } finally {
+ cursor.close();
+ }
+ } finally {
+ largeFile1.delete();
+ largeFile2.delete();
+ }
+ }
+}
diff --git a/core/tests/coretests/src/android/net/DownloadManagerStressTest.java b/core/tests/coretests/src/android/net/DownloadManagerStressTest.java
new file mode 100644
index 000000000000..9fa8620b0931
--- /dev/null
+++ b/core/tests/coretests/src/android/net/DownloadManagerStressTest.java
@@ -0,0 +1,156 @@
+/*
+ * Copyright (C) 2010 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.net;
+
+import java.io.File;
+import java.util.Random;
+
+import android.database.Cursor;
+import android.net.DownloadManager.Query;
+import android.net.DownloadManager.Request;
+import android.os.ParcelFileDescriptor;
+import android.test.suitebuilder.annotation.LargeTest;
+import android.util.Log;
+
+
+public class DownloadManagerStressTest extends DownloadManagerBaseTest {
+ private static String LOG_TAG = "android.net.DownloadManagerStressTest";
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public void setUp() throws Exception {
+ super.setUp();
+ mServer.play(0);
+ removeAllCurrentDownloads();
+ }
+
+ /**
+ * Attempts to downloading thousands of files simultaneously
+ */
+ public void testDownloadThousands() throws Exception {
+ int NUM_FILES = 1500;
+ int MAX_FILE_SIZE = 3000;
+ long[] reqs = new long[NUM_FILES];
+
+ // need to be sure all current downloads have stopped first
+ MultipleDownloadsCompletedReceiver receiver = registerNewMultipleDownloadsReceiver();
+ Cursor cursor = null;
+ try {
+ Random r = new LoggingRng();
+ for (int i = 0; i < NUM_FILES; ++i) {
+ int size = r.nextInt(MAX_FILE_SIZE);
+ byte[] blobData = generateData(size, DataType.TEXT);
+
+ Uri uri = getServerUri(DEFAULT_FILENAME);
+ Request request = new Request(uri);
+ request.setTitle(String.format("%s--%d", DEFAULT_FILENAME, i));
+
+ // Prepare the mock server with a standard response
+ enqueueResponse(HTTP_OK, blobData);
+
+ Log.i(LOG_TAG, "issuing request: " + i);
+ long reqId = mDownloadManager.enqueue(request);
+ reqs[i] = reqId;
+ }
+
+ // wait for the download to complete or timeout
+ waitForDownloadsOrTimeout(WAIT_FOR_DOWNLOAD_POLL_TIME, MAX_WAIT_FOR_DOWNLOAD_TIME);
+ cursor = mDownloadManager.query(new Query());
+ assertEquals(NUM_FILES, cursor.getCount());
+ Log.i(LOG_TAG, "Verified number of downloads in download manager is what we expect.");
+ while (cursor.moveToNext()) {
+ int status = cursor.getInt(cursor.getColumnIndex(DownloadManager.COLUMN_STATUS));
+ String filename = cursor.getString(cursor.getColumnIndex(
+ DownloadManager.COLUMN_URI));
+ String errorString = String.format("File %s failed to download successfully. " +
+ "Status code: %d", filename, status);
+ assertEquals(errorString, DownloadManager.STATUS_SUCCESSFUL, status);
+ }
+ Log.i(LOG_TAG, "Verified each download was successful.");
+ assertEquals(NUM_FILES, receiver.numDownloadsCompleted());
+ Log.i(LOG_TAG, "Verified number of completed downloads in our receiver.");
+
+ // Verify that for each request, we can open the downloaded file
+ for (int i = 0; i < NUM_FILES; ++i) {
+ ParcelFileDescriptor pfd = mDownloadManager.openDownloadedFile(reqs[i]);
+ pfd.close();
+ }
+ Log.i(LOG_TAG, "Verified we can open each file.");
+ } finally {
+ if (cursor != null) {
+ cursor.close();
+ }
+ mContext.unregisterReceiver(receiver);
+ removeAllCurrentDownloads();
+ }
+ }
+
+ /**
+ * Tests trying to download a large file (50M bytes).
+ */
+ public void testDownloadLargeFile() throws Exception {
+ long fileSize = 50000000L; // note: kept relatively small to not exceed /cache dir size
+ File largeFile = createFileOnSD(null, fileSize, DataType.TEXT, null);
+ MultipleDownloadsCompletedReceiver receiver = registerNewMultipleDownloadsReceiver();
+
+ try {
+ long dlRequest = doStandardEnqueue(largeFile);
+
+ // wait for the download to complete
+ waitForDownloadOrTimeout(dlRequest);
+
+ ParcelFileDescriptor pfd = mDownloadManager.openDownloadedFile(dlRequest);
+ verifyFileContents(pfd, largeFile);
+ verifyFileSize(pfd, largeFile.length());
+
+ assertEquals(1, receiver.numDownloadsCompleted());
+ mContext.unregisterReceiver(receiver);
+ } catch (Exception e) {
+ throw e;
+ } finally {
+ largeFile.delete();
+ }
+ }
+
+ /**
+ * Tests trying to download a large file (~300M bytes) when there's not enough space in cache
+ */
+ public void testInsufficientSpace() throws Exception {
+ long fileSize = 300000000L;
+ File largeFile = createFileOnSD(null, fileSize, DataType.TEXT, null);
+
+ Cursor cursor = null;
+ try {
+ long dlRequest = doStandardEnqueue(largeFile);
+
+ // wait for the download to complete
+ waitForDownloadOrTimeout(dlRequest);
+
+ cursor = getCursor(dlRequest);
+ verifyInt(cursor, DownloadManager.COLUMN_STATUS, DownloadManager.STATUS_FAILED);
+ verifyInt(cursor, DownloadManager.COLUMN_ERROR_CODE,
+ DownloadManager.ERROR_INSUFFICIENT_SPACE);
+ } finally {
+ if (cursor != null) {
+ cursor.close();
+ }
+ largeFile.delete();
+ }
+ }
+}
diff --git a/core/tests/coretests/src/android/net/http/HttpsThroughHttpProxyTest.java b/core/tests/coretests/src/android/net/http/HttpsThroughHttpProxyTest.java
new file mode 100644
index 000000000000..95aad91a6f10
--- /dev/null
+++ b/core/tests/coretests/src/android/net/http/HttpsThroughHttpProxyTest.java
@@ -0,0 +1,142 @@
+/*
+ * Copyright (C) 2010 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.net.http;
+
+import java.io.IOException;
+import java.io.InputStreamReader;
+import java.io.Reader;
+import java.io.StringWriter;
+import java.util.Arrays;
+import java.util.List;
+import junit.framework.TestCase;
+import libcore.javax.net.ssl.TestSSLContext;
+import org.apache.http.HttpHost;
+import org.apache.http.HttpResponse;
+import org.apache.http.client.HttpClient;
+import org.apache.http.client.methods.HttpGet;
+import org.apache.http.conn.params.ConnRoutePNames;
+import org.apache.http.conn.scheme.Scheme;
+import org.apache.http.conn.ssl.AllowAllHostnameVerifier;
+import org.apache.http.conn.ssl.SSLSocketFactory;
+import org.apache.http.impl.client.DefaultHttpClient;
+import tests.http.MockResponse;
+import tests.http.MockWebServer;
+import tests.http.RecordedRequest;
+
+public class HttpsThroughHttpProxyTest extends TestCase {
+
+ public void testConnectViaHttps() throws IOException, InterruptedException {
+ TestSSLContext testSSLContext = TestSSLContext.create();
+
+ MockWebServer server = new MockWebServer();
+ server.useHttps(testSSLContext.serverContext.getSocketFactory(), false);
+ server.enqueue(new MockResponse()
+ .setResponseCode(200)
+ .setBody("this response comes via HTTPS"));
+ server.play();
+
+ HttpClient httpClient = new DefaultHttpClient();
+ SSLSocketFactory sslSocketFactory = new SSLSocketFactory(
+ testSSLContext.clientContext.getSocketFactory());
+ sslSocketFactory.setHostnameVerifier(new AllowAllHostnameVerifier());
+ httpClient.getConnectionManager().getSchemeRegistry()
+ .register(new Scheme("https", sslSocketFactory, server.getPort()));
+
+ HttpResponse response = httpClient.execute(
+ new HttpGet("https://localhost:" + server.getPort() + "/foo"));
+ assertEquals("this response comes via HTTPS", contentToString(response));
+
+ RecordedRequest request = server.takeRequest();
+ assertEquals("GET /foo HTTP/1.1", request.getRequestLine());
+ }
+
+ /**
+ * http://code.google.com/p/android/issues/detail?id=2690
+ */
+ public void testConnectViaProxy() throws IOException, InterruptedException {
+ MockWebServer proxy = new MockWebServer();
+ MockResponse mockResponse = new MockResponse()
+ .setResponseCode(200)
+ .setBody("this response comes via a proxy");
+ proxy.enqueue(mockResponse);
+ proxy.play();
+
+ HttpClient httpProxyClient = new DefaultHttpClient();
+ httpProxyClient.getParams().setParameter(
+ ConnRoutePNames.DEFAULT_PROXY, new HttpHost("localhost", proxy.getPort()));
+
+ HttpResponse response = httpProxyClient.execute(new HttpGet("http://android.com/foo"));
+ assertEquals("this response comes via a proxy", contentToString(response));
+
+ RecordedRequest request = proxy.takeRequest();
+ assertEquals("GET http://android.com/foo HTTP/1.1", request.getRequestLine());
+ assertContains(request.getHeaders(), "Host: android.com");
+ }
+
+ public void testConnectViaHttpProxyToHttps() throws IOException, InterruptedException {
+ TestSSLContext testSSLContext = TestSSLContext.create();
+
+ MockWebServer proxy = new MockWebServer();
+ proxy.useHttps(testSSLContext.serverContext.getSocketFactory(), true);
+ MockResponse connectResponse = new MockResponse()
+ .setResponseCode(200);
+ connectResponse.getHeaders().clear();
+ proxy.enqueue(connectResponse);
+ proxy.enqueue(new MockResponse()
+ .setResponseCode(200)
+ .setBody("this response comes via a secure proxy"));
+ proxy.play();
+
+ HttpClient httpProxyClient = new DefaultHttpClient();
+ HttpHost proxyHost = new HttpHost("localhost", proxy.getPort());
+ httpProxyClient.getParams().setParameter(
+ ConnRoutePNames.DEFAULT_PROXY, proxyHost);
+ SSLSocketFactory sslSocketFactory = new SSLSocketFactory(
+ testSSLContext.clientContext.getSocketFactory());
+ sslSocketFactory.setHostnameVerifier(new AllowAllHostnameVerifier());
+ httpProxyClient.getConnectionManager().getSchemeRegistry()
+ .register(new Scheme("https", sslSocketFactory, 443));
+
+ HttpResponse response = httpProxyClient.execute(new HttpGet("https://android.com/foo"));
+ assertEquals("this response comes via a secure proxy", contentToString(response));
+
+ RecordedRequest connect = proxy.takeRequest();
+ assertEquals("Connect line failure on proxy " + proxyHost.toHostString(),
+ "CONNECT android.com:443 HTTP/1.1", connect.getRequestLine());
+ assertContains(connect.getHeaders(), "Host: android.com");
+
+ RecordedRequest get = proxy.takeRequest();
+ assertEquals("GET /foo HTTP/1.1", get.getRequestLine());
+ assertContains(get.getHeaders(), "Host: android.com");
+ }
+
+ private void assertContains(List<String> headers, String header) {
+ assertTrue(headers.toString(), headers.contains(header));
+ }
+
+ private String contentToString(HttpResponse response) throws IOException {
+ StringWriter writer = new StringWriter();
+ char[] buffer = new char[1024];
+ Reader reader = new InputStreamReader(response.getEntity().getContent());
+ int length;
+ while ((length = reader.read(buffer)) != -1) {
+ writer.write(buffer, 0, length);
+ }
+ reader.close();
+ return writer.toString();
+ }
+}
diff --git a/core/tests/coretests/src/android/os/FileObserverTest.java b/core/tests/coretests/src/android/os/FileObserverTest.java
index ca4e0d657c46..93e27af44170 100644
--- a/core/tests/coretests/src/android/os/FileObserverTest.java
+++ b/core/tests/coretests/src/android/os/FileObserverTest.java
@@ -19,9 +19,8 @@ package android.os;
import com.google.android.collect.Lists;
import com.google.android.collect.Maps;
-import android.os.FileObserver;
import android.test.AndroidTestCase;
-import android.test.suitebuilder.annotation.LargeTest;
+import android.test.suitebuilder.annotation.MediumTest;
import android.util.Log;
import java.io.File;
@@ -69,7 +68,7 @@ public class FileObserverTest extends AndroidTestCase {
}
}
- @LargeTest
+ @MediumTest
public void testRun() throws Exception {
// make file changes and wait for them
assertTrue(mTestFile.exists());
diff --git a/core/tests/coretests/src/android/os/HierarchicalStateMachineTest.java b/core/tests/coretests/src/android/os/HierarchicalStateMachineTest.java
index 89b3fb61ddd2..68209876319a 100644
--- a/core/tests/coretests/src/android/os/HierarchicalStateMachineTest.java
+++ b/core/tests/coretests/src/android/os/HierarchicalStateMachineTest.java
@@ -16,23 +16,15 @@
package android.os;
-import junit.framework.TestCase;
+import com.android.internal.util.HierarchicalState;
+import com.android.internal.util.HierarchicalStateMachine;
+import com.android.internal.util.ProcessedMessages;
-import android.os.Debug;
-import android.os.HandlerThread;
-import android.os.Looper;
-import android.os.Message;
-import android.os.SystemClock;
+import android.test.suitebuilder.annotation.MediumTest;
import android.test.suitebuilder.annotation.SmallTest;
-
import android.util.Log;
-import com.android.internal.util.HierarchicalStateMachine;
-import com.android.internal.util.HierarchicalState;
-import com.android.internal.util.ProcessedMessages;
-
-import java.util.ArrayList;
-import java.util.Arrays;
+import junit.framework.TestCase;
/**
* Test for HierarchicalStateMachine.
@@ -74,15 +66,15 @@ public class HierarchicalStateMachineTest extends TestCase {
if (isQuit(message)) {
mQuitCount += 1;
if (mQuitCount > 2) {
- // Returning false to actually quit
- return false;
+ // Returning NOT_HANDLED to actually quit
+ return NOT_HANDLED;
} else {
// Do NOT quit
- return true;
+ return HANDLED;
}
} else {
// All other message are handled
- return true;
+ return HANDLED;
}
}
}
@@ -172,12 +164,18 @@ public class HierarchicalStateMachineTest extends TestCase {
class S1 extends HierarchicalState {
@Override protected void enter() {
+ // Test that message is HSM_INIT_CMD
+ assertEquals(HSM_INIT_CMD, getCurrentMessage().what);
+
// Test that a transition in enter and the initial state works
mS1EnterCount += 1;
transitionTo(mS2);
Log.d(TAG, "S1.enter");
}
@Override protected void exit() {
+ // Test that message is HSM_INIT_CMD
+ assertEquals(HSM_INIT_CMD, getCurrentMessage().what);
+
mS1ExitCount += 1;
Log.d(TAG, "S1.exit");
}
@@ -185,10 +183,16 @@ public class HierarchicalStateMachineTest extends TestCase {
class S2 extends HierarchicalState {
@Override protected void enter() {
+ // Test that message is HSM_INIT_CMD
+ assertEquals(HSM_INIT_CMD, getCurrentMessage().what);
+
mS2EnterCount += 1;
Log.d(TAG, "S2.enter");
}
@Override protected void exit() {
+ // Test that message is TEST_CMD_1
+ assertEquals(TEST_CMD_1, getCurrentMessage().what);
+
// Test transition in exit work
mS2ExitCount += 1;
transitionTo(mS4);
@@ -196,10 +200,10 @@ public class HierarchicalStateMachineTest extends TestCase {
}
@Override protected boolean processMessage(Message message) {
// Start a transition to S3 but it will be
- // changed to a transition to S4
+ // changed to a transition to S4 in exit
transitionTo(mS3);
Log.d(TAG, "S2.processMessage");
- return true;
+ return HANDLED;
}
}
@@ -264,7 +268,7 @@ public class HierarchicalStateMachineTest extends TestCase {
}
synchronized (smEnterExitTranstionToTest) {
- smEnterExitTranstionToTest.sendMessage(1);
+ smEnterExitTranstionToTest.sendMessage(TEST_CMD_1);
try {
// wait for the messages to be handled
@@ -321,7 +325,7 @@ public class HierarchicalStateMachineTest extends TestCase {
if (message.what == TEST_CMD_6) {
transitionToHaltingState();
}
- return true;
+ return HANDLED;
}
}
@@ -415,7 +419,7 @@ public class HierarchicalStateMachineTest extends TestCase {
assertEquals(1, mExitCount);
transitionToHaltingState();
}
- return true;
+ return HANDLED;
}
@Override protected void exit() {
@@ -437,7 +441,7 @@ public class HierarchicalStateMachineTest extends TestCase {
private int mExitCount;
}
- @SmallTest
+ @MediumTest
public void testStateMachine1() throws Exception {
StateMachine1 sm1 = new StateMachine1("sm1");
sm1.start();
@@ -510,7 +514,7 @@ public class HierarchicalStateMachineTest extends TestCase {
if (message.what == TEST_CMD_2) {
transitionTo(mS2);
}
- return true;
+ return HANDLED;
}
@Override protected void exit() {
@@ -523,7 +527,7 @@ public class HierarchicalStateMachineTest extends TestCase {
if (message.what == TEST_CMD_2) {
transitionToHaltingState();
}
- return true;
+ return HANDLED;
}
}
@@ -542,7 +546,7 @@ public class HierarchicalStateMachineTest extends TestCase {
private boolean mDidExit = false;
}
- @SmallTest
+ @MediumTest
public void testStateMachine2() throws Exception {
StateMachine2 sm2 = new StateMachine2("sm2");
sm2.start();
@@ -612,13 +616,13 @@ public class HierarchicalStateMachineTest extends TestCase {
if (message.what == TEST_CMD_2) {
transitionToHaltingState();
}
- return true;
+ return HANDLED;
}
}
class ChildState extends HierarchicalState {
@Override protected boolean processMessage(Message message) {
- return false;
+ return NOT_HANDLED;
}
}
@@ -634,7 +638,7 @@ public class HierarchicalStateMachineTest extends TestCase {
private ChildState mChildState = new ChildState();
}
- @SmallTest
+ @MediumTest
public void testStateMachine3() throws Exception {
StateMachine3 sm3 = new StateMachine3("sm3");
sm3.start();
@@ -697,20 +701,20 @@ public class HierarchicalStateMachineTest extends TestCase {
if (message.what == TEST_CMD_2) {
transitionToHaltingState();
}
- return true;
+ return HANDLED;
}
}
class ChildState1 extends HierarchicalState {
@Override protected boolean processMessage(Message message) {
transitionTo(mChildState2);
- return true;
+ return HANDLED;
}
}
class ChildState2 extends HierarchicalState {
@Override protected boolean processMessage(Message message) {
- return false;
+ return NOT_HANDLED;
}
}
@@ -727,7 +731,7 @@ public class HierarchicalStateMachineTest extends TestCase {
private ChildState2 mChildState2 = new ChildState2();
}
- @SmallTest
+ @MediumTest
public void testStateMachine4() throws Exception {
StateMachine4 sm4 = new StateMachine4("sm4");
sm4.start();
@@ -794,7 +798,7 @@ public class HierarchicalStateMachineTest extends TestCase {
mParentState1EnterCount += 1;
}
@Override protected boolean processMessage(Message message) {
- return true;
+ return HANDLED;
}
@Override protected void exit() {
mParentState1ExitCount += 1;
@@ -822,7 +826,7 @@ public class HierarchicalStateMachineTest extends TestCase {
assertEquals(0, mChildState5ExitCount);
transitionTo(mChildState2);
- return true;
+ return HANDLED;
}
@Override protected void exit() {
mChildState1ExitCount += 1;
@@ -850,7 +854,7 @@ public class HierarchicalStateMachineTest extends TestCase {
assertEquals(0, mChildState5ExitCount);
transitionTo(mChildState5);
- return true;
+ return HANDLED;
}
@Override protected void exit() {
mChildState2ExitCount += 1;
@@ -878,7 +882,7 @@ public class HierarchicalStateMachineTest extends TestCase {
assertEquals(1, mChildState5ExitCount);
transitionToHaltingState();
- return true;
+ return HANDLED;
}
@Override protected void exit() {
mParentState2ExitCount += 1;
@@ -906,7 +910,7 @@ public class HierarchicalStateMachineTest extends TestCase {
assertEquals(1, mChildState5ExitCount);
transitionTo(mChildState4);
- return true;
+ return HANDLED;
}
@Override protected void exit() {
mChildState3ExitCount += 1;
@@ -934,7 +938,7 @@ public class HierarchicalStateMachineTest extends TestCase {
assertEquals(1, mChildState5ExitCount);
transitionTo(mParentState2);
- return true;
+ return HANDLED;
}
@Override protected void exit() {
mChildState4ExitCount += 1;
@@ -962,7 +966,7 @@ public class HierarchicalStateMachineTest extends TestCase {
assertEquals(0, mChildState5ExitCount);
transitionTo(mChildState3);
- return true;
+ return HANDLED;
}
@Override protected void exit() {
mChildState5ExitCount += 1;
@@ -1001,7 +1005,7 @@ public class HierarchicalStateMachineTest extends TestCase {
private int mChildState5ExitCount = 0;
}
- @SmallTest
+ @MediumTest
public void testStateMachine5() throws Exception {
StateMachine5 sm5 = new StateMachine5("sm5");
sm5.start();
@@ -1108,7 +1112,7 @@ public class HierarchicalStateMachineTest extends TestCase {
mArrivalTimeMsg2 = SystemClock.elapsedRealtime();
transitionToHaltingState();
}
- return true;
+ return HANDLED;
}
@Override protected void exit() {
@@ -1129,7 +1133,7 @@ public class HierarchicalStateMachineTest extends TestCase {
private long mArrivalTimeMsg2;
}
- @SmallTest
+ @MediumTest
public void testStateMachine6() throws Exception {
long sentTimeMsg2;
final int DELAY_TIME = 250;
@@ -1190,7 +1194,7 @@ public class HierarchicalStateMachineTest extends TestCase {
class S1 extends HierarchicalState {
@Override protected boolean processMessage(Message message) {
transitionTo(mS2);
- return true;
+ return HANDLED;
}
@Override protected void exit() {
sendMessage(TEST_CMD_2);
@@ -1216,7 +1220,7 @@ public class HierarchicalStateMachineTest extends TestCase {
if (mMsgCount == 2) {
transitionToHaltingState();
}
- return true;
+ return HANDLED;
}
@Override protected void exit() {
@@ -1239,7 +1243,7 @@ public class HierarchicalStateMachineTest extends TestCase {
private long mArrivalTimeMsg3;
}
- @SmallTest
+ @MediumTest
public void testStateMachine7() throws Exception {
long sentTimeMsg2;
final int SM7_DELAY_FUDGE = 20;
@@ -1300,7 +1304,7 @@ public class HierarchicalStateMachineTest extends TestCase {
if (message.what == TEST_CMD_2) {
transitionToHaltingState();
}
- return false;
+ return NOT_HANDLED;
}
}
@@ -1369,7 +1373,7 @@ public class HierarchicalStateMachineTest extends TestCase {
if (message.what == TEST_CMD_4) {
transitionToHaltingState();
}
- return true;
+ return HANDLED;
}
}
@@ -1391,7 +1395,7 @@ public class HierarchicalStateMachineTest extends TestCase {
private static int sharedCounter = 0;
private static Object waitObject = new Object();
- @SmallTest
+ @MediumTest
public void testStateMachineSharedThread() throws Exception {
if (DBG) Log.d(TAG, "testStateMachineSharedThread E");
@@ -1436,7 +1440,7 @@ public class HierarchicalStateMachineTest extends TestCase {
if (DBG) Log.d(TAG, "testStateMachineSharedThread X");
}
- @SmallTest
+ @MediumTest
public void testHsm1() throws Exception {
if (DBG) Log.d(TAG, "testHsm1 E");
@@ -1563,10 +1567,10 @@ class Hsm1 extends HierarchicalStateMachine {
if (message.what == CMD_1) {
// Transition to ourself to show that enter/exit is called
transitionTo(mS1);
- return true;
+ return HANDLED;
} else {
// Let parent process all other messages
- return false;
+ return NOT_HANDLED;
}
}
@Override protected void exit() {
@@ -1618,7 +1622,7 @@ class Hsm1 extends HierarchicalStateMachine {
transitionToHaltingState();
break;
}
- return true;
+ return HANDLED;
}
@Override protected void exit() {
Log.d(TAG, "P2.exit");
diff --git a/core/tests/coretests/src/android/os/PerformanceCollectorTest.java b/core/tests/coretests/src/android/os/PerformanceCollectorTest.java
index a382239e7869..7533c84673de 100644
--- a/core/tests/coretests/src/android/os/PerformanceCollectorTest.java
+++ b/core/tests/coretests/src/android/os/PerformanceCollectorTest.java
@@ -16,11 +16,8 @@
package android.os;
-import android.os.Bundle;
-import android.os.Parcelable;
-import android.os.PerformanceCollector;
-import android.os.Process;
import android.os.PerformanceCollector.PerformanceResultsWriter;
+import android.test.suitebuilder.annotation.MediumTest;
import android.test.suitebuilder.annotation.SmallTest;
import java.lang.reflect.Field;
@@ -56,7 +53,7 @@ public class PerformanceCollectorTest extends TestCase {
assertEquals(2, snapshot.size());
}
- @SmallTest
+ @MediumTest
public void testEndSnapshotNoWriter() throws Exception {
mPerfCollector.beginSnapshot("testEndSnapshotNoWriter");
workForRandomLongPeriod();
@@ -116,7 +113,7 @@ public class PerformanceCollectorTest extends TestCase {
assertEquals(2, snapshot.size());
}
- @SmallTest
+ @MediumTest
public void testEndSnapshot() throws Exception {
MockPerformanceResultsWriter writer = new MockPerformanceResultsWriter();
mPerfCollector.setPerformanceResultsWriter(writer);
@@ -232,7 +229,7 @@ public class PerformanceCollectorTest extends TestCase {
assertEquals("Hello World", results.getString("testAddMeasurementStringNonEmpty"));
}
- @SmallTest
+ @MediumTest
public void testSimpleSequence() throws Exception {
MockPerformanceResultsWriter writer = new MockPerformanceResultsWriter();
mPerfCollector.setPerformanceResultsWriter(writer);
@@ -264,7 +261,7 @@ public class PerformanceCollectorTest extends TestCase {
verifyTimingBundle(timing, labels);
}
- @SmallTest
+ @MediumTest
public void testLongSequence() throws Exception {
MockPerformanceResultsWriter writer = new MockPerformanceResultsWriter();
mPerfCollector.setPerformanceResultsWriter(writer);
@@ -350,7 +347,7 @@ public class PerformanceCollectorTest extends TestCase {
* Verify that snapshotting and timing do not interfere w/ each other,
* by staggering calls to snapshot and timing functions.
*/
- @SmallTest
+ @MediumTest
public void testOutOfOrderSequence() {
MockPerformanceResultsWriter writer = new MockPerformanceResultsWriter();
mPerfCollector.setPerformanceResultsWriter(writer);
diff --git a/core/tests/coretests/src/android/os/PowerManagerTest.java b/core/tests/coretests/src/android/os/PowerManagerTest.java
index e089b3e0768e..9893c161fec8 100644
--- a/core/tests/coretests/src/android/os/PowerManagerTest.java
+++ b/core/tests/coretests/src/android/os/PowerManagerTest.java
@@ -17,9 +17,8 @@
package android.os;
import android.content.Context;
-import android.os.PowerManager;
import android.test.AndroidTestCase;
-import android.test.suitebuilder.annotation.MediumTest;
+import android.test.suitebuilder.annotation.SmallTest;
public class PowerManagerTest extends AndroidTestCase {
@@ -39,7 +38,7 @@ public class PowerManagerTest extends AndroidTestCase {
*
* @throws Exception
*/
- @MediumTest
+ @SmallTest
public void testPreconditions() throws Exception {
assertNotNull(mPm);
}
@@ -49,7 +48,7 @@ public class PowerManagerTest extends AndroidTestCase {
*
* @throws Exception
*/
- @MediumTest
+ @SmallTest
public void testNewWakeLock() throws Exception {
PowerManager.WakeLock wl = mPm.newWakeLock(PowerManager.FULL_WAKE_LOCK, "FULL_WAKE_LOCK");
doTestWakeLock(wl);
@@ -74,7 +73,7 @@ public class PowerManagerTest extends AndroidTestCase {
*
* @throws Exception
*/
- @MediumTest
+ @SmallTest
public void testBadNewWakeLock() throws Exception {
final int badFlags = PowerManager.SCREEN_BRIGHT_WAKE_LOCK
diff --git a/core/tests/coretests/src/android/os/storage/StorageListener.java b/core/tests/coretests/src/android/os/storage/StorageListener.java
index d6dae2227cda..6a26b88d5c44 100644
--- a/core/tests/coretests/src/android/os/storage/StorageListener.java
+++ b/core/tests/coretests/src/android/os/storage/StorageListener.java
@@ -21,21 +21,24 @@ import android.util.Log;
public class StorageListener extends StorageEventListener {
private static final boolean localLOGV = true;
- public static final String TAG="StorageListener";
+ public static final String TAG = "StorageListener";
- String oldState;
- String newState;
- String path;
+ private String mTargetState;
private boolean doneFlag = false;
+
+ public StorageListener(String targetState) {
+ mTargetState = targetState;
+ }
+
@Override
public void onStorageStateChanged(String path, String oldState, String newState) {
if (localLOGV) Log.i(TAG, "Storage state changed from " + oldState + " to " + newState);
+
synchronized (this) {
- this.oldState = oldState;
- this.newState = newState;
- this.path = path;
- doneFlag = true;
- notifyAll();
+ if (mTargetState.equals(newState)) {
+ doneFlag = true;
+ notifyAll();
+ }
}
}
diff --git a/core/tests/coretests/src/android/pim/vcard/ContentValuesVerifier.java b/core/tests/coretests/src/android/pim/vcard/ContentValuesVerifier.java
deleted file mode 100644
index b9e9875cd9a7..000000000000
--- a/core/tests/coretests/src/android/pim/vcard/ContentValuesVerifier.java
+++ /dev/null
@@ -1,101 +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.pim.vcard;
-
-import android.pim.vcard.VCardConfig;
-import android.pim.vcard.VCardEntry;
-import android.pim.vcard.VCardEntryConstructor;
-import android.pim.vcard.VCardEntryHandler;
-import android.pim.vcard.VCardParser;
-import android.pim.vcard.VCardParser_V21;
-import android.pim.vcard.VCardParser_V30;
-import android.pim.vcard.exception.VCardException;
-import android.test.AndroidTestCase;
-
-import java.io.IOException;
-import java.io.InputStream;
-import java.util.ArrayList;
-import java.util.List;
-
-/* package */ class ContentValuesVerifier implements VCardEntryHandler {
- private AndroidTestCase mTestCase;
- private List<ContentValuesVerifierElem> mContentValuesVerifierElemList =
- new ArrayList<ContentValuesVerifierElem>();
- private int mIndex;
-
- public ContentValuesVerifierElem addElem(AndroidTestCase androidTestCase) {
- mTestCase = androidTestCase;
- ContentValuesVerifierElem importVerifier = new ContentValuesVerifierElem(androidTestCase);
- mContentValuesVerifierElemList.add(importVerifier);
- return importVerifier;
- }
-
- public void verify(int resId, int vCardType) throws IOException, VCardException {
- verify(mTestCase.getContext().getResources().openRawResource(resId), vCardType);
- }
-
- public void verify(int resId, int vCardType, final VCardParser vCardParser)
- throws IOException, VCardException {
- verify(mTestCase.getContext().getResources().openRawResource(resId),
- vCardType, vCardParser);
- }
-
- public void verify(InputStream is, int vCardType) throws IOException, VCardException {
- final VCardParser vCardParser;
- if (VCardConfig.isV30(vCardType)) {
- vCardParser = new VCardParser_V30(true); // use StrictParsing
- } else {
- vCardParser = new VCardParser_V21();
- }
- verify(is, vCardType, vCardParser);
- }
-
- public void verify(InputStream is, int vCardType, final VCardParser vCardParser)
- throws IOException, VCardException {
- VCardEntryConstructor builder =
- new VCardEntryConstructor(null, null, false, vCardType, null);
- builder.addEntryHandler(this);
- try {
- vCardParser.parse(is, builder);
- } finally {
- if (is != null) {
- try {
- is.close();
- } catch (IOException e) {
- }
- }
- }
- }
-
- public void onStart() {
- for (ContentValuesVerifierElem elem : mContentValuesVerifierElemList) {
- elem.onParsingStart();
- }
- }
-
- public void onEntryCreated(VCardEntry entry) {
- mTestCase.assertTrue(mIndex < mContentValuesVerifierElemList.size());
- mContentValuesVerifierElemList.get(mIndex).onEntryCreated(entry);
- mIndex++;
- }
-
- public void onEnd() {
- for (ContentValuesVerifierElem elem : mContentValuesVerifierElemList) {
- elem.onParsingEnd();
- elem.verifyResolver();
- }
- }
-}
diff --git a/core/tests/coretests/src/android/pim/vcard/VCardExporterTests.java b/core/tests/coretests/src/android/pim/vcard/VCardExporterTests.java
index 004a197352d9..2bec46287fae 100644
--- a/core/tests/coretests/src/android/pim/vcard/VCardExporterTests.java
+++ b/core/tests/coretests/src/android/pim/vcard/VCardExporterTests.java
@@ -17,7 +17,10 @@
package android.pim.vcard;
import android.content.ContentValues;
-import android.pim.vcard.VCardConfig;
+import android.pim.vcard.test_utils.ContactEntry;
+import android.pim.vcard.test_utils.PropertyNodesVerifierElem;
+import android.pim.vcard.test_utils.PropertyNodesVerifierElem.TypeSet;
+import android.pim.vcard.test_utils.VCardTestsBase;
import android.provider.ContactsContract.CommonDataKinds.Email;
import android.provider.ContactsContract.CommonDataKinds.Event;
import android.provider.ContactsContract.CommonDataKinds.Im;
@@ -31,8 +34,6 @@ import android.provider.ContactsContract.CommonDataKinds.StructuredName;
import android.provider.ContactsContract.CommonDataKinds.StructuredPostal;
import android.provider.ContactsContract.CommonDataKinds.Website;
-import android.pim.vcard.PropertyNodesVerifierElem.TypeSet;
-
import java.util.Arrays;
/**
@@ -56,7 +57,6 @@ public class VCardExporterTests extends VCardTestsBase {
}
private void testStructuredNameBasic(int vcardType) {
- final boolean isV30 = VCardConfig.isV30(vcardType);
mVerifier.initForExportTest(vcardType);
mVerifier.addInputEntry().addContentValues(StructuredName.CONTENT_ITEM_TYPE)
.put(StructuredName.FAMILY_NAME, "AppropriateFamilyName")
@@ -64,28 +64,15 @@ public class VCardExporterTests extends VCardTestsBase {
.put(StructuredName.MIDDLE_NAME, "AppropriateMiddleName")
.put(StructuredName.PREFIX, "AppropriatePrefix")
.put(StructuredName.SUFFIX, "AppropriateSuffix")
- .put(StructuredName.PHONETIC_FAMILY_NAME, "AppropriatePhoneticFamily")
- .put(StructuredName.PHONETIC_GIVEN_NAME, "AppropriatePhoneticGiven")
- .put(StructuredName.PHONETIC_MIDDLE_NAME, "AppropriatePhoneticMiddle");
+ .put(StructuredName.DISPLAY_NAME, "DISPLAY NAME");
- PropertyNodesVerifierElem elem = mVerifier.addPropertyNodesVerifierElem()
+ mVerifier.addPropertyNodesVerifierElem()
.addExpectedNodeWithOrder("N",
"AppropriateFamilyName;AppropriateGivenName;AppropriateMiddleName;"
+ "AppropriatePrefix;AppropriateSuffix",
Arrays.asList("AppropriateFamilyName", "AppropriateGivenName",
"AppropriateMiddleName", "AppropriatePrefix", "AppropriateSuffix"))
- .addExpectedNodeWithOrder("FN",
- "AppropriatePrefix AppropriateGivenName "
- + "AppropriateMiddleName AppropriateFamilyName AppropriateSuffix")
- .addExpectedNode("X-PHONETIC-FIRST-NAME", "AppropriatePhoneticGiven")
- .addExpectedNode("X-PHONETIC-MIDDLE-NAME", "AppropriatePhoneticMiddle")
- .addExpectedNode("X-PHONETIC-LAST-NAME", "AppropriatePhoneticFamily");
-
- if (isV30) {
- elem.addExpectedNode("SORT-STRING",
- "AppropriatePhoneticGiven AppropriatePhoneticMiddle "
- + "AppropriatePhoneticFamily");
- }
+ .addExpectedNodeWithOrder("FN", "DISPLAY NAME");
}
public void testStructuredNameBasicV21() {
@@ -96,6 +83,10 @@ public class VCardExporterTests extends VCardTestsBase {
testStructuredNameBasic(V30);
}
+ public void testStructuredNameBasicV40() {
+ testStructuredNameBasic(V40);
+ }
+
/**
* Test that only "primary" StructuredName is emitted, so that our vCard file
* will not confuse the external importer, assuming there may be some importer
@@ -103,18 +94,15 @@ public class VCardExporterTests extends VCardTestsBase {
* Note that more than one "N", "FN", etc. properties are acceptable in vCard spec.
*/
private void testStructuredNameUsePrimaryCommon(int vcardType) {
- final boolean isV30 = (vcardType == V30);
mVerifier.initForExportTest(vcardType);
- ContactEntry entry = mVerifier.addInputEntry();
+ final ContactEntry entry = mVerifier.addInputEntry();
entry.addContentValues(StructuredName.CONTENT_ITEM_TYPE)
.put(StructuredName.FAMILY_NAME, "DoNotEmitFamilyName1")
.put(StructuredName.GIVEN_NAME, "DoNotEmitGivenName1")
.put(StructuredName.MIDDLE_NAME, "DoNotEmitMiddleName1")
.put(StructuredName.PREFIX, "DoNotEmitPrefix1")
.put(StructuredName.SUFFIX, "DoNotEmitSuffix1")
- .put(StructuredName.PHONETIC_FAMILY_NAME, "DoNotEmitPhoneticFamily1")
- .put(StructuredName.PHONETIC_GIVEN_NAME, "DoNotEmitPhoneticGiven1")
- .put(StructuredName.PHONETIC_MIDDLE_NAME, "DoNotEmitPhoneticMiddle1");
+ .put(StructuredName.DISPLAY_NAME, "DoNotEmitDisplayName1");
// With "IS_PRIMARY=1". This is what we should use.
entry.addContentValues(StructuredName.CONTENT_ITEM_TYPE)
@@ -123,41 +111,30 @@ public class VCardExporterTests extends VCardTestsBase {
.put(StructuredName.MIDDLE_NAME, "AppropriateMiddleName")
.put(StructuredName.PREFIX, "AppropriatePrefix")
.put(StructuredName.SUFFIX, "AppropriateSuffix")
- .put(StructuredName.PHONETIC_FAMILY_NAME, "AppropriatePhoneticFamily")
- .put(StructuredName.PHONETIC_GIVEN_NAME, "AppropriatePhoneticGiven")
- .put(StructuredName.PHONETIC_MIDDLE_NAME, "AppropriatePhoneticMiddle")
+ .put(StructuredName.DISPLAY_NAME, "AppropriateDisplayName")
.put(StructuredName.IS_PRIMARY, 1);
// With "IS_PRIMARY=1", but we should ignore this time, since this is second, not first.
+ // vCard 2.1 does not specify anything about the number of N properties. We choose not
+ // emitting this property.
+ // vCard 3.0 does (There must be one N property)
+ // vCard 4.0 (rev13) does (cardinality (0, 1)).
entry.addContentValues(StructuredName.CONTENT_ITEM_TYPE)
.put(StructuredName.FAMILY_NAME, "DoNotEmitFamilyName2")
.put(StructuredName.GIVEN_NAME, "DoNotEmitGivenName2")
.put(StructuredName.MIDDLE_NAME, "DoNotEmitMiddleName2")
.put(StructuredName.PREFIX, "DoNotEmitPrefix2")
.put(StructuredName.SUFFIX, "DoNotEmitSuffix2")
- .put(StructuredName.PHONETIC_FAMILY_NAME, "DoNotEmitPhoneticFamily2")
- .put(StructuredName.PHONETIC_GIVEN_NAME, "DoNotEmitPhoneticGiven2")
- .put(StructuredName.PHONETIC_MIDDLE_NAME, "DoNotEmitPhoneticMiddle2")
+ .put(StructuredName.DISPLAY_NAME, "DoNotEmitDisplayName2")
.put(StructuredName.IS_PRIMARY, 1);
- PropertyNodesVerifierElem elem = mVerifier.addPropertyNodesVerifierElem()
+ mVerifier.addPropertyNodesVerifierElem()
.addExpectedNodeWithOrder("N",
"AppropriateFamilyName;AppropriateGivenName;AppropriateMiddleName;"
+ "AppropriatePrefix;AppropriateSuffix",
Arrays.asList("AppropriateFamilyName", "AppropriateGivenName",
"AppropriateMiddleName", "AppropriatePrefix", "AppropriateSuffix"))
- .addExpectedNodeWithOrder("FN",
- "AppropriatePrefix AppropriateGivenName "
- + "AppropriateMiddleName AppropriateFamilyName AppropriateSuffix")
- .addExpectedNode("X-PHONETIC-FIRST-NAME", "AppropriatePhoneticGiven")
- .addExpectedNode("X-PHONETIC-MIDDLE-NAME", "AppropriatePhoneticMiddle")
- .addExpectedNode("X-PHONETIC-LAST-NAME", "AppropriatePhoneticFamily");
-
- if (isV30) {
- elem.addExpectedNode("SORT-STRING",
- "AppropriatePhoneticGiven AppropriatePhoneticMiddle "
- + "AppropriatePhoneticFamily");
- }
+ .addExpectedNodeWithOrder("FN", "AppropriateDisplayName");
}
public void testStructuredNameUsePrimaryV21() {
@@ -168,14 +145,152 @@ public class VCardExporterTests extends VCardTestsBase {
testStructuredNameUsePrimaryCommon(V30);
}
+ public void testStructuredNameUsePrimaryV40() {
+ testStructuredNameUsePrimaryCommon(V40);
+ }
+
/**
* Tests that only "super primary" StructuredName is emitted.
* See also the comment in {@link #testStructuredNameUsePrimaryCommon(int)}.
*/
private void testStructuredNameUseSuperPrimaryCommon(int vcardType) {
- final boolean isV30 = (vcardType == V30);
mVerifier.initForExportTest(vcardType);
- ContactEntry entry = mVerifier.addInputEntry();
+ final ContactEntry entry = mVerifier.addInputEntry();
+ entry.addContentValues(StructuredName.CONTENT_ITEM_TYPE)
+ .put(StructuredName.FAMILY_NAME, "DoNotEmitFamilyName1")
+ .put(StructuredName.GIVEN_NAME, "DoNotEmitGivenName1")
+ .put(StructuredName.MIDDLE_NAME, "DoNotEmitMiddleName1")
+ .put(StructuredName.PREFIX, "DoNotEmitPrefix1")
+ .put(StructuredName.SUFFIX, "DoNotEmitSuffix1")
+ .put(StructuredName.DISPLAY_NAME, "DoNotEmitDisplay1");
+
+ // With "IS_PRIMARY=1", but we should ignore this time.
+ entry.addContentValues(StructuredName.CONTENT_ITEM_TYPE)
+ .put(StructuredName.FAMILY_NAME, "DoNotEmitFamilyName2")
+ .put(StructuredName.GIVEN_NAME, "DoNotEmitGivenName2")
+ .put(StructuredName.MIDDLE_NAME, "DoNotEmitMiddleName2")
+ .put(StructuredName.PREFIX, "DoNotEmitPrefix2")
+ .put(StructuredName.SUFFIX, "DoNotEmitSuffix2")
+ .put(StructuredName.DISPLAY_NAME, "DoNotEmitDisplay2")
+ .put(StructuredName.IS_PRIMARY, 1);
+
+ // With "IS_SUPER_PRIMARY=1". This is what we should use.
+ entry.addContentValues(StructuredName.CONTENT_ITEM_TYPE)
+ .put(StructuredName.FAMILY_NAME, "AppropriateFamilyName")
+ .put(StructuredName.GIVEN_NAME, "AppropriateGivenName")
+ .put(StructuredName.MIDDLE_NAME, "AppropriateMiddleName")
+ .put(StructuredName.PREFIX, "AppropriatePrefix")
+ .put(StructuredName.SUFFIX, "AppropriateSuffix")
+ .put(StructuredName.DISPLAY_NAME, "AppropriateDisplayName")
+ .put(StructuredName.IS_SUPER_PRIMARY, 1);
+
+ entry.addContentValues(StructuredName.CONTENT_ITEM_TYPE)
+ .put(StructuredName.FAMILY_NAME, "DoNotEmitFamilyName3")
+ .put(StructuredName.GIVEN_NAME, "DoNotEmitGivenName3")
+ .put(StructuredName.MIDDLE_NAME, "DoNotEmitMiddleName3")
+ .put(StructuredName.PREFIX, "DoNotEmitPrefix3")
+ .put(StructuredName.SUFFIX, "DoNotEmitSuffix3")
+ .put(StructuredName.DISPLAY_NAME, "DoNotEmitDisplay3")
+ .put(StructuredName.IS_PRIMARY, 1);
+
+ final PropertyNodesVerifierElem elem = mVerifier.addPropertyNodesVerifierElem();
+ elem.addExpectedNodeWithOrder("N",
+ "AppropriateFamilyName;AppropriateGivenName;AppropriateMiddleName;"
+ + "AppropriatePrefix;AppropriateSuffix",
+ Arrays.asList("AppropriateFamilyName", "AppropriateGivenName",
+ "AppropriateMiddleName", "AppropriatePrefix", "AppropriateSuffix"));
+
+ elem.addExpectedNodeWithOrder("FN", "AppropriateDisplayName");
+ }
+
+ public void testStructuredNameUseSuperPrimaryV21() {
+ testStructuredNameUseSuperPrimaryCommon(V21);
+ }
+
+ public void testStructuredNameUseSuperPrimaryV30() {
+ testStructuredNameUseSuperPrimaryCommon(V30);
+ }
+
+ public void testStructuredNameUseSuperPrimaryV40() {
+ testStructuredNameUseSuperPrimaryCommon(V40);
+ }
+
+ /**
+ * Tests phonetic names field are handled correctly.
+ *
+ * vCard 2.1 does not have any field corresponding to them.
+ * vCard 3.0 has SORT-STRING property, which does not support multiple values inside it.
+ * vCard 4.0 (rev13) has SORT-AS parameter, which has three values (family, given, middle)
+ * inside it.
+ */
+ private void testStructuredNamePhoneticNameCommon(int vcardType) {
+ mVerifier.initForExportTest(vcardType);
+ final ContactEntry entry = mVerifier.addInputEntry();
+ entry.addContentValues(StructuredName.CONTENT_ITEM_TYPE)
+ .put(StructuredName.FAMILY_NAME, "AppropriateFamilyName")
+ .put(StructuredName.GIVEN_NAME, "AppropriateGivenName")
+ .put(StructuredName.MIDDLE_NAME, "AppropriateMiddleName")
+ .put(StructuredName.PREFIX, "AppropriatePrefix")
+ .put(StructuredName.SUFFIX, "AppropriateSuffix")
+ .put(StructuredName.DISPLAY_NAME, "AppropriateDisplayName")
+ .put(StructuredName.PHONETIC_FAMILY_NAME, "AppropriatePhoneticFamily")
+ .put(StructuredName.PHONETIC_GIVEN_NAME, "AppropriatePhoneticGiven")
+ .put(StructuredName.PHONETIC_MIDDLE_NAME, "AppropriatePhoneticMiddle");
+
+ final PropertyNodesVerifierElem elem = mVerifier.addPropertyNodesVerifierElem();
+ if (VCardConfig.isVersion40(vcardType)) {
+ final ContentValues contentValues = new ContentValues();
+ contentValues.put("SORT-AS",
+ "AppropriateFamilyName;AppropriateGivenName;AppropriateMiddleName");
+ // vCard 4.0 (rev13) now uses SORT-AS parameter, which is not compatible with
+ // either 2.1 nor 3.0.
+ elem.addExpectedNodeWithOrder("N",
+ "AppropriateFamilyName;AppropriateGivenName;AppropriateMiddleName;"
+ + "AppropriatePrefix;AppropriateSuffix",
+ Arrays.asList("AppropriateFamilyName", "AppropriateGivenName",
+ "AppropriateMiddleName", "AppropriatePrefix", "AppropriateSuffix"),
+ contentValues);
+ } else {
+ elem.addExpectedNodeWithOrder("N",
+ "AppropriateFamilyName;AppropriateGivenName;AppropriateMiddleName;"
+ + "AppropriatePrefix;AppropriateSuffix",
+ Arrays.asList("AppropriateFamilyName", "AppropriateGivenName",
+ "AppropriateMiddleName", "AppropriatePrefix", "AppropriateSuffix"));
+ if (VCardConfig.isVersion30(vcardType)) {
+ elem.addExpectedNode("SORT-STRING",
+ "AppropriatePhoneticGiven AppropriatePhoneticMiddle"
+ + " AppropriatePhoneticFamily");
+ }
+ }
+
+ elem.addExpectedNodeWithOrder("FN", "AppropriateDisplayName")
+ .addExpectedNode("X-PHONETIC-FIRST-NAME", "AppropriatePhoneticGiven")
+ .addExpectedNode("X-PHONETIC-MIDDLE-NAME", "AppropriatePhoneticMiddle")
+ .addExpectedNode("X-PHONETIC-LAST-NAME", "AppropriatePhoneticFamily");
+ }
+
+ public void testStructuredNamePhoneticNameV21() {
+ testStructuredNamePhoneticNameCommon(V21);
+ }
+
+ public void testStructuredNamePhoneticNameV30() {
+ testStructuredNamePhoneticNameCommon(V30);
+ }
+
+ public void testStructuredNamePhoneticNameV40() {
+ testStructuredNamePhoneticNameCommon(V40);
+ }
+
+ // TODO: need to add test cases confirming escaping, empty values, etc.
+
+ /**
+ * Confirms all the other sides of the handling is correctly interpreted at one time.
+ *
+ * A kind of regression test for StructuredName handling.
+ */
+ private void testStructuredNameComplicatedCommon(int vcardType) {
+ mVerifier.initForExportTest(vcardType);
+ final ContactEntry entry = mVerifier.addInputEntry();
entry.addContentValues(StructuredName.CONTENT_ITEM_TYPE)
.put(StructuredName.FAMILY_NAME, "DoNotEmitFamilyName1")
.put(StructuredName.GIVEN_NAME, "DoNotEmitGivenName1")
@@ -221,32 +336,50 @@ public class VCardExporterTests extends VCardTestsBase {
.put(StructuredName.PHONETIC_MIDDLE_NAME, "DoNotEmitPhoneticMiddle3")
.put(StructuredName.IS_PRIMARY, 1);
- PropertyNodesVerifierElem elem = mVerifier.addPropertyNodesVerifierElem()
- .addExpectedNodeWithOrder("N",
- "AppropriateFamilyName;AppropriateGivenName;AppropriateMiddleName;"
- + "AppropriatePrefix;AppropriateSuffix",
- Arrays.asList("AppropriateFamilyName", "AppropriateGivenName",
- "AppropriateMiddleName", "AppropriatePrefix", "AppropriateSuffix"))
- .addExpectedNodeWithOrder("FN",
- "AppropriatePrefix AppropriateGivenName "
- + "AppropriateMiddleName AppropriateFamilyName AppropriateSuffix")
- .addExpectedNode("X-PHONETIC-FIRST-NAME", "AppropriatePhoneticGiven")
- .addExpectedNode("X-PHONETIC-MIDDLE-NAME", "AppropriatePhoneticMiddle")
- .addExpectedNode("X-PHONETIC-LAST-NAME", "AppropriatePhoneticFamily");
-
- if (isV30) {
- elem.addExpectedNode("SORT-STRING",
- "AppropriatePhoneticGiven AppropriatePhoneticMiddle"
- + " AppropriatePhoneticFamily");
+ final PropertyNodesVerifierElem elem = mVerifier.addPropertyNodesVerifierElem();
+ if (VCardConfig.isVersion40(vcardType)) {
+ final ContentValues contentValues = new ContentValues();
+ contentValues.put("SORT-AS",
+ "AppropriateFamilyName;AppropriateGivenName;AppropriateMiddleName");
+ // vCard 4.0 (rev13) now uses SORT-AS parameter, which is not compatible with
+ // either 2.1 nor 3.0.
+ elem.addExpectedNodeWithOrder("N",
+ "AppropriateFamilyName;AppropriateGivenName;AppropriateMiddleName;"
+ + "AppropriatePrefix;AppropriateSuffix",
+ Arrays.asList("AppropriateFamilyName", "AppropriateGivenName",
+ "AppropriateMiddleName", "AppropriatePrefix", "AppropriateSuffix"),
+ contentValues);
+ } else {
+ elem.addExpectedNodeWithOrder("N",
+ "AppropriateFamilyName;AppropriateGivenName;AppropriateMiddleName;"
+ + "AppropriatePrefix;AppropriateSuffix",
+ Arrays.asList("AppropriateFamilyName", "AppropriateGivenName",
+ "AppropriateMiddleName", "AppropriatePrefix", "AppropriateSuffix"));
+ if (VCardConfig.isVersion30(vcardType)) {
+ elem.addExpectedNode("SORT-STRING",
+ "AppropriatePhoneticGiven AppropriatePhoneticMiddle"
+ + " AppropriatePhoneticFamily");
+ }
}
+
+ elem.addExpectedNodeWithOrder("FN",
+ "AppropriatePrefix AppropriateGivenName "
+ + "AppropriateMiddleName AppropriateFamilyName AppropriateSuffix")
+ .addExpectedNode("X-PHONETIC-FIRST-NAME", "AppropriatePhoneticGiven")
+ .addExpectedNode("X-PHONETIC-MIDDLE-NAME", "AppropriatePhoneticMiddle")
+ .addExpectedNode("X-PHONETIC-LAST-NAME", "AppropriatePhoneticFamily");
}
- public void testStructuredNameUseSuperPrimaryV21() {
- testStructuredNameUseSuperPrimaryCommon(V21);
+ public void testStructuredNameComplicatedV21() {
+ testStructuredNameComplicatedCommon(V21);
}
- public void testStructuredNameUseSuperPrimaryV30() {
- testStructuredNameUseSuperPrimaryCommon(V30);
+ public void testStructuredNameComplicatedV30() {
+ testStructuredNameComplicatedCommon(V30);
+ }
+
+ public void testStructuredNameComplicatedV40() {
+ testStructuredNameComplicatedCommon(V40);
}
public void testNickNameV30() {
@@ -258,6 +391,15 @@ public class VCardExporterTests extends VCardTestsBase {
.addExpectedNodeWithOrder("NICKNAME", "Nicky");
}
+ public void testNickNameV40() {
+ mVerifier.initForExportTest(V40);
+ mVerifier.addInputEntry().addContentValues(Nickname.CONTENT_ITEM_TYPE)
+ .put(Nickname.NAME, "Nicky");
+
+ mVerifier.addPropertyNodesVerifierElemWithEmptyName()
+ .addExpectedNodeWithOrder("NICKNAME", "Nicky");
+ }
+
private void testPhoneBasicCommon(int vcardType) {
mVerifier.initForExportTest(vcardType);
mVerifier.addInputEntry().addContentValues(Phone.CONTENT_ITEM_TYPE)
@@ -275,6 +417,20 @@ public class VCardExporterTests extends VCardTestsBase {
testPhoneBasicCommon(V30);
}
+ public void testPhoneBasicV40() {
+ testPhoneBasicCommon(V40);
+ }
+
+ public void testPhoneRefrainFormatting() {
+ mVerifier.initForExportTest(V21 | VCardConfig.FLAG_REFRAIN_PHONE_NUMBER_FORMATTING);
+ mVerifier.addInputEntry().addContentValues(Phone.CONTENT_ITEM_TYPE)
+ .put(Phone.NUMBER, "1234567890(abcdefghijklmnopqrstuvwxyz)")
+ .put(Phone.TYPE, Phone.TYPE_HOME);
+ mVerifier.addPropertyNodesVerifierElemWithEmptyName()
+ .addExpectedNode("TEL", "1234567890(abcdefghijklmnopqrstuvwxyz)",
+ new TypeSet("HOME"));
+ }
+
/**
* Tests that vCard composer emits corresponding type param which we expect.
*/
@@ -357,6 +513,10 @@ public class VCardExporterTests extends VCardTestsBase {
testPhoneVariousTypeSupport(V30);
}
+ public void testPhoneVariousTypeSupportV40() {
+ testPhoneVariousTypeSupport(V40);
+ }
+
/**
* Tests that "PREF"s are emitted appropriately.
*/
@@ -393,6 +553,10 @@ public class VCardExporterTests extends VCardTestsBase {
testPhonePrefHandlingCommon(V30);
}
+ public void testPhonePrefHandlingV40() {
+ testPhonePrefHandlingCommon(V40);
+ }
+
private void testMiscPhoneTypeHandling(int vcardType) {
mVerifier.initForExportTest(vcardType);
ContactEntry entry = mVerifier.addInputEntry();
@@ -428,14 +592,26 @@ public class VCardExporterTests extends VCardTestsBase {
.put(Phone.TYPE, Phone.TYPE_CUSTOM)
.put(Phone.LABEL, "invalid");
PropertyNodesVerifierElem elem = mVerifier.addPropertyNodesVerifierElemWithEmptyName();
- elem.addExpectedNode("TEL", "1", new TypeSet("MODEM"))
- .addExpectedNode("TEL", "2", new TypeSet("MSG"))
- .addExpectedNode("TEL", "3", new TypeSet("BBS"))
- .addExpectedNode("TEL", "4", new TypeSet("VIDEO"))
- .addExpectedNode("TEL", "5", new TypeSet("VOICE"))
- .addExpectedNode("TEL", "6", new TypeSet("CELL"))
- .addExpectedNode("TEL", "7", new TypeSet("CELL"))
- .addExpectedNode("TEL", "8", new TypeSet("X-invalid"));
+ if (VCardConfig.isVersion30(vcardType) || VCardConfig.isVersion40(vcardType)) {
+ // vCard 3.0 accepts "invalid". Also stop using toUpper()
+ elem.addExpectedNode("TEL", "1", new TypeSet("Modem"))
+ .addExpectedNode("TEL", "2", new TypeSet("MSG"))
+ .addExpectedNode("TEL", "3", new TypeSet("BBS"))
+ .addExpectedNode("TEL", "4", new TypeSet("VIDEO"))
+ .addExpectedNode("TEL", "5", new TypeSet("VOICE"))
+ .addExpectedNode("TEL", "6", new TypeSet("CELL"))
+ .addExpectedNode("TEL", "7", new TypeSet("CELL"))
+ .addExpectedNode("TEL", "8", new TypeSet("invalid"));
+ } else {
+ elem.addExpectedNode("TEL", "1", new TypeSet("MODEM"))
+ .addExpectedNode("TEL", "2", new TypeSet("MSG"))
+ .addExpectedNode("TEL", "3", new TypeSet("BBS"))
+ .addExpectedNode("TEL", "4", new TypeSet("VIDEO"))
+ .addExpectedNode("TEL", "5", new TypeSet("VOICE"))
+ .addExpectedNode("TEL", "6", new TypeSet("CELL"))
+ .addExpectedNode("TEL", "7", new TypeSet("CELL"))
+ .addExpectedNode("TEL", "8", new TypeSet("X-invalid"));
+ }
}
public void testPhoneTypeHandlingV21() {
@@ -446,6 +622,10 @@ public class VCardExporterTests extends VCardTestsBase {
testMiscPhoneTypeHandling(V30);
}
+ public void testPhoneTypeHandlingV40() {
+ testMiscPhoneTypeHandling(V40);
+ }
+
private void testEmailBasicCommon(int vcardType) {
mVerifier.initForExportTest(vcardType);
mVerifier.addInputEntry().addContentValues(Email.CONTENT_ITEM_TYPE)
@@ -462,6 +642,10 @@ public class VCardExporterTests extends VCardTestsBase {
testEmailBasicCommon(V30);
}
+ public void testEmailBasicV40() {
+ testEmailBasicCommon(V40);
+ }
+
private void testEmailVariousTypeSupportCommon(int vcardType) {
mVerifier.initForExportTest(vcardType);
ContactEntry entry = mVerifier.addInputEntry();
@@ -492,6 +676,10 @@ public class VCardExporterTests extends VCardTestsBase {
testEmailVariousTypeSupportCommon(V30);
}
+ public void testEmailVariousTypeSupportV40() {
+ testEmailVariousTypeSupportCommon(V40);
+ }
+
private void testEmailPrefHandlingCommon(int vcardType) {
mVerifier.initForExportTest(vcardType);
ContactEntry entry = mVerifier.addInputEntry();
@@ -516,6 +704,10 @@ public class VCardExporterTests extends VCardTestsBase {
testEmailPrefHandlingCommon(V30);
}
+ public void testEmailPrefHandlingV40() {
+ testEmailPrefHandlingCommon(V40);
+ }
+
private void testPostalAddressCommon(int vcardType) {
mVerifier.initForExportTest(vcardType);
mVerifier.addInputEntry().addContentValues(StructuredPostal.CONTENT_ITEM_TYPE)
@@ -547,6 +739,10 @@ public class VCardExporterTests extends VCardTestsBase {
testPostalAddressCommon(V30);
}
+ public void testPostalAddressV40() {
+ testPostalAddressCommon(V40);
+ }
+
private void testPostalAddressNonNeighborhood(int vcardType) {
mVerifier.initForExportTest(vcardType);
mVerifier.addInputEntry().addContentValues(StructuredPostal.CONTENT_ITEM_TYPE)
@@ -564,6 +760,10 @@ public class VCardExporterTests extends VCardTestsBase {
testPostalAddressNonNeighborhood(V30);
}
+ public void testPostalAddressNonNeighborhoodV40() {
+ testPostalAddressNonNeighborhood(V40);
+ }
+
private void testPostalAddressNonCity(int vcardType) {
mVerifier.initForExportTest(vcardType);
mVerifier.addInputEntry().addContentValues(StructuredPostal.CONTENT_ITEM_TYPE)
@@ -581,6 +781,10 @@ public class VCardExporterTests extends VCardTestsBase {
testPostalAddressNonCity(V30);
}
+ public void testPostalAddressNonCityV40() {
+ testPostalAddressNonCity(V40);
+ }
+
private void testPostalOnlyWithFormattedAddressCommon(int vcardType) {
mVerifier.initForExportTest(vcardType);
mVerifier.addInputEntry().addContentValues(StructuredPostal.CONTENT_ITEM_TYPE)
@@ -601,6 +805,10 @@ public class VCardExporterTests extends VCardTestsBase {
testPostalOnlyWithFormattedAddressCommon(V30);
}
+ public void testPostalOnlyWithFormattedAddressV40() {
+ testPostalOnlyWithFormattedAddressCommon(V40);
+ }
+
/**
* Tests that the vCard composer honors formatted data when it is available
* even when it is partial.
@@ -626,6 +834,10 @@ public class VCardExporterTests extends VCardTestsBase {
testPostalWithBothStructuredAndFormattedCommon(V30);
}
+ public void testPostalWithBothStructuredAndFormattedV40() {
+ testPostalWithBothStructuredAndFormattedCommon(V40);
+ }
+
private void testOrganizationCommon(int vcardType) {
mVerifier.initForExportTest(vcardType);
ContactEntry entry = mVerifier.addInputEntry();
@@ -663,6 +875,10 @@ public class VCardExporterTests extends VCardTestsBase {
testOrganizationCommon(V30);
}
+ public void testOrganizationV40() {
+ testOrganizationCommon(V40);
+ }
+
private void testImVariousTypeSupportCommon(int vcardType) {
mVerifier.initForExportTest(vcardType);
ContactEntry entry = mVerifier.addInputEntry();
@@ -715,6 +931,10 @@ public class VCardExporterTests extends VCardTestsBase {
testImVariousTypeSupportCommon(V30);
}
+ public void testImBasicV40() {
+ testImVariousTypeSupportCommon(V40);
+ }
+
private void testImPrefHandlingCommon(int vcardType) {
mVerifier.initForExportTest(vcardType);
ContactEntry entry = mVerifier.addInputEntry();
@@ -740,6 +960,10 @@ public class VCardExporterTests extends VCardTestsBase {
testImPrefHandlingCommon(V30);
}
+ public void testImPrefHandlingV40() {
+ testImPrefHandlingCommon(V40);
+ }
+
private void testWebsiteCommon(int vcardType) {
mVerifier.initForExportTest(vcardType);
ContactEntry entry = mVerifier.addInputEntry();
@@ -764,6 +988,10 @@ public class VCardExporterTests extends VCardTestsBase {
testWebsiteCommon(V30);
}
+ public void testWebsiteV40() {
+ testWebsiteCommon(V40);
+ }
+
private String getAndroidPropValue(final String mimeType, String value, Integer type) {
return getAndroidPropValue(mimeType, value, type, null);
}
@@ -817,6 +1045,10 @@ public class VCardExporterTests extends VCardTestsBase {
testEventCommon(V30);
}
+ public void testEventV40() {
+ testEventCommon(V40);
+ }
+
private void testNoteCommon(int vcardType) {
mVerifier.initForExportTest(vcardType);
ContactEntry entry = mVerifier.addInputEntry();
@@ -838,8 +1070,13 @@ public class VCardExporterTests extends VCardTestsBase {
testNoteCommon(V30);
}
+ public void testNoteV40() {
+ testNoteCommon(V40);
+ }
+
private void testPhotoCommon(int vcardType) {
- final boolean isV30 = vcardType == V30;
+ final boolean useB =
+ (VCardConfig.isVersion30(vcardType) || VCardConfig.isVersion40(vcardType));
mVerifier.initForExportTest(vcardType);
ContactEntry entry = mVerifier.addInputEntry();
entry.addContentValues(StructuredName.CONTENT_ITEM_TYPE)
@@ -848,7 +1085,7 @@ public class VCardExporterTests extends VCardTestsBase {
.put(Photo.PHOTO, sPhotoByteArray);
ContentValues contentValuesForPhoto = new ContentValues();
- contentValuesForPhoto.put("ENCODING", (isV30 ? "b" : "BASE64"));
+ contentValuesForPhoto.put("ENCODING", (useB ? "b" : "BASE64"));
mVerifier.addPropertyNodesVerifierElem()
.addExpectedNode("FN", "PhotoTest")
.addExpectedNode("N", "PhotoTest;;;;",
@@ -865,6 +1102,10 @@ public class VCardExporterTests extends VCardTestsBase {
testPhotoCommon(V30);
}
+ public void testPhotoV40() {
+ testPhotoCommon(V40);
+ }
+
private void testRelationCommon(int vcardType) {
mVerifier.initForExportTest(vcardType);
mVerifier.addInputEntry().addContentValues(Relation.CONTENT_ITEM_TYPE)
@@ -935,18 +1176,22 @@ public class VCardExporterTests extends VCardTestsBase {
entry.addContentValues(StructuredName.CONTENT_ITEM_TYPE)
.put(StructuredName.IS_PRIMARY, 1); // Empty name. Should be ignored.
entry.addContentValues(StructuredName.CONTENT_ITEM_TYPE)
- .put(StructuredName.FAMILY_NAME, "family1"); // Not primary. Should be ignored.
+ .put(StructuredName.FAMILY_NAME, "family1") // Not primary. Should be ignored.
+ .put(StructuredName.DISPLAY_NAME, "display");
entry.addContentValues(StructuredName.CONTENT_ITEM_TYPE)
.put(StructuredName.IS_PRIMARY, 1)
- .put(StructuredName.FAMILY_NAME, "family2"); // This entry is what we want.
+ .put(StructuredName.FAMILY_NAME, "family2") // This entry is what we want.
+ .put(StructuredName.DISPLAY_NAME, "display");
entry.addContentValues(StructuredName.CONTENT_ITEM_TYPE)
.put(StructuredName.IS_PRIMARY, 1)
- .put(StructuredName.FAMILY_NAME, "family3");
+ .put(StructuredName.FAMILY_NAME, "family3")
+ .put(StructuredName.DISPLAY_NAME, "display");
entry.addContentValues(StructuredName.CONTENT_ITEM_TYPE)
- .put(StructuredName.FAMILY_NAME, "family4");
+ .put(StructuredName.FAMILY_NAME, "family4")
+ .put(StructuredName.DISPLAY_NAME, "display");
mVerifier.addPropertyNodesVerifierElem()
.addExpectedNode("N", Arrays.asList("family2", "", "", "", ""))
- .addExpectedNode("FN", "family2");
+ .addExpectedNode("FN", "display");
}
public void testPickUpNonEmptyContentValuesV21() {
@@ -956,4 +1201,23 @@ public class VCardExporterTests extends VCardTestsBase {
public void testPickUpNonEmptyContentValuesV30() {
testPickUpNonEmptyContentValuesCommon(V30);
}
+
+ public void testPickUpNonEmptyContentValuesV40() {
+ testPickUpNonEmptyContentValuesCommon(V40);
+ }
+
+ public void testUseMultiByteTypeV30() {
+ mVerifier.initForExportTest(V30);
+ final ContactEntry entry = mVerifier.addInputEntry();
+ entry.addContentValues(Phone.CONTENT_ITEM_TYPE)
+ .put(Phone.TYPE, Phone.TYPE_CUSTOM)
+ .put(Phone.LABEL, "\u96FB\u8A71")
+ .put(Phone.NUMBER, "1");
+ mVerifier.addLineVerifierElem()
+ .addExpected("N:")
+ .addExpected("FN:")
+ .addExpected("TEL;TYPE=\u96FB\u8A71:1");
+ mVerifier.addPropertyNodesVerifierElemWithEmptyName()
+ .addExpectedNode("TEL", "1", new TypeSet("\u96FB\u8A71"));
+ }
}
diff --git a/core/tests/coretests/src/android/pim/vcard/VCardImporterTests.java b/core/tests/coretests/src/android/pim/vcard/VCardImporterTests.java
index 21f22540c697..09e2914420da 100644
--- a/core/tests/coretests/src/android/pim/vcard/VCardImporterTests.java
+++ b/core/tests/coretests/src/android/pim/vcard/VCardImporterTests.java
@@ -15,11 +15,17 @@
*/
package android.pim.vcard;
+import com.android.frameworks.coretests.R;
+
import android.content.ContentValues;
-import android.pim.vcard.VCardConfig;
-import android.provider.ContactsContract.Data;
+import android.pim.vcard.test_utils.PropertyNodesVerifierElem.TypeSet;
+import android.pim.vcard.test_utils.VCardTestsBase;
+import android.pim.vcard.test_utils.ContentValuesVerifier;
+import android.pim.vcard.test_utils.ContentValuesVerifierElem;
import android.provider.ContactsContract.CommonDataKinds.Email;
import android.provider.ContactsContract.CommonDataKinds.Event;
+import android.provider.ContactsContract.CommonDataKinds.Im;
+import android.provider.ContactsContract.CommonDataKinds.Nickname;
import android.provider.ContactsContract.CommonDataKinds.Note;
import android.provider.ContactsContract.CommonDataKinds.Organization;
import android.provider.ContactsContract.CommonDataKinds.Phone;
@@ -27,9 +33,7 @@ import android.provider.ContactsContract.CommonDataKinds.Photo;
import android.provider.ContactsContract.CommonDataKinds.StructuredName;
import android.provider.ContactsContract.CommonDataKinds.StructuredPostal;
import android.provider.ContactsContract.CommonDataKinds.Website;
-
-import com.android.frameworks.coretests.R;
-import android.pim.vcard.PropertyNodesVerifierElem.TypeSet;
+import android.provider.ContactsContract.Data;
import java.util.Arrays;
@@ -405,12 +409,12 @@ public class VCardImporterTests extends VCardTestsBase {
public void testV21SimpleCase1_Parsing() {
mVerifier.initForImportTest(V21, R.raw.v21_simple_1);
- mVerifier.addPropertyNodesVerifierElem()
+ mVerifier.addPropertyNodesVerifierElemWithoutVersion() // no "VERSION:2.1" line.
.addExpectedNodeWithOrder("N", "Ando;Roid;", Arrays.asList("Ando", "Roid", ""));
}
public void testV21SimpleCase1_Type_Generic() {
- mVerifier.initForImportTest(VCardConfig.VCARD_TYPE_V21_GENERIC_UTF8, R.raw.v21_simple_1);
+ mVerifier.initForImportTest(VCardConfig.VCARD_TYPE_V21_GENERIC, R.raw.v21_simple_1);
mVerifier.addContentValuesVerifierElem()
.addExpected(StructuredName.CONTENT_ITEM_TYPE)
.put(StructuredName.FAMILY_NAME, "Ando")
@@ -419,7 +423,7 @@ public class VCardImporterTests extends VCardTestsBase {
}
public void testV21SimpleCase1_Type_Japanese() {
- mVerifier.initForImportTest(VCardConfig.VCARD_TYPE_V21_JAPANESE_SJIS, R.raw.v21_simple_1);
+ mVerifier.initForImportTest(VCardConfig.VCARD_TYPE_V21_JAPANESE, R.raw.v21_simple_1);
mVerifier.addContentValuesVerifierElem()
.addExpected(StructuredName.CONTENT_ITEM_TYPE)
.put(StructuredName.FAMILY_NAME, "Ando")
@@ -431,7 +435,7 @@ public class VCardImporterTests extends VCardTestsBase {
}
public void testV21SimpleCase2() {
- mVerifier.initForImportTest(VCardConfig.VCARD_TYPE_V21_JAPANESE_SJIS, R.raw.v21_simple_2);
+ mVerifier.initForImportTest(VCardConfig.VCARD_TYPE_V21_JAPANESE, R.raw.v21_simple_2);
mVerifier.addContentValuesVerifierElem()
.addExpected(StructuredName.CONTENT_ITEM_TYPE)
.put(StructuredName.DISPLAY_NAME, "Ando Roid");
@@ -454,7 +458,6 @@ public class VCardImporterTests extends VCardTestsBase {
public void testV21BackslashCase_Parsing() {
mVerifier.initForImportTest(V21, R.raw.v21_backslash);
mVerifier.addPropertyNodesVerifierElem()
- .addExpectedNodeWithOrder("VERSION", "2.1")
.addExpectedNodeWithOrder("N", ";A;B\\;C\\;;D;:E;\\\\;",
Arrays.asList("", "A;B\\", "C\\;", "D", ":E", "\\\\", ""))
.addExpectedNodeWithOrder("FN", "A;B\\C\\;D:E\\\\");
@@ -549,11 +552,11 @@ public class VCardImporterTests extends VCardTestsBase {
public void testV21ComplicatedCase_Parsing() {
mVerifier.initForImportTest(V21, R.raw.v21_complicated);
mVerifier.addPropertyNodesVerifierElem()
- .addExpectedNodeWithOrder("VERSION", "2.1")
.addExpectedNodeWithOrder("N", "Gump;Forrest;Hoge;Pos;Tao",
Arrays.asList("Gump", "Forrest", "Hoge", "Pos", "Tao"))
.addExpectedNodeWithOrder("FN", "Joe Due")
- .addExpectedNodeWithOrder("ORG", "Gump Shrimp Co.;Sales Dept.;Manager;Fish keeper",
+ .addExpectedNodeWithOrder("ORG",
+ "Gump Shrimp Co.;Sales Dept.;Manager;Fish keeper",
Arrays.asList("Gump Shrimp Co.", "Sales Dept.;Manager", "Fish keeper"))
.addExpectedNodeWithOrder("ROLE", "Fish Cake Keeper!")
.addExpectedNodeWithOrder("TITLE", "Shrimp Man")
@@ -583,7 +586,8 @@ public class VCardImporterTests extends VCardTestsBase {
.addExpectedNodeWithOrder("EMAIL", "forrestgump@walladalla.com",
new TypeSet("PREF", "INTERNET"))
.addExpectedNodeWithOrder("EMAIL", "cell@example.com", new TypeSet("CELL"))
- .addExpectedNodeWithOrder("NOTE", "The following note is the example from RFC 2045.")
+ .addExpectedNodeWithOrder("NOTE",
+ "The following note is the example from RFC 2045.")
.addExpectedNodeWithOrder("NOTE",
"Now's the time for all folk to come to the aid of their country.",
null, null, mContentValuesForQP, null, null)
@@ -677,12 +681,24 @@ public class VCardImporterTests extends VCardTestsBase {
.put(Website.TYPE, Website.TYPE_HOMEPAGE);
}
+ public void testInvalidMultipleLineV21() {
+ mVerifier.initForImportTest(V21, R.raw.v21_invalid_multiple_line);
+ ContentValuesVerifierElem elem = mVerifier.addContentValuesVerifierElem();
+ elem.addExpected(StructuredName.CONTENT_ITEM_TYPE)
+ .put(StructuredName.GIVEN_NAME, "Omega")
+ .put(StructuredName.DISPLAY_NAME, "Omega");
+ elem.addExpected(Email.CONTENT_ITEM_TYPE)
+ .put(Email.TYPE, Email.TYPE_CUSTOM)
+ .put(Email.LABEL, "INTERNET")
+ .put(Email.ADDRESS, "\"Omega\" <omega@example.com>");
+ }
+
public void testV30Simple_Parsing() {
mVerifier.initForImportTest(V30, R.raw.v30_simple);
mVerifier.addPropertyNodesVerifierElem()
- .addExpectedNodeWithOrder("VERSION", "3.0")
.addExpectedNodeWithOrder("FN", "And Roid")
- .addExpectedNodeWithOrder("N", "And;Roid;;;", Arrays.asList("And", "Roid", "", "", ""))
+ .addExpectedNodeWithOrder("N", "And;Roid;;;",
+ Arrays.asList("And", "Roid", "", "", ""))
.addExpectedNodeWithOrder("ORG", "Open;Handset; Alliance",
Arrays.asList("Open", "Handset", " Alliance"))
.addExpectedNodeWithOrder("SORT-STRING", "android")
@@ -717,10 +733,8 @@ public class VCardImporterTests extends VCardTestsBase {
// Though Japanese careers append ";;;;" at the end of the value of "SOUND",
// vCard 2.1/3.0 specification does not allow multiple values.
// Do not need to handle it as multiple values.
- mVerifier.initForImportTest(VCardConfig.VCARD_TYPE_V21_JAPANESE_SJIS,
- R.raw.v21_japanese_1);
+ mVerifier.initForImportTest(VCardConfig.VCARD_TYPE_V21_JAPANESE, R.raw.v21_japanese_1);
mVerifier.addPropertyNodesVerifierElem()
- .addExpectedNodeWithOrder("VERSION", "2.1", null, null, null, null, null)
.addExpectedNodeWithOrder("N", "\u5B89\u85E4\u30ED\u30A4\u30C9;;;;",
Arrays.asList("\u5B89\u85E4\u30ED\u30A4\u30C9", "", "", "", ""),
null, mContentValuesForSJis, null, null)
@@ -752,37 +766,35 @@ public class VCardImporterTests extends VCardTestsBase {
/**
* Verifies vCard with Japanese can be parsed correctly with
- * {@link android.pim.vcard.VCardConfig#VCARD_TYPE_V21_GENERIC_UTF8}.
+ * {@link com.android.vcard.VCardConfig#VCARD_TYPE_V21_GENERIC}.
*/
public void testV21Japanese1_Type_Generic_Utf8() {
testV21Japanese1Common(
- R.raw.v21_japanese_1, VCardConfig.VCARD_TYPE_V21_GENERIC_UTF8, false);
+ R.raw.v21_japanese_1, VCardConfig.VCARD_TYPE_V21_GENERIC, false);
}
/**
* Verifies vCard with Japanese can be parsed correctly with
- * {@link android.pim.vcard.VCardConfig#VCARD_TYPE_V21_JAPANESE_SJIS}.
+ * {@link com.android.vcard.VCardConfig#VCARD_TYPE_V21_JAPANESE}.
*/
public void testV21Japanese1_Type_Japanese_Sjis() {
testV21Japanese1Common(
- R.raw.v21_japanese_1, VCardConfig.VCARD_TYPE_V21_JAPANESE_SJIS, true);
+ R.raw.v21_japanese_1, VCardConfig.VCARD_TYPE_V21_JAPANESE, true);
}
/**
* Verifies vCard with Japanese can be parsed correctly with
- * {@link android.pim.vcard.VCardConfig#VCARD_TYPE_V21_JAPANESE_UTF8}.
+ * {@link com.android.vcard.VCardConfig#VCARD_TYPE_V21_JAPANESE}.
* since vCard 2.1 specifies the charset of each line if it contains non-Ascii.
*/
public void testV21Japanese1_Type_Japanese_Utf8() {
testV21Japanese1Common(
- R.raw.v21_japanese_1, VCardConfig.VCARD_TYPE_V21_JAPANESE_UTF8, true);
+ R.raw.v21_japanese_1, VCardConfig.VCARD_TYPE_V21_JAPANESE, true);
}
public void testV21Japanese2_Parsing() {
- mVerifier.initForImportTest(VCardConfig.VCARD_TYPE_V21_JAPANESE_SJIS,
- R.raw.v21_japanese_2);
+ mVerifier.initForImportTest(VCardConfig.VCARD_TYPE_V21_JAPANESE, R.raw.v21_japanese_2);
mVerifier.addPropertyNodesVerifierElem()
- .addExpectedNodeWithOrder("VERSION", "2.1")
.addExpectedNodeWithOrder("N", "\u5B89\u85E4;\u30ED\u30A4\u30C9\u0031;;;",
Arrays.asList("\u5B89\u85E4", "\u30ED\u30A4\u30C9\u0031",
"", "", ""),
@@ -838,10 +850,8 @@ public class VCardImporterTests extends VCardTestsBase {
}
public void testV21MultipleEntryCase_Parse() {
- mVerifier.initForImportTest(VCardConfig.VCARD_TYPE_V21_JAPANESE_SJIS,
- R.raw.v21_multiple_entry);
+ mVerifier.initForImportTest(VCardConfig.VCARD_TYPE_V21_JAPANESE, R.raw.v21_multiple_entry);
mVerifier.addPropertyNodesVerifierElem()
- .addExpectedNodeWithOrder("VERSION", "2.1")
.addExpectedNodeWithOrder("N", "\u5B89\u85E4\u30ED\u30A4\u30C9\u0033;;;;",
Arrays.asList("\u5B89\u85E4\u30ED\u30A4\u30C9\u0033", "", "", "", ""),
null, mContentValuesForSJis, null, null)
@@ -854,7 +864,6 @@ public class VCardImporterTests extends VCardTestsBase {
.addExpectedNodeWithOrder("TEL", "11", new TypeSet("X-NEC-SCHOOL"))
.addExpectedNodeWithOrder("TEL", "12", new TypeSet("FAX", "HOME"));
mVerifier.addPropertyNodesVerifierElem()
- .addExpectedNodeWithOrder("VERSION", "2.1")
.addExpectedNodeWithOrder("N", "\u5B89\u85E4\u30ED\u30A4\u30C9\u0034;;;;",
Arrays.asList("\u5B89\u85E4\u30ED\u30A4\u30C9\u0034", "", "", "", ""),
null, mContentValuesForSJis, null, null)
@@ -867,7 +876,6 @@ public class VCardImporterTests extends VCardTestsBase {
.addExpectedNodeWithOrder("TEL", "15", new TypeSet("X-NEC-FAMILY"))
.addExpectedNodeWithOrder("TEL", "16", new TypeSet("X-NEC-GIRL"));
mVerifier.addPropertyNodesVerifierElem()
- .addExpectedNodeWithOrder("VERSION", "2.1")
.addExpectedNodeWithOrder("N", "\u5B89\u85E4\u30ED\u30A4\u30C9\u0035;;;;",
Arrays.asList("\u5B89\u85E4\u30ED\u30A4\u30C9\u0035", "", "", "", ""),
null, mContentValuesForSJis, null, null)
@@ -882,8 +890,7 @@ public class VCardImporterTests extends VCardTestsBase {
}
public void testV21MultipleEntryCase() {
- mVerifier.initForImportTest(VCardConfig.VCARD_TYPE_V21_JAPANESE_SJIS,
- R.raw.v21_multiple_entry);
+ mVerifier.initForImportTest(VCardConfig.VCARD_TYPE_V21_JAPANESE, R.raw.v21_multiple_entry);
ContentValuesVerifierElem elem = mVerifier.addContentValuesVerifierElem();
elem.addExpected(StructuredName.CONTENT_ITEM_TYPE)
.put(StructuredName.FAMILY_NAME, "\u5B89\u85E4\u30ED\u30A4\u30C9\u0033")
@@ -957,7 +964,6 @@ public class VCardImporterTests extends VCardTestsBase {
ContentValues contentValuesForValue = new ContentValues();
contentValuesForValue.put("VALUE", "DATE");
mVerifier.addPropertyNodesVerifierElem()
- .addExpectedNodeWithOrder("VERSION", "2.1")
.addExpectedNodeWithOrder("N", Arrays.asList("Example", "", "", "", ""))
.addExpectedNodeWithOrder("FN", "Example")
.addExpectedNodeWithOrder("ANNIVERSARY", "20091010", contentValuesForValue)
@@ -974,6 +980,9 @@ public class VCardImporterTests extends VCardTestsBase {
elem.addExpected(StructuredName.CONTENT_ITEM_TYPE)
.put(StructuredName.FAMILY_NAME, "Example")
.put(StructuredName.DISPLAY_NAME, "Example");
+ elem.addExpected(Event.CONTENT_ITEM_TYPE)
+ .put(Event.TYPE, Event.TYPE_ANNIVERSARY)
+ .put(Event.START_DATE, "20091010");
}
public void testTolerateInvalidCommentLikeLineV21() {
@@ -988,16 +997,15 @@ public class VCardImporterTests extends VCardTestsBase {
}
public void testPagerV30_Parse() {
- mVerifier.initForImportTest(V30, R.raw.v30_comma_separated);
+ mVerifier.initForImportTest(V30, R.raw.v30_pager);
mVerifier.addPropertyNodesVerifierElem()
- .addExpectedNodeWithOrder("VERSION", "3.0")
.addExpectedNodeWithOrder("N", Arrays.asList("F", "G", "M", "", ""))
.addExpectedNodeWithOrder("TEL", "6101231234@pagersample.com",
new TypeSet("WORK", "MSG", "PAGER"));
}
public void testPagerV30() {
- mVerifier.initForImportTest(V30, R.raw.v30_comma_separated);
+ mVerifier.initForImportTest(V30, R.raw.v30_pager);
ContentValuesVerifierElem elem = mVerifier.addContentValuesVerifierElem();
elem.addExpected(StructuredName.CONTENT_ITEM_TYPE)
.put(StructuredName.FAMILY_NAME, "F")
@@ -1008,4 +1016,93 @@ public class VCardImporterTests extends VCardTestsBase {
.put(Phone.TYPE, Phone.TYPE_PAGER)
.put(Phone.NUMBER, "6101231234@pagersample.com");
}
+
+ public void testMultiBytePropV30_Parse() {
+ mVerifier.initForImportTest(V30, R.raw.v30_multibyte_param);
+ mVerifier.addPropertyNodesVerifierElem()
+ .addExpectedNodeWithOrder("N", Arrays.asList("F", "G", "M", "", ""))
+ .addExpectedNodeWithOrder("TEL", "1", new TypeSet("\u8D39"));
+ }
+
+ public void testMultiBytePropV30() {
+ mVerifier.initForImportTest(V30, R.raw.v30_multibyte_param);
+ final ContentValuesVerifierElem elem = mVerifier.addContentValuesVerifierElem();
+ elem.addExpected(StructuredName.CONTENT_ITEM_TYPE)
+ .put(StructuredName.FAMILY_NAME, "F")
+ .put(StructuredName.MIDDLE_NAME, "M")
+ .put(StructuredName.GIVEN_NAME, "G")
+ .put(StructuredName.DISPLAY_NAME, "G M F");
+ elem.addExpected(Phone.CONTENT_ITEM_TYPE)
+ .put(Phone.TYPE, Phone.TYPE_CUSTOM)
+ .put(Phone.LABEL, "\u8D39")
+ .put(Phone.NUMBER, "1");
+ }
+
+ public void testCommaSeparatedParamsV30_Parse() {
+ mVerifier.initForImportTest(V30, R.raw.v30_comma_separated);
+ mVerifier.addPropertyNodesVerifierElem()
+ .addExpectedNodeWithOrder("N", Arrays.asList("F", "G", "M", "", ""),
+ new TypeSet("PREF", "HOME"))
+ .addExpectedNodeWithOrder("TEL", "1",
+ new TypeSet("COMMA,SEPARATED:INSIDE.DQUOTE", "PREF"));
+ }
+
+ public void testSortAsV40_Parse() {
+ mVerifier.initForImportTest(V40, R.raw.v40_sort_as);
+
+ final ContentValues contentValuesForSortAsN = new ContentValues();
+ contentValuesForSortAsN.put("SORT-AS",
+ "\u3042\u3093\u3069\u3046;\u308D\u3044\u3069");
+ final ContentValues contentValuesForSortAsOrg = new ContentValues();
+ contentValuesForSortAsOrg.put("SORT-AS",
+ "\u3050\u30FC\u3050\u308B;\u3051\u3093\u3055\u304F\u3076\u3082\u3093");
+
+ mVerifier.addPropertyNodesVerifierElem()
+ .addExpectedNodeWithOrder("FN", "\u5B89\u85E4\u0020\u30ED\u30A4\u30C9")
+ .addExpectedNodeWithOrder("N",
+ Arrays.asList("\u5B89\u85E4", "\u30ED\u30A4\u30C9", "", "", ""),
+ contentValuesForSortAsN)
+ .addExpectedNodeWithOrder("ORG",
+ Arrays.asList("\u30B0\u30FC\u30B0\u30EB", "\u691C\u7D22\u90E8\u9580"),
+ contentValuesForSortAsOrg, new TypeSet("WORK"));
+ }
+
+ public void testSortAsV40() {
+ mVerifier.initForImportTest(V40, R.raw.v40_sort_as);
+ final ContentValuesVerifierElem elem = mVerifier.addContentValuesVerifierElem();
+ elem.addExpected(StructuredName.CONTENT_ITEM_TYPE)
+ .put(StructuredName.FAMILY_NAME, "\u5B89\u85E4")
+ .put(StructuredName.GIVEN_NAME, "\u30ED\u30A4\u30C9")
+ .put(StructuredName.DISPLAY_NAME, "\u5B89\u85E4\u0020\u30ED\u30A4\u30C9")
+ .put(StructuredName.PHONETIC_FAMILY_NAME, "\u3042\u3093\u3069\u3046")
+ .put(StructuredName.PHONETIC_GIVEN_NAME,
+ "\u308D\u3044\u3069");
+ elem.addExpected(Organization.CONTENT_ITEM_TYPE)
+ .put(Organization.TYPE, Organization.TYPE_WORK)
+ .put(Organization.COMPANY, "\u30B0\u30FC\u30B0\u30EB")
+ .put(Organization.DEPARTMENT, "\u691C\u7D22\u90E8\u9580")
+ .put(Organization.PHONETIC_NAME,
+ "\u3050\u30FC\u3050\u308B\u3051\u3093\u3055\u304F\u3076\u3082\u3093");
+ }
+
+ public void testIMV21_Parse() {
+ mVerifier.initForImportTest(V21, R.raw.v21_im);
+ mVerifier.addPropertyNodesVerifierElem()
+ .addExpectedNodeWithOrder("X-ANDROID-CUSTOM",
+ Arrays.asList("vnd.android.cursor.item/nickname", "Nick", "1",
+ "", "", "", "", "", "", "", "", "", "", "", "", "")) // 13
+ .addExpectedNodeWithOrder("X-GOOGLE-TALK", "hhh@gmail.com");
+ }
+
+ public void testIMV21() {
+ mVerifier.initForImportTest(V21, R.raw.v21_im);
+ final ContentValuesVerifierElem elem = mVerifier.addContentValuesVerifierElem();
+ elem.addExpected(Nickname.CONTENT_ITEM_TYPE)
+ .put(Nickname.NAME, "Nick")
+ .put(Nickname.TYPE, "1");
+ elem.addExpected(Im.CONTENT_ITEM_TYPE)
+ .put(Im.PROTOCOL, Im.PROTOCOL_GOOGLE_TALK)
+ .put(Im.TYPE, Im.TYPE_HOME)
+ .put(Im.DATA, "hhh@gmail.com");
+ }
}
diff --git a/core/tests/coretests/src/android/pim/vcard/VCardJapanizationTests.java b/core/tests/coretests/src/android/pim/vcard/VCardJapanizationTests.java
index 5b60342c872b..8a99419dfa11 100644
--- a/core/tests/coretests/src/android/pim/vcard/VCardJapanizationTests.java
+++ b/core/tests/coretests/src/android/pim/vcard/VCardJapanizationTests.java
@@ -13,19 +13,20 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-
package android.pim.vcard;
import android.content.ContentValues;
-import android.pim.vcard.VCardConfig;
+import android.pim.vcard.test_utils.ContactEntry;
+import android.pim.vcard.test_utils.ContentValuesBuilder;
+import android.pim.vcard.test_utils.PropertyNodesVerifierElem;
+import android.pim.vcard.test_utils.PropertyNodesVerifierElem.TypeSet;
+import android.pim.vcard.test_utils.VCardTestsBase;
import android.provider.ContactsContract.CommonDataKinds.Nickname;
import android.provider.ContactsContract.CommonDataKinds.Note;
import android.provider.ContactsContract.CommonDataKinds.Phone;
import android.provider.ContactsContract.CommonDataKinds.StructuredName;
import android.provider.ContactsContract.CommonDataKinds.StructuredPostal;
-import android.pim.vcard.PropertyNodesVerifierElem.TypeSet;
-
import java.util.Arrays;
public class VCardJapanizationTests extends VCardTestsBase {
@@ -39,7 +40,7 @@ public class VCardJapanizationTests extends VCardTestsBase {
.put(StructuredName.PREFIX, "Dr.")
.put(StructuredName.SUFFIX, "Ph.D");
ContentValues contentValues =
- (VCardConfig.isV30(vcardType) ? null : mContentValuesForQPAndUtf8);
+ (VCardConfig.isVersion21(vcardType) ? mContentValuesForQPAndUtf8 : null);
mVerifier.addPropertyNodesVerifierElem()
.addExpectedNode("FN", "Dr. \u3075\u308B\u3069 B \u3091\u308A\u304B Ph.D",
contentValues)
@@ -50,15 +51,15 @@ public class VCardJapanizationTests extends VCardTestsBase {
}
public void testNameUtf8V21() {
- testNameUtf8Common(VCardConfig.VCARD_TYPE_V21_JAPANESE_UTF8);
+ testNameUtf8Common(VCardConfig.VCARD_TYPE_V21_JAPANESE);
}
public void testNameUtf8V30() {
- testNameUtf8Common(VCardConfig.VCARD_TYPE_V30_JAPANESE_UTF8);
+ testNameUtf8Common(VCardConfig.VCARD_TYPE_V30_JAPANESE);
}
public void testNameShiftJis() {
- mVerifier.initForExportTest(VCardConfig.VCARD_TYPE_V30_JAPANESE_SJIS);
+ mVerifier.initForExportTest(VCardConfig.VCARD_TYPE_V30_JAPANESE, "Shift_JIS");
ContactEntry entry = mVerifier.addInputEntry();
entry.addContentValues(StructuredName.CONTENT_ITEM_TYPE)
.put(StructuredName.FAMILY_NAME, "\u3075\u308B\u3069")
@@ -80,7 +81,7 @@ public class VCardJapanizationTests extends VCardTestsBase {
* DoCoMo phones require all name elements should be in "family name" field.
*/
public void testNameDoCoMo() {
- mVerifier.initForExportTest(VCardConfig.VCARD_TYPE_DOCOMO);
+ mVerifier.initForExportTest(VCardConfig.VCARD_TYPE_DOCOMO, "Shift_JIS");
ContactEntry entry = mVerifier.addInputEntry();
entry.addContentValues(StructuredName.CONTENT_ITEM_TYPE)
.put(StructuredName.FAMILY_NAME, "\u3075\u308B\u3069")
@@ -105,8 +106,8 @@ public class VCardJapanizationTests extends VCardTestsBase {
.addExpectedNode("X-DCM-HMN-MODE", "");
}
- private void testPhoneticNameCommon(int vcardType) {
- mVerifier.initForExportTest(vcardType);
+ private void testPhoneticNameCommon(int vcardType, String charset) {
+ mVerifier.initForExportTest(vcardType, charset);
ContactEntry entry = mVerifier.addInputEntry();
entry.addContentValues(StructuredName.CONTENT_ITEM_TYPE)
.put(StructuredName.PHONETIC_FAMILY_NAME, "\u3084\u307E\u3060")
@@ -114,10 +115,10 @@ public class VCardJapanizationTests extends VCardTestsBase {
.put(StructuredName.PHONETIC_GIVEN_NAME, "\u305F\u308D\u3046");
final ContentValues contentValues =
- (VCardConfig.usesShiftJis(vcardType) ?
- (VCardConfig.isV30(vcardType) ? mContentValuesForSJis :
- mContentValuesForQPAndSJis) :
- (VCardConfig.isV30(vcardType) ? null : mContentValuesForQPAndUtf8));
+ ("SHIFT_JIS".equalsIgnoreCase(charset) ?
+ (VCardConfig.isVersion21(vcardType) ? mContentValuesForQPAndSJis :
+ mContentValuesForSJis) :
+ (VCardConfig.isVersion21(vcardType) ? mContentValuesForQPAndUtf8 : null));
PropertyNodesVerifierElem elem = mVerifier.addPropertyNodesVerifierElemWithEmptyName();
elem.addExpectedNode("X-PHONETIC-LAST-NAME", "\u3084\u307E\u3060",
contentValues)
@@ -126,7 +127,7 @@ public class VCardJapanizationTests extends VCardTestsBase {
contentValues)
.addExpectedNode("X-PHONETIC-FIRST-NAME", "\u305F\u308D\u3046",
contentValues);
- if (VCardConfig.isV30(vcardType)) {
+ if (!VCardConfig.isVersion21(vcardType)) {
elem.addExpectedNode("SORT-STRING",
"\u3084\u307E\u3060 \u30DF\u30C9\u30EB\u30CD\u30FC\u30E0 \u305F\u308D\u3046",
contentValues);
@@ -142,23 +143,23 @@ public class VCardJapanizationTests extends VCardTestsBase {
}
public void testPhoneticNameForJapaneseV21Utf8() {
- testPhoneticNameCommon(VCardConfig.VCARD_TYPE_V21_JAPANESE_UTF8);
+ testPhoneticNameCommon(VCardConfig.VCARD_TYPE_V21_JAPANESE, null);
}
public void testPhoneticNameForJapaneseV21Sjis() {
- testPhoneticNameCommon(VCardConfig.VCARD_TYPE_V21_JAPANESE_SJIS);
+ testPhoneticNameCommon(VCardConfig.VCARD_TYPE_V21_JAPANESE, "Shift_JIS");
}
public void testPhoneticNameForJapaneseV30Utf8() {
- testPhoneticNameCommon(VCardConfig.VCARD_TYPE_V30_JAPANESE_UTF8);
+ testPhoneticNameCommon(VCardConfig.VCARD_TYPE_V30_JAPANESE, null);
}
public void testPhoneticNameForJapaneseV30SJis() {
- testPhoneticNameCommon(VCardConfig.VCARD_TYPE_V30_JAPANESE_SJIS);
+ testPhoneticNameCommon(VCardConfig.VCARD_TYPE_V30_JAPANESE, "Shift_JIS");
}
public void testPhoneticNameForMobileV21_1() {
- mVerifier.initForExportTest(VCardConfig.VCARD_TYPE_V21_JAPANESE_MOBILE);
+ mVerifier.initForExportTest(VCardConfig.VCARD_TYPE_V21_JAPANESE_MOBILE, "Shift_JIS");
ContactEntry entry = mVerifier.addInputEntry();
entry.addContentValues(StructuredName.CONTENT_ITEM_TYPE)
.put(StructuredName.PHONETIC_FAMILY_NAME, "\u3084\u307E\u3060")
@@ -182,7 +183,7 @@ public class VCardJapanizationTests extends VCardTestsBase {
}
public void testPhoneticNameForMobileV21_2() {
- mVerifier.initForExportTest(VCardConfig.VCARD_TYPE_V21_JAPANESE_MOBILE);
+ mVerifier.initForExportTest(VCardConfig.VCARD_TYPE_V21_JAPANESE_MOBILE, "Shift_JIS");
ContactEntry entry = mVerifier.addInputEntry();
entry.addContentValues(StructuredName.CONTENT_ITEM_TYPE)
.put(StructuredName.PHONETIC_FAMILY_NAME, "\u3084\u307E\u3060")
@@ -198,8 +199,8 @@ public class VCardJapanizationTests extends VCardTestsBase {
.put(StructuredName.DISPLAY_NAME, "\uFF94\uFF8F\uFF80\uFF9E \uFF80\uFF9B\uFF73");
}
- private void testPostalAddressWithJapaneseCommon(int vcardType) {
- mVerifier.initForExportTest(vcardType);
+ private void testPostalAddressWithJapaneseCommon(int vcardType, String charset) {
+ mVerifier.initForExportTest(vcardType, charset);
ContactEntry entry = mVerifier.addInputEntry();
entry.addContentValues(StructuredPostal.CONTENT_ITEM_TYPE)
.put(StructuredPostal.POBOX, "\u79C1\u66F8\u7BB107")
@@ -214,11 +215,11 @@ public class VCardJapanizationTests extends VCardTestsBase {
.put(StructuredPostal.TYPE, StructuredPostal.TYPE_CUSTOM)
.put(StructuredPostal.LABEL, "\u304A\u3082\u3061\u304B\u3048\u308A");
- ContentValues contentValues = (VCardConfig.usesShiftJis(vcardType) ?
- (VCardConfig.isV30(vcardType) ? mContentValuesForSJis :
- mContentValuesForQPAndSJis) :
- (VCardConfig.isV30(vcardType) ? mContentValuesForUtf8 :
- mContentValuesForQPAndUtf8));
+ ContentValues contentValues = ("UTF-8".equalsIgnoreCase(charset) ?
+ (VCardConfig.isVersion21(vcardType) ? mContentValuesForQPAndSJis :
+ mContentValuesForSJis) :
+ (VCardConfig.isVersion21(vcardType) ? mContentValuesForQPAndUtf8 :
+ mContentValuesForUtf8));
PropertyNodesVerifierElem elem = mVerifier.addPropertyNodesVerifierElemWithEmptyName();
// LABEL must be ignored in vCard 2.1. As for vCard 3.0, the current behavior is
@@ -240,7 +241,7 @@ public class VCardJapanizationTests extends VCardTestsBase {
.put(StructuredPostal.TYPE, StructuredPostal.TYPE_HOME);
}
public void testPostalAddresswithJapaneseV21() {
- testPostalAddressWithJapaneseCommon(VCardConfig.VCARD_TYPE_V21_JAPANESE_SJIS);
+ testPostalAddressWithJapaneseCommon(VCardConfig.VCARD_TYPE_V21_JAPANESE, "Shift_JIS");
}
/**
@@ -248,7 +249,7 @@ public class VCardJapanizationTests extends VCardTestsBase {
* Prefered type must (should?) be: HOME > WORK > OTHER > CUSTOM
*/
public void testPostalAdrressForDoCoMo_1() {
- mVerifier.initForExportTest(VCardConfig.VCARD_TYPE_DOCOMO);
+ mVerifier.initForExportTest(VCardConfig.VCARD_TYPE_DOCOMO, "Shift_JIS");
ContactEntry entry = mVerifier.addInputEntry();
entry.addContentValues(StructuredPostal.CONTENT_ITEM_TYPE)
.put(StructuredPostal.TYPE, StructuredPostal.TYPE_WORK)
@@ -276,7 +277,7 @@ public class VCardJapanizationTests extends VCardTestsBase {
}
public void testPostalAdrressForDoCoMo_2() {
- mVerifier.initForExportTest(VCardConfig.VCARD_TYPE_DOCOMO);
+ mVerifier.initForExportTest(VCardConfig.VCARD_TYPE_DOCOMO, "Shift_JIS");
ContactEntry entry = mVerifier.addInputEntry();
entry.addContentValues(StructuredPostal.CONTENT_ITEM_TYPE)
.put(StructuredPostal.TYPE, StructuredPostal.TYPE_OTHER)
@@ -301,7 +302,7 @@ public class VCardJapanizationTests extends VCardTestsBase {
}
public void testPostalAdrressForDoCoMo_3() {
- mVerifier.initForExportTest(VCardConfig.VCARD_TYPE_DOCOMO);
+ mVerifier.initForExportTest(VCardConfig.VCARD_TYPE_DOCOMO, "Shift_JIS");
ContactEntry entry = mVerifier.addInputEntry();
entry.addContentValues(StructuredPostal.CONTENT_ITEM_TYPE)
.put(StructuredPostal.TYPE, StructuredPostal.TYPE_CUSTOM)
@@ -329,7 +330,7 @@ public class VCardJapanizationTests extends VCardTestsBase {
* Verifies the vCard exporter tolerates null TYPE.
*/
public void testPostalAdrressForDoCoMo_4() {
- mVerifier.initForExportTest(VCardConfig.VCARD_TYPE_DOCOMO);
+ mVerifier.initForExportTest(VCardConfig.VCARD_TYPE_DOCOMO, "Shift_JIS");
ContactEntry entry = mVerifier.addInputEntry();
entry.addContentValues(StructuredPostal.CONTENT_ITEM_TYPE)
.put(StructuredPostal.POBOX, "1");
@@ -371,15 +372,15 @@ public class VCardJapanizationTests extends VCardTestsBase {
}
public void testJapanesePhoneNumberV21_1() {
- testJapanesePhoneNumberCommon(VCardConfig.VCARD_TYPE_V21_JAPANESE_UTF8);
+ testJapanesePhoneNumberCommon(VCardConfig.VCARD_TYPE_V21_JAPANESE);
}
public void testJapanesePhoneNumberV30() {
- testJapanesePhoneNumberCommon(VCardConfig.VCARD_TYPE_V30_JAPANESE_UTF8);
+ testJapanesePhoneNumberCommon(VCardConfig.VCARD_TYPE_V30_JAPANESE);
}
public void testJapanesePhoneNumberDoCoMo() {
- mVerifier.initForExportTest(VCardConfig.VCARD_TYPE_DOCOMO);
+ mVerifier.initForExportTest(VCardConfig.VCARD_TYPE_DOCOMO, "Shift_JIS");
ContactEntry entry = mVerifier.addInputEntry();
entry.addContentValues(Phone.CONTENT_ITEM_TYPE)
.put(Phone.NUMBER, "0312341234")
@@ -399,7 +400,7 @@ public class VCardJapanizationTests extends VCardTestsBase {
}
public void testNoteDoCoMo() {
- mVerifier.initForExportTest(VCardConfig.VCARD_TYPE_DOCOMO);
+ mVerifier.initForExportTest(VCardConfig.VCARD_TYPE_DOCOMO, "Shift_JIS");
ContactEntry entry = mVerifier.addInputEntry();
entry.addContentValues(Note.CONTENT_ITEM_TYPE)
.put(Note.NOTE, "note1");
@@ -421,7 +422,7 @@ public class VCardJapanizationTests extends VCardTestsBase {
}
public void testAndroidCustomV21() {
- mVerifier.initForExportTest(VCardConfig.VCARD_TYPE_V21_GENERIC_UTF8);
+ mVerifier.initForExportTest(VCardConfig.VCARD_TYPE_V21_GENERIC);
mVerifier.addInputEntry().addContentValues(Nickname.CONTENT_ITEM_TYPE)
.put(Nickname.NAME, "\u304D\u3083\u30FC\u30A8\u30C3\u30C1\u30FC");
mVerifier.addPropertyNodesVerifierElemWithEmptyName()
diff --git a/core/tests/coretests/src/android/pim/vcard/VCardTestRunner.java b/core/tests/coretests/src/android/pim/vcard/VCardTestRunner.java
new file mode 100644
index 000000000000..a3a4393ef395
--- /dev/null
+++ b/core/tests/coretests/src/android/pim/vcard/VCardTestRunner.java
@@ -0,0 +1,42 @@
+/*
+ * Copyright (C) 2010 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package android.pim.vcard;
+
+import android.test.InstrumentationTestRunner;
+import android.test.InstrumentationTestSuite;
+
+import junit.framework.TestSuite;
+
+/**
+ * Usage: adb shell am instrument -w com.android.vcard.tests/.VCardTestRunnerTestRunner
+ */
+public class VCardTestRunner extends InstrumentationTestRunner {
+ @Override
+ public TestSuite getAllTests() {
+ TestSuite suite = new InstrumentationTestSuite(this);
+ suite.addTestSuite(VCardUtilsTests.class);
+ suite.addTestSuite(VCardTestUtilsTests.class);
+ suite.addTestSuite(VCardImporterTests.class);
+ suite.addTestSuite(VCardExporterTests.class);
+ suite.addTestSuite(VCardJapanizationTests.class);
+ return suite;
+ }
+
+ @Override
+ public ClassLoader getLoader() {
+ return VCardTestRunner.class.getClassLoader();
+ }
+} \ No newline at end of file
diff --git a/core/tests/coretests/src/android/pim/vcard/VCardTestUtilsTests.java b/core/tests/coretests/src/android/pim/vcard/VCardTestUtilsTests.java
new file mode 100644
index 000000000000..3ff5cf7a5158
--- /dev/null
+++ b/core/tests/coretests/src/android/pim/vcard/VCardTestUtilsTests.java
@@ -0,0 +1,98 @@
+/*
+ * Copyright (C) 2010 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package android.pim.vcard;
+
+import com.android.frameworks.coretests.R;
+
+import android.pim.vcard.test_utils.VCardVerifier;
+import android.provider.ContactsContract.CommonDataKinds.StructuredName;
+import android.test.AndroidTestCase;
+
+import junit.framework.AssertionFailedError;
+import junit.framework.TestCase;
+
+import java.util.Arrays;
+
+/**
+ * Tests confirming utilities for vCard tests work fine.
+ *
+ * Now that the foundation classes for vCard test cases became too complicated to
+ * rely on without testing itself.
+ */
+public class VCardTestUtilsTests extends AndroidTestCase {
+ public void testShouldFailAtPropertyNodeVerification() {
+ boolean failureDetected = false;
+ try {
+ final VCardVerifier verifier = new VCardVerifier(this);
+ verifier.initForImportTest(VCardConfig.VCARD_TYPE_V21_GENERIC, R.raw.v21_backslash);
+ verifier.addPropertyNodesVerifierElem()
+ .addExpectedNodeWithOrder("N", ";A;B\\;C\\;;D;:E;\\\\;--", // wrong
+ Arrays.asList("", "A;B\\", "C\\;", "D", ":E", "\\\\", ""))
+ .addExpectedNodeWithOrder("FN", "A;B\\C\\;D:E\\\\");
+ verifier.verify();
+ } catch (AssertionFailedError e) {
+ failureDetected = true;
+ }
+ if (!failureDetected) {
+ TestCase.fail("Test case that should fail actually succeeded.");
+ }
+ }
+
+ public void testShouldFailAtContentValueVerification() {
+ boolean failureDetected = false;
+ try {
+ final VCardVerifier verifier = new VCardVerifier(this);
+ verifier.initForImportTest(VCardConfig.VCARD_TYPE_V21_GENERIC, R.raw.v21_backslash);
+ verifier.addContentValuesVerifierElem()
+ .addExpected(StructuredName.CONTENT_ITEM_TYPE)
+ .put(StructuredName.GIVEN_NAME, "A;B\\")
+ .put(StructuredName.MIDDLE_NAME, "C\\;")
+ .put(StructuredName.PREFIX, "D")
+ .put(StructuredName.SUFFIX, ":E");
+ // DISPLAY_NAME is missing.
+ verifier.verify();
+ } catch (AssertionFailedError e) {
+ failureDetected = true;
+ }
+ if (!failureDetected) {
+ TestCase.fail("Test case that should fail actually succeeded.");
+ }
+ }
+
+ public void testShouldFailAtLineVerification() {
+ boolean failureDetected = false;
+ try {
+ final VCardVerifier verifier = new VCardVerifier(this);
+ verifier.initForExportTest(VCardConfig.VCARD_TYPE_V30_GENERIC);
+ verifier.addInputEntry().addContentValues(StructuredName.CONTENT_ITEM_TYPE)
+ .put(StructuredName.FAMILY_NAME, "\\")
+ .put(StructuredName.GIVEN_NAME, ";")
+ .put(StructuredName.MIDDLE_NAME, ",")
+ .put(StructuredName.PREFIX, "\n")
+ .put(StructuredName.DISPLAY_NAME, "[<{Unescaped:Asciis}>]");
+ verifier.addLineVerifierElem()
+ .addExpected("TEL:1") // wrong
+ .addExpected("FN:[<{Unescaped:Asciis}>]");
+ verifier.verify();
+ } catch (AssertionFailedError e) {
+ failureDetected = true;
+ }
+ if (!failureDetected) {
+ TestCase.fail("Test case that should fail actually succeeded.");
+ }
+ }
+
+}
diff --git a/core/tests/coretests/src/android/pim/vcard/VCardTestsBase.java b/core/tests/coretests/src/android/pim/vcard/VCardTestsBase.java
deleted file mode 100644
index 0857e0c6e3ad..000000000000
--- a/core/tests/coretests/src/android/pim/vcard/VCardTestsBase.java
+++ /dev/null
@@ -1,169 +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.pim.vcard;
-
-import android.content.ContentProvider;
-import android.content.ContentProviderOperation;
-import android.content.ContentProviderResult;
-import android.content.ContentValues;
-import android.content.EntityIterator;
-import android.content.res.AssetFileDescriptor;
-import android.database.Cursor;
-import android.database.CursorWindow;
-import android.database.IBulkCursor;
-import android.database.IContentObserver;
-import android.net.Uri;
-import android.os.IBinder;
-import android.os.ParcelFileDescriptor;
-import android.os.RemoteException;
-import android.pim.vcard.VCardConfig;
-import android.test.AndroidTestCase;
-import android.util.Log;
-
-import java.util.ArrayList;
-
-/**
- * Almost a dead copy of android.test.mock.MockContentProvider, but different in that this
- * class extends ContentProvider, not implementing IContentProvider,
- * so that MockContentResolver is able to accept this class :(
- */
-class MockContentProvider extends ContentProvider {
- @Override
- public boolean onCreate() {
- return true;
- }
-
- @Override
- public int bulkInsert(Uri url, ContentValues[] initialValues) {
- throw new UnsupportedOperationException("unimplemented mock method");
- }
-
- @SuppressWarnings("unused")
- public IBulkCursor bulkQuery(Uri url, String[] projection, String selection,
- String[] selectionArgs, String sortOrder, IContentObserver observer,
- CursorWindow window) throws RemoteException {
- throw new UnsupportedOperationException("unimplemented mock method");
- }
-
- @Override
- @SuppressWarnings("unused")
- public int delete(Uri url, String selection, String[] selectionArgs) {
- throw new UnsupportedOperationException("unimplemented mock method");
- }
-
- @Override
- public String getType(Uri url) {
- throw new UnsupportedOperationException("unimplemented mock method");
- }
-
- @Override
- public Uri insert(Uri url, ContentValues initialValues) {
- throw new UnsupportedOperationException("unimplemented mock method");
- }
-
- @Override
- public ParcelFileDescriptor openFile(Uri url, String mode) {
- throw new UnsupportedOperationException("unimplemented mock method");
- }
-
- @Override
- public AssetFileDescriptor openAssetFile(Uri uri, String mode) {
- throw new UnsupportedOperationException("unimplemented mock method");
- }
-
- @Override
- public ContentProviderResult[] applyBatch(ArrayList<ContentProviderOperation> operations) {
- throw new UnsupportedOperationException("unimplemented mock method");
- }
-
- @Override
- public Cursor query(Uri url, String[] projection, String selection, String[] selectionArgs,
- String sortOrder) {
- throw new UnsupportedOperationException("unimplemented mock method");
- }
-
- @Override
- public int update(Uri url, ContentValues values, String selection, String[] selectionArgs) {
- throw new UnsupportedOperationException("unimplemented mock method");
- }
-
- public IBinder asBinder() {
- throw new UnsupportedOperationException("unimplemented mock method");
- }
-}
-
-/**
- * BaseClass for vCard unit tests with utility classes.
- * Please do not add each unit test here.
- */
-/* package */ class VCardTestsBase extends AndroidTestCase {
- public static final int V21 = VCardConfig.VCARD_TYPE_V21_GENERIC_UTF8;
- public static final int V30 = VCardConfig.VCARD_TYPE_V30_GENERIC_UTF8;
-
- // Do not modify these during tests.
- protected final ContentValues mContentValuesForQP;
- protected final ContentValues mContentValuesForSJis;
- protected final ContentValues mContentValuesForUtf8;
- protected final ContentValues mContentValuesForQPAndSJis;
- protected final ContentValues mContentValuesForQPAndUtf8;
- protected final ContentValues mContentValuesForBase64V21;
- protected final ContentValues mContentValuesForBase64V30;
-
- protected VCardVerifier mVerifier;
- private boolean mSkipVerification;
-
- public VCardTestsBase() {
- super();
- mContentValuesForQP = new ContentValues();
- mContentValuesForQP.put("ENCODING", "QUOTED-PRINTABLE");
- mContentValuesForSJis = new ContentValues();
- mContentValuesForSJis.put("CHARSET", "SHIFT_JIS");
- mContentValuesForUtf8 = new ContentValues();
- mContentValuesForUtf8.put("CHARSET", "UTF-8");
- mContentValuesForQPAndSJis = new ContentValues();
- mContentValuesForQPAndSJis.put("ENCODING", "QUOTED-PRINTABLE");
- mContentValuesForQPAndSJis.put("CHARSET", "SHIFT_JIS");
- mContentValuesForQPAndUtf8 = new ContentValues();
- mContentValuesForQPAndUtf8.put("ENCODING", "QUOTED-PRINTABLE");
- mContentValuesForQPAndUtf8.put("CHARSET", "UTF-8");
- mContentValuesForBase64V21 = new ContentValues();
- mContentValuesForBase64V21.put("ENCODING", "BASE64");
- mContentValuesForBase64V30 = new ContentValues();
- mContentValuesForBase64V30.put("ENCODING", "b");
- }
-
- @Override
- public void testAndroidTestCaseSetupProperly() {
- super.testAndroidTestCaseSetupProperly();
- mSkipVerification = true;
- }
-
- @Override
- public void setUp() throws Exception{
- super.setUp();
- mVerifier = new VCardVerifier(this);
- mSkipVerification = false;
- }
-
- @Override
- public void tearDown() throws Exception {
- super.tearDown();
- if (!mSkipVerification) {
- mVerifier.verify();
- }
- }
-}
diff --git a/core/tests/coretests/src/android/pim/vcard/VCardUtilsTests.java b/core/tests/coretests/src/android/pim/vcard/VCardUtilsTests.java
index 59299f9dff35..251fab212768 100644
--- a/core/tests/coretests/src/android/pim/vcard/VCardUtilsTests.java
+++ b/core/tests/coretests/src/android/pim/vcard/VCardUtilsTests.java
@@ -13,10 +13,9 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-
package android.pim.vcard;
-import android.pim.vcard.VCardUtils;
+import android.text.TextUtils;
import junit.framework.TestCase;
@@ -82,4 +81,38 @@ public class VCardUtilsTests extends TestCase {
assertFalse(VCardUtils.containsOnlyAlphaDigitHyphen(String.valueOf((char)i)));
}
}
+
+ public void testToStringAvailableAsV30ParamValue() {
+ // Smoke tests.
+ assertEquals("HOME", VCardUtils.toStringAsV30ParamValue("HOME"));
+ assertEquals("TEL", VCardUtils.toStringAsV30ParamValue("TEL"));
+ assertEquals("PAGER", VCardUtils.toStringAsV30ParamValue("PAGER"));
+
+ assertTrue(TextUtils.isEmpty(VCardUtils.toStringAsV30ParamValue("")));
+ assertTrue(TextUtils.isEmpty(VCardUtils.toStringAsV30ParamValue(null)));
+ assertTrue(TextUtils.isEmpty(VCardUtils.toStringAsV30ParamValue(" \t")));
+
+ // non-Ascii must be allowed
+ assertEquals("\u4E8B\u52D9\u6240",
+ VCardUtils.toStringAsV30ParamValue("\u4E8B\u52D9\u6240"));
+ // Reported as bug report.
+ assertEquals("\u8D39", VCardUtils.toStringAsV30ParamValue("\u8D39"));
+ assertEquals("\"comma,separated\"",
+ VCardUtils.toStringAsV30ParamValue("comma,separated"));
+ assertEquals("\"colon:aware\"",
+ VCardUtils.toStringAsV30ParamValue("colon:aware"));
+ // CTL characters.
+ assertEquals("CTLExample",
+ VCardUtils.toStringAsV30ParamValue("CTL\u0001Example"));
+ assertTrue(TextUtils.isEmpty(
+ VCardUtils.toStringAsV30ParamValue("\u0001\u0002\u0003")));
+ // DQUOTE must be removed.
+ assertEquals("quoted",
+ VCardUtils.toStringAsV30ParamValue("\"quoted\""));
+ // DQUOTE must be removed basically, but we should detect a space, which
+ // require us to use DQUOTE again.
+ // Right-side has one more illegal dquote to test quote-handle code thoroughly.
+ assertEquals("\"Already quoted\"",
+ VCardUtils.toStringAsV30ParamValue("\"Already quoted\"\""));
+ }
}
diff --git a/core/tests/coretests/src/android/pim/vcard/VCardVerifier.java b/core/tests/coretests/src/android/pim/vcard/VCardVerifier.java
deleted file mode 100644
index bfc315829c2d..000000000000
--- a/core/tests/coretests/src/android/pim/vcard/VCardVerifier.java
+++ /dev/null
@@ -1,306 +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.pim.vcard;
-
-import android.content.ContentProvider;
-import android.content.ContentResolver;
-import android.content.Context;
-import android.content.EntityIterator;
-import android.net.Uri;
-import android.pim.vcard.VCardComposer;
-import android.pim.vcard.VCardConfig;
-import android.pim.vcard.VCardEntryConstructor;
-import android.pim.vcard.VCardInterpreter;
-import android.pim.vcard.VCardInterpreterCollection;
-import android.pim.vcard.VCardParser;
-import android.pim.vcard.VCardParser_V21;
-import android.pim.vcard.VCardParser_V30;
-import android.pim.vcard.exception.VCardException;
-import android.test.AndroidTestCase;
-import android.test.mock.MockContext;
-
-import java.io.ByteArrayInputStream;
-import java.io.IOException;
-import java.io.InputStream;
-import java.lang.reflect.Method;
-import java.util.Arrays;
-
-/* package */ class CustomMockContext extends MockContext {
- final ContentResolver mResolver;
- public CustomMockContext(ContentResolver resolver) {
- mResolver = resolver;
- }
-
- @Override
- public ContentResolver getContentResolver() {
- return mResolver;
- }
-}
-
-/* package */ class VCardVerifier {
- private class VCardVerifierInternal implements VCardComposer.OneEntryHandler {
- public boolean onInit(Context context) {
- return true;
- }
- public boolean onEntryCreated(String vcard) {
- verifyOneVCard(vcard);
- return true;
- }
- public void onTerminate() {
- }
- }
-
- private final AndroidTestCase mTestCase;
- private final VCardVerifierInternal mVCardVerifierInternal;
- private int mVCardType;
- private boolean mIsV30;
- private boolean mIsDoCoMo;
-
- // Only one of them must be non-empty.
- private ExportTestResolver mExportTestResolver;
- private InputStream mInputStream;
-
- // To allow duplication, use list instead of set.
- // When null, we don't need to do the verification.
- private PropertyNodesVerifier mPropertyNodesVerifier;
- private LineVerifier mLineVerifier;
- private ContentValuesVerifier mContentValuesVerifier;
- private boolean mInitialized;
- private boolean mVerified = false;
-
- public VCardVerifier(AndroidTestCase androidTestCase) {
- mTestCase = androidTestCase;
- mVCardVerifierInternal = new VCardVerifierInternal();
- mExportTestResolver = null;
- mInputStream = null;
- mInitialized = false;
- mVerified = false;
- }
-
- public void initForExportTest(int vcardType) {
- if (mInitialized) {
- mTestCase.fail("Already initialized");
- }
- mExportTestResolver = new ExportTestResolver(mTestCase);
- mVCardType = vcardType;
- mIsV30 = VCardConfig.isV30(vcardType);
- mIsDoCoMo = VCardConfig.isDoCoMo(vcardType);
- mInitialized = true;
- }
-
- public void initForImportTest(int vcardType, int resId) {
- if (mInitialized) {
- mTestCase.fail("Already initialized");
- }
- mVCardType = vcardType;
- mIsV30 = VCardConfig.isV30(vcardType);
- mIsDoCoMo = VCardConfig.isDoCoMo(vcardType);
- setInputResourceId(resId);
- mInitialized = true;
- }
-
- private void setInputResourceId(int resId) {
- InputStream inputStream = mTestCase.getContext().getResources().openRawResource(resId);
- if (inputStream == null) {
- mTestCase.fail("Wrong resId: " + resId);
- }
- setInputStream(inputStream);
- }
-
- private void setInputStream(InputStream inputStream) {
- if (mExportTestResolver != null) {
- mTestCase.fail("addInputEntry() is called.");
- } else if (mInputStream != null) {
- mTestCase.fail("InputStream is already set");
- }
- mInputStream = inputStream;
- }
-
- public ContactEntry addInputEntry() {
- if (!mInitialized) {
- mTestCase.fail("Not initialized");
- }
- if (mInputStream != null) {
- mTestCase.fail("setInputStream is called");
- }
- return mExportTestResolver.addInputContactEntry();
- }
-
- public PropertyNodesVerifierElem addPropertyNodesVerifierElem() {
- if (!mInitialized) {
- mTestCase.fail("Not initialized");
- }
- if (mPropertyNodesVerifier == null) {
- mPropertyNodesVerifier = new PropertyNodesVerifier(mTestCase);
- }
- PropertyNodesVerifierElem elem =
- mPropertyNodesVerifier.addPropertyNodesVerifierElem();
- elem.addExpectedNodeWithOrder("VERSION", (mIsV30 ? "3.0" : "2.1"));
-
- return elem;
- }
-
- public PropertyNodesVerifierElem addPropertyNodesVerifierElemWithEmptyName() {
- if (!mInitialized) {
- mTestCase.fail("Not initialized");
- }
- PropertyNodesVerifierElem elem = addPropertyNodesVerifierElem();
- if (mIsV30) {
- elem.addExpectedNodeWithOrder("N", "").addExpectedNodeWithOrder("FN", "");
- } else if (mIsDoCoMo) {
- elem.addExpectedNodeWithOrder("N", "");
- }
- return elem;
- }
-
- public LineVerifierElem addLineVerifierElem() {
- if (!mInitialized) {
- mTestCase.fail("Not initialized");
- }
- if (mLineVerifier == null) {
- mLineVerifier = new LineVerifier(mTestCase, mVCardType);
- }
- return mLineVerifier.addLineVerifierElem();
- }
-
- public ContentValuesVerifierElem addContentValuesVerifierElem() {
- if (!mInitialized) {
- mTestCase.fail("Not initialized");
- }
- if (mContentValuesVerifier == null) {
- mContentValuesVerifier = new ContentValuesVerifier();
- }
-
- return mContentValuesVerifier.addElem(mTestCase);
- }
-
- private void verifyOneVCard(final String vcard) {
- // Log.d("@@@", vcard);
- final VCardInterpreter builder;
- if (mContentValuesVerifier != null) {
- final VNodeBuilder vnodeBuilder = mPropertyNodesVerifier;
- final VCardEntryConstructor vcardDataBuilder =
- new VCardEntryConstructor(mVCardType);
- vcardDataBuilder.addEntryHandler(mContentValuesVerifier);
- if (mPropertyNodesVerifier != null) {
- builder = new VCardInterpreterCollection(Arrays.asList(
- mPropertyNodesVerifier, vcardDataBuilder));
- } else {
- builder = vnodeBuilder;
- }
- } else {
- if (mPropertyNodesVerifier != null) {
- builder = mPropertyNodesVerifier;
- } else {
- return;
- }
- }
-
- final VCardParser parser =
- (mIsV30 ? new VCardParser_V30(true) : new VCardParser_V21());
- InputStream is = null;
- try {
- String charset =
- (VCardConfig.usesShiftJis(mVCardType) ? "SHIFT_JIS" : "UTF-8");
- is = new ByteArrayInputStream(vcard.getBytes(charset));
- mTestCase.assertEquals(true, parser.parse(is, null, builder));
- } catch (IOException e) {
- mTestCase.fail("Unexpected IOException: " + e.getMessage());
- } catch (VCardException e) {
- mTestCase.fail("Unexpected VCardException: " + e.getMessage());
- } finally {
- if (is != null) {
- try {
- is.close();
- } catch (IOException e) {
- }
- }
- }
- }
-
- public void verify() {
- if (!mInitialized) {
- mTestCase.fail("Not initialized.");
- }
- if (mVerified) {
- mTestCase.fail("verify() was called twice.");
- }
- if (mInputStream != null) {
- try {
- verifyForImportTest();
- } catch (IOException e) {
- mTestCase.fail("IOException was thrown: " + e.getMessage());
- } catch (VCardException e) {
- mTestCase.fail("VCardException was thrown: " + e.getMessage());
- }
- } else if (mExportTestResolver != null){
- verifyForExportTest();
- } else {
- mTestCase.fail("No input is determined");
- }
- mVerified = true;
- }
-
- private void verifyForImportTest() throws IOException, VCardException {
- if (mLineVerifier != null) {
- mTestCase.fail("Not supported now.");
- }
- if (mContentValuesVerifier != null) {
- mContentValuesVerifier.verify(mInputStream, mVCardType);
- }
- }
-
- public static EntityIterator mockGetEntityIteratorMethod(
- final ContentResolver resolver,
- final Uri uri, final String selection,
- final String[] selectionArgs, final String sortOrder) {
- final ContentProvider provider =
- resolver.acquireContentProviderClient(uri).getLocalContentProvider();
- return ((ExportTestProvider)provider).queryEntities(
- uri, selection, selectionArgs, sortOrder);
- }
-
- private Method getMockGetEntityIteratorMethod()
- throws SecurityException, NoSuchMethodException {
- return this.getClass().getMethod("mockGetEntityIteratorMethod",
- ContentResolver.class, Uri.class, String.class, String[].class, String.class);
- }
-
- private void verifyForExportTest() {
- final VCardComposer composer =
- new VCardComposer(new CustomMockContext(mExportTestResolver), mVCardType);
- composer.addHandler(mLineVerifier);
- composer.addHandler(mVCardVerifierInternal);
- if (!composer.init(VCardComposer.CONTACTS_TEST_CONTENT_URI, null, null, null)) {
- mTestCase.fail("init() failed. Reason: " + composer.getErrorReason());
- }
- mTestCase.assertFalse(composer.isAfterLast());
- try {
- while (!composer.isAfterLast()) {
- try {
- final Method mockGetEntityIteratorMethod = getMockGetEntityIteratorMethod();
- mTestCase.assertTrue(
- composer.createOneEntry(getMockGetEntityIteratorMethod()));
- } catch (Exception e) {
- e.printStackTrace();
- mTestCase.fail();
- }
- }
- } finally {
- composer.terminate();
- }
- }
-}
diff --git a/core/tests/coretests/src/android/pim/vcard/test_utils/ContactEntry.java b/core/tests/coretests/src/android/pim/vcard/test_utils/ContactEntry.java
new file mode 100644
index 000000000000..843750e789b3
--- /dev/null
+++ b/core/tests/coretests/src/android/pim/vcard/test_utils/ContactEntry.java
@@ -0,0 +1,43 @@
+/*
+ * Copyright (C) 2010 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not
+ * use this file except in compliance with the License. You may obtain a copy of
+ * the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations under
+ * the License.
+ */
+package android.pim.vcard.test_utils;
+
+import android.content.ContentValues;
+import android.provider.ContactsContract.Data;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * <p>
+ * The class representing one contact, which should contain multiple ContentValues like
+ * StructuredName, Email, etc.
+ * </p>
+ */
+public final class ContactEntry {
+ private final List<ContentValues> mContentValuesList = new ArrayList<ContentValues>();
+
+ public ContentValuesBuilder addContentValues(String mimeType) {
+ ContentValues contentValues = new ContentValues();
+ contentValues.put(Data.MIMETYPE, mimeType);
+ mContentValuesList.add(contentValues);
+ return new ContentValuesBuilder(contentValues);
+ }
+
+ public List<ContentValues> getList() {
+ return mContentValuesList;
+ }
+} \ No newline at end of file
diff --git a/core/tests/coretests/src/android/pim/vcard/ContentValuesBuilder.java b/core/tests/coretests/src/android/pim/vcard/test_utils/ContentValuesBuilder.java
index b3c0773903fa..bdcccf98e6d9 100644
--- a/core/tests/coretests/src/android/pim/vcard/ContentValuesBuilder.java
+++ b/core/tests/coretests/src/android/pim/vcard/test_utils/ContentValuesBuilder.java
@@ -13,8 +13,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-
-package android.pim.vcard;
+package android.pim.vcard.test_utils;
import android.content.ContentValues;
@@ -22,7 +21,7 @@ import android.content.ContentValues;
* ContentValues-like class which enables users to chain put() methods and restricts
* the other methods.
*/
-/* package */ class ContentValuesBuilder {
+public class ContentValuesBuilder {
private final ContentValues mContentValues;
public ContentValuesBuilder(final ContentValues contentValues) {
@@ -34,6 +33,7 @@ import android.content.ContentValues;
return this;
}
+ /*
public ContentValuesBuilder put(String key, Byte value) {
mContentValues.put(key, value);
return this;
@@ -42,13 +42,14 @@ import android.content.ContentValues;
public ContentValuesBuilder put(String key, Short value) {
mContentValues.put(key, value);
return this;
- }
+ }*/
public ContentValuesBuilder put(String key, Integer value) {
mContentValues.put(key, value);
return this;
}
+ /*
public ContentValuesBuilder put(String key, Long value) {
mContentValues.put(key, value);
return this;
@@ -67,7 +68,7 @@ import android.content.ContentValues;
public ContentValuesBuilder put(String key, Boolean value) {
mContentValues.put(key, value);
return this;
- }
+ }*/
public ContentValuesBuilder put(String key, byte[] value) {
mContentValues.put(key, value);
diff --git a/core/tests/coretests/src/android/pim/vcard/test_utils/ContentValuesVerifier.java b/core/tests/coretests/src/android/pim/vcard/test_utils/ContentValuesVerifier.java
new file mode 100644
index 000000000000..d0613c65c256
--- /dev/null
+++ b/core/tests/coretests/src/android/pim/vcard/test_utils/ContentValuesVerifier.java
@@ -0,0 +1,54 @@
+/*
+ * 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.pim.vcard.test_utils;
+
+import android.pim.vcard.VCardEntry;
+import android.pim.vcard.VCardEntryHandler;
+import android.test.AndroidTestCase;
+
+import java.util.ArrayList;
+import java.util.List;
+
+public class ContentValuesVerifier implements VCardEntryHandler {
+ private List<ContentValuesVerifierElem> mContentValuesVerifierElemList =
+ new ArrayList<ContentValuesVerifierElem>();
+ private int mIndex;
+
+ public ContentValuesVerifierElem addElem(AndroidTestCase androidTestCase) {
+ ContentValuesVerifierElem elem = new ContentValuesVerifierElem(androidTestCase);
+ mContentValuesVerifierElemList.add(elem);
+ return elem;
+ }
+
+ public void onStart() {
+ for (ContentValuesVerifierElem elem : mContentValuesVerifierElemList) {
+ elem.onParsingStart();
+ }
+ }
+
+ public void onEntryCreated(VCardEntry entry) {
+ AndroidTestCase.assertTrue(mIndex < mContentValuesVerifierElemList.size());
+ mContentValuesVerifierElemList.get(mIndex).onEntryCreated(entry);
+ mIndex++;
+ }
+
+ public void onEnd() {
+ for (ContentValuesVerifierElem elem : mContentValuesVerifierElemList) {
+ elem.onParsingEnd();
+ elem.verifyResolver();
+ }
+ }
+}
diff --git a/core/tests/coretests/src/android/pim/vcard/ContentValuesVerifierElem.java b/core/tests/coretests/src/android/pim/vcard/test_utils/ContentValuesVerifierElem.java
index 2edbb36d4220..03c18e1f0c69 100644
--- a/core/tests/coretests/src/android/pim/vcard/ContentValuesVerifierElem.java
+++ b/core/tests/coretests/src/android/pim/vcard/test_utils/ContentValuesVerifierElem.java
@@ -13,17 +13,15 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-package android.pim.vcard;
+package android.pim.vcard.test_utils;
import android.content.ContentValues;
-import android.pim.vcard.VCardConfig;
import android.pim.vcard.VCardEntry;
import android.pim.vcard.VCardEntryCommitter;
import android.pim.vcard.VCardEntryConstructor;
import android.pim.vcard.VCardEntryHandler;
import android.pim.vcard.VCardParser;
-import android.pim.vcard.VCardParser_V21;
-import android.pim.vcard.VCardParser_V30;
+import android.pim.vcard.VCardUtils;
import android.pim.vcard.exception.VCardException;
import android.provider.ContactsContract.Data;
import android.test.AndroidTestCase;
@@ -31,7 +29,7 @@ import android.test.AndroidTestCase;
import java.io.IOException;
import java.io.InputStream;
-/* package */ class ContentValuesVerifierElem {
+public class ContentValuesVerifierElem {
private final AndroidTestCase mTestCase;
private final ImportTestResolver mResolver;
private final VCardEntryHandler mHandler;
@@ -49,20 +47,14 @@ import java.io.InputStream;
return new ContentValuesBuilder(contentValues);
}
- public void verify(int resId, int vCardType)
+ public void verify(int resId, int vcardType)
throws IOException, VCardException {
- verify(mTestCase.getContext().getResources().openRawResource(resId), vCardType);
+ verify(mTestCase.getContext().getResources().openRawResource(resId), vcardType);
}
- public void verify(InputStream is, int vCardType) throws IOException, VCardException {
- final VCardParser vCardParser;
- if (VCardConfig.isV30(vCardType)) {
- vCardParser = new VCardParser_V30(true); // use StrictParsing
- } else {
- vCardParser = new VCardParser_V21();
- }
- VCardEntryConstructor builder =
- new VCardEntryConstructor(null, null, false, vCardType, null);
+ public void verify(InputStream is, int vcardType) throws IOException, VCardException {
+ final VCardParser vCardParser = VCardUtils.getAppropriateParser(vcardType);
+ final VCardEntryConstructor builder = new VCardEntryConstructor(vcardType, null);
builder.addEntryHandler(mHandler);
try {
vCardParser.parse(is, builder);
diff --git a/core/tests/coretests/src/android/pim/vcard/ExportTestResolver.java b/core/tests/coretests/src/android/pim/vcard/test_utils/ExportTestProvider.java
index 5968e83647d1..e095258ff592 100644
--- a/core/tests/coretests/src/android/pim/vcard/ExportTestResolver.java
+++ b/core/tests/coretests/src/android/pim/vcard/test_utils/ExportTestProvider.java
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2009 The Android Open Source Project
+ * Copyright (C) 2010 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
* use this file except in compliance with the License. You may obtain a copy of
@@ -13,7 +13,7 @@
* License for the specific language governing permissions and limitations under
* the License.
*/
-package android.pim.vcard;
+package android.pim.vcard.test_utils;
import android.content.ContentResolver;
import android.content.ContentValues;
@@ -21,10 +21,12 @@ import android.content.Entity;
import android.content.EntityIterator;
import android.database.Cursor;
import android.net.Uri;
+import android.pim.vcard.VCardComposer;
import android.provider.ContactsContract.Contacts;
import android.provider.ContactsContract.Data;
import android.provider.ContactsContract.RawContacts;
-import android.test.mock.MockContentResolver;
+import android.test.AndroidTestCase;
+import android.test.mock.MockContentProvider;
import android.test.mock.MockCursor;
import junit.framework.TestCase;
@@ -33,78 +35,44 @@ import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
-/* package */ public class ExportTestResolver extends MockContentResolver {
- ExportTestProvider mProvider;
- public ExportTestResolver(TestCase testCase) {
- mProvider = new ExportTestProvider(testCase);
- addProvider(VCardComposer.VCARD_TEST_AUTHORITY, mProvider);
- addProvider(RawContacts.CONTENT_URI.getAuthority(), mProvider);
- }
-
- public ContactEntry addInputContactEntry() {
- return mProvider.buildInputEntry();
- }
-}
+public class ExportTestProvider extends MockContentProvider {
+ final private ArrayList<ContactEntry> mContactEntryList = new ArrayList<ContactEntry>();
-/* package */ class MockEntityIterator implements EntityIterator {
- List<Entity> mEntityList;
- Iterator<Entity> mIterator;
+ private static class MockEntityIterator implements EntityIterator {
+ List<Entity> mEntityList;
+ Iterator<Entity> mIterator;
- public MockEntityIterator(List<ContentValues> contentValuesList) {
- mEntityList = new ArrayList<Entity>();
- Entity entity = new Entity(new ContentValues());
- for (ContentValues contentValues : contentValuesList) {
- entity.addSubValue(Data.CONTENT_URI, contentValues);
+ public MockEntityIterator(List<ContentValues> contentValuesList) {
+ mEntityList = new ArrayList<Entity>();
+ Entity entity = new Entity(new ContentValues());
+ for (ContentValues contentValues : contentValuesList) {
+ entity.addSubValue(Data.CONTENT_URI, contentValues);
+ }
+ mEntityList.add(entity);
+ mIterator = mEntityList.iterator();
}
- mEntityList.add(entity);
- mIterator = mEntityList.iterator();
- }
- public boolean hasNext() {
- return mIterator.hasNext();
- }
-
- public Entity next() {
- return mIterator.next();
- }
-
- public void remove() {
- throw new UnsupportedOperationException("remove not supported");
- }
+ public boolean hasNext() {
+ return mIterator.hasNext();
+ }
- public void reset() {
- mIterator = mEntityList.iterator();
- }
+ public Entity next() {
+ return mIterator.next();
+ }
- public void close() {
- }
-}
+ public void remove() {
+ throw new UnsupportedOperationException("remove not supported");
+ }
-/**
- * Represents one contact, which should contain multiple ContentValues like
- * StructuredName, Email, etc.
- */
-/* package */ class ContactEntry {
- private final List<ContentValues> mContentValuesList = new ArrayList<ContentValues>();
-
- public ContentValuesBuilder addContentValues(String mimeType) {
- ContentValues contentValues = new ContentValues();
- contentValues.put(Data.MIMETYPE, mimeType);
- mContentValuesList.add(contentValues);
- return new ContentValuesBuilder(contentValues);
- }
+ public void reset() {
+ mIterator = mEntityList.iterator();
+ }
- public List<ContentValues> getList() {
- return mContentValuesList;
+ public void close() {
+ }
}
-}
-
-/* package */ class ExportTestProvider extends MockContentProvider {
- final private TestCase mTestCase;
- final private ArrayList<ContactEntry> mContactEntryList = new ArrayList<ContactEntry>();
- public ExportTestProvider(TestCase testCase) {
- mTestCase = testCase;
+ public ExportTestProvider(AndroidTestCase androidTestCase) {
}
public ContactEntry buildInputEntry() {
@@ -121,27 +89,17 @@ import java.util.List;
* We still keep using this method since we don't have a propeer way to know
* which value in the ContentValue corresponds to the entry in Contacts database.
* </p>
- * <p>
- * Detail:
- * There's an easy way to know which index "family name" corresponds to, via
- * {@link android.provider.ContactsContract}.
- * FAMILY_NAME equals DATA3, so the corresponding index
- * for "family name" should be 2 (note that index is 0-origin).
- * However, we cannot know what the index 2 corresponds to; it may be "family name",
- * "label" for now, but may be the other some column in the future. We don't have
- * convenient way to know the original data structure.
- * </p>
*/
public EntityIterator queryEntities(Uri uri,
String selection, String[] selectionArgs, String sortOrder) {
- mTestCase.assertTrue(uri != null);
- mTestCase.assertTrue(ContentResolver.SCHEME_CONTENT.equals(uri.getScheme()));
+ TestCase.assertTrue(uri != null);
+ TestCase.assertTrue(ContentResolver.SCHEME_CONTENT.equals(uri.getScheme()));
final String authority = uri.getAuthority();
- mTestCase.assertTrue(RawContacts.CONTENT_URI.getAuthority().equals(authority));
- mTestCase.assertTrue((Data.CONTACT_ID + "=?").equals(selection));
- mTestCase.assertEquals(1, selectionArgs.length);
+ TestCase.assertTrue(RawContacts.CONTENT_URI.getAuthority().equals(authority));
+ TestCase.assertTrue((Data.CONTACT_ID + "=?").equals(selection));
+ TestCase.assertEquals(1, selectionArgs.length);
final int id = Integer.parseInt(selectionArgs[0]);
- mTestCase.assertTrue(id >= 0 && id < mContactEntryList.size());
+ TestCase.assertTrue(id >= 0 && id < mContactEntryList.size());
return new MockEntityIterator(mContactEntryList.get(id).getList());
}
@@ -149,11 +107,11 @@ import java.util.List;
@Override
public Cursor query(Uri uri,String[] projection,
String selection, String[] selectionArgs, String sortOrder) {
- mTestCase.assertTrue(VCardComposer.CONTACTS_TEST_CONTENT_URI.equals(uri));
+ TestCase.assertTrue(VCardComposer.CONTACTS_TEST_CONTENT_URI.equals(uri));
// In this test, following arguments are not supported.
- mTestCase.assertNull(selection);
- mTestCase.assertNull(selectionArgs);
- mTestCase.assertNull(sortOrder);
+ TestCase.assertNull(selection);
+ TestCase.assertNull(selectionArgs);
+ TestCase.assertNull(sortOrder);
return new MockCursor() {
int mCurrentPosition = -1;
@@ -191,14 +149,14 @@ import java.util.List;
@Override
public int getColumnIndex(String columnName) {
- mTestCase.assertEquals(Contacts._ID, columnName);
+ TestCase.assertEquals(Contacts._ID, columnName);
return 0;
}
@Override
public int getInt(int columnIndex) {
- mTestCase.assertEquals(0, columnIndex);
- mTestCase.assertTrue(mCurrentPosition >= 0
+ TestCase.assertEquals(0, columnIndex);
+ TestCase.assertTrue(mCurrentPosition >= 0
&& mCurrentPosition < mContactEntryList.size());
return mCurrentPosition;
}
@@ -213,4 +171,4 @@ import java.util.List;
}
};
}
-}
+} \ No newline at end of file
diff --git a/core/tests/coretests/src/android/pim/vcard/test_utils/ExportTestResolver.java b/core/tests/coretests/src/android/pim/vcard/test_utils/ExportTestResolver.java
new file mode 100644
index 000000000000..606d91afaa34
--- /dev/null
+++ b/core/tests/coretests/src/android/pim/vcard/test_utils/ExportTestResolver.java
@@ -0,0 +1,38 @@
+/*
+ * 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.pim.vcard.test_utils;
+
+import android.pim.vcard.VCardComposer;
+import android.provider.ContactsContract.RawContacts;
+import android.test.AndroidTestCase;
+import android.test.mock.MockContentResolver;
+
+public class ExportTestResolver extends MockContentResolver {
+ private final ExportTestProvider mProvider;
+ public ExportTestResolver(AndroidTestCase androidTestCase) {
+ mProvider = new ExportTestProvider(androidTestCase);
+ addProvider(VCardComposer.VCARD_TEST_AUTHORITY, mProvider);
+ addProvider(RawContacts.CONTENT_URI.getAuthority(), mProvider);
+ }
+
+ public ContactEntry addInputContactEntry() {
+ return mProvider.buildInputEntry();
+ }
+
+ public ExportTestProvider getProvider() {
+ return mProvider;
+ }
+}
diff --git a/core/tests/coretests/src/android/pim/vcard/ImportTestResolver.java b/core/tests/coretests/src/android/pim/vcard/test_utils/ImportTestProvider.java
index c3f6f798ba7c..df89491afab5 100644
--- a/core/tests/coretests/src/android/pim/vcard/ImportTestResolver.java
+++ b/core/tests/coretests/src/android/pim/vcard/test_utils/ImportTestProvider.java
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2009 The Android Open Source Project
+ * Copyright (C) 2010 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -13,14 +13,12 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-package android.pim.vcard;
+package android.pim.vcard.test_utils;
import android.content.ContentProviderOperation;
import android.content.ContentProviderResult;
import android.content.ContentValues;
import android.net.Uri;
-import android.provider.ContactsContract.Data;
-import android.provider.ContactsContract.RawContacts;
import android.provider.ContactsContract.CommonDataKinds.Email;
import android.provider.ContactsContract.CommonDataKinds.Event;
import android.provider.ContactsContract.CommonDataKinds.GroupMembership;
@@ -34,7 +32,10 @@ import android.provider.ContactsContract.CommonDataKinds.Relation;
import android.provider.ContactsContract.CommonDataKinds.StructuredName;
import android.provider.ContactsContract.CommonDataKinds.StructuredPostal;
import android.provider.ContactsContract.CommonDataKinds.Website;
-import android.test.mock.MockContentResolver;
+import android.provider.ContactsContract.Data;
+import android.provider.ContactsContract.RawContacts;
+import android.test.AndroidTestCase;
+import android.test.mock.MockContentProvider;
import android.text.TextUtils;
import junit.framework.TestCase;
@@ -45,43 +46,12 @@ import java.util.Collection;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
+import java.util.Map.Entry;
import java.util.Set;
import java.util.SortedMap;
import java.util.TreeMap;
-import java.util.Map.Entry;
-
-/* package */ class ImportTestResolver extends MockContentResolver {
- final ImportTestProvider mProvider;
-
- public ImportTestResolver(TestCase testCase) {
- mProvider = new ImportTestProvider(testCase);
- }
-
- @Override
- public ContentProviderResult[] applyBatch(String authority,
- ArrayList<ContentProviderOperation> operations) {
- equalsString(authority, RawContacts.CONTENT_URI.toString());
- return mProvider.applyBatch(operations);
- }
- public void addExpectedContentValues(ContentValues expectedContentValues) {
- mProvider.addExpectedContentValues(expectedContentValues);
- }
-
- public void verify() {
- mProvider.verify();
- }
-
- private static boolean equalsString(String a, String b) {
- if (a == null || a.length() == 0) {
- return b == null || b.length() == 0;
- } else {
- return a.equals(b);
- }
- }
-}
-
-/* package */ class ImportTestProvider extends MockContentProvider {
+public class ImportTestProvider extends MockContentProvider {
private static final Set<String> sKnownMimeTypeSet =
new HashSet<String>(Arrays.asList(StructuredName.CONTENT_ITEM_TYPE,
Nickname.CONTENT_ITEM_TYPE, Phone.CONTENT_ITEM_TYPE,
@@ -94,10 +64,7 @@ import java.util.Map.Entry;
final Map<String, Collection<ContentValues>> mMimeTypeToExpectedContentValues;
- private final TestCase mTestCase;
-
- public ImportTestProvider(TestCase testCase) {
- mTestCase = testCase;
+ public ImportTestProvider(AndroidTestCase androidTestCase) {
mMimeTypeToExpectedContentValues =
new HashMap<String, Collection<ContentValues>>();
for (String acceptanbleMimeType : sKnownMimeTypeSet) {
@@ -112,7 +79,7 @@ import java.util.Map.Entry;
public void addExpectedContentValues(ContentValues expectedContentValues) {
final String mimeType = expectedContentValues.getAsString(Data.MIMETYPE);
if (!sKnownMimeTypeSet.contains(mimeType)) {
- mTestCase.fail(String.format(
+ TestCase.fail(String.format(
"Unknow MimeType %s in the test code. Test code should be broken.",
mimeType));
}
@@ -126,7 +93,7 @@ import java.util.Map.Entry;
public ContentProviderResult[] applyBatch(
ArrayList<ContentProviderOperation> operations) {
if (operations == null) {
- mTestCase.fail("There is no operation.");
+ TestCase.fail("There is no operation.");
}
final int size = operations.size();
@@ -147,12 +114,12 @@ import java.util.Map.Entry;
fakeResultArray, i);
final Uri uri = operation.getUri();
if (uri.equals(RawContacts.CONTENT_URI)) {
- mTestCase.assertNull(actualContentValues.get(RawContacts.ACCOUNT_NAME));
- mTestCase.assertNull(actualContentValues.get(RawContacts.ACCOUNT_TYPE));
+ TestCase.assertNull(actualContentValues.get(RawContacts.ACCOUNT_NAME));
+ TestCase.assertNull(actualContentValues.get(RawContacts.ACCOUNT_TYPE));
} else if (uri.equals(Data.CONTENT_URI)) {
final String mimeType = actualContentValues.getAsString(Data.MIMETYPE);
if (!sKnownMimeTypeSet.contains(mimeType)) {
- mTestCase.fail(String.format(
+ TestCase.fail(String.format(
"Unknown MimeType %s. Probably added after developing this test",
mimeType));
}
@@ -184,7 +151,7 @@ import java.util.Map.Entry;
final Collection<ContentValues> contentValuesCollection =
mMimeTypeToExpectedContentValues.get(mimeType);
if (contentValuesCollection.isEmpty()) {
- mTestCase.fail("ContentValues for MimeType " + mimeType
+ TestCase.fail("ContentValues for MimeType " + mimeType
+ " is not expected at all (" + actualContentValues + ")");
}
boolean checked = false;
@@ -196,23 +163,25 @@ import java.util.Map.Entry;
+ convertToEasilyReadableString(actualContentValues));*/
if (equalsForContentValues(expectedContentValues,
actualContentValues)) {
- mTestCase.assertTrue(contentValuesCollection.remove(expectedContentValues));
+ TestCase.assertTrue(contentValuesCollection.remove(expectedContentValues));
checked = true;
break;
}
}
if (!checked) {
final StringBuilder builder = new StringBuilder();
+ builder.append("\n");
builder.append("Unexpected: ");
builder.append(convertToEasilyReadableString(actualContentValues));
- builder.append("\nExpected: ");
+ builder.append("\n");
+ builder.append("Expected : ");
for (ContentValues expectedContentValues : contentValuesCollection) {
builder.append(convertToEasilyReadableString(expectedContentValues));
}
- mTestCase.fail(builder.toString());
+ TestCase.fail(builder.toString());
}
} else {
- mTestCase.fail("Unexpected Uri has come: " + uri);
+ TestCase.fail("Unexpected Uri has come: " + uri);
}
} // for (int i = 0; i < size; i++) {
return fakeResultArray;
@@ -231,7 +200,7 @@ import java.util.Map.Entry;
final String failMsg =
"There is(are) remaining expected ContentValues instance(s): \n"
+ builder.toString();
- mTestCase.fail(failMsg);
+ TestCase.fail(failMsg);
}
}
@@ -251,7 +220,7 @@ import java.util.Map.Entry;
if (Data.MIMETYPE.equals(key)) {
mimeTypeValue = valueString;
} else {
- mTestCase.assertNotNull(key);
+ TestCase.assertNotNull(key);
sortedMap.put(key, valueString);
}
}
@@ -272,7 +241,7 @@ import java.util.Map.Entry;
}
private static boolean equalsForContentValues(
- ContentValues expected, ContentValues actual) {
+ final ContentValues expected, final ContentValues actual) {
if (expected == actual) {
return true;
} else if (expected == null || actual == null || expected.size() != actual.size()) {
@@ -285,15 +254,21 @@ import java.util.Map.Entry;
if (!actual.containsKey(key)) {
return false;
}
+ // Type mismatch usuall happens as importer doesn't care the type of each value.
+ // For example, variable type might be Integer when importing the type of TEL,
+ // while variable type would be String when importing the type of RELATION.
+ final Object actualValue = actual.get(key);
if (value instanceof byte[]) {
- Object actualValue = actual.get(key);
if (!Arrays.equals((byte[])value, (byte[])actualValue)) {
+ byte[] e = (byte[])value;
+ byte[] a = (byte[])actualValue;
return false;
}
- } else if (!value.equals(actual.get(key))) {
- return false;
+ } else if (!value.equals(actualValue) &&
+ !value.toString().equals(actualValue.toString())) {
+ return false;
}
}
return true;
}
-}
+} \ No newline at end of file
diff --git a/core/tests/coretests/src/android/pim/vcard/test_utils/ImportTestResolver.java b/core/tests/coretests/src/android/pim/vcard/test_utils/ImportTestResolver.java
new file mode 100644
index 000000000000..1822afefe71f
--- /dev/null
+++ b/core/tests/coretests/src/android/pim/vcard/test_utils/ImportTestResolver.java
@@ -0,0 +1,56 @@
+/*
+ * 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.pim.vcard.test_utils;
+
+import android.content.ContentProviderOperation;
+import android.content.ContentProviderResult;
+import android.content.ContentValues;
+import android.provider.ContactsContract.RawContacts;
+import android.test.AndroidTestCase;
+import android.test.mock.MockContentResolver;
+
+import java.util.ArrayList;
+
+public class ImportTestResolver extends MockContentResolver {
+ private final ImportTestProvider mProvider;
+
+ public ImportTestResolver(AndroidTestCase androidTestCase) {
+ mProvider = new ImportTestProvider(androidTestCase);
+ }
+
+ @Override
+ public ContentProviderResult[] applyBatch(String authority,
+ ArrayList<ContentProviderOperation> operations) {
+ equalsString(authority, RawContacts.CONTENT_URI.toString());
+ return mProvider.applyBatch(operations);
+ }
+
+ public void addExpectedContentValues(ContentValues expectedContentValues) {
+ mProvider.addExpectedContentValues(expectedContentValues);
+ }
+
+ public void verify() {
+ mProvider.verify();
+ }
+
+ private static boolean equalsString(String a, String b) {
+ if (a == null || a.length() == 0) {
+ return b == null || b.length() == 0;
+ } else {
+ return a.equals(b);
+ }
+ }
+}
diff --git a/core/tests/coretests/src/android/pim/vcard/LineVerifier.java b/core/tests/coretests/src/android/pim/vcard/test_utils/LineVerifier.java
index cef15fd762c0..e314ac5798b1 100644
--- a/core/tests/coretests/src/android/pim/vcard/LineVerifier.java
+++ b/core/tests/coretests/src/android/pim/vcard/test_utils/LineVerifier.java
@@ -13,39 +13,40 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-package android.pim.vcard;
+package android.pim.vcard.test_utils;
import android.content.Context;
import android.pim.vcard.VCardComposer;
+import android.test.AndroidTestCase;
import junit.framework.TestCase;
import java.util.ArrayList;
-class LineVerifier implements VCardComposer.OneEntryHandler {
- private final TestCase mTestCase;
+public class LineVerifier implements VCardComposer.OneEntryHandler {
+ private final AndroidTestCase mAndroidTestCase;
private final ArrayList<LineVerifierElem> mLineVerifierElemList;
private int mVCardType;
private int index;
- public LineVerifier(TestCase testCase, int vcardType) {
- mTestCase = testCase;
+ public LineVerifier(AndroidTestCase androidTestCase, int vcardType) {
+ mAndroidTestCase = androidTestCase;
mLineVerifierElemList = new ArrayList<LineVerifierElem>();
mVCardType = vcardType;
}
public LineVerifierElem addLineVerifierElem() {
- LineVerifierElem lineVerifier = new LineVerifierElem(mTestCase, mVCardType);
+ LineVerifierElem lineVerifier = new LineVerifierElem(mAndroidTestCase, mVCardType);
mLineVerifierElemList.add(lineVerifier);
return lineVerifier;
}
public void verify(String vcard) {
if (index >= mLineVerifierElemList.size()) {
- mTestCase.fail("Insufficient number of LineVerifier (" + index + ")");
+ TestCase.fail("Insufficient number of LineVerifier (" + index + ")");
}
- LineVerifierElem lineVerifier = mLineVerifierElemList.get(index);
+ final LineVerifierElem lineVerifier = mLineVerifierElemList.get(index);
lineVerifier.verify(vcard);
index++;
diff --git a/core/tests/coretests/src/android/pim/vcard/LineVerifierElem.java b/core/tests/coretests/src/android/pim/vcard/test_utils/LineVerifierElem.java
index b23b29be8a6a..e23a9cded618 100644
--- a/core/tests/coretests/src/android/pim/vcard/LineVerifierElem.java
+++ b/core/tests/coretests/src/android/pim/vcard/test_utils/LineVerifierElem.java
@@ -13,9 +13,10 @@
* License for the specific language governing permissions and limitations under
* the License.
*/
-package android.pim.vcard;
+package android.pim.vcard.test_utils;
import android.pim.vcard.VCardConfig;
+import android.test.AndroidTestCase;
import android.text.TextUtils;
import junit.framework.TestCase;
@@ -23,14 +24,12 @@ import junit.framework.TestCase;
import java.util.ArrayList;
import java.util.List;
-class LineVerifierElem {
- private final TestCase mTestCase;
+public class LineVerifierElem {
private final List<String> mExpectedLineList = new ArrayList<String>();
- private final boolean mIsV30;
+ private final int mVCardType;
- public LineVerifierElem(TestCase testCase, int vcardType) {
- mTestCase = testCase;
- mIsV30 = VCardConfig.isV30(vcardType);
+ public LineVerifierElem(AndroidTestCase androidTestCase, int vcardType) {
+ mVCardType = vcardType;
}
public LineVerifierElem addExpected(final String line) {
@@ -55,21 +54,23 @@ class LineVerifierElem {
if ("BEGIN:VCARD".equalsIgnoreCase(line)) {
if (beginExists) {
- mTestCase.fail("Multiple \"BEGIN:VCARD\" line found");
+ TestCase.fail("Multiple \"BEGIN:VCARD\" line found");
} else {
beginExists = true;
continue;
}
} else if ("END:VCARD".equalsIgnoreCase(line)) {
if (endExists) {
- mTestCase.fail("Multiple \"END:VCARD\" line found");
+ TestCase.fail("Multiple \"END:VCARD\" line found");
} else {
endExists = true;
continue;
}
- } else if ((mIsV30 ? "VERSION:3.0" : "VERSION:2.1").equalsIgnoreCase(line)) {
+ } else if ((VCardConfig.isVersion21(mVCardType) ? "VERSION:2.1" :
+ (VCardConfig.isVersion30(mVCardType) ? "VERSION:3.0" :
+ "VERSION:4.0")).equalsIgnoreCase(line)) {
if (versionExists) {
- mTestCase.fail("Multiple VERSION line + found");
+ TestCase.fail("Multiple VERSION line + found");
} else {
versionExists = true;
continue;
@@ -77,18 +78,16 @@ class LineVerifierElem {
}
if (!beginExists) {
- mTestCase.fail("Property other than BEGIN came before BEGIN property: "
- + line);
+ TestCase.fail("Property other than BEGIN came before BEGIN property: " + line);
} else if (endExists) {
- mTestCase.fail("Property other than END came after END property: "
- + line);
+ TestCase.fail("Property other than END came after END property: " + line);
}
final int index = mExpectedLineList.indexOf(line);
if (index >= 0) {
mExpectedLineList.remove(index);
} else {
- mTestCase.fail("Unexpected line: " + line);
+ TestCase.fail("Unexpected line: " + line);
}
}
@@ -99,7 +98,7 @@ class LineVerifierElem {
buffer.append("\n");
}
- mTestCase.fail("Expected line(s) not found:" + buffer.toString());
+ TestCase.fail("Expected line(s) not found:" + buffer.toString());
}
}
}
diff --git a/core/tests/coretests/src/android/pim/vcard/PropertyNode.java b/core/tests/coretests/src/android/pim/vcard/test_utils/PropertyNode.java
index 2c1f6d28de98..de7ad8eaa64e 100644
--- a/core/tests/coretests/src/android/pim/vcard/PropertyNode.java
+++ b/core/tests/coretests/src/android/pim/vcard/test_utils/PropertyNode.java
@@ -13,11 +13,10 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-package android.pim.vcard;
+package android.pim.vcard.test_utils;
import android.content.ContentValues;
import android.pim.vcard.VCardEntry;
-import android.util.Log;
import java.util.ArrayList;
import java.util.Arrays;
@@ -26,12 +25,18 @@ import java.util.List;
import java.util.Set;
/**
+ * <p>
+ * The class representing one property (e.g. "N;ENCODING=UTF-8:family:given:middle:prefix:suffix").
+ * </p>
+ * <p>
* Previously used in main vCard handling code but now exists only for testing.
- *
+ * </p>
+ * <p>
* Especially useful for testing parser code (VCardParser), since all properties can be
* checked via this class unlike {@link VCardEntry}, which only emits the result of
* interpretation of the content of each vCard. We cannot know whether vCard parser or
- * ContactStruct is wrong withouth this class.
+ * {@link VCardEntry} is wrong without this class.
+ * </p>
*/
public class PropertyNode {
public String propName;
@@ -43,7 +48,8 @@ public class PropertyNode {
*/
public byte[] propValue_bytes;
- /** param store: key=paramType, value=paramValue
+ /**
+ * param store: key=paramType, value=paramValue
* Note that currently PropertyNode class does not support multiple param-values
* defined in vCard 3.0 (See also RFC 2426). multiple-values are stored as
* one String value like "A,B", not ["A", "B"]...
diff --git a/core/tests/coretests/src/android/pim/vcard/test_utils/PropertyNodesVerifier.java b/core/tests/coretests/src/android/pim/vcard/test_utils/PropertyNodesVerifier.java
new file mode 100644
index 000000000000..422928494594
--- /dev/null
+++ b/core/tests/coretests/src/android/pim/vcard/test_utils/PropertyNodesVerifier.java
@@ -0,0 +1,82 @@
+/*
+ * 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.pim.vcard.test_utils;
+
+import android.pim.vcard.VCardParser;
+import android.pim.vcard.VCardUtils;
+import android.pim.vcard.exception.VCardException;
+import android.test.AndroidTestCase;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.ArrayList;
+import java.util.List;
+
+public class PropertyNodesVerifier extends VNodeBuilder {
+ private final List<PropertyNodesVerifierElem> mPropertyNodesVerifierElemList;
+ private final AndroidTestCase mAndroidTestCase;
+ private int mIndex;
+
+ public PropertyNodesVerifier(AndroidTestCase testCase) {
+ super();
+ mPropertyNodesVerifierElemList = new ArrayList<PropertyNodesVerifierElem>();
+ mAndroidTestCase = testCase;
+ }
+
+ public PropertyNodesVerifierElem addPropertyNodesVerifierElem() {
+ PropertyNodesVerifierElem elem = new PropertyNodesVerifierElem(mAndroidTestCase);
+ mPropertyNodesVerifierElemList.add(elem);
+ return elem;
+ }
+
+ public void verify(int resId, int vcardType) throws IOException, VCardException {
+ verify(mAndroidTestCase.getContext().getResources().openRawResource(resId), vcardType);
+ }
+
+ public void verify(int resId, int vcardType, final VCardParser parser)
+ throws IOException, VCardException {
+ verify(mAndroidTestCase.getContext().getResources().openRawResource(resId),
+ vcardType, parser);
+ }
+
+ public void verify(InputStream is, int vcardType) throws IOException, VCardException {
+ final VCardParser parser = VCardUtils.getAppropriateParser(vcardType);
+ verify(is, vcardType, parser);
+ }
+
+ public void verify(InputStream is, int vcardType, final VCardParser parser)
+ throws IOException, VCardException {
+ try {
+ parser.parse(is, this);
+ } finally {
+ if (is != null) {
+ try {
+ is.close();
+ } catch (IOException e) {
+ }
+ }
+ }
+ }
+
+ @Override
+ public void endEntry() {
+ super.endEntry();
+ AndroidTestCase.assertTrue(mIndex < mPropertyNodesVerifierElemList.size());
+ AndroidTestCase.assertTrue(mIndex < vNodeList.size());
+ mPropertyNodesVerifierElemList.get(mIndex).verify(vNodeList.get(mIndex));
+ mIndex++;
+ }
+}
diff --git a/core/tests/coretests/src/android/pim/vcard/PropertyNodesVerifier.java b/core/tests/coretests/src/android/pim/vcard/test_utils/PropertyNodesVerifierElem.java
index cfdd0743fa5c..44c6abc9d0ae 100644
--- a/core/tests/coretests/src/android/pim/vcard/PropertyNodesVerifier.java
+++ b/core/tests/coretests/src/android/pim/vcard/test_utils/PropertyNodesVerifierElem.java
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2009 The Android Open Source Project
+ * Copyright (C) 2010 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -13,87 +13,19 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-package android.pim.vcard;
+package android.pim.vcard.test_utils;
import android.content.ContentValues;
-import android.pim.vcard.VCardConfig;
-import android.pim.vcard.VCardParser;
-import android.pim.vcard.VCardParser_V21;
-import android.pim.vcard.VCardParser_V30;
-import android.pim.vcard.exception.VCardException;
import android.test.AndroidTestCase;
import junit.framework.TestCase;
-import java.io.IOException;
-import java.io.InputStream;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
-/* package */ class PropertyNodesVerifier extends VNodeBuilder {
- private final List<PropertyNodesVerifierElem> mPropertyNodesVerifierElemList;
- private final AndroidTestCase mAndroidTestCase;
- private int mIndex;
-
- public PropertyNodesVerifier(AndroidTestCase testCase) {
- mPropertyNodesVerifierElemList = new ArrayList<PropertyNodesVerifierElem>();
- mAndroidTestCase = testCase;
- }
-
- public PropertyNodesVerifierElem addPropertyNodesVerifierElem() {
- PropertyNodesVerifierElem elem = new PropertyNodesVerifierElem(mAndroidTestCase);
- mPropertyNodesVerifierElemList.add(elem);
- return elem;
- }
-
- public void verify(int resId, int vCardType)
- throws IOException, VCardException {
- verify(mAndroidTestCase.getContext().getResources().openRawResource(resId), vCardType);
- }
-
- public void verify(int resId, int vCardType, final VCardParser vCardParser)
- throws IOException, VCardException {
- verify(mAndroidTestCase.getContext().getResources().openRawResource(resId),
- vCardType, vCardParser);
- }
-
- public void verify(InputStream is, int vCardType) throws IOException, VCardException {
- final VCardParser vCardParser;
- if (VCardConfig.isV30(vCardType)) {
- vCardParser = new VCardParser_V30(true); // Use StrictParsing.
- } else {
- vCardParser = new VCardParser_V21();
- }
- verify(is, vCardType, vCardParser);
- }
-
- public void verify(InputStream is, int vCardType, final VCardParser vCardParser)
- throws IOException, VCardException {
- try {
- vCardParser.parse(is, this);
- } finally {
- if (is != null) {
- try {
- is.close();
- } catch (IOException e) {
- }
- }
- }
- }
-
- @Override
- public void endEntry() {
- super.endEntry();
- mAndroidTestCase.assertTrue(mIndex < mPropertyNodesVerifierElemList.size());
- mAndroidTestCase.assertTrue(mIndex < vNodeList.size());
- mPropertyNodesVerifierElemList.get(mIndex).verify(vNodeList.get(mIndex));
- mIndex++;
- }
-}
-
/**
* Utility class which verifies input VNode.
*
@@ -102,7 +34,7 @@ import java.util.List;
* If the node does not exist in the "ordered list", the class refers to
* "unorderd expected property set" and checks the node is expected somewhere.
*/
-/* package */ class PropertyNodesVerifierElem {
+public class PropertyNodesVerifierElem {
public static class TypeSet extends HashSet<String> {
public TypeSet(String ... array) {
super(Arrays.asList(array));
@@ -119,12 +51,10 @@ import java.util.List;
// Intentionally use ArrayList instead of Set, assuming there may be more than one
// exactly same objects.
private final ArrayList<PropertyNode> mUnorderedNodeList;
- private final TestCase mTestCase;
- public PropertyNodesVerifierElem(TestCase testCase) {
+ public PropertyNodesVerifierElem(AndroidTestCase androidTestCase) {
mOrderedNodeMap = new HashMap<String, List<PropertyNode>>();
mUnorderedNodeList = new ArrayList<PropertyNode>();
- mTestCase = testCase;
}
// WithOrder
@@ -170,6 +100,12 @@ import java.util.List;
paramMap_TYPE, null);
}
+ public PropertyNodesVerifierElem addExpectedNodeWithOrder(String propName,
+ List<String> propValueList, ContentValues paramMap, TypeSet paramMap_TYPE) {
+ return addExpectedNodeWithOrder(propName, null, propValueList, null, paramMap,
+ paramMap_TYPE, null);
+ }
+
public PropertyNodesVerifierElem addExpectedNodeWithOrder(String propName, String propValue,
ContentValues paramMap, TypeSet paramMap_TYPE) {
return addExpectedNodeWithOrder(propName, propValue, null, null,
@@ -183,12 +119,18 @@ import java.util.List;
}
public PropertyNodesVerifierElem addExpectedNodeWithOrder(String propName, String propValue,
+ List<String> propValueList, ContentValues paramMap) {
+ return addExpectedNodeWithOrder(propName, propValue, propValueList, null, paramMap,
+ null, null);
+ }
+
+ public PropertyNodesVerifierElem addExpectedNodeWithOrder(String propName, String propValue,
List<String> propValueList, byte[] propValue_bytes,
ContentValues paramMap, TypeSet paramMap_TYPE, GroupSet propGroupSet) {
if (propValue == null && propValueList != null) {
propValue = concatinateListWithSemiColon(propValueList);
}
- PropertyNode propertyNode = new PropertyNode(propName,
+ final PropertyNode propertyNode = new PropertyNode(propName,
propValue, propValueList, propValue_bytes,
paramMap, paramMap_TYPE, propGroupSet);
List<PropertyNode> expectedNodeList = mOrderedNodeMap.get(propName);
@@ -267,8 +209,9 @@ import java.util.List;
for (PropertyNode actualNode : vnode.propList) {
verifyNode(actualNode.propName, actualNode);
}
+
if (!mOrderedNodeMap.isEmpty() || !mUnorderedNodeList.isEmpty()) {
- List<String> expectedProps = new ArrayList<String>();
+ final List<String> expectedProps = new ArrayList<String>();
for (List<PropertyNode> nodes : mOrderedNodeMap.values()) {
for (PropertyNode node : nodes) {
if (!expectedProps.contains(node.propName)) {
@@ -281,18 +224,19 @@ import java.util.List;
expectedProps.add(node.propName);
}
}
- mTestCase.fail("Expected property " + Arrays.toString(expectedProps.toArray())
+ TestCase.fail("Expected property " + Arrays.toString(expectedProps.toArray())
+ " was not found.");
}
}
private void verifyNode(final String propName, final PropertyNode actualNode) {
- List<PropertyNode> expectedNodeList = mOrderedNodeMap.get(propName);
+ final List<PropertyNode> expectedNodeList = mOrderedNodeMap.get(propName);
final int size = (expectedNodeList != null ? expectedNodeList.size() : 0);
if (size > 0) {
for (int i = 0; i < size; i++) {
- PropertyNode expectedNode = expectedNodeList.get(i);
- List<PropertyNode> expectedButDifferentValueList = new ArrayList<PropertyNode>();
+ final PropertyNode expectedNode = expectedNodeList.get(i);
+ final List<PropertyNode> expectedButDifferentValueList =
+ new ArrayList<PropertyNode>();
if (expectedNode.propName.equals(propName)) {
if (expectedNode.equals(actualNode)) {
expectedNodeList.remove(i);
@@ -318,7 +262,7 @@ import java.util.List;
expectedButDifferentValueList);
} else {
// There's no expected node with same propName.
- mTestCase.fail("Unexpected property \"" + propName + "\" exists.");
+ TestCase.fail("Unexpected property \"" + propName + "\" exists.");
}
}
} else {
@@ -333,7 +277,7 @@ import java.util.List;
expectedButDifferentValueList);
} else {
// There's no expected node with same propName.
- mTestCase.fail("Unexpected property \"" + propName + "\" exists.");
+ TestCase.fail("Unexpected property \"" + propName + "\" exists.");
}
}
}
@@ -379,7 +323,7 @@ import java.util.List;
builder.append(expectedNode.toString());
builder.append("\n");
}
- mTestCase.fail("Property \"" + propName + "\" has wrong value.\n"
+ TestCase.fail("Property \"" + propName + "\" has wrong value.\n"
+ builder.toString()
+ " actual: " + actualNode.toString());
}
diff --git a/core/tests/coretests/src/android/pim/vcard/test_utils/VCardTestsBase.java b/core/tests/coretests/src/android/pim/vcard/test_utils/VCardTestsBase.java
new file mode 100644
index 000000000000..e7413ab29534
--- /dev/null
+++ b/core/tests/coretests/src/android/pim/vcard/test_utils/VCardTestsBase.java
@@ -0,0 +1,84 @@
+/*
+ * 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.pim.vcard.test_utils;
+
+import android.content.ContentValues;
+import android.pim.vcard.VCardConfig;
+import android.test.AndroidTestCase;
+
+/**
+ * BaseClass for vCard unit tests with utility classes.
+ * Please do not add each unit test here.
+ */
+public class VCardTestsBase extends AndroidTestCase {
+ public static final int V21 = VCardConfig.VCARD_TYPE_V21_GENERIC;
+ public static final int V30 = VCardConfig.VCARD_TYPE_V30_GENERIC;
+ public static final int V40 = VCardConfig.VCARD_TYPE_V40_GENERIC;
+
+ // Do not modify these during tests.
+ protected final ContentValues mContentValuesForQP;
+ protected final ContentValues mContentValuesForSJis;
+ protected final ContentValues mContentValuesForUtf8;
+ protected final ContentValues mContentValuesForQPAndSJis;
+ protected final ContentValues mContentValuesForQPAndUtf8;
+ protected final ContentValues mContentValuesForBase64V21;
+ protected final ContentValues mContentValuesForBase64V30;
+
+ protected VCardVerifier mVerifier;
+ private boolean mSkipVerification;
+
+ public VCardTestsBase() {
+ super();
+ // Not using constants in vCard code since it may be wrong.
+ mContentValuesForQP = new ContentValues();
+ mContentValuesForQP.put("ENCODING", "QUOTED-PRINTABLE");
+ mContentValuesForSJis = new ContentValues();
+ mContentValuesForSJis.put("CHARSET", "SHIFT_JIS");
+ mContentValuesForUtf8 = new ContentValues();
+ mContentValuesForUtf8.put("CHARSET", "UTF-8");
+ mContentValuesForQPAndSJis = new ContentValues();
+ mContentValuesForQPAndSJis.put("ENCODING", "QUOTED-PRINTABLE");
+ mContentValuesForQPAndSJis.put("CHARSET", "SHIFT_JIS");
+ mContentValuesForQPAndUtf8 = new ContentValues();
+ mContentValuesForQPAndUtf8.put("ENCODING", "QUOTED-PRINTABLE");
+ mContentValuesForQPAndUtf8.put("CHARSET", "UTF-8");
+ mContentValuesForBase64V21 = new ContentValues();
+ mContentValuesForBase64V21.put("ENCODING", "BASE64");
+ mContentValuesForBase64V30 = new ContentValues();
+ mContentValuesForBase64V30.put("ENCODING", "b");
+ }
+
+ @Override
+ public void testAndroidTestCaseSetupProperly() {
+ super.testAndroidTestCaseSetupProperly();
+ mSkipVerification = true;
+ }
+
+ @Override
+ public void setUp() throws Exception{
+ super.setUp();
+ mVerifier = new VCardVerifier(this);
+ mSkipVerification = false;
+ }
+
+ @Override
+ public void tearDown() throws Exception {
+ super.tearDown();
+ if (!mSkipVerification) {
+ mVerifier.verify();
+ }
+ }
+}
diff --git a/core/tests/coretests/src/android/pim/vcard/test_utils/VCardVerifier.java b/core/tests/coretests/src/android/pim/vcard/test_utils/VCardVerifier.java
new file mode 100644
index 000000000000..7379a5b947e0
--- /dev/null
+++ b/core/tests/coretests/src/android/pim/vcard/test_utils/VCardVerifier.java
@@ -0,0 +1,370 @@
+/*
+ * 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.pim.vcard.test_utils;
+
+import android.content.ContentResolver;
+import android.content.Context;
+import android.content.EntityIterator;
+import android.net.Uri;
+import android.pim.vcard.VCardComposer;
+import android.pim.vcard.VCardConfig;
+import android.pim.vcard.VCardEntryConstructor;
+import android.pim.vcard.VCardInterpreter;
+import android.pim.vcard.VCardInterpreterCollection;
+import android.pim.vcard.VCardParser;
+import android.pim.vcard.VCardUtils;
+import android.pim.vcard.exception.VCardException;
+import android.test.AndroidTestCase;
+import android.test.mock.MockContext;
+import android.text.TextUtils;
+import android.util.Log;
+
+import junit.framework.TestCase;
+
+import java.io.ByteArrayInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.lang.reflect.Method;
+import java.util.Arrays;
+
+/**
+ * <p>
+ * The class lets users checks that given expected vCard data are same as given actual vCard data.
+ * Able to verify both vCard importer/exporter.
+ * </p>
+ * <p>
+ * First a user has to initialize the object by calling either
+ * {@link #initForImportTest(int, int)} or {@link #initForExportTest(int)}.
+ * "Round trip test" (import -> export -> import, or export -> import -> export) is not supported.
+ * </p>
+ */
+public class VCardVerifier {
+ private static final String LOG_TAG = "VCardVerifier";
+
+ private static class CustomMockContext extends MockContext {
+ final ContentResolver mResolver;
+ public CustomMockContext(ContentResolver resolver) {
+ mResolver = resolver;
+ }
+
+ @Override
+ public ContentResolver getContentResolver() {
+ return mResolver;
+ }
+ }
+
+ private class VCardVerifierInternal implements VCardComposer.OneEntryHandler {
+ public boolean onInit(Context context) {
+ return true;
+ }
+ public boolean onEntryCreated(String vcard) {
+ verifyOneVCardForExport(vcard);
+ return true;
+ }
+ public void onTerminate() {
+ }
+ }
+
+ private final AndroidTestCase mAndroidTestCase;
+ private final VCardVerifierInternal mVCardVerifierInternal;
+ private int mVCardType;
+ private boolean mIsDoCoMo;
+
+ // Only one of them must be non-empty.
+ private ExportTestResolver mExportTestResolver;
+ private InputStream mInputStream;
+
+ // To allow duplication, use list instead of set.
+ // When null, we don't need to do the verification.
+ private PropertyNodesVerifier mPropertyNodesVerifier;
+ private LineVerifier mLineVerifier;
+ private ContentValuesVerifier mContentValuesVerifier;
+ private boolean mInitialized;
+ private boolean mVerified = false;
+ private String mCharset;
+
+ // Called by VCardTestsBase
+ public VCardVerifier(AndroidTestCase androidTestCase) {
+ mAndroidTestCase = androidTestCase;
+ mVCardVerifierInternal = new VCardVerifierInternal();
+ mExportTestResolver = null;
+ mInputStream = null;
+ mInitialized = false;
+ mVerified = false;
+ }
+
+ // Should be called at the beginning of each import test.
+ public void initForImportTest(int vcardType, int resId) {
+ if (mInitialized) {
+ AndroidTestCase.fail("Already initialized");
+ }
+ mVCardType = vcardType;
+ mIsDoCoMo = VCardConfig.isDoCoMo(vcardType);
+ setInputResourceId(resId);
+ mInitialized = true;
+ }
+
+ // Should be called at the beginning of each export test.
+ public void initForExportTest(int vcardType) {
+ initForExportTest(vcardType, "UTF-8");
+ }
+
+ public void initForExportTest(int vcardType, String charset) {
+ if (mInitialized) {
+ AndroidTestCase.fail("Already initialized");
+ }
+ mExportTestResolver = new ExportTestResolver(mAndroidTestCase);
+ mVCardType = vcardType;
+ mIsDoCoMo = VCardConfig.isDoCoMo(vcardType);
+ mInitialized = true;
+ if (TextUtils.isEmpty(charset)) {
+ mCharset = "UTF-8";
+ } else {
+ mCharset = charset;
+ }
+ }
+
+ private void setInputResourceId(int resId) {
+ InputStream inputStream = mAndroidTestCase.getContext().getResources().openRawResource(resId);
+ if (inputStream == null) {
+ AndroidTestCase.fail("Wrong resId: " + resId);
+ }
+ setInputStream(inputStream);
+ }
+
+ private void setInputStream(InputStream inputStream) {
+ if (mExportTestResolver != null) {
+ AndroidTestCase.fail("addInputEntry() is called.");
+ } else if (mInputStream != null) {
+ AndroidTestCase.fail("InputStream is already set");
+ }
+ mInputStream = inputStream;
+ }
+
+ public ContactEntry addInputEntry() {
+ if (!mInitialized) {
+ AndroidTestCase.fail("Not initialized");
+ }
+ if (mInputStream != null) {
+ AndroidTestCase.fail("setInputStream is called");
+ }
+ return mExportTestResolver.addInputContactEntry();
+ }
+
+ public PropertyNodesVerifierElem addPropertyNodesVerifierElemWithoutVersion() {
+ if (!mInitialized) {
+ AndroidTestCase.fail("Not initialized");
+ }
+ if (mPropertyNodesVerifier == null) {
+ mPropertyNodesVerifier = new PropertyNodesVerifier(mAndroidTestCase);
+ }
+ return mPropertyNodesVerifier.addPropertyNodesVerifierElem();
+ }
+
+ public PropertyNodesVerifierElem addPropertyNodesVerifierElem() {
+ final PropertyNodesVerifierElem elem = addPropertyNodesVerifierElemWithoutVersion();
+ final String versionString;
+ if (VCardConfig.isVersion21(mVCardType)) {
+ versionString = "2.1";
+ } else if (VCardConfig.isVersion30(mVCardType)) {
+ versionString = "3.0";
+ } else if (VCardConfig.isVersion40(mVCardType)) {
+ versionString = "4.0";
+ } else {
+ throw new RuntimeException("Unexpected vcard type during a unit test");
+ }
+ elem.addExpectedNodeWithOrder("VERSION", versionString);
+
+ return elem;
+ }
+
+ public PropertyNodesVerifierElem addPropertyNodesVerifierElemWithEmptyName() {
+ if (!mInitialized) {
+ AndroidTestCase.fail("Not initialized");
+ }
+ final PropertyNodesVerifierElem elem = addPropertyNodesVerifierElem();
+ if (VCardConfig.isVersion40(mVCardType)) {
+ elem.addExpectedNodeWithOrder("FN", "");
+ } else if (VCardConfig.isVersion30(mVCardType)) {
+ elem.addExpectedNodeWithOrder("N", "");
+ elem.addExpectedNodeWithOrder("FN", "");
+ } else if (mIsDoCoMo) {
+ elem.addExpectedNodeWithOrder("N", "");
+ }
+ return elem;
+ }
+
+ public LineVerifierElem addLineVerifierElem() {
+ if (!mInitialized) {
+ AndroidTestCase.fail("Not initialized");
+ }
+ if (mLineVerifier == null) {
+ mLineVerifier = new LineVerifier(mAndroidTestCase, mVCardType);
+ }
+ return mLineVerifier.addLineVerifierElem();
+ }
+
+ public ContentValuesVerifierElem addContentValuesVerifierElem() {
+ if (!mInitialized) {
+ AndroidTestCase.fail("Not initialized");
+ }
+ if (mContentValuesVerifier == null) {
+ mContentValuesVerifier = new ContentValuesVerifier();
+ }
+
+ return mContentValuesVerifier.addElem(mAndroidTestCase);
+ }
+
+ /**
+ * Sets up sub-verifiers correctly and try parse given vCard as InputStream.
+ * Errors around InputStream must be handled outside this method.
+ *
+ * Used both from {@link #verifyForImportTest()} and from {@link #verifyForExportTest()}.
+ */
+ private void verifyWithInputStream(InputStream is) throws IOException {
+ final VCardInterpreter interpreter;
+ if (mContentValuesVerifier != null) {
+ final VCardEntryConstructor constructor = new VCardEntryConstructor(mVCardType);
+ constructor.addEntryHandler(mContentValuesVerifier);
+ if (mPropertyNodesVerifier != null) {
+ interpreter = new VCardInterpreterCollection(Arrays.asList(
+ mPropertyNodesVerifier, constructor));
+ } else {
+ interpreter = constructor;
+ }
+ } else {
+ if (mPropertyNodesVerifier != null) {
+ interpreter = mPropertyNodesVerifier;
+ } else {
+ interpreter = null;
+ }
+ }
+
+ try {
+ // Note: we must not specify charset toward vCard parsers. This code checks whether
+ // those parsers are able to encode given binary without any extra information for
+ // charset.
+ final VCardParser parser = VCardUtils.getAppropriateParser(mVCardType);
+ parser.parse(is, interpreter);
+ } catch (VCardException e) {
+ AndroidTestCase.fail("Unexpected VCardException: " + e.getMessage());
+ }
+ }
+
+ private void verifyOneVCardForExport(final String vcard) {
+ Log.d(LOG_TAG, vcard);
+ InputStream is = null;
+ try {
+ is = new ByteArrayInputStream(vcard.getBytes(mCharset));
+ verifyWithInputStream(is);
+ } catch (IOException e) {
+ AndroidTestCase.fail("Unexpected IOException: " + e.getMessage());
+ } finally {
+ if (is != null) {
+ try {
+ is.close();
+ } catch (IOException e) {
+ AndroidTestCase.fail("Unexpected IOException: " + e.getMessage());
+ }
+ }
+ }
+ }
+
+ public void verify() {
+ if (!mInitialized) {
+ TestCase.fail("Not initialized.");
+ }
+ if (mVerified) {
+ TestCase.fail("verify() was called twice.");
+ }
+
+ if (mInputStream != null) {
+ if (mExportTestResolver != null){
+ TestCase.fail("There are two input sources.");
+ }
+ verifyForImportTest();
+ } else if (mExportTestResolver != null){
+ verifyForExportTest();
+ } else {
+ TestCase.fail("No input is determined");
+ }
+ mVerified = true;
+ }
+
+ private void verifyForImportTest() {
+ if (mLineVerifier != null) {
+ AndroidTestCase.fail("Not supported now.");
+ }
+
+ try {
+ verifyWithInputStream(mInputStream);
+ } catch (IOException e) {
+ AndroidTestCase.fail("IOException was thrown: " + e.getMessage());
+ } finally {
+ if (mInputStream != null) {
+ try {
+ mInputStream.close();
+ } catch (IOException e) {
+ }
+ }
+ }
+ }
+
+ public static EntityIterator mockGetEntityIteratorMethod(
+ final ContentResolver resolver,
+ final Uri uri, final String selection,
+ final String[] selectionArgs, final String sortOrder) {
+ if (ExportTestResolver.class.equals(resolver.getClass())) {
+ return ((ExportTestResolver)resolver).getProvider().queryEntities(
+ uri, selection, selectionArgs, sortOrder);
+ }
+
+ Log.e(LOG_TAG, "Unexpected provider given.");
+ return null;
+ }
+
+ private Method getMockGetEntityIteratorMethod()
+ throws SecurityException, NoSuchMethodException {
+ return this.getClass().getMethod("mockGetEntityIteratorMethod",
+ ContentResolver.class, Uri.class, String.class, String[].class, String.class);
+ }
+
+ private void verifyForExportTest() {
+ final VCardComposer composer =
+ new VCardComposer(new CustomMockContext(mExportTestResolver), mVCardType, mCharset);
+ composer.addHandler(mLineVerifier);
+ composer.addHandler(mVCardVerifierInternal);
+ if (!composer.init(VCardComposer.CONTACTS_TEST_CONTENT_URI, null, null, null)) {
+ AndroidTestCase.fail("init() failed. Reason: " + composer.getErrorReason());
+ }
+ AndroidTestCase.assertFalse(composer.isAfterLast());
+ try {
+ while (!composer.isAfterLast()) {
+ try {
+ final Method mockGetEntityIteratorMethod = getMockGetEntityIteratorMethod();
+ AndroidTestCase.assertNotNull(mockGetEntityIteratorMethod);
+ AndroidTestCase.assertTrue(
+ composer.createOneEntry(mockGetEntityIteratorMethod));
+ } catch (Exception e) {
+ e.printStackTrace();
+ AndroidTestCase.fail(e.toString());
+ }
+ }
+ } finally {
+ composer.terminate();
+ }
+ }
+}
diff --git a/core/tests/coretests/src/android/pim/vcard/VNode.java b/core/tests/coretests/src/android/pim/vcard/test_utils/VNode.java
index 79f10dc92e19..b890e2c2be60 100644
--- a/core/tests/coretests/src/android/pim/vcard/VNode.java
+++ b/core/tests/coretests/src/android/pim/vcard/test_utils/VNode.java
@@ -13,7 +13,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-package android.pim.vcard;
+package android.pim.vcard.test_utils;
import java.util.ArrayList;
diff --git a/core/tests/coretests/src/android/pim/vcard/VNodeBuilder.java b/core/tests/coretests/src/android/pim/vcard/test_utils/VNodeBuilder.java
index 0e6c3259b5fa..883703407352 100644
--- a/core/tests/coretests/src/android/pim/vcard/VNodeBuilder.java
+++ b/core/tests/coretests/src/android/pim/vcard/test_utils/VNodeBuilder.java
@@ -13,18 +13,16 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-package android.pim.vcard;
+package android.pim.vcard.test_utils;
import android.content.ContentValues;
-import android.pim.vcard.VCardInterpreter;
import android.pim.vcard.VCardConfig;
+import android.pim.vcard.VCardInterpreter;
+import android.pim.vcard.VCardUtils;
+import android.util.Base64;
import android.util.CharsetUtils;
import android.util.Log;
-import org.apache.commons.codec.DecoderException;
-import org.apache.commons.codec.binary.Base64;
-import org.apache.commons.codec.net.QuotedPrintableCodec;
-
import java.io.UnsupportedEncodingException;
import java.nio.ByteBuffer;
import java.nio.charset.Charset;
@@ -32,34 +30,29 @@ import java.util.ArrayList;
import java.util.List;
/**
- * Store the parse result to custom datastruct: VNode, PropertyNode
+ * <p>
+ * The class storing the parse result to custom datastruct:
+ * {@link VNode}, and {@link PropertyNode}.
* Maybe several vcard instance, so use vNodeList to store.
- * VNode: standy by a vcard instance.
- * PropertyNode: standy by a property line of a card.
- *
- * Previously used in main vCard handling code but now exists only for testing.
+ * </p>
+ * <p>
+ * This is called VNode, not VCardNode, since it was used for expressing vCalendar (iCal).
+ * </p>
*/
public class VNodeBuilder implements VCardInterpreter {
static private String LOG_TAG = "VNodeBuilder";
- /**
- * If there's no other information available, this class uses this charset for encoding
- * byte arrays.
- */
- static public String TARGET_CHARSET = "UTF-8";
-
- /** type=VNode */
public List<VNode> vNodeList = new ArrayList<VNode>();
private int mNodeListPos = 0;
private VNode mCurrentVNode;
private PropertyNode mCurrentPropNode;
private String mCurrentParamType;
-
+
/**
* The charset using which VParser parses the text.
*/
private String mSourceCharset;
-
+
/**
* The charset with which byte array is encoded to String.
*/
@@ -68,27 +61,15 @@ public class VNodeBuilder implements VCardInterpreter {
private boolean mStrictLineBreakParsing;
public VNodeBuilder() {
- this(VCardConfig.DEFAULT_CHARSET, TARGET_CHARSET, false);
+ this(VCardConfig.DEFAULT_IMPORT_CHARSET, false);
}
- public VNodeBuilder(String charset, boolean strictLineBreakParsing) {
- this(null, charset, strictLineBreakParsing);
- }
-
- /**
- * @hide sourceCharset is temporal.
- */
- public VNodeBuilder(String sourceCharset, String targetCharset,
- boolean strictLineBreakParsing) {
- if (sourceCharset != null) {
- mSourceCharset = sourceCharset;
- } else {
- mSourceCharset = VCardConfig.DEFAULT_CHARSET;
- }
+ public VNodeBuilder(String targetCharset, boolean strictLineBreakParsing) {
+ mSourceCharset = VCardConfig.DEFAULT_INTERMEDIATE_CHARSET;
if (targetCharset != null) {
mTargetCharset = targetCharset;
} else {
- mTargetCharset = TARGET_CHARSET;
+ mTargetCharset = VCardConfig.DEFAULT_IMPORT_CHARSET;
}
mStrictLineBreakParsing = strictLineBreakParsing;
}
@@ -149,7 +130,6 @@ public class VNodeBuilder implements VCardInterpreter {
mCurrentPropNode.propName = name;
}
- // Used only in VCard.
public void propertyGroup(String group) {
mCurrentPropNode.propGroupSet.add(group);
}
@@ -159,6 +139,12 @@ public class VNodeBuilder implements VCardInterpreter {
}
public void propertyParamValue(String value) {
+ if (!VCardUtils.containsOnlyAlphaDigitHyphen(value)) {
+ value = VCardUtils.convertStringCharset(value,
+ VCardConfig.DEFAULT_INTERMEDIATE_CHARSET,
+ VCardConfig.DEFAULT_IMPORT_CHARSET);
+ }
+
if (mCurrentParamType == null ||
mCurrentParamType.equalsIgnoreCase("TYPE")) {
mCurrentPropNode.paramMap_TYPE.add(value);
@@ -192,71 +178,11 @@ public class VNodeBuilder implements VCardInterpreter {
encoding = encoding.toUpperCase();
if (encoding.equals("BASE64") || encoding.equals("B")) {
// Assume BASE64 is used only when the number of values is 1.
- mCurrentPropNode.propValue_bytes =
- Base64.decodeBase64(value.getBytes());
+ mCurrentPropNode.propValue_bytes = Base64.decode(value.getBytes(), Base64.NO_WRAP);
return value;
} else if (encoding.equals("QUOTED-PRINTABLE")) {
- String quotedPrintable = value
- .replaceAll("= ", " ").replaceAll("=\t", "\t");
- String[] lines;
- if (mStrictLineBreakParsing) {
- lines = quotedPrintable.split("\r\n");
- } else {
- StringBuilder builder = new StringBuilder();
- int length = quotedPrintable.length();
- ArrayList<String> list = new ArrayList<String>();
- for (int i = 0; i < length; i++) {
- char ch = quotedPrintable.charAt(i);
- if (ch == '\n') {
- list.add(builder.toString());
- builder = new StringBuilder();
- } else if (ch == '\r') {
- list.add(builder.toString());
- builder = new StringBuilder();
- if (i < length - 1) {
- char nextCh = quotedPrintable.charAt(i + 1);
- if (nextCh == '\n') {
- i++;
- }
- }
- } else {
- builder.append(ch);
- }
- }
- String finalLine = builder.toString();
- if (finalLine.length() > 0) {
- list.add(finalLine);
- }
- lines = list.toArray(new String[0]);
- }
- StringBuilder builder = new StringBuilder();
- for (String line : lines) {
- if (line.endsWith("=")) {
- line = line.substring(0, line.length() - 1);
- }
- builder.append(line);
- }
- byte[] bytes;
- try {
- bytes = builder.toString().getBytes(mSourceCharset);
- } catch (UnsupportedEncodingException e1) {
- Log.e(LOG_TAG, "Failed to encode: charset=" + mSourceCharset);
- bytes = builder.toString().getBytes();
- }
-
- try {
- bytes = QuotedPrintableCodec.decodeQuotedPrintable(bytes);
- } catch (DecoderException e) {
- Log.e(LOG_TAG, "Failed to decode quoted-printable: " + e);
- return "";
- }
-
- try {
- return new String(bytes, targetCharset);
- } catch (UnsupportedEncodingException e) {
- Log.e(LOG_TAG, "Failed to encode: charset=" + targetCharset);
- return new String(bytes);
- }
+ return VCardUtils.parseQuotedPrintable(
+ value, mStrictLineBreakParsing, mSourceCharset, targetCharset);
}
// Unknown encoding. Fall back to default.
}
@@ -309,6 +235,6 @@ public class VNodeBuilder implements VCardInterpreter {
}
public String getResult(){
- return null;
+ throw new RuntimeException("Not supported");
}
}
diff --git a/core/tests/coretests/src/android/text/HtmlTest.java b/core/tests/coretests/src/android/text/HtmlTest.java
index c07d212bedc3..b2298f7bfa83 100644
--- a/core/tests/coretests/src/android/text/HtmlTest.java
+++ b/core/tests/coretests/src/android/text/HtmlTest.java
@@ -19,7 +19,6 @@ package android.text;
import android.content.res.ColorStateList;
import android.content.res.Resources;
import android.graphics.Typeface;
-import android.test.suitebuilder.annotation.MediumTest;
import android.test.suitebuilder.annotation.SmallTest;
import android.text.style.ForegroundColorSpan;
import android.text.style.QuoteSpan;
@@ -36,7 +35,7 @@ import junit.framework.TestCase;
public class HtmlTest extends TestCase {
- @MediumTest
+ @SmallTest
public void testSingleTagOnWhileString() {
Spanned spanned = Html.fromHtml("<b>hello</b>");
Object[] spans = spanned.getSpans(-1, 100, Object.class);
@@ -46,7 +45,7 @@ public class HtmlTest extends TestCase {
assertEquals(5, spanned.getSpanEnd(span));
}
- @MediumTest
+ @SmallTest
public void testEmptyFontTag() {
Spanned spanned = Html.fromHtml("Hello <font color=\"#ff00ff00\"></font>");
Object[] spans = spanned.getSpans(0, 100, Object.class);
@@ -54,7 +53,7 @@ public class HtmlTest extends TestCase {
}
/** Tests that the parser can handle mal-formed HTML. */
- @MediumTest
+ @SmallTest
public void testBadHtml() {
Spanned spanned = Html.fromHtml("Hello <b>b<i>bi</b>i</i>");
Object[] spans = spanned.getSpans(0, 100, Object.class);
@@ -69,13 +68,13 @@ public class HtmlTest extends TestCase {
assertEquals(10, spanned.getSpanEnd(spans[2]));
}
- @MediumTest
+ @SmallTest
public void testSymbols() {
String spanned = Html.fromHtml("&copy; &gt; &lt").toString();
assertEquals("\u00a9 > <", spanned);
}
- @MediumTest
+ @SmallTest
public void testColor() throws Exception {
Spanned s;
ForegroundColorSpan[] colors;
@@ -95,7 +94,7 @@ public class HtmlTest extends TestCase {
assertEquals(0, colors.length);
}
- @MediumTest
+ @SmallTest
public void testResourceColor() throws Exception {
ColorStateList c =
Resources.getSystem().getColorStateList(android.R.color.primary_text_dark);
diff --git a/core/tests/coretests/src/android/text/PackedIntVectorTest.java b/core/tests/coretests/src/android/text/PackedIntVectorTest.java
new file mode 100644
index 000000000000..1dc683e87937
--- /dev/null
+++ b/core/tests/coretests/src/android/text/PackedIntVectorTest.java
@@ -0,0 +1,158 @@
+/*
+ * Copyright (C) 2007 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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.text;
+
+import junit.framework.TestCase;
+
+/**
+ * PackedIntVectorTest tests the features of android.util.PackedIntVector.
+ */
+public class PackedIntVectorTest extends TestCase {
+
+ public void testBasic() throws Exception {
+ for (int width = 0; width < 10; width++) {
+ PackedIntVector p = new PackedIntVector(width);
+ int[] ins = new int[width];
+
+ for (int height = width * 2; height < width * 4; height++) {
+ assertEquals(p.width(), width);
+
+ // Test adding rows.
+
+ for (int i = 0; i < height; i++) {
+ int at;
+
+ if (i % 2 == 0) {
+ at = i;
+ } else {
+ at = p.size() - i;
+ }
+
+ for (int j = 0; j < width; j++) {
+ ins[j] = i + j;
+ }
+
+ if (i == height / 2) {
+ p.insertAt(at, null);
+ } else {
+ p.insertAt(at, ins);
+ }
+
+ assertEquals(p.size(), i + 1);
+
+ for (int j = 0; j < width; j++) {
+ if (i == height / 2) {
+ assertEquals(0, p.getValue(at, j));
+ } else {
+ assertEquals(p.getValue(at, j), i + j);
+ }
+ }
+ }
+
+ // Test setting values.
+
+ for (int i = 0; i < height; i++) {
+ for (int j = 0; j < width; j++) {
+ p.setValue(i, j, i * j);
+
+ assertEquals(p.getValue(i, j), i * j);
+ }
+ }
+
+ // Test offsetting values.
+
+ for (int j = 0; j < width; j++) {
+ p.adjustValuesBelow(j * 2, j, j + 27);
+ }
+
+ for (int i = 0; i < height; i++) {
+ for (int j = 0; j < width; j++) {
+ int expect = i * j;
+
+ if (i >= j * 2) {
+ expect += j + 27;
+ }
+
+ assertEquals(p.getValue(i, j), expect);
+ }
+ }
+
+ for (int j = 0; j < width; j++) {
+ p.adjustValuesBelow(j, j, j * j + 14);
+ }
+
+ for (int i = 0; i < height; i++) {
+ for (int j = 0; j < width; j++) {
+ int expect = i * j;
+
+ if (i >= j * 2) {
+ expect += j + 27;
+ }
+ if (i >= j) {
+ expect += j * j + 14;
+ }
+
+ assertEquals(p.getValue(i, j), expect);
+ }
+ }
+
+ // Test undoing offsets.
+
+ for (int j = 0; j < width; j++) {
+ p.adjustValuesBelow(j * 2, j, -(j + 27));
+ p.adjustValuesBelow(j, j, -(j * j + 14));
+ }
+
+ for (int i = 0; i < height; i++) {
+ for (int j = 0; j < width; j++) {
+ assertEquals(p.getValue(i, j), i * j);
+ }
+ }
+
+ // Test deleting rows.
+
+ while (p.size() > 0) {
+ int osize = p.size();
+ int del = osize / 3;
+
+ if (del == 0) {
+ del = 1;
+ }
+
+ int at = (osize - del) / 2;
+ p.deleteAt(at, del);
+
+ assertEquals(p.size(), osize - del);
+
+ for (int i = 0; i < at; i++) {
+ for (int j = 0; j < width; j++) {
+ assertEquals(p.getValue(i, j), i * j);
+ }
+ }
+
+ for (int i = at; i < p.size(); i++) {
+ for (int j = 0; j < width; j++) {
+ assertEquals(p.getValue(i, j), (i + height - p.size()) * j);
+ }
+ }
+ }
+
+ assertEquals(0, p.size());
+ }
+ }
+ }
+}
diff --git a/core/tests/coretests/src/android/text/TextUtilsTest.java b/core/tests/coretests/src/android/text/TextUtilsTest.java
index 5b427be23dc7..1beba53a1e29 100644
--- a/core/tests/coretests/src/android/text/TextUtilsTest.java
+++ b/core/tests/coretests/src/android/text/TextUtilsTest.java
@@ -26,6 +26,8 @@ import android.text.SpannedString;
import android.text.TextPaint;
import android.text.TextUtils;
import android.text.style.StyleSpan;
+import android.text.util.Rfc822Token;
+import android.text.util.Rfc822Tokenizer;
import android.test.MoreAsserts;
import com.android.common.Rfc822Validator;
@@ -269,6 +271,24 @@ public class TextUtilsTest extends TestCase {
}
}
+ @SmallTest
+ public void testRfc822TokenizerFullAddress() {
+ Rfc822Token[] tokens = Rfc822Tokenizer.tokenize("Foo Bar (something) <foo@google.com>");
+ assertNotNull(tokens);
+ assertEquals(1, tokens.length);
+ assertEquals("foo@google.com", tokens[0].getAddress());
+ assertEquals("Foo Bar", tokens[0].getName());
+ assertEquals("something",tokens[0].getComment());
+ }
+
+ @SmallTest
+ public void testRfc822TokenizeItemWithError() {
+ Rfc822Token[] tokens = Rfc822Tokenizer.tokenize("\"Foo Bar\\");
+ assertNotNull(tokens);
+ assertEquals(1, tokens.length);
+ assertEquals("Foo Bar", tokens[0].getAddress());
+ }
+
@LargeTest
public void testEllipsize() {
CharSequence s1 = "The quick brown fox jumps over \u00FEhe lazy dog.";
@@ -329,6 +349,26 @@ public class TextUtilsTest extends TestCase {
}
}
+ @SmallTest
+ public void testDelimitedStringContains() {
+ assertFalse(TextUtils.delimitedStringContains("", ',', null));
+ assertFalse(TextUtils.delimitedStringContains(null, ',', ""));
+ // Whole match
+ assertTrue(TextUtils.delimitedStringContains("gps", ',', "gps"));
+ // At beginning.
+ assertTrue(TextUtils.delimitedStringContains("gps,gpsx,network,mock", ',', "gps"));
+ assertTrue(TextUtils.delimitedStringContains("gps,network,mock", ',', "gps"));
+ // In middle, both without, before & after a false match.
+ assertTrue(TextUtils.delimitedStringContains("network,gps,mock", ',', "gps"));
+ assertTrue(TextUtils.delimitedStringContains("network,gps,gpsx,mock", ',', "gps"));
+ assertTrue(TextUtils.delimitedStringContains("network,gpsx,gps,mock", ',', "gps"));
+ // At the end.
+ assertTrue(TextUtils.delimitedStringContains("network,mock,gps", ',', "gps"));
+ assertTrue(TextUtils.delimitedStringContains("network,mock,gpsx,gps", ',', "gps"));
+ // Not present (but with a false match)
+ assertFalse(TextUtils.delimitedStringContains("network,mock,gpsx", ',', "gps"));
+ }
+
/**
* CharSequence wrapper for testing the cases where text is copied into
* a char array instead of working from a String or a Spanned.
diff --git a/core/tests/coretests/src/android/text/util/LinkifyTest.java b/core/tests/coretests/src/android/text/util/LinkifyTest.java
index 99c6501f817d..444eb0c6a8d8 100644
--- a/core/tests/coretests/src/android/text/util/LinkifyTest.java
+++ b/core/tests/coretests/src/android/text/util/LinkifyTest.java
@@ -17,10 +17,8 @@
package android.text.util;
import android.test.AndroidTestCase;
-import android.test.suitebuilder.annotation.MediumTest;
import android.test.suitebuilder.annotation.SmallTest;
import android.text.method.LinkMovementMethod;
-import android.text.util.Linkify;
import android.widget.TextView;
/**
@@ -39,7 +37,7 @@ public class LinkifyTest extends AndroidTestCase {
assertTrue(tv.getUrls().length == 0);
}
- @MediumTest
+ @SmallTest
public void testNormal() throws Exception {
TextView tv;
diff --git a/core/tests/coretests/src/android/util/MonthDisplayHelperTest.java b/core/tests/coretests/src/android/util/MonthDisplayHelperTest.java
index 5207ad918943..55da665c7b34 100644
--- a/core/tests/coretests/src/android/util/MonthDisplayHelperTest.java
+++ b/core/tests/coretests/src/android/util/MonthDisplayHelperTest.java
@@ -16,13 +16,11 @@
package android.util;
-import junit.framework.TestCase;
-import junit.framework.Test;
-import junit.framework.TestSuite;
+import android.test.suitebuilder.annotation.SmallTest;
import java.util.Calendar;
-import android.test.suitebuilder.annotation.SmallTest;
-import android.test.suitebuilder.annotation.MediumTest;
+
+import junit.framework.TestCase;
/**
* Unit tests for {@link MonthDisplayHelper}.
@@ -42,7 +40,7 @@ public class MonthDisplayHelperTest extends TestCase {
new MonthDisplayHelper(2007, Calendar.SEPTEMBER).getFirstDayOfMonth());
}
- @MediumTest
+ @SmallTest
public void testNumberOfDaysInCurrentMonth() {
assertEquals(30,
new MonthDisplayHelper(2007, Calendar.SEPTEMBER).getNumberOfDaysInMonth());
diff --git a/core/tests/coretests/src/android/view/FocusFinderTest.java b/core/tests/coretests/src/android/view/FocusFinderTest.java
index 186689fb57b1..6f1dd7c40184 100644
--- a/core/tests/coretests/src/android/view/FocusFinderTest.java
+++ b/core/tests/coretests/src/android/view/FocusFinderTest.java
@@ -18,7 +18,6 @@ package android.view;
import android.graphics.Rect;
import android.test.AndroidTestCase;
-import android.test.suitebuilder.annotation.MediumTest;
import android.test.suitebuilder.annotation.SmallTest;
public class FocusFinderTest extends AndroidTestCase {
@@ -239,7 +238,7 @@ public class FocusFinderTest extends AndroidTestCase {
* A non-candidate (even a much closer one) is always a worse choice
* than a real candidate.
*/
- @MediumTest
+ @SmallTest
public void testSomeCandidateBetterThanNonCandidate() {
Rect src = new Rect(0, 0, 50, 50); // (left, top, right, bottom)
diff --git a/core/tests/coretests/src/android/view/VelocityTest.java b/core/tests/coretests/src/android/view/VelocityTest.java
new file mode 100644
index 000000000000..fb28e1e30f0a
--- /dev/null
+++ b/core/tests/coretests/src/android/view/VelocityTest.java
@@ -0,0 +1,285 @@
+/*
+ * Copyright (C) 2010 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.frameworktest.view;
+
+import junit.framework.Assert;
+
+import android.test.InstrumentationTestCase;
+import android.test.suitebuilder.annotation.MediumTest;
+import android.view.MotionEvent;
+import android.view.VelocityTracker;
+import android.view.animation.AccelerateInterpolator;
+import android.view.animation.DecelerateInterpolator;
+import android.view.animation.Interpolator;
+import android.view.animation.LinearInterpolator;
+
+/**
+ * Exercises {@link android.view.VelocityTracker} to compute correct velocity.<br>
+ * To launch this test, use :<br>
+ * <code>./development/testrunner/runtest.py framework -c com.android.frameworktest.view.VelocityTest</code>
+ */
+public class VelocityTest extends InstrumentationTestCase {
+
+ @MediumTest
+ public void testInitialCondiditions() {
+ VelocityTracker vt = VelocityTracker.obtain();
+ assertNotNull(vt);
+ vt.recycle();
+ }
+
+ /**
+ * Test that {@link android.view.VelocityTracker}.clear() clears
+ * the previous values after a call to computeCurrentVelocity()
+ */
+ @MediumTest
+ public void testClear() {
+ long t = System.currentTimeMillis();
+ VelocityTracker vt = VelocityTracker.obtain();
+ drag(vt, 100, 200, 100, 200, 10, t, 300);
+ vt.computeCurrentVelocity(1);
+ assertFalse("Velocity should not be null", vt.getXVelocity() == 0.0f);
+ assertFalse("Velocity should not be null", vt.getYVelocity() == 0.0f);
+ vt.clear();
+ vt.computeCurrentVelocity(1);
+ assertEquals(0.0f, vt.getXVelocity());
+ assertEquals(0.0f, vt.getYVelocity());
+ vt.recycle();
+ }
+
+ @MediumTest
+ public void testDragAcceleration () {
+ long t = System.currentTimeMillis();
+ VelocityTracker vt = VelocityTracker.obtain();
+ drag(vt, 100, 200, 100, 200, 15, t, 400, new AccelerateInterpolator());
+ vt.computeCurrentVelocity(1000);
+ assertGreater(250.0f, vt.getXVelocity());
+ assertGreater(250.0f, vt.getYVelocity());
+ vt.recycle();
+ }
+
+ @MediumTest
+ public void testDragDeceleration () {
+ long t = System.currentTimeMillis();
+ VelocityTracker vt = VelocityTracker.obtain();
+ drag(vt, 100, 200, 100, 200, 15, t, 400, new DecelerateInterpolator());
+ vt.computeCurrentVelocity(1000);
+ assertLower(250.0f, vt.getXVelocity());
+ assertLower(250.0f, vt.getYVelocity());
+ vt.recycle();
+ }
+
+ @MediumTest
+ public void testDragLinearHorizontal() {
+ long t = System.currentTimeMillis();
+ VelocityTracker vt = VelocityTracker.obtain();
+ // 100px in 400ms => 250px/s
+ drag(vt, 100, 200, 200, 200, 15, t, 400);
+ vt.computeCurrentVelocity(1000);
+ assertEquals(0.0f, vt.getYVelocity());
+ assertEqualFuzzy(250.0f, vt.getXVelocity(), 4f);
+ vt.recycle();
+ }
+
+ @MediumTest
+ public void testDragLinearVertical() {
+ long t = System.currentTimeMillis();
+ VelocityTracker vt = VelocityTracker.obtain();
+ // 100px in 400ms => 250px/s
+ drag(vt, 200, 200, 100, 200, 15, t, 400);
+ vt.computeCurrentVelocity(1000);
+ assertEquals(0.0f, vt.getXVelocity());
+ assertEqualFuzzy(250.0f, vt.getYVelocity(), 4f);
+ vt.recycle();
+ }
+
+ /**
+ * Test dragging with two points only
+ * (velocity must be an exact value)
+ */
+ @MediumTest
+ public void testDragWith2Points () {
+ long t = System.currentTimeMillis();
+ VelocityTracker vt = VelocityTracker.obtain();
+ // 100px, 2 steps, 100ms => 1000px/s
+ drag(vt, 100, 200, 100, 200, 2, t, 100);
+ vt.computeCurrentVelocity(1000);
+ assertEquals(1000.0f, vt.getXVelocity());
+ assertEquals(1000.0f, vt.getYVelocity());
+ vt.recycle();
+ }
+
+ /**
+ * Velocity is independent of the number of points used during
+ * the same interval
+ */
+ @MediumTest
+ public void testStabilityInNbPoints () {
+ long t = System.currentTimeMillis();
+ VelocityTracker vt = VelocityTracker.obtain();
+ drag(vt, 100, 200, 100, 200, 10, t, 400); // 10 steps over 400ms
+ vt.computeCurrentVelocity(1);
+ float firstX = vt.getXVelocity();
+ float firstY = vt.getYVelocity();
+ vt.clear();
+ drag(vt, 100, 200, 100, 200, 20, t, 400); // 20 steps over 400ms
+ vt.computeCurrentVelocity(1);
+ float secondX = vt.getXVelocity();
+ float secondY = vt.getYVelocity();
+ assertEqualFuzzy(firstX, secondX, 0.1f);
+ assertEqualFuzzy(firstY, secondY, 0.1f);
+ vt.recycle();
+ }
+
+ /**
+ * Velocity is independent of the time when the events occurs,
+ * it only depends on delays between the events.
+ */
+ @MediumTest
+ public void testStabilityInTime () {
+ long t = System.currentTimeMillis();
+ VelocityTracker vt = VelocityTracker.obtain();
+ drag(vt, 100, 200, 100, 200, 10, t, 400);
+ vt.computeCurrentVelocity(1);
+ float firstX = vt.getXVelocity();
+ float firstY = vt.getYVelocity();
+ vt.clear();
+ drag(vt, 100, 200, 100, 200, 10, t + 3600*1000, 400); // on hour later
+ vt.computeCurrentVelocity(1);
+ float secondX = vt.getXVelocity();
+ float secondY = vt.getYVelocity();
+ assertEqualFuzzy(firstX, secondX, 0.1f);
+ assertEqualFuzzy(firstY, secondY, 0.1f);
+ vt.recycle();
+ }
+
+ /**
+ * Velocity is independent of the position of the events,
+ * it only depends on their relative distance.
+ */
+ @MediumTest
+ public void testStabilityInSpace () {
+ long t = System.currentTimeMillis();
+ VelocityTracker vt = VelocityTracker.obtain();
+ drag(vt, 100, 200, 100, 200, 10, t, 400);
+ vt.computeCurrentVelocity(1);
+ float firstX = vt.getXVelocity();
+ float firstY = vt.getYVelocity();
+ vt.clear();
+ drag(vt, 200, 300, 200, 300, 10, t, 400); // 100px further
+ vt.computeCurrentVelocity(1);
+ float secondX = vt.getXVelocity();
+ float secondY = vt.getYVelocity();
+ assertEqualFuzzy(firstX, secondX, 0.1f);
+ assertEqualFuzzy(firstY, secondY, 0.1f);
+ vt.recycle();
+ }
+
+ /**
+ * Test that calls to {@link android.view.VelocityTracker}.computeCurrentVelocity()
+ * will output same values when using the same data.
+ */
+ @MediumTest
+ public void testStabilityOfComputation() {
+ long t = System.currentTimeMillis();
+ VelocityTracker vt = VelocityTracker.obtain();
+ drag(vt, 100, 200, 100, 200, 10, t, 300);
+ vt.computeCurrentVelocity(1);
+ float firstX = vt.getXVelocity();
+ float firstY = vt.getYVelocity();
+ vt.computeCurrentVelocity(1);
+ float secondX = vt.getXVelocity();
+ float secondY = vt.getYVelocity();
+ assertEquals(firstX, secondX);
+ assertEquals(firstY, secondY);
+ vt.recycle();
+ }
+
+ /**
+ * Test the units parameter of {@link android.view.VelocityTracker}.computeCurrentVelocity()
+ */
+ @MediumTest
+ public void testStabilityOfUnits() {
+ long t = System.currentTimeMillis();
+ VelocityTracker vt = VelocityTracker.obtain();
+ drag(vt, 100, 200, 100, 200, 10, t, 300);
+ vt.computeCurrentVelocity(1);
+ float firstX = vt.getXVelocity();
+ float firstY = vt.getYVelocity();
+ vt.computeCurrentVelocity(1000);
+ float secondX = vt.getXVelocity();
+ float secondY = vt.getYVelocity();
+ assertEqualFuzzy(firstX, secondX / 1000.0f, 0.1f);
+ assertEqualFuzzy(firstY, secondY / 1000.0f, 0.1f);
+ vt.recycle();
+ }
+
+ /**
+ * Simulate a drag by giving directly MotionEvents to
+ * the VelocityTracker using a linear interpolator
+ */
+ private void drag(VelocityTracker vt, int startX, int endX, int startY, int endY, int steps,
+ long startime, int duration) {
+ drag(vt, startX, endX, startY, endY, steps, startime, duration, new LinearInterpolator());
+ }
+
+ /**
+ * Simulate a drag by giving directly MotionEvents to
+ * the VelocityTracker using a given interpolator
+ */
+ private void drag(VelocityTracker vt, int startX, int endX, int startY, int endY, int steps,
+ long startime, int duration, Interpolator interpolator) {
+ addMotionEvent(vt, startX, startY, startime, MotionEvent.ACTION_DOWN);
+ float dt = duration / (float)steps;
+ int distX = endX - startX;
+ int distY = endY - startY;
+ for (int i=1; i<steps-1; i++) {
+ float ii = interpolator.getInterpolation(i / (float)steps);
+ int x = (int) (startX + distX * ii);
+ int y = (int) (startY + distY * ii);
+ long time = startime + (int) (i * dt);
+ addMotionEvent(vt, x, y, time, MotionEvent.ACTION_MOVE);
+ }
+ addMotionEvent(vt, endX, endY, startime + duration, MotionEvent.ACTION_UP);
+ }
+
+ private void addMotionEvent(VelocityTracker vt, int x, int y, long time, int action) {
+ MotionEvent me = MotionEvent.obtain(time, time, action, x, y, 0);
+ vt.addMovement(me);
+ me.recycle();
+ }
+
+ /**
+ * Float imprecision of the average computations and filtering
+ * (removing last MotionEvent for N > 3) implies that tests
+ * accepts some approximated values.
+ */
+ private void assertEqualFuzzy(float expected, float actual, float threshold) {
+ boolean fuzzyEqual = actual >= expected - threshold && actual <= expected + threshold;
+ Assert.assertTrue("Expected: <"+expected+"> but was: <"+actual+
+ "> while accepting a variation of: <"+threshold+">", fuzzyEqual);
+ }
+
+ private void assertGreater(float minExpected, float actual) {
+ Assert.assertTrue("Expected: minimum <"+minExpected+"> but was: <"+actual+">",
+ actual > minExpected);
+ }
+
+ private void assertLower(float maxExpected, float actual) {
+ Assert.assertTrue("Expected: maximum <"+maxExpected+"> but was: <"+actual+">",
+ actual < maxExpected);
+ }
+}
diff --git a/core/tests/coretests/src/android/view/accessibility/RecycleAccessibilityEventTest.java b/core/tests/coretests/src/android/view/accessibility/RecycleAccessibilityEventTest.java
index df8d8362a6b2..bbf1696eb25b 100644
--- a/core/tests/coretests/src/android/view/accessibility/RecycleAccessibilityEventTest.java
+++ b/core/tests/coretests/src/android/view/accessibility/RecycleAccessibilityEventTest.java
@@ -14,8 +14,7 @@
package android.view.accessibility;
-import android.test.suitebuilder.annotation.MediumTest;
-import android.view.accessibility.AccessibilityEvent;
+import android.test.suitebuilder.annotation.SmallTest;
import junit.framework.TestCase;
@@ -39,7 +38,7 @@ public class RecycleAccessibilityEventTest extends TestCase {
/**
* If an {@link AccessibilityEvent} is marshaled/unmarshaled correctly
*/
- @MediumTest
+ @SmallTest
public void testAccessibilityEventViewTextChangedType() {
AccessibilityEvent first =
AccessibilityEvent.obtain(AccessibilityEvent.TYPE_VIEW_TEXT_CHANGED);
diff --git a/core/tests/coretests/src/android/widget/RadioGroupPreCheckedTest.java b/core/tests/coretests/src/android/widget/RadioGroupPreCheckedTest.java
index 855caaec95a8..1ab362835bbe 100644
--- a/core/tests/coretests/src/android/widget/RadioGroupPreCheckedTest.java
+++ b/core/tests/coretests/src/android/widget/RadioGroupPreCheckedTest.java
@@ -16,23 +16,22 @@
package android.widget;
-import android.test.TouchUtils;
-import android.widget.RadioButton;
-import android.widget.RadioGroup;
import com.android.frameworks.coretests.R;
import android.test.ActivityInstrumentationTestCase2;
+import android.test.TouchUtils;
import android.test.suitebuilder.annotation.LargeTest;
+import android.test.suitebuilder.annotation.MediumTest;
/**
* Exercises {@link android.widget.RadioGroup}'s check feature.
*/
public class RadioGroupPreCheckedTest extends ActivityInstrumentationTestCase2<RadioGroupActivity> {
public RadioGroupPreCheckedTest() {
- super("com.android.frameworks.coretests", RadioGroupActivity.class);
+ super(RadioGroupActivity.class);
}
- @LargeTest
+ @MediumTest
public void testRadioButtonPreChecked() throws Exception {
final RadioGroupActivity activity = getActivity();
diff --git a/core/tests/coretests/src/android/widget/expandablelistview/ExpandableListWithHeadersTest.java b/core/tests/coretests/src/android/widget/expandablelistview/ExpandableListWithHeadersTest.java
index 64a0fff8e63b..c74c8539659f 100644
--- a/core/tests/coretests/src/android/widget/expandablelistview/ExpandableListWithHeadersTest.java
+++ b/core/tests/coretests/src/android/widget/expandablelistview/ExpandableListWithHeadersTest.java
@@ -62,20 +62,20 @@ public class ExpandableListWithHeadersTest extends
assertTrue(mExpandableListView.isGroupExpanded(0));
}
- @MediumTest
+ @LargeTest
public void testContextMenus() {
ExpandableListTester tester = new ExpandableListTester(mExpandableListView, this);
tester.testContextMenus();
}
- @MediumTest
+ @LargeTest
public void testConvertionBetweenFlatAndPacked() {
ExpandableListTester tester = new ExpandableListTester(mExpandableListView, this);
tester.testConvertionBetweenFlatAndPackedOnGroups();
tester.testConvertionBetweenFlatAndPackedOnChildren();
}
- @MediumTest
+ @LargeTest
public void testSelectedPosition() {
ExpandableListTester tester = new ExpandableListTester(mExpandableListView, this);
tester.testSelectedPositionOnGroups();
diff --git a/core/tests/coretests/src/android/widget/gridview/touch/GridTouchStackFromBottomManyTest.java b/core/tests/coretests/src/android/widget/gridview/touch/GridTouchStackFromBottomManyTest.java
index f8e6ae7a0317..9a8d3074890b 100644
--- a/core/tests/coretests/src/android/widget/gridview/touch/GridTouchStackFromBottomManyTest.java
+++ b/core/tests/coretests/src/android/widget/gridview/touch/GridTouchStackFromBottomManyTest.java
@@ -67,7 +67,7 @@ public class GridTouchStackFromBottomManyTest extends ActivityInstrumentationTes
mGridView.getListPaddingTop(), firstChild.getTop());
}
- @MediumTest
+ @LargeTest
public void testScrollToBottom() {
TouchUtils.scrollToBottom(this, mGridView);
diff --git a/core/tests/coretests/src/android/widget/listview/arrowscroll/ListInterleaveFocusablesTest.java b/core/tests/coretests/src/android/widget/listview/arrowscroll/ListInterleaveFocusablesTest.java
index 6238dab6a2fd..ec8ab7e77357 100644
--- a/core/tests/coretests/src/android/widget/listview/arrowscroll/ListInterleaveFocusablesTest.java
+++ b/core/tests/coretests/src/android/widget/listview/arrowscroll/ListInterleaveFocusablesTest.java
@@ -16,22 +16,20 @@
package android.widget.listview.arrowscroll;
-import android.test.ActivityInstrumentationTestCase;
-import android.test.suitebuilder.annotation.LargeTest;
+import android.test.ActivityInstrumentationTestCase2;
import android.test.suitebuilder.annotation.MediumTest;
-import android.widget.ListView;
+import android.util.ListUtil;
import android.view.KeyEvent;
import android.view.View;
-
+import android.widget.ListView;
import android.widget.listview.ListInterleaveFocusables;
-import android.util.ListUtil;
-public class ListInterleaveFocusablesTest extends ActivityInstrumentationTestCase<ListInterleaveFocusables> {
+public class ListInterleaveFocusablesTest extends ActivityInstrumentationTestCase2<ListInterleaveFocusables> {
private ListView mListView;
private ListUtil mListUtil;
public ListInterleaveFocusablesTest() {
- super("com.android.frameworks.coretests", ListInterleaveFocusables.class);
+ super(ListInterleaveFocusables.class);
}
@Override
@@ -42,7 +40,7 @@ public class ListInterleaveFocusablesTest extends ActivityInstrumentationTestCas
mListUtil = new ListUtil(mListView, getInstrumentation());
}
- @LargeTest
+ @MediumTest
public void testPreconditions() {
assertEquals(7, mListView.getChildCount());
assertTrue(mListView.getChildAt(1).isFocusable());
diff --git a/core/tests/coretests/src/android/widget/listview/arrowscroll/ListOfItemsTallerThanScreenTest.java b/core/tests/coretests/src/android/widget/listview/arrowscroll/ListOfItemsTallerThanScreenTest.java
index 5960942282a9..6805b728f540 100644
--- a/core/tests/coretests/src/android/widget/listview/arrowscroll/ListOfItemsTallerThanScreenTest.java
+++ b/core/tests/coretests/src/android/widget/listview/arrowscroll/ListOfItemsTallerThanScreenTest.java
@@ -16,16 +16,15 @@
package android.widget.listview.arrowscroll;
-import android.test.ActivityInstrumentationTestCase;
-import android.test.suitebuilder.annotation.LargeTest;
+import android.test.ActivityInstrumentationTestCase2;
import android.test.suitebuilder.annotation.MediumTest;
-import android.widget.ListView;
-import android.view.View;
import android.view.KeyEvent;
+import android.view.View;
+import android.widget.ListView;
import android.widget.listview.ListOfItemsTallerThanScreen;
public class ListOfItemsTallerThanScreenTest
- extends ActivityInstrumentationTestCase<ListOfItemsTallerThanScreen> {
+ extends ActivityInstrumentationTestCase2<ListOfItemsTallerThanScreen> {
private ListView mListView;
private ListOfItemsTallerThanScreen mActivity;
@@ -38,7 +37,7 @@ public class ListOfItemsTallerThanScreenTest
}
public ListOfItemsTallerThanScreenTest() {
- super("com.android.frameworks.coretests", ListOfItemsTallerThanScreen.class);
+ super(ListOfItemsTallerThanScreen.class);
}
@MediumTest
@@ -126,7 +125,7 @@ public class ListOfItemsTallerThanScreenTest
1, mListView.getChildCount());
}
- @LargeTest
+ @MediumTest
public void testScrollDownToLastItem() {
final int numItems = mListView.getAdapter().getCount();
diff --git a/core/tests/coretests/src/android/widget/listview/arrowscroll/ListOfShortShortTallShortShortTest.java b/core/tests/coretests/src/android/widget/listview/arrowscroll/ListOfShortShortTallShortShortTest.java
index a5d4906b0c7d..5aa27b267025 100644
--- a/core/tests/coretests/src/android/widget/listview/arrowscroll/ListOfShortShortTallShortShortTest.java
+++ b/core/tests/coretests/src/android/widget/listview/arrowscroll/ListOfShortShortTallShortShortTest.java
@@ -16,20 +16,19 @@
package android.widget.listview.arrowscroll;
-import android.test.ActivityInstrumentationTestCase;
-import android.test.suitebuilder.annotation.LargeTest;
+import android.test.ActivityInstrumentationTestCase2;
import android.test.suitebuilder.annotation.MediumTest;
+import android.util.ListUtil;
import android.view.KeyEvent;
import android.widget.ListView;
import android.widget.listview.ListOfShortShortTallShortShort;
-import android.util.ListUtil;
-public class ListOfShortShortTallShortShortTest extends ActivityInstrumentationTestCase<ListOfShortShortTallShortShort> {
+public class ListOfShortShortTallShortShortTest extends ActivityInstrumentationTestCase2<ListOfShortShortTallShortShort> {
private ListView mListView;
private ListUtil mListUtil;
public ListOfShortShortTallShortShortTest() {
- super("com.android.frameworks.coretests", ListOfShortShortTallShortShort.class);
+ super(ListOfShortShortTallShortShort.class);
}
@Override
@@ -68,7 +67,7 @@ public class ListOfShortShortTallShortShortTest extends ActivityInstrumentationT
1, mListView.getChildCount());
}
- @LargeTest
+ @MediumTest
public void testFadeInTwoBottomItems() {
// put 2nd item selected
sendKeys(KeyEvent.KEYCODE_DPAD_DOWN);
@@ -89,7 +88,7 @@ public class ListOfShortShortTallShortShortTest extends ActivityInstrumentationT
mListView.getChildAt(2).getBottom() >= mListUtil.getListBottom());
}
- @LargeTest
+ @MediumTest
public void testFadeOutBottomTwoItems() throws Exception {
mListUtil.arrowScrollToSelectedPosition(4);
@@ -110,7 +109,7 @@ public class ListOfShortShortTallShortShortTest extends ActivityInstrumentationT
1, mListView.getChildCount());
}
- @LargeTest
+ @MediumTest
public void testFadeInTopTwoItems() throws Exception {
mListUtil.arrowScrollToSelectedPosition(4);
diff --git a/core/tests/coretests/src/android/widget/listview/arrowscroll/ListWithScreenOfNoSelectablesTest.java b/core/tests/coretests/src/android/widget/listview/arrowscroll/ListWithScreenOfNoSelectablesTest.java
index 80716501d503..b68631a84b1f 100644
--- a/core/tests/coretests/src/android/widget/listview/arrowscroll/ListWithScreenOfNoSelectablesTest.java
+++ b/core/tests/coretests/src/android/widget/listview/arrowscroll/ListWithScreenOfNoSelectablesTest.java
@@ -16,21 +16,19 @@
package android.widget.listview.arrowscroll;
-import android.widget.listview.ListWithScreenOfNoSelectables;
-
-import android.test.ActivityInstrumentationTestCase;
-import android.test.suitebuilder.annotation.LargeTest;
+import android.test.ActivityInstrumentationTestCase2;
import android.test.suitebuilder.annotation.MediumTest;
import android.view.KeyEvent;
import android.view.View;
import android.widget.ListView;
+import android.widget.listview.ListWithScreenOfNoSelectables;
-public class ListWithScreenOfNoSelectablesTest extends ActivityInstrumentationTestCase<ListWithScreenOfNoSelectables> {
+public class ListWithScreenOfNoSelectablesTest extends ActivityInstrumentationTestCase2<ListWithScreenOfNoSelectables> {
private ListView mListView;
public ListWithScreenOfNoSelectablesTest() {
- super("com.android.frameworks.coretests", ListWithScreenOfNoSelectables.class);
+ super(ListWithScreenOfNoSelectables.class);
}
@Override
@@ -56,7 +54,7 @@ public class ListWithScreenOfNoSelectablesTest extends ActivityInstrumentationTe
@MediumTest
public void testGoFromSelectedViewExistsToNoSelectedViewExists() {
- // go down untile first (and only selectable) item is off screen
+ // go down until first (and only selectable) item is off screen
View first = mListView.getChildAt(0);
while (first.getParent() != null) {
sendKeys(KeyEvent.KEYCODE_DPAD_DOWN);
@@ -67,7 +65,7 @@ public class ListWithScreenOfNoSelectablesTest extends ActivityInstrumentationTe
assertNull("selected view", mListView.getSelectedView());
}
- @LargeTest
+ @MediumTest
public void testPanDownAcrossUnselectableChildrenToBottom() {
final int lastPosition = mListView.getCount() - 1;
final int maxDowns = 20;
diff --git a/core/tests/coretests/src/com/android/internal/http/multipart/MultipartTest.java b/core/tests/coretests/src/com/android/internal/http/multipart/MultipartTest.java
new file mode 100644
index 000000000000..32e13a7ac7f8
--- /dev/null
+++ b/core/tests/coretests/src/com/android/internal/http/multipart/MultipartTest.java
@@ -0,0 +1,118 @@
+/*
+ * Copyright (C) 2008 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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.internal.http.multipart;
+
+import junit.framework.TestCase;
+import org.apache.http.Header;
+import org.apache.http.util.EncodingUtils;
+
+import java.io.BufferedWriter;
+import java.io.ByteArrayOutputStream;
+import java.io.File;
+import java.io.FileWriter;
+
+public class MultipartTest extends TestCase {
+
+ public void testParts() throws Exception {
+ StringBuffer filebuffer = new StringBuffer();
+ String filepartStr = "this is file part";
+ filebuffer.append(filepartStr);
+ File upload = File.createTempFile("Multipart", "test");
+
+ FileWriter outFile = new FileWriter(upload);
+ BufferedWriter out = new BufferedWriter(outFile);
+ try {
+ out.write(filebuffer.toString());
+ out.flush();
+ } finally {
+ out.close();
+ }
+
+ Part[] parts = new Part[3];
+ parts[0] = new StringPart("stringpart", "PART1!!");
+ parts[1] = new FilePart(upload.getName(), upload);
+ parts[2] = new StringPart("stringpart", "PART2!!");
+
+ MultipartEntity me = new MultipartEntity(parts);
+ ByteArrayOutputStream os = new ByteArrayOutputStream();
+ me.writeTo(os);
+ Header h = me.getContentType();
+ String boundry = EncodingUtils.getAsciiString(me.getMultipartBoundary());
+ StringBuffer contentType = new StringBuffer("multipart/form-data");
+ contentType.append("; boundary=");
+ contentType.append(boundry);
+ assertEquals("Multipart content type error", contentType.toString(), h.getValue());
+ final String CRLF = "\r\n";
+ StringBuffer output = new StringBuffer();
+
+ output.append("--");
+ output.append(boundry);
+ output.append(CRLF);
+
+ output.append("Content-Disposition: form-data; name=\"stringpart\"");
+ output.append(CRLF);
+ output.append("Content-Type: text/plain; charset=US-ASCII");
+ output.append(CRLF);
+ output.append("Content-Transfer-Encoding: 8bit");
+ output.append(CRLF);
+ output.append(CRLF);
+ output.append("PART1!!");
+ output.append(CRLF);
+
+ output.append("--");
+ output.append(boundry);
+ output.append(CRLF);
+
+ output.append("Content-Disposition: form-data; name=\"");
+ output.append(upload.getName());
+ output.append("\"; filename=\"");
+ output.append(upload.getName());
+ output.append("\"");
+
+ output.append(CRLF);
+ output.append("Content-Type: application/octet-stream; charset=ISO-8859-1");
+ output.append(CRLF);
+ output.append("Content-Transfer-Encoding: binary");
+ output.append(CRLF);
+ output.append(CRLF);
+ output.append(filepartStr);
+ output.append(CRLF);
+
+ output.append("--");
+ output.append(boundry);
+ output.append(CRLF);
+
+ output.append("Content-Disposition: form-data; name=\"stringpart\"");
+ output.append(CRLF);
+ output.append("Content-Type: text/plain; charset=US-ASCII");
+ output.append(CRLF);
+ output.append("Content-Transfer-Encoding: 8bit");
+ output.append(CRLF);
+ output.append(CRLF);
+ output.append("PART2!!");
+ output.append(CRLF);
+
+ output.append("--");
+ output.append(boundry);
+ output.append("--");
+ output.append(CRLF);
+ // System.out.print(output.toString());
+ assertEquals("Multipart content error", output.toString(), os.toString());
+
+ // System.out.print(os.toString());
+ }
+}
diff --git a/core/tests/coretests/src/com/android/internal/os/LoggingPrintStreamTest.java b/core/tests/coretests/src/com/android/internal/os/LoggingPrintStreamTest.java
new file mode 100644
index 000000000000..4d016d14c6e4
--- /dev/null
+++ b/core/tests/coretests/src/com/android/internal/os/LoggingPrintStreamTest.java
@@ -0,0 +1,184 @@
+/*
+ * Copyright (C) 2008 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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.internal.os;
+
+import junit.framework.TestCase;
+
+import java.io.PrintWriter;
+import java.io.StringWriter;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.List;
+
+public class LoggingPrintStreamTest extends TestCase {
+
+ TestPrintStream out = new TestPrintStream();
+
+ public void testPrintException() {
+ @SuppressWarnings("ThrowableInstanceNeverThrown")
+ Throwable t = new Throwable("Ignore me.");
+
+ StringWriter sout = new StringWriter();
+ t.printStackTrace(new PrintWriter(sout));
+
+ t.printStackTrace(out);
+ // t.printStackTrace();
+
+ String[] lines = sout.toString().split("\\n");
+ assertEquals(Arrays.asList(lines), out.lines);
+ }
+
+ public void testPrintObject() {
+ Object o = new Object();
+ out.print(4);
+ out.print(o);
+ out.print(2);
+ out.flush();
+ assertEquals(Arrays.asList("4" + o + "2"), out.lines);
+ }
+
+ public void testPrintlnObject() {
+ Object o = new Object();
+ out.print(4);
+ out.println(o);
+ out.print(2);
+ out.flush();
+ assertEquals(Arrays.asList("4" + o, "2"), out.lines);
+ }
+
+ public void testPrintf() {
+ out.printf("Name: %s\nEmployer: %s", "Bob", "Google");
+ assertEquals(Arrays.asList("Name: Bob"), out.lines);
+ out.flush();
+ assertEquals(Arrays.asList("Name: Bob", "Employer: Google"), out.lines);
+ }
+
+ public void testPrintInt() {
+ out.print(4);
+ out.print(2);
+ assertTrue(out.lines.isEmpty());
+ out.flush();
+ assertEquals(Collections.singletonList("42"), out.lines);
+ }
+
+ public void testPrintlnInt() {
+ out.println(4);
+ out.println(2);
+ assertEquals(Arrays.asList("4", "2"), out.lines);
+ }
+
+ public void testPrintCharArray() {
+ out.print("Foo\nBar\nTee".toCharArray());
+ assertEquals(Arrays.asList("Foo", "Bar"), out.lines);
+ out.flush();
+ assertEquals(Arrays.asList("Foo", "Bar", "Tee"), out.lines);
+ }
+
+ public void testPrintString() {
+ out.print("Foo\nBar\nTee");
+ assertEquals(Arrays.asList("Foo", "Bar"), out.lines);
+ out.flush();
+ assertEquals(Arrays.asList("Foo", "Bar", "Tee"), out.lines);
+ }
+
+ public void testPrintlnCharArray() {
+ out.println("Foo\nBar\nTee".toCharArray());
+ assertEquals(Arrays.asList("Foo", "Bar", "Tee"), out.lines);
+ }
+
+ public void testPrintlnString() {
+ out.println("Foo\nBar\nTee");
+ assertEquals(Arrays.asList("Foo", "Bar", "Tee"), out.lines);
+ }
+
+ public void testPrintlnStringWithBufferedData() {
+ out.print(5);
+ out.println("Foo\nBar\nTee");
+ assertEquals(Arrays.asList("5Foo", "Bar", "Tee"), out.lines);
+ }
+
+ public void testAppend() {
+ out.append("Foo\n")
+ .append('4')
+ .append('\n')
+ .append("Bar", 1, 2)
+ .append('\n');
+ assertEquals(Arrays.asList("Foo", "4", "a"), out.lines);
+ }
+
+ public void testMultiByteCharactersSpanningBuffers() throws Exception {
+ // assume 3*1000 bytes won't fit in LoggingPrintStream's internal buffer
+ StringBuilder builder = new StringBuilder();
+ for (int i = 0; i < 1000; i++) {
+ builder.append("\u20AC"); // a Euro character; 3 bytes in UTF-8
+ }
+ String expected = builder.toString();
+
+ out.write(expected.getBytes("UTF-8"));
+ out.flush();
+ assertEquals(Arrays.asList(expected), out.lines);
+ }
+
+ public void testWriteOneByteAtATimeMultibyteCharacters() throws Exception {
+ String expected = " \u20AC \u20AC \u20AC \u20AC ";
+ for (byte b : expected.getBytes()) {
+ out.write(b);
+ }
+ out.flush();
+ assertEquals(Arrays.asList(expected), out.lines);
+ }
+
+ public void testWriteByteArrayAtATimeMultibyteCharacters() throws Exception {
+ String expected = " \u20AC \u20AC \u20AC \u20AC ";
+ out.write(expected.getBytes());
+ out.flush();
+ assertEquals(Arrays.asList(expected), out.lines);
+ }
+
+ public void testWriteWithOffsetsMultibyteCharacters() throws Exception {
+ String expected = " \u20AC \u20AC \u20AC \u20AC ";
+ byte[] bytes = expected.getBytes();
+ int i = 0;
+ while (i < bytes.length - 5) {
+ out.write(bytes, i, 5);
+ i += 5;
+ }
+ out.write(bytes, i, bytes.length - i);
+ out.flush();
+ assertEquals(Arrays.asList(expected), out.lines);
+ }
+
+ public void testWriteFlushesOnNewlines() throws Exception {
+ String a = " \u20AC \u20AC ";
+ String b = " \u20AC \u20AC ";
+ String c = " ";
+ String toWrite = a + "\n" + b + "\n" + c;
+ out.write(toWrite.getBytes());
+ out.flush();
+ assertEquals(Arrays.asList(a, b, c), out.lines);
+ }
+
+ static class TestPrintStream extends LoggingPrintStream {
+
+ final List<String> lines = new ArrayList<String>();
+
+ protected void log(String line) {
+ lines.add(line);
+ }
+ }
+}
diff --git a/core/tests/hosttests/src/android/content/pm/PackageManagerHostTestUtils.java b/core/tests/hosttests/src/android/content/pm/PackageManagerHostTestUtils.java
index 91cbe2fc328f..fed39c949523 100644
--- a/core/tests/hosttests/src/android/content/pm/PackageManagerHostTestUtils.java
+++ b/core/tests/hosttests/src/android/content/pm/PackageManagerHostTestUtils.java
@@ -37,6 +37,9 @@ import java.io.IOException;
import java.io.StringReader;
import java.lang.Runtime;
import java.lang.Process;
+import java.util.Hashtable;
+import java.util.Map;
+import java.util.Map.Entry;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
@@ -117,12 +120,33 @@ public class PackageManagerHostTestUtils extends Assert {
/**
* Helper method to run tests and return the listener that collected the results.
+ *
+ * For the optional params, pass null to use the default values.
+
* @param pkgName Android application package for tests
+ * @param className (optional) The class containing the method to test
+ * @param methodName (optional) The method in the class of which to test
+ * @param runnerName (optional) The name of the TestRunner of the test on the device to be run
+ * @param params (optional) Any additional parameters to pass into the Test Runner
* @return the {@link CollectingTestRunListener}
*/
- private CollectingTestRunListener doRunTests(String pkgName) throws IOException {
- RemoteAndroidTestRunner testRunner = new RemoteAndroidTestRunner(
- pkgName, mDevice);
+ private CollectingTestRunListener doRunTests(String pkgName, String className, String
+ methodName, String runnerName, Map<String, String> params) throws IOException {
+
+ RemoteAndroidTestRunner testRunner = new RemoteAndroidTestRunner(pkgName, runnerName,
+ mDevice);
+
+ if (className != null && methodName != null) {
+ testRunner.setMethodName(className, methodName);
+ }
+
+ // Add in any additional args to pass into the test
+ if (params != null) {
+ for (Entry<String, String> argPair : params.entrySet()) {
+ testRunner.addInstrumentationArg(argPair.getKey(), argPair.getValue());
+ }
+ }
+
CollectingTestRunListener listener = new CollectingTestRunListener();
testRunner.run(listener);
return listener;
@@ -132,10 +156,27 @@ public class PackageManagerHostTestUtils extends Assert {
* Runs the specified packages tests, and returns whether all tests passed or not.
*
* @param pkgName Android application package for tests
+ * @param className The class containing the method to test
+ * @param methodName The method in the class of which to test
+ * @param runnerName The name of the TestRunner of the test on the device to be run
+ * @param params Any additional parameters to pass into the Test Runner
+ * @return true if test passed, false otherwise.
+ */
+ public boolean runDeviceTestsDidAllTestsPass(String pkgName, String className,
+ String methodName, String runnerName, Map<String, String> params) throws IOException {
+ CollectingTestRunListener listener = doRunTests(pkgName, className, methodName,
+ runnerName, params);
+ return listener.didAllTestsPass();
+ }
+
+ /**
+ * Runs the specified packages tests, and returns whether all tests passed or not.
+ *
+ * @param pkgName Android application package for tests
* @return true if every test passed, false otherwise.
*/
public boolean runDeviceTestsDidAllTestsPass(String pkgName) throws IOException {
- CollectingTestRunListener listener = doRunTests(pkgName);
+ CollectingTestRunListener listener = doRunTests(pkgName, null, null, null, null);
return listener.didAllTestsPass();
}
@@ -452,7 +493,7 @@ public class PackageManagerHostTestUtils extends Assert {
}
// For collecting results from running device tests
- private static class CollectingTestRunListener implements ITestRunListener {
+ public static class CollectingTestRunListener implements ITestRunListener {
private boolean mAllTestsPassed = true;
private String mTestRunErrorMessage = null;
diff --git a/core/tests/hosttests/src/android/net/DownloadManagerHostTests.java b/core/tests/hosttests/src/android/net/DownloadManagerHostTests.java
new file mode 100644
index 000000000000..ed280c916ec4
--- /dev/null
+++ b/core/tests/hosttests/src/android/net/DownloadManagerHostTests.java
@@ -0,0 +1,201 @@
+/*
+ * Copyright (C) 2010 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.net;
+
+import android.content.pm.PackageManagerHostTestUtils;
+import android.content.pm.PackageManagerHostTestUtils.CollectingTestRunListener;
+
+import com.android.ddmlib.IDevice;
+import com.android.ddmlib.IShellOutputReceiver;
+import com.android.ddmlib.Log;
+import com.android.ddmlib.MultiLineReceiver;
+import com.android.ddmlib.SyncService;
+import com.android.ddmlib.SyncService.ISyncProgressMonitor;
+import com.android.ddmlib.SyncService.SyncResult;
+import com.android.hosttest.DeviceTestCase;
+import com.android.hosttest.DeviceTestSuite;
+
+import java.io.File;
+import java.io.IOException;
+import java.util.Hashtable;
+
+import junit.framework.Test;
+
+/**
+ * Host-based tests of the DownloadManager API. (Uses a device-based app to actually invoke the
+ * various tests.)
+ */
+public class DownloadManagerHostTests extends DeviceTestCase {
+ protected PackageManagerHostTestUtils mPMUtils = null;
+
+ private static final String LOG_TAG = "android.net.DownloadManagerHostTests";
+ private static final String FILE_DOWNLOAD_APK = "DownloadManagerTestApp.apk";
+ private static final String FILE_DOWNLOAD_PKG = "com.android.frameworks.downloadmanagertests";
+ private static final String FILE_DOWNLOAD_CLASS =
+ "com.android.frameworks.downloadmanagertests.DownloadManagerTestApp";
+ private static final String DOWNLOAD_TEST_RUNNER_NAME =
+ "com.android.frameworks.downloadmanagertests.DownloadManagerTestRunner";
+
+ // Extra parameters to pass to the TestRunner
+ private static final String EXTERNAL_DOWNLOAD_URI_KEY = "external_download_uri";
+ // Note: External environment variable ANDROID_TEST_EXTERNAL_URI must be set to point to the
+ // external URI under which the files downloaded by the tests can be found. Note that the Uri
+ // must be accessible by the device during a test run.
+ private static String EXTERNAL_DOWNLOAD_URI_VALUE = null;
+
+ Hashtable<String, String> mExtraParams = null;
+
+ public static Test suite() {
+ return new DeviceTestSuite(DownloadManagerHostTests.class);
+ }
+
+ @Override
+ protected void setUp() throws Exception {
+ super.setUp();
+ // ensure apk path has been set before test is run
+ assertNotNull(getTestAppPath());
+ mPMUtils = new PackageManagerHostTestUtils(getDevice());
+ EXTERNAL_DOWNLOAD_URI_VALUE = System.getenv("ANDROID_TEST_EXTERNAL_URI");
+ assertNotNull(EXTERNAL_DOWNLOAD_URI_VALUE);
+ mExtraParams = getExtraParams();
+ }
+
+ /**
+ * Helper function to get extra params that can be used to pass into the helper app.
+ */
+ protected Hashtable<String, String> getExtraParams() {
+ Hashtable<String, String> extraParams = new Hashtable<String, String>();
+ extraParams.put(EXTERNAL_DOWNLOAD_URI_KEY, EXTERNAL_DOWNLOAD_URI_VALUE);
+ return extraParams;
+ }
+
+ /**
+ * Tests that a large download over WiFi
+ * @throws Exception if the test failed at any point
+ */
+ public void testLargeDownloadOverWiFi() throws Exception {
+ mPMUtils.installAppAndVerifyExistsOnDevice(String.format("%s%s%s", getTestAppPath(),
+ File.separator, FILE_DOWNLOAD_APK), FILE_DOWNLOAD_PKG, true);
+
+ boolean testPassed = mPMUtils.runDeviceTestsDidAllTestsPass(FILE_DOWNLOAD_PKG,
+ FILE_DOWNLOAD_CLASS, "runLargeDownloadOverWiFi", DOWNLOAD_TEST_RUNNER_NAME,
+ mExtraParams);
+
+ assertTrue("Failed to install large file over WiFi in < 10 minutes!", testPassed);
+ }
+
+ /**
+ * Spawns a device-based function to initiate a download on the device, reboots the device,
+ * then waits and verifies the download succeeded.
+ *
+ * @throws Exception if the test failed at any point
+ */
+ public void testDownloadManagerSingleReboot() throws Exception {
+ mPMUtils.installAppAndVerifyExistsOnDevice(String.format("%s%s%s", getTestAppPath(),
+ File.separator, FILE_DOWNLOAD_APK), FILE_DOWNLOAD_PKG, true);
+
+ boolean testPassed = mPMUtils.runDeviceTestsDidAllTestsPass(FILE_DOWNLOAD_PKG,
+ FILE_DOWNLOAD_CLASS, "initiateDownload", DOWNLOAD_TEST_RUNNER_NAME,
+ mExtraParams);
+
+ assertTrue("Failed to initiate download properly!", testPassed);
+ mPMUtils.rebootDevice();
+ testPassed = mPMUtils.runDeviceTestsDidAllTestsPass(FILE_DOWNLOAD_PKG,
+ FILE_DOWNLOAD_CLASS, "verifyFileDownloadSucceeded", DOWNLOAD_TEST_RUNNER_NAME,
+ mExtraParams);
+ assertTrue("Failed to verify initiated download completed properyly!", testPassed);
+ }
+
+ /**
+ * Spawns a device-based function to initiate a download on the device, reboots the device three
+ * times (using different intervals), then waits and verifies the download succeeded.
+ *
+ * @throws Exception if the test failed at any point
+ */
+ public void testDownloadManagerMultipleReboots() throws Exception {
+ mPMUtils.installAppAndVerifyExistsOnDevice(String.format("%s%s%s", getTestAppPath(),
+ File.separator, FILE_DOWNLOAD_APK), FILE_DOWNLOAD_PKG, true);
+
+ boolean testPassed = mPMUtils.runDeviceTestsDidAllTestsPass(FILE_DOWNLOAD_PKG,
+ FILE_DOWNLOAD_CLASS, "initiateDownload", DOWNLOAD_TEST_RUNNER_NAME,
+ mExtraParams);
+
+ assertTrue("Failed to initiate download properly!", testPassed);
+ Thread.sleep(5000);
+
+ // Do 3 random reboots - after 13, 9, and 19 seconds
+ Log.i(LOG_TAG, "First reboot...");
+ mPMUtils.rebootDevice();
+ Thread.sleep(13000);
+ Log.i(LOG_TAG, "Second reboot...");
+ mPMUtils.rebootDevice();
+ Thread.sleep(9000);
+ Log.i(LOG_TAG, "Third reboot...");
+ mPMUtils.rebootDevice();
+ Thread.sleep(19000);
+ testPassed = mPMUtils.runDeviceTestsDidAllTestsPass(FILE_DOWNLOAD_PKG,
+ FILE_DOWNLOAD_CLASS, "verifyFileDownloadSucceeded", DOWNLOAD_TEST_RUNNER_NAME,
+ mExtraParams);
+ assertTrue("Failed to verify initiated download completed properyly!", testPassed);
+ }
+
+ /**
+ * Spawns a device-based function to test download while WiFi is enabled/disabled multiple times
+ * during the download.
+ *
+ * @throws Exception if the test failed at any point
+ */
+ public void testDownloadMultipleWiFiEnableDisable() throws Exception {
+ mPMUtils.installAppAndVerifyExistsOnDevice(String.format("%s%s%s", getTestAppPath(),
+ File.separator, FILE_DOWNLOAD_APK), FILE_DOWNLOAD_PKG, true);
+
+ boolean testPassed = mPMUtils.runDeviceTestsDidAllTestsPass(FILE_DOWNLOAD_PKG,
+ FILE_DOWNLOAD_CLASS, "runDownloadMultipleWiFiEnableDisable",
+ DOWNLOAD_TEST_RUNNER_NAME, mExtraParams);
+ assertTrue(testPassed);
+ }
+
+ /**
+ * Spawns a device-based function to test switching on/off both airplane mode and WiFi
+ *
+ * @throws Exception if the test failed at any point
+ */
+ public void testDownloadMultipleSwitching() throws Exception {
+ mPMUtils.installAppAndVerifyExistsOnDevice(String.format("%s%s%s", getTestAppPath(),
+ File.separator, FILE_DOWNLOAD_APK), FILE_DOWNLOAD_PKG, true);
+
+ boolean testPassed = mPMUtils.runDeviceTestsDidAllTestsPass(FILE_DOWNLOAD_PKG,
+ FILE_DOWNLOAD_CLASS, "runDownloadMultipleSwitching",
+ DOWNLOAD_TEST_RUNNER_NAME, mExtraParams);
+ assertTrue(testPassed);
+ }
+
+ /**
+ * Spawns a device-based function to test switching on/off airplane mode multiple times
+ *
+ * @throws Exception if the test failed at any point
+ */
+ public void testDownloadMultipleAirplaneModeEnableDisable() throws Exception {
+ mPMUtils.installAppAndVerifyExistsOnDevice(String.format("%s%s%s", getTestAppPath(),
+ File.separator, FILE_DOWNLOAD_APK), FILE_DOWNLOAD_PKG, true);
+
+ boolean testPassed = mPMUtils.runDeviceTestsDidAllTestsPass(FILE_DOWNLOAD_PKG,
+ FILE_DOWNLOAD_CLASS, "runDownloadMultipleAirplaneModeEnableDisable",
+ DOWNLOAD_TEST_RUNNER_NAME, mExtraParams);
+ assertTrue(testPassed);
+ }
+}
diff --git a/core/tests/hosttests/test-apps/DownloadManagerTestApp/Android.mk b/core/tests/hosttests/test-apps/DownloadManagerTestApp/Android.mk
new file mode 100644
index 000000000000..576765c742b0
--- /dev/null
+++ b/core/tests/hosttests/test-apps/DownloadManagerTestApp/Android.mk
@@ -0,0 +1,29 @@
+# Copyright (C) 2010 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+LOCAL_PATH:= $(call my-dir)
+
+include $(CLEAR_VARS)
+
+LOCAL_MODULE_TAGS := tests
+
+LOCAL_SRC_FILES := $(call all-java-files-under, src) \
+ ../../../coretests/src/android/net/DownloadManagerBaseTest.java
+
+LOCAL_STATIC_JAVA_LIBRARIES := android-common frameworks-core-util-lib
+LOCAL_SDK_VERSION := current
+
+LOCAL_PACKAGE_NAME := DownloadManagerTestApp
+
+include $(BUILD_PACKAGE)
diff --git a/core/tests/hosttests/test-apps/DownloadManagerTestApp/AndroidManifest.xml b/core/tests/hosttests/test-apps/DownloadManagerTestApp/AndroidManifest.xml
new file mode 100644
index 000000000000..3f2be3cab6e6
--- /dev/null
+++ b/core/tests/hosttests/test-apps/DownloadManagerTestApp/AndroidManifest.xml
@@ -0,0 +1,35 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2010 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+ package="com.android.frameworks.downloadmanagertests">
+
+ <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
+ <uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
+ <uses-permission android:name="android.permission.CHANGE_WIFI_STATE" />
+ <uses-permission android:name="android.permission.INTERNET" />
+ <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
+ <uses-permission android:name="android.permission.WRITE_SETTINGS" />
+
+ <application android:label="DownloadManagerTestApp">
+ <uses-library android:name="android.test.runner" />
+ </application>
+
+ <instrumentation
+ android:name=".DownloadManagerTestRunner"
+ android:targetPackage="com.android.frameworks.downloadmanagertests"
+ android:label="Frameworks Download Manager Test App" />
+
+</manifest>
diff --git a/core/tests/hosttests/test-apps/DownloadManagerTestApp/src/com/android/frameworks/DownloadManagerTestApp.java b/core/tests/hosttests/test-apps/DownloadManagerTestApp/src/com/android/frameworks/DownloadManagerTestApp.java
new file mode 100644
index 000000000000..ef8135398583
--- /dev/null
+++ b/core/tests/hosttests/test-apps/DownloadManagerTestApp/src/com/android/frameworks/DownloadManagerTestApp.java
@@ -0,0 +1,463 @@
+/*
+ * Copyright (C) 2010 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.frameworks.downloadmanagertests;
+
+import android.content.Context;
+import android.content.Intent;
+import android.database.Cursor;
+import android.net.DownloadManager;
+import android.net.DownloadManager.Query;
+import android.net.DownloadManager.Request;
+import android.net.DownloadManagerBaseTest;
+import android.net.Uri;
+import android.os.Environment;
+import android.os.ParcelFileDescriptor;
+import android.provider.Settings;
+import android.test.suitebuilder.annotation.LargeTest;
+import android.util.Log;
+
+import java.io.DataInputStream;
+import java.io.DataOutputStream;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileOutputStream;
+import java.io.FileWriter;
+
+import coretestutils.http.MockResponse;
+import coretestutils.http.MockWebServer;
+import coretestutils.http.RecordedRequest;
+
+/**
+ * Class to test downloading files from a real (not mock) external server.
+ */
+public class DownloadManagerTestApp extends DownloadManagerBaseTest {
+ protected static String DOWNLOAD_STARTED_FLAG = "DMTEST_DOWNLOAD_STARTED";
+ protected static String LOG_TAG =
+ "com.android.frameworks.downloadmanagertests.DownloadManagerTestApp";
+
+ protected static String DOWNLOAD_500K_FILENAME = "External541kb.apk";
+ protected static long DOWNLOAD_500K_FILESIZE = 570927;
+ protected static String DOWNLOAD_1MB_FILENAME = "External1mb.apk";
+ protected static long DOWNLOAD_1MB_FILESIZE = 1041262;
+ protected static String DOWNLOAD_10MB_FILENAME = "External10mb.apk";
+ protected static long DOWNLOAD_10MB_FILESIZE = 10258741;
+
+ // Values to be obtained from TestRunner
+ private String externalDownloadUriValue = null;
+
+ /**
+ * {@inheritDoc }
+ */
+ @Override
+ public void setUp() throws Exception {
+ super.setUp();
+ DownloadManagerTestRunner mRunner = (DownloadManagerTestRunner)getInstrumentation();
+ externalDownloadUriValue = mRunner.externalDownloadUriValue;
+ assertNotNull(externalDownloadUriValue);
+
+ if (!externalDownloadUriValue.endsWith("/")) {
+ externalDownloadUriValue += "/";
+ }
+ }
+
+ /**
+ * Gets the external URL of the file to download
+ *
+ * @return the Uri of the external file to download
+ */
+ private Uri getExternalFileUri(String file) {
+ return Uri.parse(externalDownloadUriValue + file);
+ }
+
+ /**
+ * Gets the path to the file that flags that a download has started. The file contains the
+ * DownloadManager id of the download being trackted between reboot sessions.
+ *
+ * @return The path of the file tracking that a download has started
+ * @throws InterruptedException if interrupted
+ * @throws Exception if timed out while waiting for SD card to mount
+ */
+ protected String getDownloadStartedFilePath() {
+ String path = Environment.getExternalStorageDirectory().getPath();
+ return path + File.separatorChar + DOWNLOAD_STARTED_FLAG;
+ }
+
+ /**
+ * Common setup steps for downloads.
+ *
+ * Note that these are not included in setUp, so that individual tests can control their own
+ * state between reboots, etc.
+ */
+ protected void doCommonDownloadSetup() throws Exception {
+ setWiFiStateOn(true);
+ setAirplaneModeOn(false);
+ waitForExternalStoreMount();
+ removeAllCurrentDownloads();
+ }
+
+ /**
+ * Initiates a download.
+ *
+ * Queues up a download to the download manager, and saves the DownloadManager's assigned
+ * download ID for this download to a file.
+ *
+ * @throws Exception if unsuccessful
+ */
+ public void initiateDownload() throws Exception {
+ String filename = DOWNLOAD_1MB_FILENAME;
+ mContext.deleteFile(DOWNLOAD_STARTED_FLAG);
+ FileOutputStream fileOutput = mContext.openFileOutput(DOWNLOAD_STARTED_FLAG, 0);
+ DataOutputStream outputFile = null;
+ doCommonDownloadSetup();
+
+ try {
+ long dlRequest = -1;
+
+ // Make sure there are no pending downloads currently going on
+ removeAllCurrentDownloads();
+
+ Uri remoteUri = getExternalFileUri(filename);
+ Request request = new Request(remoteUri);
+
+ dlRequest = mDownloadManager.enqueue(request);
+ waitForDownloadToStart(dlRequest);
+ assertTrue(dlRequest != -1);
+
+ // Store ID of download for later retrieval
+ outputFile = new DataOutputStream(fileOutput);
+ outputFile.writeLong(dlRequest);
+ } finally {
+ if (outputFile != null) {
+ outputFile.flush();
+ outputFile.close();
+ }
+ }
+ }
+
+ /**
+ * Waits for a previously-initiated download and verifies it has completed successfully.
+ *
+ * @throws Exception if unsuccessful
+ */
+ public void verifyFileDownloadSucceeded() throws Exception {
+ String filename = DOWNLOAD_1MB_FILENAME;
+ long filesize = DOWNLOAD_1MB_FILESIZE;
+ long dlRequest = -1;
+ boolean rebootMarkerValid = false;
+ DataInputStream dataInputFile = null;
+
+ setWiFiStateOn(true);
+ setAirplaneModeOn(false);
+
+ try {
+ FileInputStream inFile = mContext.openFileInput(DOWNLOAD_STARTED_FLAG);
+ dataInputFile = new DataInputStream(inFile);
+ dlRequest = dataInputFile.readLong();
+ } catch (Exception e) {
+ // The file was't valid so we just leave the flag false
+ Log.i(LOG_TAG, "Unable to determine initial download id.");
+ throw e;
+ } finally {
+ if (dataInputFile != null) {
+ dataInputFile.close();
+ }
+ mContext.deleteFile(DOWNLOAD_STARTED_FLAG);
+ }
+
+ assertTrue(dlRequest != -1);
+ Cursor cursor = getCursor(dlRequest);
+ ParcelFileDescriptor pfd = null;
+ try {
+ assertTrue("Unable to query last initiated download!", cursor.moveToFirst());
+
+ int columnIndex = cursor.getColumnIndex(DownloadManager.COLUMN_STATUS);
+ int status = cursor.getInt(columnIndex);
+ int currentWaitTime = 0;
+
+ // Wait until the download finishes
+ waitForDownloadOrTimeout(dlRequest);
+
+ Log.i(LOG_TAG, "Verifying download information...");
+ // Verify specific info about the file (size, name, etc)...
+ pfd = mDownloadManager.openDownloadedFile(dlRequest);
+ verifyFileSize(pfd, filesize);
+ } catch (Exception e) {
+ Log.i(LOG_TAG, "error: " + e.toString());
+ throw e;
+ } finally {
+ // Clean up...
+ cursor.close();
+ mDownloadManager.remove(dlRequest);
+ if (pfd != null) {
+ pfd.close();
+ }
+ }
+ }
+
+ /**
+ * Tests downloading a large file over WiFi (~10 Mb).
+ *
+ * @throws Exception if unsuccessful
+ */
+ public void runLargeDownloadOverWiFi() throws Exception {
+ String filename = DOWNLOAD_10MB_FILENAME;
+ long filesize = DOWNLOAD_10MB_FILESIZE;
+ long dlRequest = -1;
+ doCommonDownloadSetup();
+
+ // Make sure there are no pending downloads currently going on
+ removeAllCurrentDownloads();
+
+ Uri remoteUri = getExternalFileUri(filename);
+ Request request = new Request(remoteUri);
+ request.setMediaType(getMimeMapping(DownloadFileType.APK));
+
+ dlRequest = mDownloadManager.enqueue(request);
+
+ // Rather large file, so wait up to 15 mins...
+ waitForDownloadOrTimeout(dlRequest, WAIT_FOR_DOWNLOAD_POLL_TIME, 15 * 60 * 1000);
+
+ Cursor cursor = getCursor(dlRequest);
+ ParcelFileDescriptor pfd = null;
+ try {
+ Log.i(LOG_TAG, "Verifying download information...");
+ // Verify specific info about the file (size, name, etc)...
+ pfd = mDownloadManager.openDownloadedFile(dlRequest);
+ verifyFileSize(pfd, filesize);
+ } finally {
+ if (pfd != null) {
+ pfd.close();
+ }
+ mDownloadManager.remove(dlRequest);
+ cursor.close();
+ }
+ }
+
+ /**
+ * Tests that downloads resume when switching back and forth from having connectivity to
+ * having no connectivity using both WiFi and airplane mode.
+ *
+ * Note: Device has no mobile access when running this test.
+ *
+ * @throws Exception if unsuccessful
+ */
+ public void runDownloadMultipleSwitching() throws Exception {
+ String filename = DOWNLOAD_500K_FILENAME;
+ long filesize = DOWNLOAD_500K_FILESIZE;
+ doCommonDownloadSetup();
+
+ String localDownloadDirectory = Environment.getExternalStorageDirectory().getPath();
+ File downloadedFile = new File(localDownloadDirectory, filename);
+
+ long dlRequest = -1;
+ try {
+ downloadedFile.delete();
+
+ // Make sure there are no pending downloads currently going on
+ removeAllCurrentDownloads();
+
+ Uri remoteUri = getExternalFileUri(filename);
+ Request request = new Request(remoteUri);
+
+ // Local destination of downloaded file
+ Uri localUri = Uri.fromFile(downloadedFile);
+ Log.i(LOG_TAG, "setting localUri to: " + localUri.getPath());
+ request.setDestinationUri(localUri);
+
+ request.setAllowedNetworkTypes(Request.NETWORK_MOBILE | Request.NETWORK_WIFI);
+
+ dlRequest = mDownloadManager.enqueue(request);
+ waitForDownloadToStart(dlRequest);
+ // make sure we're starting to download some data...
+ waitForFileToGrow(downloadedFile);
+
+ // download disable
+ setWiFiStateOn(false);
+
+ // download disable
+ Log.i(LOG_TAG, "Turning on airplane mode...");
+ setAirplaneModeOn(true);
+ Thread.sleep(30 * 1000); // wait 30 secs
+
+ // download disable
+ setWiFiStateOn(true);
+ Thread.sleep(30 * 1000); // wait 30 secs
+
+ // download enable
+ Log.i(LOG_TAG, "Turning off airplane mode...");
+ setAirplaneModeOn(false);
+ Thread.sleep(5 * 1000); // wait 5 seconds
+
+ // download disable
+ Log.i(LOG_TAG, "Turning off WiFi...");
+ setWiFiStateOn(false);
+ Thread.sleep(30 * 1000); // wait 30 secs
+
+ // finally, turn WiFi back on and finish up the download
+ Log.i(LOG_TAG, "Turning on WiFi...");
+ setWiFiStateOn(true);
+ Log.i(LOG_TAG, "Waiting up to 3 minutes for download to complete...");
+ waitForDownloadsOrTimeout(dlRequest, 3 * 60 * 1000);
+ ParcelFileDescriptor pfd = mDownloadManager.openDownloadedFile(dlRequest);
+ verifyFileSize(pfd, filesize);
+ } finally {
+ Log.i(LOG_TAG, "Cleaning up files...");
+ if (dlRequest != -1) {
+ mDownloadManager.remove(dlRequest);
+ }
+ downloadedFile.delete();
+ }
+ }
+
+ /**
+ * Tests that downloads resume when switching on/off WiFi at various intervals.
+ *
+ * Note: Device has no mobile access when running this test.
+ *
+ * @throws Exception if unsuccessful
+ */
+ public void runDownloadMultipleWiFiEnableDisable() throws Exception {
+ String filename = DOWNLOAD_500K_FILENAME;
+ long filesize = DOWNLOAD_500K_FILESIZE;
+ doCommonDownloadSetup();
+
+ String localDownloadDirectory = Environment.getExternalStorageDirectory().getPath();
+ File downloadedFile = new File(localDownloadDirectory, filename);
+ long dlRequest = -1;
+ try {
+ downloadedFile.delete();
+
+ // Make sure there are no pending downloads currently going on
+ removeAllCurrentDownloads();
+
+ Uri remoteUri = getExternalFileUri(filename);
+ Request request = new Request(remoteUri);
+
+ // Local destination of downloaded file
+ Uri localUri = Uri.fromFile(downloadedFile);
+ Log.i(LOG_TAG, "setting localUri to: " + localUri.getPath());
+ request.setDestinationUri(localUri);
+
+ request.setAllowedNetworkTypes(Request.NETWORK_WIFI);
+
+ dlRequest = mDownloadManager.enqueue(request);
+ waitForDownloadToStart(dlRequest);
+ // are we making any progress?
+ waitForFileToGrow(downloadedFile);
+
+ // download disable
+ Log.i(LOG_TAG, "Turning off WiFi...");
+ setWiFiStateOn(false);
+ Thread.sleep(40 * 1000); // wait 40 seconds
+
+ // enable download...
+ Log.i(LOG_TAG, "Turning on WiFi again...");
+ setWiFiStateOn(true);
+ waitForFileToGrow(downloadedFile);
+
+ // download disable
+ Log.i(LOG_TAG, "Turning off WiFi...");
+ setWiFiStateOn(false);
+ Thread.sleep(20 * 1000); // wait 20 seconds
+
+ // enable download...
+ Log.i(LOG_TAG, "Turning on WiFi again...");
+ setWiFiStateOn(true);
+
+ Log.i(LOG_TAG, "Waiting up to 3 minutes for download to complete...");
+ waitForDownloadsOrTimeout(dlRequest, 3 * 60 * 1000);
+ ParcelFileDescriptor pfd = mDownloadManager.openDownloadedFile(dlRequest);
+ verifyFileSize(pfd, filesize);
+ } finally {
+ Log.i(LOG_TAG, "Cleaning up files...");
+ if (dlRequest != -1) {
+ mDownloadManager.remove(dlRequest);
+ }
+ downloadedFile.delete();
+ }
+ }
+
+ /**
+ * Tests that downloads resume when switching on/off Airplane mode numerous times at
+ * various intervals.
+ *
+ * Note: Device has no mobile access when running this test.
+ *
+ * @throws Exception if unsuccessful
+ */
+ public void runDownloadMultipleAirplaneModeEnableDisable() throws Exception {
+ String filename = DOWNLOAD_500K_FILENAME;
+ long filesize = DOWNLOAD_500K_FILESIZE;
+ // make sure WiFi is enabled, and airplane mode is not on
+ doCommonDownloadSetup();
+
+ String localDownloadDirectory = Environment.getExternalStorageDirectory().getPath();
+ File downloadedFile = new File(localDownloadDirectory, filename);
+ long dlRequest = -1;
+ try {
+ downloadedFile.delete();
+
+ // Make sure there are no pending downloads currently going on
+ removeAllCurrentDownloads();
+
+ Uri remoteUri = getExternalFileUri(filename);
+ Request request = new Request(remoteUri);
+
+ // Local destination of downloaded file
+ Uri localUri = Uri.fromFile(downloadedFile);
+ Log.i(LOG_TAG, "setting localUri to: " + localUri.getPath());
+ request.setDestinationUri(localUri);
+
+ request.setAllowedNetworkTypes(Request.NETWORK_WIFI);
+
+ dlRequest = mDownloadManager.enqueue(request);
+ waitForDownloadToStart(dlRequest);
+ // are we making any progress?
+ waitForFileToGrow(downloadedFile);
+
+ // download disable
+ Log.i(LOG_TAG, "Turning on Airplane mode...");
+ setAirplaneModeOn(true);
+ Thread.sleep(60 * 1000); // wait 1 minute
+
+ // download enable
+ Log.i(LOG_TAG, "Turning off Airplane mode...");
+ setAirplaneModeOn(false);
+ // make sure we're starting to download some data...
+ waitForFileToGrow(downloadedFile);
+
+ // reenable the connection to start up the download again
+ Log.i(LOG_TAG, "Turning on Airplane mode again...");
+ setAirplaneModeOn(true);
+ Thread.sleep(20 * 1000); // wait 20 seconds
+
+ // Finish up the download...
+ Log.i(LOG_TAG, "Turning off Airplane mode again...");
+ setAirplaneModeOn(false);
+
+ Log.i(LOG_TAG, "Waiting up to 3 minutes for donwload to complete...");
+ waitForDownloadsOrTimeout(dlRequest, 180 * 1000); // wait up to 3 mins before timeout
+ ParcelFileDescriptor pfd = mDownloadManager.openDownloadedFile(dlRequest);
+ verifyFileSize(pfd, filesize);
+ } finally {
+ Log.i(LOG_TAG, "Cleaning up files...");
+ if (dlRequest != -1) {
+ mDownloadManager.remove(dlRequest);
+ }
+ downloadedFile.delete();
+ }
+ }
+}
diff --git a/core/tests/hosttests/test-apps/DownloadManagerTestApp/src/com/android/frameworks/DownloadManagerTestRunner.java b/core/tests/hosttests/test-apps/DownloadManagerTestApp/src/com/android/frameworks/DownloadManagerTestRunner.java
new file mode 100644
index 000000000000..0f166195b4be
--- /dev/null
+++ b/core/tests/hosttests/test-apps/DownloadManagerTestApp/src/com/android/frameworks/DownloadManagerTestRunner.java
@@ -0,0 +1,63 @@
+/*
+ * Copyright (C) 2010, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.frameworks.downloadmanagertests;
+
+import android.os.Bundle;
+import android.test.InstrumentationTestRunner;
+import android.test.InstrumentationTestSuite;
+import android.util.Log;
+
+import com.android.frameworks.downloadmanagertests.DownloadManagerTestApp;
+
+import junit.framework.TestSuite;
+
+/**
+ * Instrumentation Test Runner for all download manager tests.
+ *
+ * To run the download manager tests:
+ *
+ * adb shell am instrument -e external_download_1mb_uri <uri> external_download_500k_uri <uri> \
+ * -w com.android.frameworks.downloadmanagertests/.DownloadManagerTestRunner
+ */
+
+public class DownloadManagerTestRunner extends InstrumentationTestRunner {
+ private static final String EXTERNAL_DOWNLOAD_URI_KEY = "external_download_uri";
+ public String externalDownloadUriValue = null;
+
+ @Override
+ public TestSuite getAllTests() {
+ TestSuite suite = new InstrumentationTestSuite(this);
+ suite.addTestSuite(DownloadManagerTestApp.class);
+ return suite;
+ }
+
+ @Override
+ public ClassLoader getLoader() {
+ return DownloadManagerTestRunner.class.getClassLoader();
+ }
+
+ @Override
+ public void onCreate(Bundle icicle) {
+ // Extract the extra params passed in from the bundle...
+ String externalDownloadUri = (String) icicle.get(EXTERNAL_DOWNLOAD_URI_KEY);
+ if (externalDownloadUri != null) {
+ externalDownloadUriValue = externalDownloadUri;
+ }
+ super.onCreate(icicle);
+ }
+
+}
diff --git a/core/tests/utillib/Android.mk b/core/tests/utillib/Android.mk
new file mode 100644
index 000000000000..299ea5a2aeec
--- /dev/null
+++ b/core/tests/utillib/Android.mk
@@ -0,0 +1,27 @@
+# Copyright (C) 2010 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+LOCAL_PATH := $(call my-dir)
+
+include $(CLEAR_VARS)
+
+LOCAL_SRC_FILES := $(call all-subdir-java-files)
+
+LOCAL_MODULE := frameworks-core-util-lib
+
+include $(BUILD_STATIC_JAVA_LIBRARY)
+
+# Build the test APKs using their own makefiles
+include $(call all-makefiles-under,$(LOCAL_PATH))
+
diff --git a/core/tests/utillib/src/coretestutils/http/MockResponse.java b/core/tests/utillib/src/coretestutils/http/MockResponse.java
new file mode 100644
index 000000000000..5b03e5fe9019
--- /dev/null
+++ b/core/tests/utillib/src/coretestutils/http/MockResponse.java
@@ -0,0 +1,239 @@
+/*
+ * Copyright (C) 2010 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package coretestutils.http;
+
+import static coretestutils.http.MockWebServer.ASCII;
+
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileNotFoundException;
+import java.io.InputStream;
+import java.io.IOException;
+import java.io.UnsupportedEncodingException;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import android.util.Log;
+
+/**
+ * A scripted response to be replayed by the mock web server.
+ */
+public class MockResponse {
+ private static final byte[] EMPTY_BODY = new byte[0];
+ static final String LOG_TAG = "coretestutils.http.MockResponse";
+
+ private String status = "HTTP/1.1 200 OK";
+ private Map<String, String> headers = new HashMap<String, String>();
+ private byte[] body = EMPTY_BODY;
+ private boolean closeConnectionAfter = false;
+ private String closeConnectionAfterHeader = null;
+ private int closeConnectionAfterXBytes = -1;
+ private int pauseConnectionAfterXBytes = -1;
+ private File bodyExternalFile = null;
+
+ public MockResponse() {
+ addHeader("Content-Length", 0);
+ }
+
+ /**
+ * Returns the HTTP response line, such as "HTTP/1.1 200 OK".
+ */
+ public String getStatus() {
+ return status;
+ }
+
+ public MockResponse setResponseCode(int code) {
+ this.status = "HTTP/1.1 " + code + " OK";
+ return this;
+ }
+
+ /**
+ * Returns the HTTP headers, such as "Content-Length: 0".
+ */
+ public List<String> getHeaders() {
+ List<String> headerStrings = new ArrayList<String>();
+ for (String header : headers.keySet()) {
+ headerStrings.add(header + ": " + headers.get(header));
+ }
+ return headerStrings;
+ }
+
+ public MockResponse addHeader(String header, String value) {
+ headers.put(header.toLowerCase(), value);
+ return this;
+ }
+
+ public MockResponse addHeader(String header, long value) {
+ return addHeader(header, Long.toString(value));
+ }
+
+ public MockResponse removeHeader(String header) {
+ headers.remove(header.toLowerCase());
+ return this;
+ }
+
+ /**
+ * Returns true if the body should come from an external file, false otherwise.
+ */
+ private boolean bodyIsExternal() {
+ return bodyExternalFile != null;
+ }
+
+ /**
+ * Returns an input stream containing the raw HTTP payload.
+ */
+ public InputStream getBody() {
+ if (bodyIsExternal()) {
+ try {
+ return new FileInputStream(bodyExternalFile);
+ } catch (FileNotFoundException e) {
+ Log.e(LOG_TAG, "File not found: " + bodyExternalFile.getAbsolutePath());
+ }
+ }
+ return new ByteArrayInputStream(this.body);
+ }
+
+ public MockResponse setBody(File body) {
+ addHeader("Content-Length", body.length());
+ this.bodyExternalFile = body;
+ return this;
+ }
+
+ public MockResponse setBody(byte[] body) {
+ addHeader("Content-Length", body.length);
+ this.body = body;
+ return this;
+ }
+
+ public MockResponse setBody(String body) {
+ try {
+ return setBody(body.getBytes(ASCII));
+ } catch (UnsupportedEncodingException e) {
+ throw new AssertionError();
+ }
+ }
+
+ /**
+ * Sets the body as chunked.
+ *
+ * Currently chunked body is not supported for external files as bodies.
+ */
+ public MockResponse setChunkedBody(byte[] body, int maxChunkSize) throws IOException {
+ addHeader("Transfer-encoding", "chunked");
+
+ ByteArrayOutputStream bytesOut = new ByteArrayOutputStream();
+ int pos = 0;
+ while (pos < body.length) {
+ int chunkSize = Math.min(body.length - pos, maxChunkSize);
+ bytesOut.write(Integer.toHexString(chunkSize).getBytes(ASCII));
+ bytesOut.write("\r\n".getBytes(ASCII));
+ bytesOut.write(body, pos, chunkSize);
+ bytesOut.write("\r\n".getBytes(ASCII));
+ pos += chunkSize;
+ }
+ bytesOut.write("0\r\n".getBytes(ASCII));
+ this.body = bytesOut.toByteArray();
+ return this;
+ }
+
+ public MockResponse setChunkedBody(String body, int maxChunkSize) throws IOException {
+ return setChunkedBody(body.getBytes(ASCII), maxChunkSize);
+ }
+
+ @Override public String toString() {
+ return status;
+ }
+
+ public boolean shouldCloseConnectionAfter() {
+ return closeConnectionAfter;
+ }
+
+ public MockResponse setCloseConnectionAfter(boolean closeConnectionAfter) {
+ this.closeConnectionAfter = closeConnectionAfter;
+ return this;
+ }
+
+ /**
+ * Sets the header after which sending the server should close the connection.
+ */
+ public MockResponse setCloseConnectionAfterHeader(String header) {
+ closeConnectionAfterHeader = header;
+ setCloseConnectionAfter(true);
+ return this;
+ }
+
+ /**
+ * Returns the header after which sending the server should close the connection.
+ */
+ public String getCloseConnectionAfterHeader() {
+ return closeConnectionAfterHeader;
+ }
+
+ /**
+ * Sets the number of bytes in the body to send before which the server should close the
+ * connection. Set to -1 to unset and send the entire body (default).
+ */
+ public MockResponse setCloseConnectionAfterXBytes(int position) {
+ closeConnectionAfterXBytes = position;
+ setCloseConnectionAfter(true);
+ return this;
+ }
+
+ /**
+ * Returns the number of bytes in the body to send before which the server should close the
+ * connection. Returns -1 if the entire body should be sent (default).
+ */
+ public int getCloseConnectionAfterXBytes() {
+ return closeConnectionAfterXBytes;
+ }
+
+ /**
+ * Sets the number of bytes in the body to send before which the server should pause the
+ * connection (stalls in sending data). Only one pause per response is supported.
+ * Set to -1 to unset pausing (default).
+ */
+ public MockResponse setPauseConnectionAfterXBytes(int position) {
+ pauseConnectionAfterXBytes = position;
+ return this;
+ }
+
+ /**
+ * Returns the number of bytes in the body to send before which the server should pause the
+ * connection (stalls in sending data). (Returns -1 if it should not pause).
+ */
+ public int getPauseConnectionAfterXBytes() {
+ return pauseConnectionAfterXBytes;
+ }
+
+ /**
+ * Returns true if this response is flagged to pause the connection mid-stream, false otherwise
+ */
+ public boolean getShouldPause() {
+ return (pauseConnectionAfterXBytes != -1);
+ }
+
+ /**
+ * Returns true if this response is flagged to close the connection mid-stream, false otherwise
+ */
+ public boolean getShouldClose() {
+ return (closeConnectionAfterXBytes != -1);
+ }
+}
diff --git a/core/tests/utillib/src/coretestutils/http/MockWebServer.java b/core/tests/utillib/src/coretestutils/http/MockWebServer.java
new file mode 100644
index 000000000000..c329ffa518c1
--- /dev/null
+++ b/core/tests/utillib/src/coretestutils/http/MockWebServer.java
@@ -0,0 +1,426 @@
+/*
+ * Copyright (C) 2010 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package coretestutils.http;
+
+import java.io.BufferedInputStream;
+import java.io.BufferedOutputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.File;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.net.MalformedURLException;
+import java.net.ServerSocket;
+import java.net.Socket;
+import java.net.URL;
+import java.util.ArrayList;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Queue;
+import java.util.concurrent.BlockingQueue;
+import java.util.concurrent.Callable;
+import java.util.concurrent.ExecutionException;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Executors;
+import java.util.concurrent.Future;
+import java.util.concurrent.LinkedBlockingQueue;
+import java.util.concurrent.TimeUnit;
+import java.util.concurrent.TimeoutException;
+
+import android.util.Log;
+
+/**
+ * A scriptable web server. Callers supply canned responses and the server
+ * replays them upon request in sequence.
+ *
+ * TODO: merge with the version from libcore/support/src/tests/java once it's in.
+ */
+public final class MockWebServer {
+ static final String ASCII = "US-ASCII";
+ static final String LOG_TAG = "coretestutils.http.MockWebServer";
+
+ private final BlockingQueue<RecordedRequest> requestQueue
+ = new LinkedBlockingQueue<RecordedRequest>();
+ private final BlockingQueue<MockResponse> responseQueue
+ = new LinkedBlockingQueue<MockResponse>();
+ private int bodyLimit = Integer.MAX_VALUE;
+ private final ExecutorService executor = Executors.newCachedThreadPool();
+ // keep Futures around so we can rethrow any exceptions thrown by Callables
+ private final Queue<Future<?>> futures = new LinkedList<Future<?>>();
+ private final Object downloadPauseLock = new Object();
+ // global flag to signal when downloads should resume on the server
+ private volatile boolean downloadResume = false;
+
+ private int port = -1;
+
+ public int getPort() {
+ if (port == -1) {
+ throw new IllegalStateException("Cannot retrieve port before calling play()");
+ }
+ return port;
+ }
+
+ /**
+ * Returns a URL for connecting to this server.
+ *
+ * @param path the request path, such as "/".
+ */
+ public URL getUrl(String path) throws MalformedURLException {
+ return new URL("http://localhost:" + getPort() + path);
+ }
+
+ /**
+ * Sets the number of bytes of the POST body to keep in memory to the given
+ * limit.
+ */
+ public void setBodyLimit(int maxBodyLength) {
+ this.bodyLimit = maxBodyLength;
+ }
+
+ public void enqueue(MockResponse response) {
+ responseQueue.add(response);
+ }
+
+ /**
+ * Awaits the next HTTP request, removes it, and returns it. Callers should
+ * use this to verify the request sent was as intended.
+ */
+ public RecordedRequest takeRequest() throws InterruptedException {
+ return requestQueue.take();
+ }
+
+ public RecordedRequest takeRequestWithTimeout(long timeoutMillis) throws InterruptedException {
+ return requestQueue.poll(timeoutMillis, TimeUnit.MILLISECONDS);
+ }
+
+ public List<RecordedRequest> drainRequests() {
+ List<RecordedRequest> requests = new ArrayList<RecordedRequest>();
+ requestQueue.drainTo(requests);
+ return requests;
+ }
+
+ /**
+ * Starts the server, serves all enqueued requests, and shuts the server
+ * down using the default (server-assigned) port.
+ */
+ public void play() throws IOException {
+ play(0);
+ }
+
+ /**
+ * Starts the server, serves all enqueued requests, and shuts the server
+ * down.
+ *
+ * @param port The port number to use to listen to connections on; pass in 0 to have the
+ * server automatically assign a free port
+ */
+ public void play(int portNumber) throws IOException {
+ final ServerSocket ss = new ServerSocket(portNumber);
+ ss.setReuseAddress(true);
+ port = ss.getLocalPort();
+ submitCallable(new Callable<Void>() {
+ public Void call() throws Exception {
+ int count = 0;
+ while (true) {
+ if (count > 0 && responseQueue.isEmpty()) {
+ ss.close();
+ executor.shutdown();
+ return null;
+ }
+
+ serveConnection(ss.accept());
+ count++;
+ }
+ }
+ });
+ }
+
+ private void serveConnection(final Socket s) {
+ submitCallable(new Callable<Void>() {
+ public Void call() throws Exception {
+ InputStream in = new BufferedInputStream(s.getInputStream());
+ OutputStream out = new BufferedOutputStream(s.getOutputStream());
+
+ int sequenceNumber = 0;
+ while (true) {
+ RecordedRequest request = readRequest(in, sequenceNumber);
+ if (request == null) {
+ if (sequenceNumber == 0) {
+ throw new IllegalStateException("Connection without any request!");
+ } else {
+ break;
+ }
+ }
+ requestQueue.add(request);
+ MockResponse response = computeResponse(request);
+ writeResponse(out, response);
+ if (response.shouldCloseConnectionAfter()) {
+ break;
+ }
+ sequenceNumber++;
+ }
+
+ in.close();
+ out.close();
+ return null;
+ }
+ });
+ }
+
+ private void submitCallable(Callable<?> callable) {
+ Future<?> future = executor.submit(callable);
+ futures.add(future);
+ }
+
+ /**
+ * Check for and raise any exceptions that have been thrown by child threads. Will not block on
+ * children still running.
+ * @throws ExecutionException for the first child thread that threw an exception
+ */
+ public void checkForExceptions() throws ExecutionException, InterruptedException {
+ final int originalSize = futures.size();
+ for (int i = 0; i < originalSize; i++) {
+ Future<?> future = futures.remove();
+ try {
+ future.get(0, TimeUnit.SECONDS);
+ } catch (TimeoutException e) {
+ futures.add(future); // still running
+ }
+ }
+ }
+
+ /**
+ * @param sequenceNumber the index of this request on this connection.
+ */
+ private RecordedRequest readRequest(InputStream in, int sequenceNumber) throws IOException {
+ String request = readAsciiUntilCrlf(in);
+ if (request.equals("")) {
+ return null; // end of data; no more requests
+ }
+
+ List<String> headers = new ArrayList<String>();
+ int contentLength = -1;
+ boolean chunked = false;
+ String header;
+ while (!(header = readAsciiUntilCrlf(in)).equals("")) {
+ headers.add(header);
+ String lowercaseHeader = header.toLowerCase();
+ if (contentLength == -1 && lowercaseHeader.startsWith("content-length:")) {
+ contentLength = Integer.parseInt(header.substring(15).trim());
+ }
+ if (lowercaseHeader.startsWith("transfer-encoding:") &&
+ lowercaseHeader.substring(18).trim().equals("chunked")) {
+ chunked = true;
+ }
+ }
+
+ boolean hasBody = false;
+ TruncatingOutputStream requestBody = new TruncatingOutputStream();
+ List<Integer> chunkSizes = new ArrayList<Integer>();
+ if (contentLength != -1) {
+ hasBody = true;
+ transfer(contentLength, in, requestBody);
+ } else if (chunked) {
+ hasBody = true;
+ while (true) {
+ int chunkSize = Integer.parseInt(readAsciiUntilCrlf(in).trim(), 16);
+ if (chunkSize == 0) {
+ readEmptyLine(in);
+ break;
+ }
+ chunkSizes.add(chunkSize);
+ transfer(chunkSize, in, requestBody);
+ readEmptyLine(in);
+ }
+ }
+
+ if (request.startsWith("GET ")) {
+ if (hasBody) {
+ throw new IllegalArgumentException("GET requests should not have a body!");
+ }
+ } else if (request.startsWith("POST ")) {
+ if (!hasBody) {
+ throw new IllegalArgumentException("POST requests must have a body!");
+ }
+ } else {
+ throw new UnsupportedOperationException("Unexpected method: " + request);
+ }
+
+ return new RecordedRequest(request, headers, chunkSizes,
+ requestBody.numBytesReceived, requestBody.toByteArray(), sequenceNumber);
+ }
+
+ /**
+ * Returns a response to satisfy {@code request}.
+ */
+ private MockResponse computeResponse(RecordedRequest request) throws InterruptedException {
+ if (responseQueue.isEmpty()) {
+ throw new IllegalStateException("Unexpected request: " + request);
+ }
+ return responseQueue.take();
+ }
+
+ private void writeResponse(OutputStream out, MockResponse response) throws IOException {
+ out.write((response.getStatus() + "\r\n").getBytes(ASCII));
+ boolean doCloseConnectionAfterHeader = (response.getCloseConnectionAfterHeader() != null);
+
+ // Send headers
+ String closeConnectionAfterHeader = response.getCloseConnectionAfterHeader();
+ for (String header : response.getHeaders()) {
+ out.write((header + "\r\n").getBytes(ASCII));
+
+ if (doCloseConnectionAfterHeader && header.startsWith(closeConnectionAfterHeader)) {
+ Log.i(LOG_TAG, "Closing connection after header" + header);
+ break;
+ }
+ }
+
+ // Send actual body data
+ if (!doCloseConnectionAfterHeader) {
+ out.write(("\r\n").getBytes(ASCII));
+
+ InputStream body = response.getBody();
+ final int READ_BLOCK_SIZE = 10000; // process blocks this size
+ byte[] currentBlock = new byte[READ_BLOCK_SIZE];
+ int currentBlockSize = 0;
+ int writtenSoFar = 0;
+
+ boolean shouldPause = response.getShouldPause();
+ boolean shouldClose = response.getShouldClose();
+ int pause = response.getPauseConnectionAfterXBytes();
+ int close = response.getCloseConnectionAfterXBytes();
+
+ // Don't bother pausing if it's set to pause -after- the connection should be dropped
+ if (shouldPause && shouldClose && (pause > close)) {
+ shouldPause = false;
+ }
+
+ // Process each block we read in...
+ while ((currentBlockSize = body.read(currentBlock)) != -1) {
+ int startIndex = 0;
+ int writeLength = currentBlockSize;
+
+ // handle the case of pausing
+ if (shouldPause && (writtenSoFar + currentBlockSize >= pause)) {
+ writeLength = pause - writtenSoFar;
+ out.write(currentBlock, 0, writeLength);
+ out.flush();
+ writtenSoFar += writeLength;
+
+ // now pause...
+ try {
+ Log.i(LOG_TAG, "Pausing connection after " + pause + " bytes");
+ // Wait until someone tells us to resume sending...
+ synchronized(downloadPauseLock) {
+ while (!downloadResume) {
+ downloadPauseLock.wait();
+ }
+ // reset resume back to false
+ downloadResume = false;
+ }
+ } catch (InterruptedException e) {
+ Log.e(LOG_TAG, "Server was interrupted during pause in download.");
+ }
+
+ startIndex = writeLength;
+ writeLength = currentBlockSize - writeLength;
+ }
+
+ // handle the case of closing the connection
+ if (shouldClose && (writtenSoFar + writeLength > close)) {
+ writeLength = close - writtenSoFar;
+ out.write(currentBlock, startIndex, writeLength);
+ writtenSoFar += writeLength;
+ Log.i(LOG_TAG, "Closing connection after " + close + " bytes");
+ break;
+ }
+ out.write(currentBlock, startIndex, writeLength);
+ writtenSoFar += writeLength;
+ }
+ }
+ out.flush();
+ }
+
+ /**
+ * Transfer bytes from {@code in} to {@code out} until either {@code length}
+ * bytes have been transferred or {@code in} is exhausted.
+ */
+ private void transfer(int length, InputStream in, OutputStream out) throws IOException {
+ byte[] buffer = new byte[1024];
+ while (length > 0) {
+ int count = in.read(buffer, 0, Math.min(buffer.length, length));
+ if (count == -1) {
+ return;
+ }
+ out.write(buffer, 0, count);
+ length -= count;
+ }
+ }
+
+ /**
+ * Returns the text from {@code in} until the next "\r\n", or null if
+ * {@code in} is exhausted.
+ */
+ private String readAsciiUntilCrlf(InputStream in) throws IOException {
+ StringBuilder builder = new StringBuilder();
+ while (true) {
+ int c = in.read();
+ if (c == '\n' && builder.length() > 0 && builder.charAt(builder.length() - 1) == '\r') {
+ builder.deleteCharAt(builder.length() - 1);
+ return builder.toString();
+ } else if (c == -1) {
+ return builder.toString();
+ } else {
+ builder.append((char) c);
+ }
+ }
+ }
+
+ private void readEmptyLine(InputStream in) throws IOException {
+ String line = readAsciiUntilCrlf(in);
+ if (!line.equals("")) {
+ throw new IllegalStateException("Expected empty but was: " + line);
+ }
+ }
+
+ /**
+ * An output stream that drops data after bodyLimit bytes.
+ */
+ private class TruncatingOutputStream extends ByteArrayOutputStream {
+ private int numBytesReceived = 0;
+ @Override public void write(byte[] buffer, int offset, int len) {
+ numBytesReceived += len;
+ super.write(buffer, offset, Math.min(len, bodyLimit - count));
+ }
+ @Override public void write(int oneByte) {
+ numBytesReceived++;
+ if (count < bodyLimit) {
+ super.write(oneByte);
+ }
+ }
+ }
+
+ /**
+ * Trigger the server to resume sending the download
+ */
+ public void doResumeDownload() {
+ synchronized (downloadPauseLock) {
+ downloadResume = true;
+ downloadPauseLock.notifyAll();
+ }
+ }
+}
diff --git a/core/tests/utillib/src/coretestutils/http/RecordedRequest.java b/core/tests/utillib/src/coretestutils/http/RecordedRequest.java
new file mode 100644
index 000000000000..293ff80dc6e9
--- /dev/null
+++ b/core/tests/utillib/src/coretestutils/http/RecordedRequest.java
@@ -0,0 +1,93 @@
+/*
+ * Copyright (C) 2010 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package coretestutils.http;
+
+import java.util.List;
+
+/**
+ * An HTTP request that came into the mock web server.
+ */
+public final class RecordedRequest {
+ private final String requestLine;
+ private final List<String> headers;
+ private final List<Integer> chunkSizes;
+ private final int bodySize;
+ private final byte[] body;
+ private final int sequenceNumber;
+
+ RecordedRequest(String requestLine, List<String> headers, List<Integer> chunkSizes,
+ int bodySize, byte[] body, int sequenceNumber) {
+ this.requestLine = requestLine;
+ this.headers = headers;
+ this.chunkSizes = chunkSizes;
+ this.bodySize = bodySize;
+ this.body = body;
+ this.sequenceNumber = sequenceNumber;
+ }
+
+ public String getRequestLine() {
+ return requestLine;
+ }
+
+ public List<String> getHeaders() {
+ return headers;
+ }
+
+ /**
+ * Returns the sizes of the chunks of this request's body, or an empty list
+ * if the request's body was empty or unchunked.
+ */
+ public List<Integer> getChunkSizes() {
+ return chunkSizes;
+ }
+
+ /**
+ * Returns the total size of the body of this POST request (before
+ * truncation).
+ */
+ public int getBodySize() {
+ return bodySize;
+ }
+
+ /**
+ * Returns the body of this POST request. This may be truncated.
+ */
+ public byte[] getBody() {
+ return body;
+ }
+
+ /**
+ * Returns the index of this request on its HTTP connection. Since a single
+ * HTTP connection may serve multiple requests, each request is assigned its
+ * own sequence number.
+ */
+ public int getSequenceNumber() {
+ return sequenceNumber;
+ }
+
+ @Override public String toString() {
+ return requestLine;
+ }
+
+ public String getMethod() {
+ return getRequestLine().split(" ")[0];
+ }
+
+ public String getPath() {
+ return getRequestLine().split(" ")[1];
+ }
+}