am fb0c02e7: (-s ours) am c74cd309: am 52c31d04: (-s ours) am 7bc0e8e2: (-s ours) DO NOT MERGE Cts Feature/Profile Annotations
Merge commit 'fb0c02e7271b3eb945e353dbcf83edf173a9b40d'
* commit 'fb0c02e7271b3eb945e353dbcf83edf173a9b40d':
DO NOT MERGE Cts Feature/Profile Annotations
diff --git a/tests/accessibilityservice/res/values/strings.xml b/tests/accessibilityservice/res/values/strings.xml
index 4c717c1..3730f85 100644
--- a/tests/accessibilityservice/res/values/strings.xml
+++ b/tests/accessibilityservice/res/values/strings.xml
@@ -20,31 +20,4 @@
<!-- String title of the mock accessibility service -->
<string name="title_delegating_accessibility_service">Delegating Accessibility Service</string>
- <!-- String title of the accessibility end-to-end test activity -->
- <string name="accessibility_end_to_end_test_activity">End-to-end test</string>
-
- <!-- String value of used as text input -->
- <string name="text_input_blah">Blah</string>
-
- <!-- String value of used as text input -->
- <string name="text_input_blah_blah">Blah blah</string>
-
- <!-- String title of the button -->
- <string name="button_title">Click me</string>
-
- <!-- String value of the first list item -->
- <string name="first_list_item">First list item</string>
-
- <!-- String value of the second list item -->
- <string name="second_list_item">Second list item</string>
-
- <!-- String alert title -->
- <string name="alert_title">Alert title</string>
-
- <!-- String alert message -->
- <string name="alert_message">Alert message</string>
-
- <!-- String notification message -->
- <string name="notification_message">Notification message</string>
-
</resources>
diff --git a/tests/core/luni-io/Android.mk b/tests/core/luni-io/Android.mk
index ed39e03..6669c6a 100644
--- a/tests/core/luni-io/Android.mk
+++ b/tests/core/luni-io/Android.mk
@@ -24,7 +24,7 @@
include $(CLEAR_VARS)
LOCAL_SRC_FILES := $(call all-java-files-under,../../../../libcore/luni/src/test/java/tests/api/java/io) \
- $(call all-java-files-under,../../../../libcore/luni/src/test/java/org/apache/harmony/luni/tests/java/io) \
+ $(call all-java-files-under,../../../../libcore/luni/src/test/java/libcore/java/io) \
$(call all-java-files-under,../../../../libcore/support/src/test/java/) \
$(call all-java-files-under,../../../../libcore/luni/src/test/java/org/apache/harmony/luni/tests/pkg1) \
$(call all-java-files-under,../../../../libcore/luni/src/test/java/org/apache/harmony/luni/tests/pkg2) \
diff --git a/tests/res/drawable/mipmapdrawable.xml b/tests/res/drawable/mipmapdrawable.xml
new file mode 100644
index 0000000..fc6342c
--- /dev/null
+++ b/tests/res/drawable/mipmapdrawable.xml
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ * 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.
+ -->
+
+<mipmap xmlns:android="http://schemas.android.com/apk/res/android">
+ <item android:drawable="@drawable/testimage"/>
+ <item android:drawable="@drawable/start"/>
+</mipmap>
+
diff --git a/tests/res/xml/mipmap_correct.xml b/tests/res/xml/mipmap_correct.xml
new file mode 100644
index 0000000..46cc360
--- /dev/null
+++ b/tests/res/xml/mipmap_correct.xml
@@ -0,0 +1,27 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+ * Copyright (C) 2008 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not
+ * use this file except in compliance with the License. You may obtain a copy of
+ * the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations under
+ * the License.
+ */
+-->
+
+<mipmap xmlns:android="http://schemas.android.com/apk/res/android" >
+ <item android:drawable="@drawable/testimage" />
+ <item>
+ <color android:color="#77ffffff" />
+ </item>
+ <item android:drawable="@drawable/start" />
+</mipmap>
+
diff --git a/tests/res/xml/mipmap_missing_item_drawable.xml b/tests/res/xml/mipmap_missing_item_drawable.xml
new file mode 100644
index 0000000..4ef6ec7
--- /dev/null
+++ b/tests/res/xml/mipmap_missing_item_drawable.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+ * Copyright (C) 2008 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not
+ * use this file except in compliance with the License. You may obtain a copy of
+ * the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations under
+ * the License.
+ */
+-->
+
+<mipmap xmlns:android="http://schemas.android.com/apk/res/android" >
+ <item/>
+</mipmap>
+
diff --git a/tests/src/android/provider/cts/TestSearchRecentSuggestionsProvider.java b/tests/src/android/provider/cts/TestSearchRecentSuggestionsProvider.java
new file mode 100644
index 0000000..d1cb1ef
--- /dev/null
+++ b/tests/src/android/provider/cts/TestSearchRecentSuggestionsProvider.java
@@ -0,0 +1,29 @@
+/*
+ * Copyright (C) 2008 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.provider.cts;
+
+import android.content.SearchRecentSuggestionsProvider;
+
+public class TestSearchRecentSuggestionsProvider extends SearchRecentSuggestionsProvider {
+ final static String AUTHORITY = "android.provider.cts.TestSRSProvider";
+ final static int MODE = DATABASE_MODE_QUERIES + DATABASE_MODE_2LINES;
+
+ public TestSearchRecentSuggestionsProvider() {
+ super();
+ setupSuggestions(AUTHORITY, MODE);
+ }
+}
diff --git a/tests/tests/accessibilityservice/AndroidManifest.xml b/tests/tests/accessibilityservice/AndroidManifest.xml
index 811c87f..b4fe6ab 100644
--- a/tests/tests/accessibilityservice/AndroidManifest.xml
+++ b/tests/tests/accessibilityservice/AndroidManifest.xml
@@ -24,7 +24,7 @@
<uses-library android:name="android.test.runner"/>
<activity android:label="@string/accessibility_end_to_end_test_activity"
- android:name="android.accessibilityservice.cts.AccessibilityEndToEndTestActivity"/>
+ android:name="android.accessibilityservice.cts.AccessibilityEndToEndTestActivity"/>
</application>
diff --git a/tests/tests/accessibilityservice/src/android/accessibilityservice/cts/AccessibilityEndToEndTest.java b/tests/tests/accessibilityservice/src/android/accessibilityservice/cts/AccessibilityEndToEndTest.java
index 5259753..7f5be31 100644
--- a/tests/tests/accessibilityservice/src/android/accessibilityservice/cts/AccessibilityEndToEndTest.java
+++ b/tests/tests/accessibilityservice/src/android/accessibilityservice/cts/AccessibilityEndToEndTest.java
@@ -16,6 +16,8 @@
package android.accessibilityservice.cts;
+import com.android.cts.accessibilityservice.R;
+
import android.accessibilityservice.AccessibilityService;
import android.accessibilityservice.IAccessibilityServiceDelegate;
import android.accessibilityservice.IAccessibilityServiceDelegateConnection;
@@ -47,8 +49,6 @@
import android.widget.EditText;
import android.widget.ListView;
-import com.android.cts.accessibilityservice.R;
-
import junit.framework.TestCase;
import java.util.Iterator;
@@ -56,23 +56,25 @@
import java.util.List;
import java.util.Queue;
+import junit.framework.TestCase;
+
/**
* This class performs end-to-end testing of the accessibility feature by
* creating an {@link Activity} and poking around so {@link AccessibilityEvent}s
* are generated and their correct dispatch verified.
- * </p>
- * Note: The end-to-end test is composed of two APKs, one with a delegating accessibility
+ * <p>
+ * Note: The end-to-end test is composed of two APKs, one with a mock accessibility
* service, another with the instrumented activity and test cases. The motivation for
* two APKs design is that CTS tests cannot access the secure settings which is
* required for enabling accessibility and accessibility services. Therefore, manual
- * installation of the <strong>CtsDelegatingAccessibilityService.apk</strong>
- * whose source is located at <strong>cts/tests/accessibilityservice</strong> is required.
+ * installation of the <strong>CtsAccessibilityServiceTestMockService.apk</strong>
+ * whose source is located at <strong>cts/tests/accessibility</strong> is required.
* Once the former package has been installed accessibility must be enabled (Settings ->
- * Accessibility), the delegating service must be enabled (Settings -> Accessibility
- * -> Delegating Accessibility Service), and then the CTS tests in this package can be
- * successfully run. Further, the delegate and tests run in separate processes since
+ * Accessibility), the mock service must be enabled (Settings -> Accessibility
+ * -> Mock Accessibility Service), and then the CTS tests in this package can be
+ * successfully run. Further, the mock and tests run in separate processes since
* the instrumentation restarts the process in which it is running and this
- * breaks the binding between the delegating accessibility service and the system.
+ * breaks the binding between the mock accessibility service and the system.
*/
public class AccessibilityEndToEndTest extends
ActivityInstrumentationTestCase2<AccessibilityEndToEndTestActivity> {
@@ -114,15 +116,17 @@
* @throws Exception If any error occurs.
*/
public AccessibilityEndToEndTest() throws Exception {
- super("com.android.cts.accessibilityservice", AccessibilityEndToEndTestActivity.class);
+ super(AccessibilityEndToEndTestActivity.class);
}
@Override
protected void setUp() throws Exception {
super.setUp();
- // wait for the activity to settle down so we do not receive
- // the event for its start, thus breaking the tests
- getInstrumentation().waitForIdleSync();
+ // TODO (svetoslavganov): This is a temporary workaround for
+ // nondeterministically failing tests with partially populated events.
+ // It seems that not all times the View hierarchy is fully
+ // instantiated on time. This seems related to bug 2630683.
+ Thread.sleep(500);
}
@LargeTest
@@ -247,7 +251,7 @@
@LargeTest
public void testTypeViewTextChangedAccessibilityEvent() throws Throwable {
- Activity activity = getActivity();
+ final Activity activity = getActivity();
// focus the edit text
final EditText editText = (EditText) activity.findViewById(R.id.edittext);
@@ -677,8 +681,7 @@
receivedEvent.isFullScreen());
TestCase.assertEquals("itemCount has incorrect value", expectedEvent.getItemCount(),
receivedEvent.getItemCount());
- // This will fail due to a bug fixed in Gingerbread. Bug 2593810 (removed the method).
- // assertEqualsNotificationAsParcelableData(expectedEvent, receivedEvent);
+ assertEqualsNotificationAsParcelableData(expectedEvent, receivedEvent);
TestCase.assertEquals("password has incorrect value", expectedEvent.isPassword(),
receivedEvent.isPassword());
TestCase.assertEquals("removedCount has incorrect value", expectedEvent
@@ -687,6 +690,30 @@
}
/**
+ * Compares the {@link android.os.Parcelable} data of the
+ * <code>expectedEvent</code> and <code>receivedEvent</code> to verify
+ * that the received event is the one that is expected.
+ */
+ private void assertEqualsNotificationAsParcelableData(AccessibilityEvent expectedEvent,
+ AccessibilityEvent receivedEvent) {
+ String message = "parcelableData has incorrect value";
+ Notification expectedNotification = (Notification) expectedEvent.getParcelableData();
+ Notification receivedNotification = (Notification) receivedEvent.getParcelableData();
+
+ if (expectedNotification == null) {
+ if (receivedNotification == null) {
+ return;
+ }
+ }
+
+ TestCase.assertNotNull(message, receivedNotification);
+
+ // we do a very simple sanity check
+ TestCase.assertEquals(message, expectedNotification.tickerText.toString(),
+ receivedNotification.tickerText.toString());
+ }
+
+ /**
* Compares the text of the <code>expectedEvent</code> and
* <code>receivedEvent</code> by comparing the string representation of
* the corresponding {@link CharSequence}s.
diff --git a/tests/tests/accessibilityservice/src/android/accessibilityservice/cts/AccessibilityEndToEndTestActivity.java b/tests/tests/accessibilityservice/src/android/accessibilityservice/cts/AccessibilityEndToEndTestActivity.java
index e806622..adfc9e6 100644
--- a/tests/tests/accessibilityservice/src/android/accessibilityservice/cts/AccessibilityEndToEndTestActivity.java
+++ b/tests/tests/accessibilityservice/src/android/accessibilityservice/cts/AccessibilityEndToEndTestActivity.java
@@ -16,6 +16,8 @@
package android.accessibilityservice.cts;
+import com.android.cts.accessibilityservice.R;
+
import android.app.Activity;
import android.content.Context;
import android.os.Bundle;
@@ -26,8 +28,6 @@
import android.widget.ListView;
import android.widget.TextView;
-import com.android.cts.accessibilityservice.R;
-
/**
* This class is an {@link Activity} used to perform end-to-end
* testing of the accessibility feature by interaction with the
diff --git a/tests/tests/accessibilityservice/src/android/accessibilityservice/cts/AccessibilityServiceInfoTest.java b/tests/tests/accessibilityservice/src/android/accessibilityservice/cts/AccessibilityServiceInfoTest.java
index 48b4aae..ab7ecd7 100644
--- a/tests/tests/accessibilityservice/src/android/accessibilityservice/cts/AccessibilityServiceInfoTest.java
+++ b/tests/tests/accessibilityservice/src/android/accessibilityservice/cts/AccessibilityServiceInfoTest.java
@@ -72,8 +72,7 @@
receivedInfo.eventTypes);
assertEquals("feedbackType not marshalled properly", sentInfo.feedbackType,
receivedInfo.feedbackType);
- // This will fail here and is fixed in Froyo. Bug 2448479.
- // assertEquals("flags not marshalled properly", sentInfo.flags, receivedInfo.flags);
+ assertEquals("flags not marshalled properly", sentInfo.flags, receivedInfo.flags);
assertEquals("notificationTimeout not marshalled properly", sentInfo.notificationTimeout,
receivedInfo.notificationTimeout);
assertEquals("packageNames not marshalled properly", sentInfo.packageNames.length,
diff --git a/tests/tests/app/src/android/app/cts/InstrumentationTest.java b/tests/tests/app/src/android/app/cts/InstrumentationTest.java
index 1861ae2..ab9e991 100644
--- a/tests/tests/app/src/android/app/cts/InstrumentationTest.java
+++ b/tests/tests/app/src/android/app/cts/InstrumentationTest.java
@@ -960,6 +960,10 @@
}
@Override
+ public void invalidatePanelMenu(int featureId) {
+ }
+
+ @Override
public void takeSurface(SurfaceHolder.Callback2 callback) {
}
diff --git a/tests/tests/content/src/android/content/cts/ContentProviderTest.java b/tests/tests/content/src/android/content/cts/ContentProviderTest.java
index 0824e84..eabd470 100644
--- a/tests/tests/content/src/android/content/cts/ContentProviderTest.java
+++ b/tests/tests/content/src/android/content/cts/ContentProviderTest.java
@@ -394,6 +394,15 @@
public Bundle call(String method, String request, Bundle args) {
return null;
}
+
+ public String[] getStreamTypes(Uri url, String mimeTypeFilter) throws RemoteException {
+ return null;
+ }
+
+ public AssetFileDescriptor openTypedAssetFile(Uri url, String mimeType, Bundle opts)
+ throws RemoteException, FileNotFoundException {
+ return null;
+ }
};
assertNull(ContentProvider.coerceToLocalContentProvider(iContentProvider));
}
diff --git a/tests/tests/database/src/android/database/cts/AbstractCursorTest.java b/tests/tests/database/src/android/database/cts/AbstractCursorTest.java
index 47c52ba..8f5fead 100644
--- a/tests/tests/database/src/android/database/cts/AbstractCursorTest.java
+++ b/tests/tests/database/src/android/database/cts/AbstractCursorTest.java
@@ -453,16 +453,9 @@
method = "getUpdatedField",
args = {int.class}
)
- @ToBeFixed(bug = "1569265", explanation = "All other updating-related methods are 'hide' and "
- + "'deprecated.")
public void testGetUpdatedField() {
mTestAbstractCursor.moveToFirst();
- try {
- assertEquals("hello", mTestAbstractCursor.getUpdatedField(0));
- fail("getUpdatedField should throws a NullPointerException here.");
- } catch (NullPointerException e) {
- // expected
- }
+ assertNull(mTestAbstractCursor.getUpdatedField(0));
}
@TestTargetNew(
@@ -746,12 +739,6 @@
return mRows.length;
}
- @Deprecated
- @Override
- public boolean deleteRow() {
- return false;
- }
-
@Override
public String[] getColumnNames() {
return mColumnNames;
diff --git a/tests/tests/database/src/android/database/cts/CursorWrapperTest.java b/tests/tests/database/src/android/database/cts/CursorWrapperTest.java
index dba9784..df90237 100644
--- a/tests/tests/database/src/android/database/cts/CursorWrapperTest.java
+++ b/tests/tests/database/src/android/database/cts/CursorWrapperTest.java
@@ -750,7 +750,17 @@
private void setupDatabase() {
File dbDir = getContext().getDir("tests", Context.MODE_PRIVATE);
- mDatabaseFile = new File(dbDir, "database_test.db");
+ /* don't use the same database name as the one in super class
+ * this class's setUp() method deletes a database file just opened by super.setUp().
+ * that can cause corruption in database in the following situation:
+ * super.setUp() creates the database, inserts some data into it.
+ * this class setUp() deletes just the database file but not the associated
+ * database files such as wal, shm files.
+ * solution is to have this class delete the whole database directory.
+ * better yet, this class shouldn't extend DatabaseCursortest at all.
+ * TODO: fix this bogus cts class hierarchy
+ */
+ mDatabaseFile = new File(dbDir, "cursor_test.db");
if (mDatabaseFile.exists()) {
mDatabaseFile.delete();
}
diff --git a/tests/tests/database/src/android/database/cts/DatabaseCursorTest.java b/tests/tests/database/src/android/database/cts/DatabaseCursorTest.java
index f60638a..da9710c 100644
--- a/tests/tests/database/src/android/database/cts/DatabaseCursorTest.java
+++ b/tests/tests/database/src/android/database/cts/DatabaseCursorTest.java
@@ -107,43 +107,6 @@
}
@MediumTest
- public void testCursorUpdate() {
- mDatabase.execSQL("CREATE TABLE test (_id INTEGER PRIMARY KEY, d INTEGER, s INTEGER);");
- for (int i = 0; i < 20; i++) {
- mDatabase.execSQL("INSERT INTO test (d, s) VALUES (" + i + "," + i % 2 + ");");
- }
-
- Cursor testCursor = getTestCursor(mDatabase.query("test", null, "s = 0", null, null, null,
- null));
-
- int dCol = testCursor.getColumnIndexOrThrow("d");
- int sCol = testCursor.getColumnIndexOrThrow("s");
-
- int count = 0;
- while (testCursor.moveToNext()) {
- assertTrue(testCursor.updateInt(dCol, 3));
- count++;
- }
- assertEquals(10, count);
-
- assertTrue(testCursor.commitUpdates());
-
- assertTrue(testCursor.requery());
-
- count = 0;
- while (testCursor.moveToNext()) {
- assertEquals(3, testCursor.getInt(dCol));
- count++;
- }
-
- assertEquals(10, count);
- assertTrue(testCursor.moveToFirst());
- assertTrue(testCursor.deleteRow());
- assertEquals(9, testCursor.getCount());
- testCursor.close();
- }
-
- @MediumTest
public void testBlob() throws Exception {
// create table
mDatabase.execSQL(
@@ -182,23 +145,6 @@
assertEquals(s, testCursor.getString(sCol));
assertEquals((double) d, testCursor.getDouble(dCol));
assertEquals((long) l, testCursor.getLong(lCol));
-
- // new byte[]
- byte[] newblob = new byte[1000];
- value = 98;
- Arrays.fill(blob, value);
-
- testCursor.updateBlob(bCol, newblob);
- cBlob = testCursor.getBlob(bCol);
- assertTrue(Arrays.equals(newblob, cBlob));
-
- // commit
- assertTrue(testCursor.commitUpdates());
- assertTrue(testCursor.requery());
- testCursor.moveToNext();
- cBlob = testCursor.getBlob(bCol);
- assertTrue(Arrays.equals(newblob, cBlob));
- testCursor.close();
}
@MediumTest
diff --git a/tests/tests/database/src/android/database/cts/DatabaseUtilsTest.java b/tests/tests/database/src/android/database/cts/DatabaseUtilsTest.java
index c47b65b..ae2a204 100644
--- a/tests/tests/database/src/android/database/cts/DatabaseUtilsTest.java
+++ b/tests/tests/database/src/android/database/cts/DatabaseUtilsTest.java
@@ -33,11 +33,15 @@
import android.database.sqlite.SQLiteException;
import android.database.sqlite.SQLiteStatement;
import android.os.Parcel;
+import android.os.ParcelFileDescriptor;
import android.test.AndroidTestCase;
+import android.test.MoreAsserts;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileNotFoundException;
+import java.io.IOException;
+import java.io.InputStream;
import java.io.PrintStream;
@TestTargetClass(android.database.DatabaseUtils.class)
@@ -64,6 +68,8 @@
assertNotNull(mDatabase);
mDatabase.execSQL("CREATE TABLE " + TABLE_NAME + " (_id INTEGER PRIMARY KEY, " +
"name TEXT, age INTEGER, address TEXT);");
+ mDatabase.execSQL(
+ "CREATE TABLE blob_test (_id INTEGER PRIMARY KEY, name TEXT, data BLOB)");
}
@Override
@@ -769,11 +775,98 @@
args = new String[] { "1000" }; // NO people can be older than this.
try {
- DatabaseUtils.stringForQuery(statement, args);
+ DatabaseUtils.blobFileDescriptorForQuery(statement, args);
fail("should throw SQLiteDoneException");
} catch (SQLiteDoneException e) {
// expected
}
statement.close();
}
-}
\ No newline at end of file
+
+ @TestTargets({
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ method = "blobFileDescriptorForQuery",
+ args = {android.database.sqlite.SQLiteDatabase.class, java.lang.String.class,
+ java.lang.String[].class}
+ ),
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ method = "blobFileDescriptorForQuery",
+ args = {android.database.sqlite.SQLiteStatement.class, java.lang.String[].class}
+ )
+ })
+ public void testBlobFileDescriptorForQuery() throws Exception {
+ String data1 = "5300FEFF";
+ String data2 = "DECAFBAD";
+ mDatabase.execSQL("INSERT INTO blob_test (name, data) VALUES ('Mike', X'" + data1 + "')");
+
+ String query = "SELECT data FROM blob_test";
+ assertFileDescriptorContent(parseBlob(data1),
+ DatabaseUtils.blobFileDescriptorForQuery(mDatabase, query, null));
+
+ mDatabase.execSQL("INSERT INTO blob_test (name, data) VALUES ('Jack', X'" + data2 + "');");
+ query = "SELECT data FROM blob_test WHERE name = ?";
+ String[] args = new String[] { "Jack" };
+ assertFileDescriptorContent(parseBlob(data2),
+ DatabaseUtils.blobFileDescriptorForQuery(mDatabase, query, args));
+
+ args = new String[] { "No such name" };
+ try {
+ DatabaseUtils.stringForQuery(mDatabase, query, args);
+ fail("should throw SQLiteDoneException");
+ } catch (SQLiteDoneException e) {
+ // expected
+ }
+
+ query = "SELECT data FROM blob_test WHERE name = ?;";
+ SQLiteStatement statement = mDatabase.compileStatement(query);
+ args = new String[] { "Mike" };
+ assertFileDescriptorContent(parseBlob(data1),
+ DatabaseUtils.blobFileDescriptorForQuery(statement, args));
+
+ args = new String[] { "No such name" };
+ try {
+ DatabaseUtils.blobFileDescriptorForQuery(statement, args);
+ fail("should throw SQLiteDoneException");
+ } catch (SQLiteDoneException e) {
+ // expected
+ }
+ statement.close();
+ }
+
+ private static byte[] parseBlob(String src) {
+ int len = src.length();
+ byte[] result = new byte[len / 2];
+
+ for (int i = 0; i < len/2; i++) {
+ int val;
+ char c1 = src.charAt(i*2);
+ char c2 = src.charAt(i*2+1);
+ int val1 = Character.digit(c1, 16);
+ int val2 = Character.digit(c2, 16);
+ val = (val1 << 4) | val2;
+ result[i] = (byte)val;
+ }
+ return result;
+ }
+
+ private static void assertFileDescriptorContent(byte[] expected, ParcelFileDescriptor fd)
+ throws IOException {
+ assertInputStreamContent(expected, new ParcelFileDescriptor.AutoCloseInputStream(fd));
+ }
+
+ private static void assertInputStreamContent(byte[] expected, InputStream is)
+ throws IOException {
+ try {
+ byte[] observed = new byte[expected.length];
+ int count = is.read(observed);
+ assertEquals(expected.length, count);
+ assertEquals(-1, is.read());
+ MoreAsserts.assertEquals(expected, observed);
+ } finally {
+ is.close();
+ }
+ }
+
+}
diff --git a/tests/tests/database/src/android/database/sqlite/cts/SQLiteCursorTest.java b/tests/tests/database/src/android/database/sqlite/cts/SQLiteCursorTest.java
index ae5b9d4..d608c2f 100644
--- a/tests/tests/database/src/android/database/sqlite/cts/SQLiteCursorTest.java
+++ b/tests/tests/database/src/android/database/sqlite/cts/SQLiteCursorTest.java
@@ -24,6 +24,7 @@
import android.content.Context;
import android.database.AbstractCursor;
+import android.database.Cursor;
import android.database.CursorWindow;
import android.database.DataSetObserver;
import android.database.StaleDataException;
@@ -79,8 +80,8 @@
TEST_SQL, TABLE_NAME);
try {
new SQLiteCursor(mDatabase, cursorDriver, TABLE_NAME, null);
- fail("constructor didn't throw NullPointerException when SQLiteQuery is null");
- } catch (NullPointerException e) {
+ fail("constructor didn't throw IllegalArgumentException when SQLiteQuery is null");
+ } catch (IllegalArgumentException e) {
}
// get SQLiteCursor by querying database
@@ -221,6 +222,44 @@
@TestTargets({
@TestTargetNew(
level = TestLevel.COMPLETE,
+ method = "requery",
+ args = {}
+ )
+ })
+ public void testRequery2() {
+ mDatabase.disableWriteAheadLogging();
+ mDatabase.execSQL("create table testRequery2 (i int);");
+ mDatabase.execSQL("insert into testRequery2 values(1);");
+ mDatabase.execSQL("insert into testRequery2 values(2);");
+ Cursor c = mDatabase.rawQuery("select * from testRequery2 order by i", null);
+ assertEquals(2, c.getCount());
+ assertTrue(c.moveToFirst());
+ assertEquals(1, c.getInt(0));
+ assertTrue(c.moveToNext());
+ assertEquals(2, c.getInt(0));
+ // add more data to the table and requery
+ mDatabase.execSQL("insert into testRequery2 values(3);");
+ assertTrue(c.requery());
+ assertEquals(3, c.getCount());
+ assertTrue(c.moveToFirst());
+ assertEquals(1, c.getInt(0));
+ assertTrue(c.moveToNext());
+ assertEquals(2, c.getInt(0));
+ assertTrue(c.moveToNext());
+ assertEquals(3, c.getInt(0));
+ // close the database and see if requery throws an exception
+ mDatabase.close();
+ try {
+ c.requery();
+ fail("expected IllegalStateException");
+ } catch (IllegalStateException e) {
+ // expected
+ }
+ }
+
+ @TestTargets({
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
method = "getColumnIndex",
args = {java.lang.String.class}
),
@@ -242,16 +281,6 @@
@TestTargetNew(
level = TestLevel.COMPLETE,
- method = "getDatabase",
- args = {}
- )
- public void testGetDatabase() {
- SQLiteCursor cursor = getCursor();
- assertSame(mDatabase, cursor.getDatabase());
- }
-
- @TestTargetNew(
- level = TestLevel.COMPLETE,
method = "setSelectionArguments",
args = {java.lang.String[].class}
)
diff --git a/tests/tests/database/src/android/database/sqlite/cts/SQLiteDatabaseTest.java b/tests/tests/database/src/android/database/sqlite/cts/SQLiteDatabaseTest.java
index 7a18cd8..e5d5a30 100644
--- a/tests/tests/database/src/android/database/sqlite/cts/SQLiteDatabaseTest.java
+++ b/tests/tests/database/src/android/database/sqlite/cts/SQLiteDatabaseTest.java
@@ -18,10 +18,7 @@
import java.io.File;
import java.util.ArrayList;
-import java.util.Iterator;
import java.util.Locale;
-import java.util.Map;
-import java.util.Set;
import android.content.ContentValues;
import android.database.Cursor;
@@ -37,6 +34,8 @@
import android.database.sqlite.SQLiteTransactionListener;
import android.test.AndroidTestCase;
import android.test.MoreAsserts;
+import android.test.suitebuilder.annotation.LargeTest;
+import android.test.suitebuilder.annotation.SmallTest;
import dalvik.annotation.TestTargets;
import dalvik.annotation.TestTargetNew;
import dalvik.annotation.TestLevel;
@@ -150,6 +149,7 @@
}
File dbFile = new File(mDatabaseDir, "database_test12345678.db");
+ dbFile.delete();
assertFalse(dbFile.exists());
db = SQLiteDatabase.openOrCreateDatabase(dbFile.getPath(), factory);
assertNotNull(db);
@@ -338,88 +338,6 @@
}
}
- @SuppressWarnings("deprecation")
- @TestTargets({
- @TestTargetNew(
- level = TestLevel.COMPLETE,
- notes = "Test getSyncedTables()",
- method = "getSyncedTables",
- args = {}
- ),
- @TestTargetNew(
- level = TestLevel.COMPLETE,
- notes = "Test markTableSyncable(String, String)",
- method = "markTableSyncable",
- args = {java.lang.String.class, java.lang.String.class}
- )
- })
- public void testGetSyncedTables() {
- mDatabase.execSQL("CREATE TABLE people (_id INTEGER PRIMARY KEY, name TEXT, "
- + "_sync_dirty INTEGER);");
- mDatabase.execSQL("CREATE TABLE _delete_people (name TEXT);");
- Map<String, String> tableMap = mDatabase.getSyncedTables();
- assertEquals(0, tableMap.size());
- mDatabase.markTableSyncable("people", "_delete_people");
- tableMap = mDatabase.getSyncedTables();
- assertEquals(1, tableMap.size());
- Set<String> keys = tableMap.keySet();
- Iterator<String> iterator = keys.iterator();
- assertTrue(iterator.hasNext());
- assertEquals("people", iterator.next());
- assertEquals("_delete_people", tableMap.get("people"));
- assertFalse(iterator.hasNext());
-
- // test sync
- mDatabase.execSQL("INSERT INTO people VALUES (0, \"foo\", 0);");
- Cursor c = mDatabase.query("people", new String[] {"_id", "name" },
- "_id = 0", null, null, null, null);
- assertTrue(c.moveToFirst());
- c.updateString(1, "updated");
- c.commitUpdates();
- c.close();
- c = mDatabase.query("people", new String[] {"_id", "_sync_dirty" },
- "_id = 0", null, null, null, null);
- assertTrue(c.moveToFirst());
- // _sync_dirty flag has been set
- assertEquals(1, c.getInt(1));
- c.close();
- }
-
- @SuppressWarnings("deprecation")
- @TestTargetNew(
- level = TestLevel.COMPLETE,
- notes = "Test markTableSyncable(String, String, String)",
- method = "markTableSyncable",
- args = {java.lang.String.class, java.lang.String.class, java.lang.String.class}
- )
- public void testMarkTableSyncable() {
- mDatabase.execSQL("CREATE TABLE phone (_id INTEGER PRIMARY KEY, _people_id INTEGER, " +
- "name TEXT);");
- mDatabase.execSQL("CREATE TABLE people (_id INTEGER PRIMARY KEY, " +
- "name TEXT, _sync_dirty INTEGER);");
- mDatabase.markTableSyncable("phone", "_people_id", "people");
-
- Map<String, String> tableMap = mDatabase.getSyncedTables();
- // since no delete table was given, there is no mapping
- assertEquals(0, tableMap.size());
-
- // test sync
- mDatabase.execSQL("INSERT INTO people VALUES (13, \"foo\", 0);");
- mDatabase.execSQL("INSERT INTO phone VALUES (0, 13, \"bar\");");
- Cursor c = mDatabase.query("phone", new String[] {"_id", "name" },
- "_id = 0", null, null, null, null);
- assertTrue(c.moveToFirst());
- c.updateString(1, "updated");
- c.commitUpdates();
- c.close();
- c = mDatabase.query("people", new String[] {"_id", "_sync_dirty" },
- "_id = 13", null, null, null, null);
- assertTrue(c.moveToFirst());
- // _sync_dirty flag has been set
- assertEquals(1, c.getInt(1));
- c.close();
- }
-
@TestTargets({
@TestTargetNew(
level = TestLevel.COMPLETE,
@@ -546,7 +464,8 @@
mDatabase.execSQL("INSERT INTO test (name, age, address) VALUES ('Jim', 35, 'Chicago');");
// delete one record.
- mDatabase.delete(TABLE_NAME, "name = 'Mike'", null);
+ int count = mDatabase.delete(TABLE_NAME, "name = 'Mike'", null);
+ assertEquals(1, count);
Cursor cursor = mDatabase.query(TABLE_NAME, TEST_PROJECTION, null,
null, null, null, null);
@@ -564,7 +483,8 @@
cursor.close();
// delete another record.
- mDatabase.delete(TABLE_NAME, "name = ?", new String[] { "Jack" });
+ count = mDatabase.delete(TABLE_NAME, "name = ?", new String[] { "Jack" });
+ assertEquals(1, count);
cursor = mDatabase.query(TABLE_NAME, TEST_PROJECTION, null, null, null,
null, null);
@@ -581,7 +501,8 @@
mDatabase.execSQL("INSERT INTO test (name, age, address) VALUES ('Jack', 30, 'London');");
// delete all records.
- mDatabase.delete(TABLE_NAME, null, null);
+ count = mDatabase.delete(TABLE_NAME, null, null);
+ assertEquals(3, count);
cursor = mDatabase.query(TABLE_NAME, TEST_PROJECTION, null, null, null, null, null);
assertNotNull(cursor);
@@ -1594,4 +1515,128 @@
assertEquals(1, cursor.getInt(0));
assertEquals(2, cursor.getInt(1));
}
+
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ notes = "test enableWriteAheadLogging",
+ method = "enableWriteAheadLogging",
+ args = {}
+ )
+ /**
+ * With sqlite's write-ahead-logging (WAL) enabled, readers get old version of data
+ * from the table that a writer is modifying at the same time.
+ * <p>
+ * This method does the following to test this sqlite3 feature
+ * <ol>
+ * <li>creates a table in the database and populates it with 5 rows of data</li>
+ * <li>do "select count(*) from this_table" and expect to receive 5</li>
+ * <li>start a writer thread who BEGINs a transaction, INSERTs a single row
+ * into this_table</li>
+ * <li>writer stops the transaction at this point, kicks off a reader thread - which will
+ * do the above SELECT query: "select count(*) from this_table"</li>
+ * <li>this query should return value 5 - because writer is still in transaction and
+ * sqlite returns OLD version of the data</li>
+ * <li>writer ends the transaction, thus making the extra row now visible to everyone</li>
+ * <li>reader is kicked off again to do the same query. this time query should
+ * return value = 6 which includes the newly inserted row into this_table.</li>
+ *</p>
+ * @throws InterruptedException
+ */
+ @LargeTest
+ public void testReaderGetsOldVersionOfDataWhenWriterIsInXact() throws InterruptedException {
+ // redo setup to create WAL enabled database
+ mDatabase.close();
+ new File(mDatabase.getPath()).delete();
+ mDatabase = SQLiteDatabase.openOrCreateDatabase(mDatabaseFile.getPath(), null, null);
+ boolean rslt = mDatabase.enableWriteAheadLogging();
+ assertTrue(rslt);
+ assertNotNull(mDatabase);
+
+ // create a new table and insert 5 records into it.
+ mDatabase.execSQL("CREATE TABLE t1 (i int, j int);");
+ mDatabase.beginTransaction();
+ for (int i = 0; i < 5; i++) {
+ mDatabase.execSQL("insert into t1 values(?,?);", new String[] {i+"", i+""});
+ }
+ mDatabase.setTransactionSuccessful();
+ mDatabase.endTransaction();
+
+ // make sure a reader can read the above data
+ ReaderQueryingData r1 = new ReaderQueryingData(5);
+ r1.start();
+ Thread.yield();
+ try {r1.join();} catch (Exception e) {}
+
+ WriterDoingSingleTransaction w = new WriterDoingSingleTransaction();
+ w.start();
+ w.join();
+ }
+
+ private class WriterDoingSingleTransaction extends Thread {
+ @Override public void run() {
+ // start a transaction
+ mDatabase.beginTransactionNonExclusive();
+ mDatabase.execSQL("insert into t1 values(?,?);", new String[] {"11", "11"});
+ assertTrue(mDatabase.isOpen());
+
+ // while the writer is in a transaction, start a reader and make sure it can still
+ // read 5 rows of data (= old data prior to the current transaction)
+ ReaderQueryingData r1 = new ReaderQueryingData(5);
+ r1.start();
+ try {r1.join();} catch (Exception e) {}
+
+ // now, have the writer do the select count(*)
+ // it should execute on the same connection as this transaction
+ // and count(*) should reflect the newly inserted row
+ Long l = DatabaseUtils.longForQuery(mDatabase, "select count(*) from t1", null);
+ assertEquals(6, l.intValue());
+
+ // end transaction
+ mDatabase.setTransactionSuccessful();
+ mDatabase.endTransaction();
+
+ // reader should now be able to read 6 rows = new data AFTER this transaction
+ r1 = new ReaderQueryingData(6);
+ r1.start();
+ try {r1.join();} catch (Exception e) {}
+ }
+ }
+
+ private class ReaderQueryingData extends Thread {
+ private int count;
+ /**
+ * constructor with a param to indicate the number of rows expected to be read
+ */
+ public ReaderQueryingData(int count) {
+ this.count = count;
+ }
+ @Override public void run() {
+ Long l = DatabaseUtils.longForQuery(mDatabase, "select count(*) from t1", null);
+ assertEquals(count, l.intValue());
+ }
+ }
+
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ notes = "test exceptions from enableWriteAheadLogging().",
+ method = "enableWriteAheadLogging",
+ args = {}
+ )
+ public void testExceptionsFromEnableWriteAheadLogging() {
+ // attach a database
+ // redo setup to create WAL enabled database
+ mDatabase.close();
+ new File(mDatabase.getPath()).delete();
+ mDatabase = SQLiteDatabase.openOrCreateDatabase(mDatabaseFile.getPath(), null, null);
+
+ // attach a database and call enableWriteAheadLogging - should not be allowed
+ mDatabase.execSQL("attach database ':memory:' as memoryDb");
+ boolean rslt = mDatabase.enableWriteAheadLogging();
+ assertFalse(rslt);
+ // enableWriteAheadLogging on memory database is not allowed
+ SQLiteDatabase db = SQLiteDatabase.create(null);
+ rslt = db.enableWriteAheadLogging();
+ assertFalse(rslt);
+ db.close();
+ }
}
diff --git a/tests/tests/database/src/android/database/sqlite/cts/SQLiteProgramTest.java b/tests/tests/database/src/android/database/sqlite/cts/SQLiteProgramTest.java
index 89918a1..a9a3293 100644
--- a/tests/tests/database/src/android/database/sqlite/cts/SQLiteProgramTest.java
+++ b/tests/tests/database/src/android/database/sqlite/cts/SQLiteProgramTest.java
@@ -20,13 +20,13 @@
import dalvik.annotation.TestTargetClass;
import dalvik.annotation.TestTargetNew;
import dalvik.annotation.TestTargets;
-import dalvik.annotation.ToBeFixed;
import android.content.Context;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteDoneException;
import android.database.sqlite.SQLiteException;
+import android.database.sqlite.SQLiteQuery;
import android.database.sqlite.SQLiteStatement;
import android.test.AndroidTestCase;
import android.test.MoreAsserts;
@@ -37,9 +37,6 @@
private SQLiteDatabase mDatabase;
- @ToBeFixed(bug="1448885", explanation="SQLiteProgram is an abstract class and its " +
- "constructor is package private, so it can not be extended directly to test. " +
- "For this reason, the test uses SQLiteStatement instead.")
@Override
protected void setUp() throws Exception {
super.setUp();
@@ -57,79 +54,6 @@
super.tearDown();
}
- @TestTargetNew(
- level = TestLevel.COMPLETE,
- notes = "Test getUniqueId()",
- method = "getUniqueId",
- args = {}
- )
- public void testGetUniqueId() {
- mDatabase.execSQL("CREATE TABLE test (_id INTEGER PRIMARY KEY, text1 TEXT, text2 TEXT, " +
- "num1 INTEGER, num2 INTEGER, image BLOB);");
- final String statement = "DELETE FROM test WHERE _id=?;";
- SQLiteStatement statementOne = mDatabase.compileStatement(statement);
- SQLiteStatement statementTwo = mDatabase.compileStatement(statement);
- // since the same compiled statement is being accessed at the same time by 2 different
- // objects, they each get their own statement id
- assertTrue(statementOne.getUniqueId() != statementTwo.getUniqueId());
- statementOne.close();
- statementTwo.close();
-
- statementOne = mDatabase.compileStatement(statement);
- int n = statementOne.getUniqueId();
- statementOne.close();
- statementTwo = mDatabase.compileStatement(statement);
- assertEquals(n, statementTwo.getUniqueId());
- statementTwo.close();
-
- // now try to compile 2 different statements and they should have different uniquerIds.
- SQLiteStatement statement1 = mDatabase.compileStatement("DELETE FROM test WHERE _id=1;");
- SQLiteStatement statement2 = mDatabase.compileStatement("DELETE FROM test WHERE _id=2;");
- assertTrue(statement1.getUniqueId() != statement2.getUniqueId());
- statement1.close();
- statement2.close();
- }
-
- @TestTargetNew(
- level = TestLevel.COMPLETE,
- notes = "Test onAllReferencesReleased(). Since sql statements are always cached in " +
- "SQLiteDatabase, compiledSql should NOT be released " +
- "when onAllReferencesReleased() is called",
- method = "onAllReferencesReleased",
- args = {}
- )
- public void testOnAllReferencesReleased() {
- mDatabase.execSQL("CREATE TABLE test (_id INTEGER PRIMARY KEY, text1 TEXT, text2 TEXT, " +
- "num1 INTEGER, num2 INTEGER, image BLOB);");
- final String statement = "DELETE FROM test WHERE _id=?;";
- SQLiteStatement statementOne = mDatabase.compileStatement(statement);
- assertTrue(statementOne.getUniqueId() > 0);
- int nStatement = statementOne.getUniqueId();
- statementOne.releaseReference();
- assertTrue(statementOne.getUniqueId() == nStatement);
- statementOne.close();
- }
-
- @TestTargetNew(
- level = TestLevel.COMPLETE,
- notes = "Test onAllReferencesReleasedFromContainer(). " +
- "Since sql statements are always cached in " +
- "SQLiteDatabase, compiledSql should NOT be released " +
- "when onAllReferencesReleasedFromContainer() is called",
- args = {}
- )
- public void testOnAllReferencesReleasedFromContainer() {
- mDatabase.execSQL("CREATE TABLE test (_id INTEGER PRIMARY KEY, text1 TEXT, text2 TEXT, " +
- "num1 INTEGER, num2 INTEGER, image BLOB);");
- final String statement = "DELETE FROM test WHERE _id=?;";
- SQLiteStatement statementOne = mDatabase.compileStatement(statement);
- assertTrue(statementOne.getUniqueId() > 0);
- int nStatement = statementOne.getUniqueId();
- statementOne.releaseReferenceFromContainer();
- assertTrue(statementOne.getUniqueId() == nStatement);
- statementOne.close();
- }
-
@TestTargets({
@TestTargetNew(
level = TestLevel.COMPLETE,
@@ -195,39 +119,36 @@
}
statement.close();
- statement = mDatabase.compileStatement("SELECT text1 FROM test;");
+ Cursor cursor = null;
try {
- statement.bindString(1, "foo");
+ cursor = mDatabase.query("test", new String[]{"text1"}, "where text1='a'",
+ new String[]{"foo"}, null, null, null);
fail("Should throw exception (no value to bind)");
} catch (SQLiteException expected) {
// expected
- }
-
- statement =
- mDatabase.compileStatement("SELECT text1 FROM test WHERE text2 = ? AND num2 = ?;");
-
- try {
- statement.bindString(0, "Jack");
- fail("Should throw exception (index is 0)");
- } catch (SQLiteException expected) {
- // expected
+ } finally {
+ if (cursor != null) {
+ cursor.close();
+ }
}
try {
- statement.bindLong(-1, 30);
- fail("Should throw exception (index is negative)");
- } catch (SQLiteException expected) {
- // expected
- }
- try {
- statement.bindDouble(3, 589.0);
+ cursor = mDatabase.query("test", new String[]{"text1"}, "where text1='a'",
+ new String[]{"foo", "bar"}, null, null, null);
fail("Should throw exception (index too large)");
} catch (SQLiteException expected) {
// expected
+ } finally {
+ if (cursor != null) {
+ cursor.close();
+ }
}
// test positive case
+ statement = mDatabase.compileStatement(
+ "SELECT text1 FROM test WHERE text2 = ? AND num2 = ?;");
statement.bindString(1, "Jack");
statement.bindLong(2, 30);
assertEquals("Mike", statement.simpleQueryForString());
+ statement.close();
}
@TestTargetNew(
@@ -303,64 +224,4 @@
MoreAsserts.assertEquals(blob, value);
cursor.close();
}
-
- @TestTargets({
- @TestTargetNew(
- level = TestLevel.NOT_FEASIBLE,
- method = "onAllReferencesReleased",
- args = {}
- ),
- @TestTargetNew(
- level = TestLevel.NOT_FEASIBLE,
- method = "onAllReferencesReleasedFromContainer",
- args = {}
- ),
- @TestTargetNew(
- level = TestLevel.NOT_FEASIBLE,
- method = "compile",
- args = {java.lang.String.class, boolean.class}
- ),
- @TestTargetNew(
- level = TestLevel.NOT_FEASIBLE,
- method = "native_bind_blob",
- args = {int.class, byte[].class}
- ),
- @TestTargetNew(
- level = TestLevel.NOT_FEASIBLE,
- method = "native_bind_double",
- args = {int.class, double.class}
- ),
- @TestTargetNew(
- level = TestLevel.NOT_FEASIBLE,
- method = "native_bind_long",
- args = {int.class, long.class}
- ),
- @TestTargetNew(
- level = TestLevel.NOT_FEASIBLE,
- method = "native_bind_null",
- args = {int.class}
- ),
- @TestTargetNew(
- level = TestLevel.NOT_FEASIBLE,
- method = "native_compile",
- args = {java.lang.String.class}
- )
- })
- @ToBeFixed(bug = "1448885", explanation = "Cannot test protected methods, since constructor" +
- " is private.")
- public void testProtectedMethods() {
- // cannot test
- }
-
- private void closeDatabaseWithOrphanedStatement(){
- try {
- mDatabase.close();
- } catch (SQLiteException e) {
- // A SQLiteException is thrown if there are some unfinialized exceptions
- // This is expected as some tests explicitly leave statements in this state
- if (!e.getMessage().equals("Unable to close due to unfinalised statements")) {
- throw e;
- }
- }
- }
}
diff --git a/tests/tests/database/src/android/database/sqlite/cts/SQLiteStatementTest.java b/tests/tests/database/src/android/database/sqlite/cts/SQLiteStatementTest.java
index ec6b79a..828045a 100644
--- a/tests/tests/database/src/android/database/sqlite/cts/SQLiteStatementTest.java
+++ b/tests/tests/database/src/android/database/sqlite/cts/SQLiteStatementTest.java
@@ -21,19 +21,35 @@
import dalvik.annotation.TestTargetNew;
import dalvik.annotation.TestTargets;
+import android.content.ContentValues;
import android.content.Context;
import android.database.Cursor;
+import android.database.DatabaseUtils;
import android.database.SQLException;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteDoneException;
import android.database.sqlite.SQLiteStatement;
+import android.os.ParcelFileDescriptor;
import android.test.AndroidTestCase;
+import android.test.MoreAsserts;
+
+import java.io.IOException;
+import java.io.InputStream;
@TestTargetClass(android.database.sqlite.SQLiteStatement.class)
public class SQLiteStatementTest extends AndroidTestCase {
private static final String STRING1 = "this is a test";
private static final String STRING2 = "another test";
+ private static final byte[][] BLOBS = new byte [][] {
+ parseBlob("86FADCF1A820666AEBD0789F47932151A2EF734269E8AC4E39630AB60519DFD8"),
+ new byte[0],
+ null,
+ parseBlob("00"),
+ parseBlob("FF"),
+ parseBlob("D7B500FECF25F7A4D83BF823D3858690790F2526013DE6CAE9A69170E2A1E47238"),
+ };
+
private static final String DATABASE_NAME = "database_test.db";
private static final int CURRENT_DATABASE_VERSION = 42;
@@ -60,40 +76,62 @@
mDatabase.execSQL("CREATE TABLE test (_id INTEGER PRIMARY KEY, data TEXT);");
}
+ private void populateBlobTable() {
+ mDatabase.execSQL("CREATE TABLE blob_test (_id INTEGER PRIMARY KEY, data BLOB)");
+ for (int i = 0; i < BLOBS.length; i++) {
+ ContentValues values = new ContentValues();
+ values.put("_id", i);
+ values.put("data", BLOBS[i]);
+ mDatabase.insert("blob_test", null, values);
+ }
+ }
+
@TestTargetNew(
level = TestLevel.COMPLETE,
- method = "execute",
+ method = "executeUpdateDelete",
args = {}
)
public void testExecute() {
+ mDatabase.disableWriteAheadLogging();
populateDefaultTable();
- Cursor c = mDatabase.query("test", null, null, null, null, null, null);
- assertEquals(0, c.getCount());
+ assertEquals(0, DatabaseUtils.longForQuery(mDatabase, "select count(*) from test", null));
- // test insert
- SQLiteStatement statement = mDatabase.compileStatement(
- "INSERT INTO test (data) VALUES ('" + STRING1 + "')");
- statement.execute();
+ // test update
+ // insert 2 rows and then update them.
+ SQLiteStatement statement1 = mDatabase.compileStatement(
+ "INSERT INTO test (data) VALUES ('" + STRING2 + "')");
+ assertEquals(1, statement1.executeInsert());
+ assertEquals(2, statement1.executeInsert());
+ SQLiteStatement statement2 =
+ mDatabase.compileStatement("UPDATE test set data = 'a' WHERE _id > 0");
+ assertEquals(2, statement2.executeUpdateDelete());
+ statement2.close();
+ // should still have 2 rows in the table
+ assertEquals(2, DatabaseUtils.longForQuery(mDatabase, "select count(*) from test", null));
- c = mDatabase.query("test", null, null, null, null, null, null);
- assertEquals(1, c.getCount());
+ // test delete
+ // insert 2 more rows and delete 3 of them
+ assertEquals(3, statement1.executeInsert());
+ assertEquals(4, statement1.executeInsert());
+ statement1.close();
+ statement2 = mDatabase.compileStatement("DELETE from test WHERE _id < 4");
+ assertEquals(3, statement2.executeUpdateDelete());
+ statement2.close();
+ // should still have 1 row1 in the table
+ assertEquals(1, DatabaseUtils.longForQuery(mDatabase, "select count(*) from test", null));
- c.moveToFirst();
- assertEquals(STRING1, c.getString(c.getColumnIndex("data")));
-
- // invalid SQL statement
- statement = mDatabase.compileStatement(
- "SELECT * FROM test WHERE data=\"" + STRING1 + "\"");
+ // if the SQL statement is something that causes rows of data to
+ // be returned, executeUpdateDelete() (and execute()) throw an exception.
+ statement2 = mDatabase.compileStatement("SELECT count(*) FROM test");
try {
- statement.execute();
- fail("There should be a SQLException thrown out.");
+ statement2.executeUpdateDelete();
+ fail("exception expected");
} catch (SQLException e) {
- // expected.
+ // expected
+ } finally {
+ statement2.close();
}
-
- c.deactivate();
- statement.close();
}
@TestTargets({
@@ -118,25 +156,33 @@
SQLiteStatement statement = mDatabase.compileStatement(
"INSERT INTO test (data) VALUES ('" + STRING2 + "')");
assertEquals(1, statement.executeInsert());
+ statement.close();
+
+ // try to insert another row with the same id. last inserted rowid should be -1
+ statement = mDatabase.compileStatement("insert or ignore into test values(1, 1);");
+ assertEquals(-1, statement.executeInsert());
+ statement.close();
c = mDatabase.query("test", null, null, null, null, null, null);
assertEquals(1, c.getCount());
c.moveToFirst();
assertEquals(STRING2, c.getString(c.getColumnIndex("data")));
+ c.close();
- // invalid SQL statement
+ // if the sql statement is something that causes rows of data to
+ // be returned, executeInsert() throws an exception
statement = mDatabase.compileStatement(
"SELECT * FROM test WHERE data=\"" + STRING2 + "\"");
try {
statement.executeInsert();
- fail("There should be a SQLException thrown out.");
+ fail("exception expected");
} catch (SQLException e) {
- // expected.
- }
+ // expected
+ } finally {
+ statement.close();
- c.deactivate();
- statement.close();
+ }
}
@TestTargetNew(
@@ -196,4 +242,177 @@
statement.close();
}
+
+ @TestTargetNew(
+ level = TestLevel.PARTIAL_COMPLETE,
+ method = "simpleQueryForBlobFileDescriptor",
+ args = {}
+ )
+ public void testSimpleQueryForBlobFileDescriptorSuccessNormal() throws IOException {
+ doTestSimpleQueryForBlobFileDescriptorSuccess(0);
+ }
+
+ @TestTargetNew(
+ level = TestLevel.PARTIAL_COMPLETE,
+ method = "simpleQueryForBlobFileDescriptor",
+ args = {}
+ )
+ public void testSimpleQueryForBlobFileDescriptorSuccessEmpty() throws IOException {
+ doTestSimpleQueryForBlobFileDescriptorSuccess(1);
+ }
+
+ @TestTargetNew(
+ level = TestLevel.PARTIAL_COMPLETE,
+ method = "simpleQueryForBlobFileDescriptor",
+ args = {}
+ )
+ public void testSimpleQueryForBlobFileDescriptorSuccessNull() {
+ populateBlobTable();
+
+ String sql = "SELECT data FROM blob_test WHERE _id = " + 2;
+ SQLiteStatement stm = mDatabase.compileStatement(sql);
+ assertNull(stm.simpleQueryForBlobFileDescriptor());
+ }
+
+ @TestTargetNew(
+ level = TestLevel.PARTIAL_COMPLETE,
+ method = "simpleQueryForBlobFileDescriptor",
+ args = {}
+ )
+ public void testSimpleQueryForBlobFileDescriptorSuccess00() throws IOException {
+ doTestSimpleQueryForBlobFileDescriptorSuccess(3);
+ }
+
+ @TestTargetNew(
+ level = TestLevel.PARTIAL_COMPLETE,
+ method = "simpleQueryForBlobFileDescriptor",
+ args = {}
+ )
+ public void testSimpleQueryForBlobFileDescriptorSuccessFF() throws IOException {
+ doTestSimpleQueryForBlobFileDescriptorSuccess(4);
+ }
+
+ @TestTargetNew(
+ level = TestLevel.PARTIAL_COMPLETE,
+ method = "simpleQueryForBlobFileDescriptor",
+ args = {}
+ )
+ public void testSimpleQueryForBlobFileDescriptorSuccessEmbeddedNul() throws IOException {
+ doTestSimpleQueryForBlobFileDescriptorSuccess(5);
+ }
+
+ private void doTestSimpleQueryForBlobFileDescriptorSuccess(int i) throws IOException {
+ populateBlobTable();
+
+ String sql = "SELECT data FROM blob_test WHERE _id = " + i;
+ SQLiteStatement stm = mDatabase.compileStatement(sql);
+ ParcelFileDescriptor fd = stm.simpleQueryForBlobFileDescriptor();
+ assertFileDescriptorContent(BLOBS[i], fd);
+ }
+
+ @TestTargetNew(
+ level = TestLevel.PARTIAL_COMPLETE,
+ method = "simpleQueryForBlobFileDescriptor",
+ args = {}
+ )
+ public void testSimpleQueryForBlobFileDescriptorSuccessParam() throws IOException {
+ populateBlobTable();
+
+ String sql = "SELECT data FROM blob_test WHERE _id = ?";
+ SQLiteStatement stm = mDatabase.compileStatement(sql);
+ stm.bindLong(1, 0);
+ ParcelFileDescriptor fd = stm.simpleQueryForBlobFileDescriptor();
+ assertFileDescriptorContent(BLOBS[0], fd);
+ }
+
+ @TestTargetNew(
+ level = TestLevel.PARTIAL_COMPLETE,
+ method = "simpleQueryForBlobFileDescriptor",
+ args = {}
+ )
+ public void testGetBlobFailureNoParam() throws Exception {
+ populateBlobTable();
+
+ String sql = "SELECT data FROM blob_test WHERE _id = 100";
+ SQLiteStatement stm = mDatabase.compileStatement(sql);
+ ParcelFileDescriptor fd = null;
+ SQLiteDoneException expectedException = null;
+ try {
+ fd = stm.simpleQueryForBlobFileDescriptor();
+ } catch (SQLiteDoneException ex) {
+ expectedException = ex;
+ } finally {
+ if (fd != null) {
+ fd.close();
+ fd = null;
+ }
+ }
+ assertNotNull("Should have thrown SQLiteDoneException", expectedException);
+ }
+
+ @TestTargetNew(
+ level = TestLevel.PARTIAL_COMPLETE,
+ method = "simpleQueryForBlobFileDescriptor",
+ args = {}
+ )
+ public void testGetBlobFailureParam() throws Exception {
+ populateBlobTable();
+
+ String sql = "SELECT data FROM blob_test WHERE _id = ?";
+ SQLiteStatement stm = mDatabase.compileStatement(sql);
+ stm.bindLong(1, 100);
+ ParcelFileDescriptor fd = null;
+ SQLiteDoneException expectedException = null;
+ try {
+ fd = stm.simpleQueryForBlobFileDescriptor();
+ } catch (SQLiteDoneException ex) {
+ expectedException = ex;
+ } finally {
+ if (fd != null) {
+ fd.close();
+ fd = null;
+ }
+ }
+ assertNotNull("Should have thrown SQLiteDoneException", expectedException);
+ }
+
+ /*
+ * Convert string of hex digits to byte array.
+ * Results are undefined for poorly formed string.
+ *
+ * @param src hex string
+ */
+ private static byte[] parseBlob(String src) {
+ int len = src.length();
+ byte[] result = new byte[len / 2];
+
+ for (int i = 0; i < len/2; i++) {
+ int val;
+ char c1 = src.charAt(i*2);
+ char c2 = src.charAt(i*2+1);
+ int val1 = Character.digit(c1, 16);
+ int val2 = Character.digit(c2, 16);
+ val = (val1 << 4) | val2;
+ result[i] = (byte)val;
+ }
+ return result;
+ }
+
+ private static void assertFileDescriptorContent(byte[] expected, ParcelFileDescriptor fd)
+ throws IOException {
+ assertInputStreamContent(expected, new ParcelFileDescriptor.AutoCloseInputStream(fd));
+ }
+
+ private static void assertInputStreamContent(byte[] expected, InputStream is)
+ throws IOException {
+ try {
+ byte[] observed = new byte[expected.length];
+ int count = is.read(observed);
+ assertEquals(expected.length, count);
+ assertEquals(-1, is.read());
+ MoreAsserts.assertEquals(expected, observed);
+ } finally {
+ is.close();
+ }
+ }
}
diff --git a/tests/tests/graphics/src/android/graphics/cts/CanvasTest.java b/tests/tests/graphics/src/android/graphics/cts/CanvasTest.java
index 07612d4..b00a383 100644
--- a/tests/tests/graphics/src/android/graphics/cts/CanvasTest.java
+++ b/tests/tests/graphics/src/android/graphics/cts/CanvasTest.java
@@ -96,7 +96,6 @@
)
public void testCanvas1() {
final Canvas c = new Canvas();
- assertNull(c.getGL());
}
@TestTargetNew(
@@ -128,36 +127,6 @@
new Canvas(mMutableBitmap);
}
- @TestTargets({
- @TestTargetNew(
- level = TestLevel.COMPLETE,
- method = "Canvas",
- args = {javax.microedition.khronos.opengles.GL.class}
- ),
- @TestTargetNew(
- level = TestLevel.COMPLETE,
- method = "getGL",
- args = {}
- )
- })
- public void testCanvas3() {
- Canvas c = new Canvas();
- assertNull(c.getGL());
- final MyGL myGL = new MyGL();
- c = new Canvas(myGL);
- assertTrue(myGL.equals(c.getGL()));
- }
-
- @TestTargetNew(
- level = TestLevel.COMPLETE,
- method = "freeGlCaches",
- args = {}
- )
- public void testFreeGlCaches() {
- // can't get the changed state
- Canvas.freeGlCaches();
- }
-
@TestTargetNew(
level = TestLevel.COMPLETE,
method = "setBitmap",
@@ -173,16 +142,6 @@
// expected
}
- // abnormal case: GL not null
- final Canvas c = new Canvas(new MyGL());
- try {
- c.setBitmap(mMutableBitmap);
- fail("should throw out RuntimeException when setting MutableBitmap to Canvas "
- + "when the Canvas is created with GL");
- } catch (RuntimeException e) {
- // expected
- }
-
// abnormal case: bitmap to be set has been recycled
mMutableBitmap.recycle();
try {
@@ -199,39 +158,6 @@
assertEquals(31, mCanvas.getHeight());
}
- @TestTargets({
- @TestTargetNew(
- level = TestLevel.COMPLETE,
- method = "setViewport",
- args = {int.class, int.class}
- ),
- @TestTargetNew(
- level = TestLevel.COMPLETE,
- method = "getWidth",
- args = {}
- ),
- @TestTargetNew(
- level = TestLevel.COMPLETE,
- method = "getHeight",
- args = {}
- )
- })
- public void testSetViewport() {
- assertEquals(BITMAP_WIDTH, mCanvas.getWidth());
- assertEquals(BITMAP_HEIGHT, mCanvas.getHeight());
-
- // set viewport has no effect for bitmap based canvas
- mCanvas.setViewport(BITMAP_HEIGHT, BITMAP_WIDTH);
- assertEquals(BITMAP_WIDTH, mCanvas.getWidth());
- assertEquals(BITMAP_HEIGHT, mCanvas.getHeight());
-
- // only GL based canvas that can set viewport
- mCanvas = new Canvas(new MyGL());
- mCanvas.setViewport(BITMAP_HEIGHT, BITMAP_WIDTH);
- assertEquals(BITMAP_HEIGHT, mCanvas.getWidth());
- assertEquals(BITMAP_WIDTH, mCanvas.getHeight());
- }
-
@TestTargetNew(
level = TestLevel.COMPLETE,
method = "isOpaque",
@@ -2266,8 +2192,4 @@
assertEquals(0.0f, values[7]);
assertEquals(1.0f, values[8]);
}
-
- private class MyGL implements GL {
- //do nothing
- }
}
diff --git a/tests/tests/graphics/src/android/graphics/drawable/cts/MipmapDrawableTest.java b/tests/tests/graphics/src/android/graphics/drawable/cts/MipmapDrawableTest.java
new file mode 100644
index 0000000..c591f3c
--- /dev/null
+++ b/tests/tests/graphics/src/android/graphics/drawable/cts/MipmapDrawableTest.java
@@ -0,0 +1,371 @@
+/*
+ * Copyright (C) 2008 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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.graphics.drawable.cts;
+
+import com.android.cts.stub.R;
+
+import dalvik.annotation.TestTargetClass;
+import dalvik.annotation.ToBeFixed;
+
+import org.xmlpull.v1.XmlPullParser;
+import org.xmlpull.v1.XmlPullParserException;
+
+import android.content.res.Resources;
+import android.content.res.XmlResourceParser;
+import android.graphics.Canvas;
+import android.graphics.ColorFilter;
+import android.graphics.Rect;
+import android.graphics.drawable.ColorDrawable;
+import android.graphics.drawable.Drawable;
+import android.graphics.drawable.MipmapDrawable;
+import android.graphics.drawable.DrawableContainer.DrawableContainerState;
+import android.test.InstrumentationTestCase;
+import android.util.Xml;
+
+import java.io.IOException;
+
+@TestTargetClass(MipmapDrawable.class)
+public class MipmapDrawableTest extends InstrumentationTestCase {
+ private MockMipmapDrawable mMipmapDrawable;
+
+ private Resources mResources;
+
+ private DrawableContainerState mDrawableContainerState;
+
+ @Override
+ protected void setUp() throws Exception {
+ super.setUp();
+ mMipmapDrawable = new MockMipmapDrawable();
+ mDrawableContainerState = (DrawableContainerState) mMipmapDrawable.getConstantState();
+ mResources = getInstrumentation().getTargetContext().getResources();
+ }
+
+ public void testMipmapDrawable() {
+ new MipmapDrawable();
+ // Check the values set in the constructor
+ assertNotNull(new MipmapDrawable().getConstantState());
+ assertTrue(new MockMipmapDrawable().hasCalledOnBoundsChanged());
+ }
+
+ public void testAddDrawable() {
+ assertEquals(0, mDrawableContainerState.getChildCount());
+
+ // nothing happens if drawable is null
+ mMipmapDrawable.reset();
+ mMipmapDrawable.addDrawable(null);
+ assertEquals(0, mDrawableContainerState.getChildCount());
+ assertFalse(mMipmapDrawable.hasCalledOnBoundsChanged());
+
+ mMipmapDrawable.reset();
+ mMipmapDrawable.addDrawable(new MockDrawable());
+ assertEquals(1, mDrawableContainerState.getChildCount());
+ assertTrue(mMipmapDrawable.hasCalledOnBoundsChanged());
+
+ mMipmapDrawable.reset();
+ mMipmapDrawable.addDrawable(new MockDrawable());
+ assertEquals(2, mDrawableContainerState.getChildCount());
+ assertTrue(mMipmapDrawable.hasCalledOnBoundsChanged());
+ }
+
+ public void testSortedByHeight() {
+ Drawable small = new MockDrawable(8);
+ Drawable medium = new MockDrawable(32);
+ Drawable large = new MockDrawable(128);
+
+ mMipmapDrawable.addDrawable(medium);
+ assertSame(medium, mDrawableContainerState.getChildren()[0]);
+
+ mMipmapDrawable.addDrawable(small);
+ assertSame(small, mDrawableContainerState.getChildren()[0]);
+ assertSame(medium, mDrawableContainerState.getChildren()[1]);
+
+ mMipmapDrawable.addDrawable(large);
+ assertSame(small, mDrawableContainerState.getChildren()[0]);
+ assertSame(medium, mDrawableContainerState.getChildren()[1]);
+ assertSame(large, mDrawableContainerState.getChildren()[2]);
+
+ mMipmapDrawable.addDrawable(small);
+ assertSame(small, mDrawableContainerState.getChildren()[0]);
+ assertSame(small, mDrawableContainerState.getChildren()[1]);
+ assertSame(medium, mDrawableContainerState.getChildren()[2]);
+ assertSame(large, mDrawableContainerState.getChildren()[3]);
+
+ mMipmapDrawable.addDrawable(medium);
+ assertSame(small, mDrawableContainerState.getChildren()[0]);
+ assertSame(small, mDrawableContainerState.getChildren()[1]);
+ assertSame(medium, mDrawableContainerState.getChildren()[2]);
+ assertSame(medium, mDrawableContainerState.getChildren()[3]);
+ assertSame(large, mDrawableContainerState.getChildren()[4]);
+
+ mMipmapDrawable.addDrawable(large);
+ assertSame(small, mDrawableContainerState.getChildren()[0]);
+ assertSame(small, mDrawableContainerState.getChildren()[1]);
+ assertSame(medium, mDrawableContainerState.getChildren()[2]);
+ assertSame(medium, mDrawableContainerState.getChildren()[3]);
+ assertSame(large, mDrawableContainerState.getChildren()[4]);
+ assertSame(large, mDrawableContainerState.getChildren()[5]);
+ }
+
+ public void testSetBoundsOneItem() {
+ // the method is not called if same bounds are set
+ mMipmapDrawable.reset();
+ mMipmapDrawable.setBounds(mMipmapDrawable.getBounds());
+ assertFalse(mMipmapDrawable.hasCalledOnBoundsChanged());
+
+ // the method is called if different bounds are set, even without drawables
+ mMipmapDrawable.reset();
+ mMipmapDrawable.setBounds(new Rect(0, 0, 0, mMipmapDrawable.getBounds().height() + 1));
+ assertTrue(mMipmapDrawable.hasCalledOnBoundsChanged());
+
+ // adding an item should check bounds to see if new drawable is more appropriate
+ mMipmapDrawable.reset();
+ Drawable item = new MockDrawable(42);
+ mMipmapDrawable.addDrawable(item);
+ assertTrue(mMipmapDrawable.hasCalledOnBoundsChanged());
+
+ // the method is called if different bounds are set
+ mMipmapDrawable.setBounds(new Rect(0, 0, 0, mMipmapDrawable.getBounds().height() + 1));
+ assertTrue(mMipmapDrawable.hasCalledOnBoundsChanged());
+
+ // check that correct drawable is selected for any size.
+ mMipmapDrawable.setBounds(new Rect(0, 0, 0, item.getIntrinsicHeight() - 1));
+ assertSame(item, mMipmapDrawable.getCurrent());
+
+ mMipmapDrawable.setBounds(new Rect(0, 0, 0, item.getIntrinsicHeight()));
+ assertSame(item, mMipmapDrawable.getCurrent());
+
+ mMipmapDrawable.setBounds(new Rect(0, 0, 0, item.getIntrinsicHeight() + 1));
+ assertSame(item, mMipmapDrawable.getCurrent());
+ }
+
+ public void testSetBounds() {
+ Drawable small = new MockDrawable(8);
+ Drawable medium = new MockDrawable(32);
+ Drawable large = new MockDrawable(128);
+
+ mMipmapDrawable.addDrawable(large);
+ mMipmapDrawable.addDrawable(small);
+ mMipmapDrawable.addDrawable(medium);
+
+ // check that correct drawable is selected.
+ mMipmapDrawable.setBounds(new Rect(0, 0, 0, small.getIntrinsicHeight() - 1));
+ assertSame(small, mMipmapDrawable.getCurrent());
+
+ mMipmapDrawable.setBounds(new Rect(0, 0, 0, small.getIntrinsicHeight()));
+ assertSame(small, mMipmapDrawable.getCurrent());
+
+ mMipmapDrawable.setBounds(new Rect(0, 0, 0, small.getIntrinsicHeight() + 1));
+ assertSame(medium, mMipmapDrawable.getCurrent());
+
+ mMipmapDrawable.setBounds(new Rect(0, 0, 0, medium.getIntrinsicHeight() - 1));
+ assertSame(medium, mMipmapDrawable.getCurrent());
+
+ mMipmapDrawable.setBounds(new Rect(0, 0, 0, medium.getIntrinsicHeight()));
+ assertSame(medium, mMipmapDrawable.getCurrent());
+
+ mMipmapDrawable.setBounds(new Rect(0, 0, 0, medium.getIntrinsicHeight() + 1));
+ assertSame(large, mMipmapDrawable.getCurrent());
+
+ mMipmapDrawable.setBounds(new Rect(0, 0, 0, large.getIntrinsicHeight() - 1));
+ assertSame(large, mMipmapDrawable.getCurrent());
+
+ mMipmapDrawable.setBounds(new Rect(0, 0, 0, large.getIntrinsicHeight()));
+ assertSame(large, mMipmapDrawable.getCurrent());
+
+ mMipmapDrawable.setBounds(new Rect(0, 0, 0, large.getIntrinsicHeight() + 1));
+ assertSame(large, mMipmapDrawable.getCurrent());
+ }
+
+ public void testSizes() {
+ // Check default value with no mipmap defined
+ assertEquals(-1, mMipmapDrawable.getIntrinsicHeight());
+ assertEquals(-1, mMipmapDrawable.getIntrinsicWidth());
+ assertEquals(0, mMipmapDrawable.getMinimumHeight());
+ assertEquals(0, mMipmapDrawable.getMinimumWidth());
+
+ Drawable small = new MockDrawable(8, 4);
+ Drawable medium = new MockDrawable(32, 16);
+ Drawable large = new MockDrawable(128, 64);
+
+ mMipmapDrawable.addDrawable(medium);
+ assertEquals(medium.getIntrinsicHeight(), mMipmapDrawable.getIntrinsicHeight());
+ assertEquals(medium.getMinimumHeight(), mMipmapDrawable.getMinimumHeight());
+
+ mMipmapDrawable.addDrawable(large);
+ assertEquals(large.getIntrinsicHeight(), mMipmapDrawable.getIntrinsicHeight());
+ assertEquals(medium.getMinimumHeight(), mMipmapDrawable.getMinimumHeight());
+
+ mMipmapDrawable.addDrawable(small);
+ assertEquals(large.getIntrinsicHeight(), mMipmapDrawable.getIntrinsicHeight());
+ assertEquals(small.getMinimumHeight(), mMipmapDrawable.getMinimumHeight());
+ }
+
+ public void testReplacementWhenAdded() {
+ Drawable small = new MockDrawable(8);
+ Drawable medium = new MockDrawable(32);
+ Drawable large = new MockDrawable(128);
+
+ // Small bounds, so that the smallest mipmap should always be selected
+ mMipmapDrawable.setBounds(new Rect(0, 0, 0, 0));
+
+ // Providing smaller versions, that should immediately be used as current
+ mMipmapDrawable.addDrawable(large);
+ assertSame(large, mMipmapDrawable.getCurrent());
+
+ mMipmapDrawable.addDrawable(medium);
+ assertSame(medium, mMipmapDrawable.getCurrent());
+
+ mMipmapDrawable.addDrawable(small);
+ assertSame(small, mMipmapDrawable.getCurrent());
+ }
+
+ public void testInflate() throws XmlPullParserException, IOException {
+ XmlResourceParser parser = getResourceParser(R.xml.mipmap_correct);
+
+ mMipmapDrawable.reset();
+ mMipmapDrawable.inflate(mResources, parser, Xml.asAttributeSet(parser));
+ assertTrue(mMipmapDrawable.hasCalledOnBoundsChanged());
+ assertEquals(3, mDrawableContainerState.getChildCount());
+
+ // The color should be the first children
+ assertTrue(mDrawableContainerState.getChildren()[0] instanceof ColorDrawable);
+ Resources resources = getInstrumentation().getTargetContext().getResources();
+
+ parser = getResourceParser(R.xml.mipmap_missing_item_drawable);
+ try {
+ mMipmapDrawable.inflate(mResources, parser, Xml.asAttributeSet(parser));
+ fail("Should throw XmlPullParserException if drawable of item is missing");
+ } catch (XmlPullParserException e) {
+ }
+ }
+
+ @ToBeFixed(bug = "1417734", explanation = "should add @throws clause into javadoc of "
+ + "MipmapDrawable#inflate(Resources, XmlPullParser, AttributeSet) when param r,"
+ + "parser or attrs is out of bounds")
+ public void testInflateWithNullParameters() throws XmlPullParserException, IOException{
+ XmlResourceParser parser = getResourceParser(R.xml.mipmap_correct);
+ try {
+ mMipmapDrawable.inflate(null, parser, Xml.asAttributeSet(parser));
+ fail("Should throw XmlPullParserException if resource is null");
+ } catch (NullPointerException e) {
+ }
+
+ try {
+ mMipmapDrawable.inflate(mResources, null, Xml.asAttributeSet(parser));
+ fail("Should throw XmlPullParserException if parser is null");
+ } catch (NullPointerException e) {
+ }
+
+ try {
+ mMipmapDrawable.inflate(mResources, parser, null);
+ fail("Should throw XmlPullParserException if AttributeSet is null");
+ } catch (NullPointerException e) {
+ }
+ }
+
+ public void testMutate() {
+ Resources resources = getInstrumentation().getTargetContext().getResources();
+ MipmapDrawable d1 = (MipmapDrawable) resources.getDrawable(R.drawable.mipmapdrawable);
+ MipmapDrawable d2 = (MipmapDrawable) resources.getDrawable(R.drawable.mipmapdrawable);
+ MipmapDrawable d3 = (MipmapDrawable) resources.getDrawable(R.drawable.mipmapdrawable);
+
+ // the state does not appear to be shared before calling mutate()
+ d1.addDrawable(resources.getDrawable(R.drawable.testimage));
+ assertEquals(3, ((DrawableContainerState) d1.getConstantState()).getChildCount());
+ assertEquals(2, ((DrawableContainerState) d2.getConstantState()).getChildCount());
+ assertEquals(2, ((DrawableContainerState) d3.getConstantState()).getChildCount());
+
+ // simply call mutate to make sure no exception is thrown
+ d1.mutate();
+ d2.mutate();
+ }
+
+ private XmlResourceParser getResourceParser(int resId) throws XmlPullParserException,
+ IOException {
+ XmlResourceParser parser = getInstrumentation().getTargetContext().getResources().getXml(
+ resId);
+ int type;
+ while ((type = parser.next()) != XmlPullParser.START_TAG
+ && type != XmlPullParser.END_DOCUMENT) {
+ // Empty loop
+ }
+ return parser;
+ }
+
+ private class MockMipmapDrawable extends MipmapDrawable {
+ private boolean mHasCalledOnBoundsChanged;
+
+ public boolean hasCalledOnBoundsChanged() {
+ return mHasCalledOnBoundsChanged;
+ }
+
+ public void reset() {
+ mHasCalledOnBoundsChanged = false;
+ }
+
+ @Override
+ protected void onBoundsChange(Rect bounds) {
+ super.onBoundsChange(bounds);
+ mHasCalledOnBoundsChanged = true;
+ }
+ }
+
+ private class MockDrawable extends Drawable {
+ int mIntrinsicHeight;
+ int mMinimumHeight;
+
+ public MockDrawable() {
+ this(0);
+ }
+
+ public MockDrawable(int intrinsicHeight) {
+ this(intrinsicHeight, intrinsicHeight);
+ }
+
+ public MockDrawable(int intrinsicHeight, int minimumHeight) {
+ mIntrinsicHeight = intrinsicHeight;
+ mMinimumHeight = minimumHeight;
+ }
+
+ @Override
+ public void draw(Canvas canvas) {
+ }
+
+ @Override
+ public int getOpacity() {
+ return 0;
+ }
+
+ @Override
+ public void setAlpha(int alpha) {
+ }
+
+ @Override
+ public void setColorFilter(ColorFilter cf) {
+ }
+
+ @Override
+ public int getIntrinsicHeight() {
+ return mIntrinsicHeight;
+ }
+
+ @Override
+ public int getMinimumHeight() {
+ return mMinimumHeight;
+ }
+ }
+}
diff --git a/tests/tests/media/src/android/media/cts/CamcorderProfileTest.java b/tests/tests/media/src/android/media/cts/CamcorderProfileTest.java
index b94da11..63f5465 100644
--- a/tests/tests/media/src/android/media/cts/CamcorderProfileTest.java
+++ b/tests/tests/media/src/android/media/cts/CamcorderProfileTest.java
@@ -33,6 +33,15 @@
private static final String TAG = "CamcorderProfileTest";
+ // Uses get without id if cameraId == -1 and get with id otherwise.
+ private CamcorderProfile getWithOptionalId(int quality, int cameraId) {
+ if (cameraId == -1) {
+ return CamcorderProfile.get(quality);
+ } else {
+ return CamcorderProfile.get(cameraId, quality);
+ }
+ }
+
private void checkProfile(CamcorderProfile profile) {
Log.v(TAG, String.format("profile: duration=%d, quality=%d, " +
"fileFormat=%d, videoCodec=%d, videoBitRate=%d, videoFrameRate=%d, " +
@@ -52,7 +61,19 @@
profile.audioChannels));
assertTrue(profile.duration > 0);
assertTrue(profile.quality == CamcorderProfile.QUALITY_LOW ||
- profile.quality == CamcorderProfile.QUALITY_HIGH);
+ profile.quality == CamcorderProfile.QUALITY_HIGH ||
+ profile.quality == CamcorderProfile.QUALITY_QCIF ||
+ profile.quality == CamcorderProfile.QUALITY_CIF ||
+ profile.quality == CamcorderProfile.QUALITY_480P ||
+ profile.quality == CamcorderProfile.QUALITY_720P ||
+ profile.quality == CamcorderProfile.QUALITY_1080P ||
+ profile.quality == CamcorderProfile.QUALITY_TIME_LAPSE_LOW ||
+ profile.quality == CamcorderProfile.QUALITY_TIME_LAPSE_HIGH ||
+ profile.quality == CamcorderProfile.QUALITY_TIME_LAPSE_QCIF ||
+ profile.quality == CamcorderProfile.QUALITY_TIME_LAPSE_CIF ||
+ profile.quality == CamcorderProfile.QUALITY_TIME_LAPSE_480P ||
+ profile.quality == CamcorderProfile.QUALITY_TIME_LAPSE_720P ||
+ profile.quality == CamcorderProfile.QUALITY_TIME_LAPSE_1080P);
assertTrue(profile.videoBitRate > 0);
assertTrue(profile.videoFrameRate > 0);
assertTrue(profile.videoFrameWidth > 0);
@@ -62,6 +83,128 @@
assertTrue(profile.audioChannels > 0);
}
+ private void assertProfileEquals(CamcorderProfile expectedProfile,
+ CamcorderProfile actualProfile) {
+ assertEquals(expectedProfile.duration, actualProfile.duration);
+ assertEquals(expectedProfile.fileFormat, actualProfile.fileFormat);
+ assertEquals(expectedProfile.videoCodec, actualProfile.videoCodec);
+ assertEquals(expectedProfile.videoBitRate, actualProfile.videoBitRate);
+ assertEquals(expectedProfile.videoFrameRate, actualProfile.videoFrameRate);
+ assertEquals(expectedProfile.videoFrameWidth, actualProfile.videoFrameWidth);
+ assertEquals(expectedProfile.videoFrameHeight, actualProfile.videoFrameHeight);
+ assertEquals(expectedProfile.audioCodec, actualProfile.audioCodec);
+ assertEquals(expectedProfile.audioBitRate, actualProfile.audioBitRate);
+ assertEquals(expectedProfile.audioSampleRate, actualProfile.audioSampleRate);
+ assertEquals(expectedProfile.audioChannels, actualProfile.audioChannels);
+ }
+
+ private void checkSpecificProfileDimensions(CamcorderProfile profile, int quality) {
+ Log.v(TAG, String.format("specific profile: quality=%d, width = %d, height = %d",
+ profile.quality, profile.videoFrameWidth, profile.videoFrameHeight));
+
+ switch (quality) {
+ case CamcorderProfile.QUALITY_QCIF:
+ case CamcorderProfile.QUALITY_TIME_LAPSE_QCIF:
+ assertEquals(176, profile.videoFrameWidth);
+ assertEquals(144, profile.videoFrameHeight);
+ break;
+
+ case CamcorderProfile.QUALITY_CIF:
+ case CamcorderProfile.QUALITY_TIME_LAPSE_CIF:
+ assertEquals(352, profile.videoFrameWidth);
+ assertEquals(288, profile.videoFrameHeight);
+ break;
+
+ case CamcorderProfile.QUALITY_480P:
+ case CamcorderProfile.QUALITY_TIME_LAPSE_480P:
+ assertEquals(720, profile.videoFrameWidth);
+ assertEquals(480, profile.videoFrameHeight);
+ break;
+
+ case CamcorderProfile.QUALITY_720P:
+ case CamcorderProfile.QUALITY_TIME_LAPSE_720P:
+ assertEquals(1280, profile.videoFrameWidth);
+ assertEquals(720, profile.videoFrameHeight);
+ break;
+
+ case CamcorderProfile.QUALITY_1080P:
+ case CamcorderProfile.QUALITY_TIME_LAPSE_1080P:
+ assertEquals(1920, profile.videoFrameWidth);
+ assertEquals(1088, profile.videoFrameHeight);
+ break;
+ }
+ }
+
+ // Checks if the existing specific profiles have the correct dimensions.
+ // Also checks that the mimimum quality specific profile matches the low profile and
+ // similarly that the maximum quality specific profile matches the high profile.
+ private void checkSpecificProfiles(int cameraId,
+ CamcorderProfile low, CamcorderProfile high, int[] specificQualities) {
+ CamcorderProfile minProfile = null;
+ CamcorderProfile maxProfile = null;
+
+ for (int i = 0; i < specificQualities.length; i++) {
+ int quality = specificQualities[i];
+ if (CamcorderProfile.hasProfile(quality)) {
+ CamcorderProfile profile = getWithOptionalId(quality, cameraId);
+ checkSpecificProfileDimensions(profile, quality);
+
+ if (minProfile == null) {
+ minProfile = profile;
+ }
+ maxProfile = profile;
+ }
+ }
+
+ assertNotNull(minProfile);
+ assertNotNull(maxProfile);
+
+ Log.v(TAG, String.format("min profile: quality=%d, width = %d, height = %d",
+ minProfile.quality, minProfile.videoFrameWidth, minProfile.videoFrameHeight));
+ Log.v(TAG, String.format("max profile: quality=%d, width = %d, height = %d",
+ maxProfile.quality, maxProfile.videoFrameWidth, maxProfile.videoFrameHeight));
+
+ assertProfileEquals(low, minProfile);
+ assertProfileEquals(high, maxProfile);
+ }
+
+ private void checkGet(int cameraId) {
+ Log.v(TAG, (cameraId == -1)
+ ? "Checking get without id"
+ : "Checking get with id = " + cameraId);
+
+ CamcorderProfile lowProfile =
+ getWithOptionalId(CamcorderProfile.QUALITY_LOW, cameraId);
+ CamcorderProfile highProfile =
+ getWithOptionalId(CamcorderProfile.QUALITY_HIGH, cameraId);
+ checkProfile(lowProfile);
+ checkProfile(highProfile);
+
+ CamcorderProfile lowTimeLapseProfile =
+ getWithOptionalId(CamcorderProfile.QUALITY_TIME_LAPSE_LOW, cameraId);
+ CamcorderProfile highTimeLapseProfile =
+ getWithOptionalId(CamcorderProfile.QUALITY_TIME_LAPSE_HIGH, cameraId);
+ checkProfile(lowTimeLapseProfile);
+ checkProfile(highTimeLapseProfile);
+
+ int[] specificProfileQualities = {CamcorderProfile.QUALITY_QCIF,
+ CamcorderProfile.QUALITY_CIF,
+ CamcorderProfile.QUALITY_480P,
+ CamcorderProfile.QUALITY_720P,
+ CamcorderProfile.QUALITY_1080P};
+
+ int[] specificTimeLapseProfileQualities = {CamcorderProfile.QUALITY_TIME_LAPSE_QCIF,
+ CamcorderProfile.QUALITY_TIME_LAPSE_CIF,
+ CamcorderProfile.QUALITY_TIME_LAPSE_480P,
+ CamcorderProfile.QUALITY_TIME_LAPSE_720P,
+ CamcorderProfile.QUALITY_TIME_LAPSE_1080P};
+
+ checkSpecificProfiles(cameraId, lowProfile, highProfile,
+ specificProfileQualities);
+ checkSpecificProfiles(cameraId, lowTimeLapseProfile, highTimeLapseProfile,
+ specificTimeLapseProfileQualities);
+ }
+
@TestTargets({
@TestTargetNew(
level = TestLevel.COMPLETE,
@@ -70,10 +213,7 @@
)
})
public void testGet() {
- CamcorderProfile lowProfile = CamcorderProfile.get(CamcorderProfile.QUALITY_LOW);
- CamcorderProfile highProfile = CamcorderProfile.get(CamcorderProfile.QUALITY_HIGH);
- checkProfile(lowProfile);
- checkProfile(highProfile);
+ checkGet(-1);
}
@TestTargets({
@@ -85,13 +225,8 @@
})
public void testGetWithId() {
int nCamera = Camera.getNumberOfCameras();
- for (int id = 0; id < nCamera; id++) {
- CamcorderProfile lowProfile = CamcorderProfile.get(id,
- CamcorderProfile.QUALITY_LOW);
- CamcorderProfile highProfile = CamcorderProfile.get(id,
- CamcorderProfile.QUALITY_HIGH);
- checkProfile(lowProfile);
- checkProfile(highProfile);
+ for (int cameraId = 0; cameraId < nCamera; cameraId++) {
+ checkGet(cameraId);
}
}
}
diff --git a/tests/tests/os/src/android/os/cts/ParcelFileDescriptorTest.java b/tests/tests/os/src/android/os/cts/ParcelFileDescriptorTest.java
index ce6658f..3974b6c 100644
--- a/tests/tests/os/src/android/os/cts/ParcelFileDescriptorTest.java
+++ b/tests/tests/os/src/android/os/cts/ParcelFileDescriptorTest.java
@@ -28,9 +28,14 @@
import android.os.Parcelable;
import android.os.ParcelFileDescriptor.AutoCloseInputStream;
import android.test.AndroidTestCase;
+import android.test.MoreAsserts;
import java.io.File;
+import java.io.FileDescriptor;
+import java.io.FileInputStream;
import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
import java.io.OutputStream;
import java.net.InetAddress;
import java.net.ServerSocket;
@@ -110,6 +115,72 @@
}
@TestTargetNew(
+ level = TestLevel.PARTIAL_COMPLETE,
+ method = "fromData",
+ args = {byte[].class}
+ )
+ public void testFromData() throws IOException {
+ assertNull(ParcelFileDescriptor.fromData(null, null));
+ byte[] data = new byte[] { 0 };
+ assertFileDescriptorContent(data, ParcelFileDescriptor.fromData(data, null));
+ data = new byte[] { 0, 1, 2, 3 };
+ assertFileDescriptorContent(data, ParcelFileDescriptor.fromData(data, null));
+ data = new byte[0];
+ assertFileDescriptorContent(data, ParcelFileDescriptor.fromData(data, null));
+
+ // Check that modifying the data does not modify the data in the FD
+ data = new byte[] { 0, 1, 2, 3 };
+ ParcelFileDescriptor pfd = ParcelFileDescriptor.fromData(data, null);
+ data[1] = 42;
+ assertFileDescriptorContent(new byte[] { 0, 1, 2, 3 }, pfd);
+ }
+
+ private static void assertFileDescriptorContent(byte[] expected, ParcelFileDescriptor fd)
+ throws IOException {
+ assertInputStreamContent(expected, new ParcelFileDescriptor.AutoCloseInputStream(fd));
+ }
+
+ private static void assertInputStreamContent(byte[] expected, InputStream is)
+ throws IOException {
+ try {
+ byte[] observed = new byte[expected.length];
+ int count = is.read(observed);
+ assertEquals(expected.length, count);
+ assertEquals(-1, is.read());
+ MoreAsserts.assertEquals(expected, observed);
+ } finally {
+ is.close();
+ }
+ }
+
+ @TestTargetNew(
+ level = TestLevel.PARTIAL_COMPLETE,
+ notes = "Tests that skip() works on FDs returned by fromData()",
+ method = "fromData",
+ args = {byte[].class}
+ )
+ public void testFromDataSkip() throws IOException {
+ byte[] data = new byte[] { 40, 41, 42, 43, 44, 45, 46 };
+ ParcelFileDescriptor pfd = ParcelFileDescriptor.fromData(data, null);
+ assertNotNull(pfd);
+ FileDescriptor fd = pfd.getFileDescriptor();
+ assertNotNull(fd);
+ assertTrue(fd.valid());
+ FileInputStream is = new FileInputStream(fd);
+ try {
+ assertEquals(1, is.skip(1));
+ assertEquals(41, is.read());
+ assertEquals(42, is.read());
+ assertEquals(2, is.skip(2));
+ assertEquals(45, is.read());
+ assertEquals(46, is.read());
+ assertEquals(-1, is.read());
+ } finally {
+ is.close();
+ }
+ }
+
+ @TestTargetNew(
level = TestLevel.COMPLETE,
method = "toString",
args = {}
diff --git a/tests/tests/provider/src/android/provider/cts/SearchRecentSuggestionsTest.java b/tests/tests/provider/src/android/provider/cts/SearchRecentSuggestionsTest.java
new file mode 100644
index 0000000..f17ecf9
--- /dev/null
+++ b/tests/tests/provider/src/android/provider/cts/SearchRecentSuggestionsTest.java
@@ -0,0 +1,233 @@
+/*
+ * Copyright (C) 2008 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.provider.cts;
+
+import dalvik.annotation.TestLevel;
+import dalvik.annotation.TestTargetClass;
+import dalvik.annotation.TestTargetNew;
+import dalvik.annotation.TestTargets;
+
+import android.content.ContentResolver;
+import android.content.ContentValues;
+import android.content.Context;
+import android.database.Cursor;
+import android.net.Uri;
+import android.provider.SearchRecentSuggestions;
+import android.test.ProviderTestCase2;
+
+@TestTargetClass(android.provider.SearchRecentSuggestions.class)
+public class SearchRecentSuggestionsTest extends
+ ProviderTestCase2<TestSearchRecentSuggestionsProvider> {
+ private final static String AUTHORITY_HEAD = "content://"
+ + TestSearchRecentSuggestionsProvider.AUTHORITY;
+
+ private Uri mTestUri;
+ private TestSearchRecentSuggestionsProvider mTestSRSProvider;
+ private Context mContext;
+
+ @Override
+ public void setUp() throws Exception {
+ super.setUp();
+ mTestUri = Uri.parse(AUTHORITY_HEAD + "/suggestions");
+ mTestSRSProvider = getProvider();
+ mContext = mTestSRSProvider.getContext();
+ }
+
+ public SearchRecentSuggestionsTest() {
+ super(TestSearchRecentSuggestionsProvider.class,
+ TestSearchRecentSuggestionsProvider.AUTHORITY);
+ }
+
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ method = "SearchRecentSuggestions",
+ args = {android.content.Context.class, java.lang.String.class, int.class}
+ )
+ public void testConstructor() {
+ new SearchRecentSuggestions(mContext, TestSearchRecentSuggestionsProvider.AUTHORITY,
+ TestSearchRecentSuggestionsProvider.MODE);
+ }
+
+ @TestTargets({
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ method = "SearchRecentSuggestions",
+ args = {android.content.Context.class, java.lang.String.class, int.class}
+ ),
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ method = "saveRecentQuery",
+ args = {java.lang.String.class, java.lang.String.class}
+ ),
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ method = "clearHistory",
+ args = {}
+ ),
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ method = "truncateHistory",
+ args = {android.content.ContentResolver.class, int.class}
+ )
+ })
+ public void testSearchRecentSuggestions() {
+ MySearchRecentSuggestions srs = new MySearchRecentSuggestions(mContext,
+ TestSearchRecentSuggestionsProvider.AUTHORITY,
+ TestSearchRecentSuggestionsProvider.MODE);
+ Cursor c = mTestSRSProvider.query(mTestUri, null, null, null, null);
+
+ try {
+ assertNotNull(c);
+ assertEquals(0, c.getCount());
+ c.close();
+
+ // insert three rows
+ String query1 = "query1";
+ String line1 = "line1";
+ srs.saveRecentQuery(query1, line1);
+ c = mTestSRSProvider.query(mTestUri, SearchRecentSuggestions.QUERIES_PROJECTION_2LINE,
+ null, null, null);
+ assertNotNull(c);
+ assertEquals(1, c.getCount());
+
+ c.moveToFirst();
+ assertEquals(query1, c
+ .getString(SearchRecentSuggestions.QUERIES_PROJECTION_QUERY_INDEX));
+ assertEquals(line1, c
+ .getString(SearchRecentSuggestions.QUERIES_PROJECTION_DISPLAY2_INDEX));
+ c.close();
+
+ String query2 = "query2";
+ String line2 = "line2";
+ srs.saveRecentQuery(query2, line2);
+ c = mTestSRSProvider.query(mTestUri, null, null, null, null);
+ assertNotNull(c);
+ assertEquals(2, c.getCount());
+ c.close();
+
+ String query3 = "query3";
+ String line3 = "line3";
+ srs.saveRecentQuery(query3, line3);
+ c = mTestSRSProvider.query(mTestUri, null, null, null, null);
+ assertNotNull(c);
+ assertEquals(3, c.getCount());
+ c.close();
+
+ // truncateHistory will delete the oldest one record
+ ContentResolver cr = mContext.getContentResolver();
+ srs.truncateHistory(cr, 2);
+ c = mTestSRSProvider.query(mTestUri, SearchRecentSuggestions.QUERIES_PROJECTION_2LINE,
+ null, null, null);
+ assertNotNull(c);
+ assertEquals(2, c.getCount());
+
+ // and the left two should be: test2 and test3, test1 should be delete
+ c.moveToFirst();
+ assertEquals(query2, c
+ .getString(SearchRecentSuggestions.QUERIES_PROJECTION_QUERY_INDEX));
+ assertEquals(line2, c
+ .getString(SearchRecentSuggestions.QUERIES_PROJECTION_DISPLAY2_INDEX));
+ c.moveToNext();
+ assertEquals(query3, c
+ .getString(SearchRecentSuggestions.QUERIES_PROJECTION_QUERY_INDEX));
+ assertEquals(line3, c
+ .getString(SearchRecentSuggestions.QUERIES_PROJECTION_DISPLAY2_INDEX));
+ c.close();
+
+ // clear all history
+ srs.clearHistory();
+ c = mTestSRSProvider.query(mTestUri, null, null, null, null);
+ assertNotNull(c);
+ assertEquals(0, c.getCount());
+ } finally {
+ c.close();
+ }
+ }
+
+ public void testSuggestionsTable() {
+ String insertDisplay1 = "display1_insert";
+ String insertDisplay2 = "display2_insert";
+ String insertQuery = "query_insert";
+
+ String updateDisplay1 = "display1_update";
+ String updateDisplay2 = "display2_update";
+ String updateQuery = "query_update";
+
+ // Test: insert
+ ContentValues value = new ContentValues();
+ value.put("display1", insertDisplay1);
+ value.put("display2", insertDisplay2);
+ value.put("query", insertQuery);
+ value.put("date", 1);
+
+ mTestSRSProvider.insert(mTestUri, value);
+
+ Cursor cursor = mTestSRSProvider.query(mTestUri,
+ SearchRecentSuggestions.QUERIES_PROJECTION_2LINE,
+ "display1=\"" + insertDisplay1 + "\"", null, null);
+ try {
+ assertNotNull(cursor);
+ assertEquals(1, cursor.getCount());
+ assertTrue(cursor.moveToFirst());
+ assertEquals(insertDisplay2, cursor
+ .getString(SearchRecentSuggestions.QUERIES_PROJECTION_DISPLAY2_INDEX));
+ assertEquals(insertQuery, cursor
+ .getString(SearchRecentSuggestions.QUERIES_PROJECTION_QUERY_INDEX));
+ assertEquals(1, cursor.getInt(SearchRecentSuggestions.QUERIES_PROJECTION_DATE_INDEX));
+ cursor.close();
+
+ // Test: update
+ /**
+ * SearchRecentSuggestionsProvider.update is not implement, always
+ * throw an UnsupportedOperationException.
+ */
+ value.clear();
+ value.put("display1", updateDisplay1);
+ value.put("display2", updateDisplay2);
+ value.put("query", updateQuery);
+ value.put("date", 2);
+
+ try {
+ mTestSRSProvider.update(mTestUri, value, "display1=\"" + insertDisplay1 + "\"",
+ null);
+ fail("There should be an UnsupportedOperationException thrown out.");
+ } catch (UnsupportedOperationException e) {
+ // expected, test success.
+ }
+
+ // Test: delete
+ mTestSRSProvider.delete(mTestUri, "display1=\"" + insertDisplay1 + "\"", null);
+ cursor = mTestSRSProvider.query(mTestUri,
+ SearchRecentSuggestions.QUERIES_PROJECTION_2LINE, "display1=\""
+ + insertDisplay1 + "\"", null, null);
+ assertNotNull(cursor);
+ assertEquals(0, cursor.getCount());
+ } finally {
+ cursor.close();
+ }
+ }
+
+ private class MySearchRecentSuggestions extends SearchRecentSuggestions {
+ public MySearchRecentSuggestions(Context context, String authority, int mode) {
+ super(context, authority, mode);
+ }
+
+ protected void truncateHistory(ContentResolver cr, int maxEntries) {
+ super.truncateHistory(cr, maxEntries);
+ }
+ }
+}
diff --git a/tests/tests/text/src/android/text/cts/SpannableStringBuilderTest.java b/tests/tests/text/src/android/text/cts/SpannableStringBuilderTest.java
index 26ebfb5..f8b4336 100644
--- a/tests/tests/text/src/android/text/cts/SpannableStringBuilderTest.java
+++ b/tests/tests/text/src/android/text/cts/SpannableStringBuilderTest.java
@@ -16,6 +16,12 @@
package android.text.cts;
+import dalvik.annotation.TestLevel;
+import dalvik.annotation.TestTargetClass;
+import dalvik.annotation.TestTargetNew;
+import dalvik.annotation.TestTargets;
+import dalvik.annotation.ToBeFixed;
+
import android.test.AndroidTestCase;
import android.text.InputFilter;
import android.text.SpannableString;
@@ -24,11 +30,6 @@
import android.text.style.StrikethroughSpan;
import android.text.style.TabStopSpan;
import android.text.style.UnderlineSpan;
-import dalvik.annotation.TestTargets;
-import dalvik.annotation.TestLevel;
-import dalvik.annotation.TestTargetNew;
-import dalvik.annotation.TestTargetClass;
-import dalvik.annotation.ToBeFixed;
/**
* Test {@link SpannableStringBuilder}.
@@ -250,6 +251,28 @@
builder.replace(0, 5, text, 0, text.length());
assertEquals("ahiabc, world", builder.toString());
+ // Replacing by an empty string (identical target indexes)
+ builder = new SpannableStringBuilder("hello, world");
+ builder.replace(4, 6, "", 0, 0);
+ assertEquals("hell world", builder.toString());
+
+ builder = new SpannableStringBuilder("hello, world");
+ builder.replace(4, 6, "any string", 5, 5);
+ assertEquals("hell world", builder.toString());
+
+ // Inserting in place (no deletion)
+ builder = new SpannableStringBuilder("hello, world");
+ builder.replace(3, 3, "any string", 0, 0);
+ assertEquals("hello, world", builder.toString());
+
+ builder = new SpannableStringBuilder("hello, world");
+ builder.replace(7, 7, "nice ", 0, 5);
+ assertEquals("hello, nice world", builder.toString());
+
+ builder = new SpannableStringBuilder("hello, world");
+ builder.replace(0, 0, "say ", 1, 4);
+ assertEquals("ay hello, world", builder.toString());
+
try {
builder.replace(0, 5, text, 10, 3);
fail("should throw IndexOutOfBoundsException here");
diff --git a/tests/tests/view/src/android/view/cts/AccessibilityEventTest.java b/tests/tests/view/src/android/view/cts/AccessibilityEventTest.java
index 731784a..f7c1e7a 100644
--- a/tests/tests/view/src/android/view/cts/AccessibilityEventTest.java
+++ b/tests/tests/view/src/android/view/cts/AccessibilityEventTest.java
@@ -202,8 +202,7 @@
TestCase.assertEquals("fromIndex not properly recycled", 0, event.getFromIndex());
TestCase.assertEquals("itemCount not properly recycled", 0, event.getItemCount());
TestCase.assertNull("packageName not properly recycled", event.getPackageName());
- // This will fail and is fixed in Gingerbread Bug: 2593810
- // TestCase.assertNull("parcelableData not properly recycled", event.getParcelableData());
+ TestCase.assertNull("parcelableData not properly recycled", event.getParcelableData());
TestCase.assertEquals("removedCount not properly recycled", 0, event.getRemovedCount());
TestCase.assertTrue("text not properly recycled", event.getText().isEmpty());
}
diff --git a/tests/tests/view/src/android/view/cts/LayoutInflaterTest.java b/tests/tests/view/src/android/view/cts/LayoutInflaterTest.java
index 6f637fc..f5bd8f4 100644
--- a/tests/tests/view/src/android/view/cts/LayoutInflaterTest.java
+++ b/tests/tests/view/src/android/view/cts/LayoutInflaterTest.java
@@ -16,6 +16,14 @@
package android.view.cts;
+import com.android.cts.stub.R;
+import com.android.internal.util.XmlUtils;
+
+import dalvik.annotation.TestLevel;
+import dalvik.annotation.TestTargetClass;
+import dalvik.annotation.TestTargetNew;
+import dalvik.annotation.TestTargets;
+
import org.xmlpull.v1.XmlPullParser;
import android.app.cts.MockActivity;
@@ -23,6 +31,7 @@
import android.content.Context;
import android.content.pm.ActivityInfo;
import android.content.pm.PackageManager;
+import android.content.res.Resources;
import android.content.res.XmlResourceParser;
import android.test.AndroidTestCase;
import android.util.AttributeSet;
@@ -35,21 +44,13 @@
import android.view.LayoutInflater.Factory;
import android.view.LayoutInflater.Filter;
import android.widget.LinearLayout;
-import com.android.cts.stub.R;
-
-import com.android.internal.util.XmlUtils;
-
-import dalvik.annotation.TestTargets;
-import dalvik.annotation.TestTargetNew;
-import dalvik.annotation.TestLevel;
-import dalvik.annotation.TestTargetClass;
@TestTargetClass(LayoutInflater.class)
public class LayoutInflaterTest extends AndroidTestCase {
private LayoutInflater mLayoutInflater;
private Context mContext;
- private Factory mFactory = new Factory() {
+ private final Factory mFactory = new Factory() {
public View onCreateView(String name, Context context,
AttributeSet attrs) {
@@ -57,7 +58,7 @@
}
};
private boolean isOnLoadClass;
- private Filter mFilter = new Filter() {
+ private final Filter mFilter = new Filter() {
@SuppressWarnings("unchecked")
public boolean onLoadClass(Class clazz) {
@@ -172,7 +173,7 @@
}
String nodeName = parser.getName();
if (!"alias".equals(nodeName)) {
- throw new RuntimeException();
+ throw new InflateException();
}
int outerDepth = parser.getDepth();
while ((type = parser.next()) != XmlPullParser.END_DOCUMENT
@@ -296,8 +297,7 @@
try {
view = mLayoutInflater.inflate(-1, null);
fail("should throw exception");
- } catch (RuntimeException e) {
-
+ } catch (Resources.NotFoundException e) {
}
LinearLayout mLayout;
mLayout = new LinearLayout(mContext);
@@ -335,7 +335,7 @@
try {
view = mLayoutInflater.inflate(-1, null, false);
fail("should throw exception");
- } catch (RuntimeException e) {
+ } catch (Resources.NotFoundException e) {
}
LinearLayout mLayout;
@@ -381,7 +381,7 @@
try {
view = mLayoutInflater.inflate(null, null);
fail("should throw exception");
- } catch (RuntimeException e) {
+ } catch (NullPointerException e) {
}
LinearLayout mLayout;
mLayout = new LinearLayout(mContext);
@@ -395,7 +395,7 @@
try {
view = mLayoutInflater.inflate(parser, mLayout);
fail("should throw exception");
- } catch (RuntimeException e) {
+ } catch (NullPointerException e) {
}
parser = getContext().getResources().getLayout(
R.layout.inflater_layout);
@@ -440,7 +440,7 @@
try {
view = mLayoutInflater.inflate(null, null, false);
fail("should throw exception");
- } catch (RuntimeException e) {
+ } catch (NullPointerException e) {
}
LinearLayout mLayout;
mLayout = new LinearLayout(mContext);
@@ -454,7 +454,7 @@
try {
view = mLayoutInflater.inflate(parser, mLayout, false);
fail("should throw exception");
- } catch (RuntimeException e) {
+ } catch (NullPointerException e) {
}
parser = getContext().getResources().getLayout(
R.layout.inflater_layout);
@@ -475,7 +475,7 @@
try {
view = mLayoutInflater.inflate(parser, mLayout, false);
fail("should throw exception");
- } catch (RuntimeException e) {
+ } catch (InflateException e) {
}
parser = null;
@@ -497,6 +497,7 @@
super(original, newContext);
}
+ @Override
public View onCreateView(String name, AttributeSet attrs)
throws ClassNotFoundException {
return super.onCreateView(name, attrs);
diff --git a/tests/tests/view/src/android/view/cts/ViewTest.java b/tests/tests/view/src/android/view/cts/ViewTest.java
index 3168312..871985c 100644
--- a/tests/tests/view/src/android/view/cts/ViewTest.java
+++ b/tests/tests/view/src/android/view/cts/ViewTest.java
@@ -47,6 +47,8 @@
import android.util.SparseArray;
import android.util.Xml;
import android.view.ContextMenu;
+import android.view.ContextMenu.ContextMenuInfo;
+import android.view.ActionMode;
import android.view.Display;
import android.view.HapticFeedbackConstants;
import android.view.KeyEvent;
@@ -54,11 +56,6 @@
import android.view.SoundEffectConstants;
import android.view.TouchDelegate;
import android.view.View;
-import android.view.ViewConfiguration;
-import android.view.ViewGroup;
-import android.view.ViewParent;
-import android.view.WindowManagerImpl;
-import android.view.ContextMenu.ContextMenuInfo;
import android.view.View.BaseSavedState;
import android.view.View.OnClickListener;
import android.view.View.OnCreateContextMenuListener;
@@ -66,6 +63,10 @@
import android.view.View.OnKeyListener;
import android.view.View.OnLongClickListener;
import android.view.View.OnTouchListener;
+import android.view.ViewConfiguration;
+import android.view.ViewGroup;
+import android.view.ViewParent;
+import android.view.WindowManagerImpl;
import android.view.animation.AlphaAnimation;
import android.view.animation.Animation;
import android.view.animation.cts.DelayedCheck;
@@ -4626,6 +4627,11 @@
return false;
}
+ public ActionMode startActionModeForChild(View originalView,
+ ActionMode.Callback callback) {
+ return null;
+ }
+
public boolean hasShowContextMenuForChild() {
return mHasShowContextMenuForChild;
}
diff --git a/tests/tests/view/src/android/view/cts/WindowTest.java b/tests/tests/view/src/android/view/cts/WindowTest.java
index 0e31888..60947b5 100644
--- a/tests/tests/view/src/android/view/cts/WindowTest.java
+++ b/tests/tests/view/src/android/view/cts/WindowTest.java
@@ -37,7 +37,7 @@
import android.os.Bundle;
import android.test.ActivityInstrumentationTestCase2;
import android.util.DisplayMetrics;
-import android.view.accessibility.AccessibilityEvent;
+import android.view.ActionMode;
import android.view.Gravity;
import android.view.InputQueue;
import android.view.KeyEvent;
@@ -50,6 +50,7 @@
import android.view.ViewGroup;
import android.view.Window;
import android.view.WindowManager;
+import android.view.accessibility.AccessibilityEvent;
import android.widget.TextView;
@TestTargetClass(Window.class)
@@ -1148,6 +1149,9 @@
public void togglePanel(int featureId, KeyEvent event) {
}
+ public void invalidatePanelMenu(int featureId) {
+ }
+
public boolean performPanelShortcut(int featureId, int keyCode, KeyEvent event, int flags) {
return true;
}
@@ -1326,5 +1330,9 @@
public boolean onSearchRequested() {
return false;
}
+
+ public ActionMode onStartActionMode(ActionMode.Callback callback) {
+ return null;
+ }
}
}
diff --git a/tests/tests/widget/src/android/widget/cts/ExpandableListTester.java b/tests/tests/widget/src/android/widget/cts/ExpandableListTester.java
new file mode 100644
index 0000000..8175807
--- /dev/null
+++ b/tests/tests/widget/src/android/widget/cts/ExpandableListTester.java
@@ -0,0 +1,241 @@
+/*
+ * 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.widget.cts;
+
+import android.app.Instrumentation;
+import android.test.ActivityInstrumentationTestCase2;
+import android.view.KeyEvent;
+import android.view.View;
+import android.widget.ExpandableListAdapter;
+import android.widget.ExpandableListView;
+import android.widget.cts.util.ExpandableListScenario;
+import android.widget.cts.util.ListUtil;
+
+import junit.framework.Assert;
+
+public class ExpandableListTester {
+ private final ExpandableListView mExpandableListView;
+ private final ExpandableListAdapter mAdapter;
+ private final ListUtil mListUtil;
+
+ private final ActivityInstrumentationTestCase2<? extends ExpandableListScenario>
+ mActivityInstrumentation;
+
+ Instrumentation mInstrumentation;
+
+ public ExpandableListTester(
+ ExpandableListView expandableListView,
+ ActivityInstrumentationTestCase2<? extends ExpandableListScenario>
+ activityInstrumentation) {
+ mExpandableListView = expandableListView;
+ Instrumentation instrumentation = activityInstrumentation.getInstrumentation();
+ mListUtil = new ListUtil(mExpandableListView, instrumentation);
+ mAdapter = mExpandableListView.getExpandableListAdapter();
+ mActivityInstrumentation = activityInstrumentation;
+ mInstrumentation = mActivityInstrumentation.getInstrumentation();
+ }
+
+ private void expandGroup(final int groupIndex, int flatPosition) {
+ Assert.assertFalse("Group is already expanded", mExpandableListView
+ .isGroupExpanded(groupIndex));
+ mListUtil.arrowScrollToSelectedPosition(flatPosition);
+ mInstrumentation.waitForIdleSync();
+ mActivityInstrumentation.sendKeys(KeyEvent.KEYCODE_DPAD_CENTER);
+ mActivityInstrumentation.getInstrumentation().waitForIdleSync();
+ Assert.assertTrue("Group did not expand " + groupIndex,
+ mExpandableListView.isGroupExpanded(groupIndex));
+ }
+
+ void testContextMenus() {
+ // Add a position tester ContextMenu listener to the ExpandableListView
+ PositionTesterContextMenuListener menuListener = new PositionTesterContextMenuListener();
+ mExpandableListView.setOnCreateContextMenuListener(menuListener);
+
+ int index = 0;
+
+ // Scrolling on header elements should trigger an AdapterContextMenu
+ for (int i=0; i<mExpandableListView.getHeaderViewsCount(); i++) {
+ // Check group index in context menu
+ menuListener.expectAdapterContextMenu(i);
+ // Make sure the group is visible so that getChild finds it
+ mListUtil.arrowScrollToSelectedPosition(index);
+ View headerChild = mExpandableListView.getChildAt(index
+ - mExpandableListView.getFirstVisiblePosition());
+ mExpandableListView.showContextMenuForChild(headerChild);
+ mInstrumentation.waitForIdleSync();
+ Assert.assertNull(menuListener.getErrorMessage(), menuListener.getErrorMessage());
+ index++;
+ }
+
+ int groupCount = mAdapter.getGroupCount();
+ for (int groupIndex = 0; groupIndex < groupCount; groupIndex++) {
+
+ // Expand group
+ expandGroup(groupIndex, index);
+
+ // Check group index in context menu
+ menuListener.expectGroupContextMenu(groupIndex);
+ // Make sure the group is visible so that getChild finds it
+ mListUtil.arrowScrollToSelectedPosition(index);
+ View groupChild = mExpandableListView.getChildAt(index
+ - mExpandableListView.getFirstVisiblePosition());
+ mExpandableListView.showContextMenuForChild(groupChild);
+ mInstrumentation.waitForIdleSync();
+ Assert.assertNull(menuListener.getErrorMessage(), menuListener.getErrorMessage());
+ index++;
+
+ final int childrenCount = mAdapter.getChildrenCount(groupIndex);
+ for (int childIndex = 0; childIndex < childrenCount; childIndex++) {
+ // Check child index in context menu
+ mListUtil.arrowScrollToSelectedPosition(index);
+ menuListener.expectChildContextMenu(groupIndex, childIndex);
+ View child = mExpandableListView.getChildAt(index
+ - mExpandableListView.getFirstVisiblePosition());
+ mExpandableListView.showContextMenuForChild(child);
+ mInstrumentation.waitForIdleSync();
+ Assert.assertNull(menuListener.getErrorMessage(), menuListener.getErrorMessage());
+ index++;
+ }
+ }
+
+ // Scrolling on footer elements should trigger an AdapterContextMenu
+ for (int i=0; i<mExpandableListView.getFooterViewsCount(); i++) {
+ // Check group index in context menu
+ menuListener.expectAdapterContextMenu(index);
+ // Make sure the group is visible so that getChild finds it
+ mListUtil.arrowScrollToSelectedPosition(index);
+ View footerChild = mExpandableListView.getChildAt(index
+ - mExpandableListView.getFirstVisiblePosition());
+ mExpandableListView.showContextMenuForChild(footerChild);
+ mInstrumentation.waitForIdleSync();
+ Assert.assertNull(menuListener.getErrorMessage(), menuListener.getErrorMessage());
+ index++;
+ }
+
+ // Cleanup: remove the listener we added.
+ mExpandableListView.setOnCreateContextMenuListener(null);
+ }
+
+ private int expandAGroup() {
+ final int groupIndex = 2;
+ final int headerCount = mExpandableListView.getHeaderViewsCount();
+ Assert.assertTrue("Not enough groups", groupIndex < mAdapter.getGroupCount());
+ expandGroup(groupIndex, groupIndex + headerCount);
+ return groupIndex;
+ }
+
+ // This method assumes that NO group is expanded when called
+ void testConvertionBetweenFlatAndPackedOnGroups() {
+ final int headerCount = mExpandableListView.getHeaderViewsCount();
+
+ for (int i=0; i<headerCount; i++) {
+ Assert.assertEquals("Non NULL position for header item",
+ ExpandableListView.PACKED_POSITION_VALUE_NULL,
+ mExpandableListView.getExpandableListPosition(i));
+ }
+
+ // Test all (non expanded) groups
+ final int groupCount = mAdapter.getGroupCount();
+ for (int groupIndex = 0; groupIndex < groupCount; groupIndex++) {
+ int expectedFlatPosition = headerCount + groupIndex;
+ long packedPositionForGroup = ExpandableListView.getPackedPositionForGroup(groupIndex);
+ Assert.assertEquals("Group not found at flat position " + expectedFlatPosition,
+ packedPositionForGroup,
+ mExpandableListView.getExpandableListPosition(expectedFlatPosition));
+
+ Assert.assertEquals("Wrong flat position for group " + groupIndex,
+ expectedFlatPosition,
+ mExpandableListView.getFlatListPosition(packedPositionForGroup));
+ }
+
+ for (int i=0; i<mExpandableListView.getFooterViewsCount(); i++) {
+ Assert.assertEquals("Non NULL position for header item",
+ ExpandableListView.PACKED_POSITION_VALUE_NULL,
+ mExpandableListView.getExpandableListPosition(headerCount + groupCount + i));
+ }
+ }
+
+ // This method assumes that NO group is expanded when called
+ void testConvertionBetweenFlatAndPackedOnChildren() {
+ // Test with an expanded group
+ final int headerCount = mExpandableListView.getHeaderViewsCount();
+ final int groupIndex = expandAGroup();
+
+ final int childrenCount = mAdapter.getChildrenCount(groupIndex);
+ for (int childIndex = 0; childIndex < childrenCount; childIndex++) {
+ int expectedFlatPosition = headerCount + groupIndex + 1 + childIndex;
+ long childPos = ExpandableListView.getPackedPositionForChild(groupIndex, childIndex);
+
+ Assert.assertEquals("Wrong flat position for child ",
+ childPos,
+ mExpandableListView.getExpandableListPosition(expectedFlatPosition));
+
+ Assert.assertEquals("Wrong flat position for child ",
+ expectedFlatPosition,
+ mExpandableListView.getFlatListPosition(childPos));
+ }
+ }
+
+ // This method assumes that NO group is expanded when called
+ void testSelectedPositionOnGroups() {
+ int index = 0;
+
+ // Scrolling on header elements should not give a valid selected position.
+ for (int i=0; i<mExpandableListView.getHeaderViewsCount(); i++) {
+ mListUtil.arrowScrollToSelectedPosition(index);
+ Assert.assertEquals("Header item is selected",
+ ExpandableListView.PACKED_POSITION_VALUE_NULL,
+ mExpandableListView.getSelectedPosition());
+ index++;
+ }
+
+ // Check selection on group items
+ final int groupCount = mAdapter.getGroupCount();
+ for (int groupIndex = 0; groupIndex < groupCount; groupIndex++) {
+ mListUtil.arrowScrollToSelectedPosition(index);
+ Assert.assertEquals("Group item is not selected",
+ ExpandableListView.getPackedPositionForGroup(groupIndex),
+ mExpandableListView.getSelectedPosition());
+ index++;
+ }
+
+ // Scrolling on footer elements should not give a valid selected position.
+ for (int i=0; i<mExpandableListView.getFooterViewsCount(); i++) {
+ mListUtil.arrowScrollToSelectedPosition(index);
+ Assert.assertEquals("Footer item is selected",
+ ExpandableListView.PACKED_POSITION_VALUE_NULL,
+ mExpandableListView.getSelectedPosition());
+ index++;
+ }
+ }
+
+ // This method assumes that NO group is expanded when called
+ void testSelectedPositionOnChildren() {
+ // Test with an expanded group
+ final int headerCount = mExpandableListView.getHeaderViewsCount();
+ final int groupIndex = expandAGroup();
+
+ final int childrenCount = mAdapter.getChildrenCount(groupIndex);
+ for (int childIndex = 0; childIndex < childrenCount; childIndex++) {
+ int childFlatPosition = headerCount + groupIndex + 1 + childIndex;
+ mListUtil.arrowScrollToSelectedPosition(childFlatPosition);
+ Assert.assertEquals("Group item is not selected",
+ ExpandableListView.getPackedPositionForChild(groupIndex, childIndex),
+ mExpandableListView.getSelectedPosition());
+ }
+ }
+}
diff --git a/tests/tests/widget/src/android/widget/cts/ExpandableListViewBasicTest.java b/tests/tests/widget/src/android/widget/cts/ExpandableListViewBasicTest.java
index c6c0b35..fc39364 100644
--- a/tests/tests/widget/src/android/widget/cts/ExpandableListViewBasicTest.java
+++ b/tests/tests/widget/src/android/widget/cts/ExpandableListViewBasicTest.java
@@ -16,7 +16,10 @@
package android.widget.cts;
-import java.util.List;
+import dalvik.annotation.TestLevel;
+import dalvik.annotation.TestTargetClass;
+import dalvik.annotation.TestTargetNew;
+import dalvik.annotation.TestTargets;
import android.test.ActivityInstrumentationTestCase2;
import android.test.suitebuilder.annotation.MediumTest;
@@ -27,21 +30,19 @@
import android.widget.cts.util.ExpandableListScenario;
import android.widget.cts.util.ListUtil;
import android.widget.cts.util.ExpandableListScenario.MyGroup;
-import dalvik.annotation.TestTargets;
-import dalvik.annotation.TestTargetNew;
-import dalvik.annotation.TestLevel;
-import dalvik.annotation.TestTargetClass;
+
+import java.util.List;
@TestTargetClass(ExpandableListView.class)
public class ExpandableListViewBasicTest extends
ActivityInstrumentationTestCase2<ExpandableListSimple> {
private ExpandableListScenario mActivity;
- private ExpandableListView mListView;
+ private ExpandableListView mExpandableListView;
private ExpandableListAdapter mAdapter;
private ListUtil mListUtil;
public ExpandableListViewBasicTest() {
- super("com.android.cts.stub", ExpandableListSimple.class);
+ super(ExpandableListSimple.class);
}
@Override
@@ -49,27 +50,27 @@
super.setUp();
mActivity = getActivity();
- mListView = mActivity.getExpandableListView();
- mAdapter = mListView.getExpandableListAdapter();
- mListUtil = new ListUtil(mListView, getInstrumentation());
+ mExpandableListView = mActivity.getExpandableListView();
+ mAdapter = mExpandableListView.getExpandableListAdapter();
+ mListUtil = new ListUtil(mExpandableListView, getInstrumentation());
}
@MediumTest
public void testPreconditions() {
assertNotNull(mActivity);
- assertNotNull(mListView);
+ assertNotNull(mExpandableListView);
}
private int expandGroup(int numChildren, boolean atLeastOneChild) {
final int groupPos = mActivity.findGroupWithNumChildren(numChildren, atLeastOneChild);
assertTrue("Could not find group to expand", groupPos >= 0);
- assertFalse("Group is already expanded", mListView.isGroupExpanded(groupPos));
+ assertFalse("Group is already expanded", mExpandableListView.isGroupExpanded(groupPos));
mListUtil.arrowScrollToSelectedPosition(groupPos);
getInstrumentation().waitForIdleSync();
sendKeys(KeyEvent.KEYCODE_DPAD_CENTER);
getInstrumentation().waitForIdleSync();
- assertTrue("Group did not expand", mListView.isGroupExpanded(groupPos));
+ assertTrue("Group did not expand", mExpandableListView.isGroupExpanded(groupPos));
return groupPos;
}
@@ -97,7 +98,7 @@
sendKeys(KeyEvent.KEYCODE_DPAD_CENTER);
getInstrumentation().waitForIdleSync();
- assertFalse("Group did not collapse", mListView.isGroupExpanded(groupPos));
+ assertFalse("Group did not collapse", mExpandableListView.isGroupExpanded(groupPos));
}
@TestTargets({
@@ -122,13 +123,13 @@
getInstrumentation().waitForIdleSync();
// Ensure it expanded
- assertTrue("Group did not expand", mListView.isGroupExpanded(0));
+ assertTrue("Group did not expand", mExpandableListView.isGroupExpanded(0));
// Wait until that's all good
getInstrumentation().waitForIdleSync();
// Make sure it expanded
- assertTrue("Group did not expand", mListView.isGroupExpanded(0));
+ assertTrue("Group did not expand", mExpandableListView.isGroupExpanded(0));
// Insert a collapsed group in front of the one just expanded
List<MyGroup> groups = mActivity.getGroups();
@@ -149,8 +150,28 @@
// Make sure the right group is expanded
assertTrue("The expanded state didn't stay with the proper group",
- mListView.isGroupExpanded(1));
+ mExpandableListView.isGroupExpanded(1));
assertFalse("The expanded state was given to the inserted group",
- mListView.isGroupExpanded(0));
+ mExpandableListView.isGroupExpanded(0));
+ }
+
+ @MediumTest
+ public void testContextMenus() {
+ ExpandableListTester tester = new ExpandableListTester(mExpandableListView, this);
+ tester.testContextMenus();
+ }
+
+ @MediumTest
+ public void testConvertionBetweenFlatAndPacked() {
+ ExpandableListTester tester = new ExpandableListTester(mExpandableListView, this);
+ tester.testConvertionBetweenFlatAndPackedOnGroups();
+ tester.testConvertionBetweenFlatAndPackedOnChildren();
+ }
+
+ @MediumTest
+ public void testSelectedPosition() {
+ ExpandableListTester tester = new ExpandableListTester(mExpandableListView, this);
+ tester.testSelectedPositionOnGroups();
+ tester.testSelectedPositionOnChildren();
}
}
diff --git a/tests/tests/widget/src/android/widget/cts/ExpandableListViewTest.java b/tests/tests/widget/src/android/widget/cts/ExpandableListViewTest.java
index af420b4..5ab7f4d 100644
--- a/tests/tests/widget/src/android/widget/cts/ExpandableListViewTest.java
+++ b/tests/tests/widget/src/android/widget/cts/ExpandableListViewTest.java
@@ -519,10 +519,10 @@
args = {int.class, int.class}
)
public void testGetPackedPositionForChild() {
- assertEquals((long) 0x8000000000000000L,
+ assertEquals(0x8000000000000000L,
ExpandableListView.getPackedPositionForChild(0, 0));
- assertEquals((long) 0xffffffffffffffffL,
+ assertEquals(0xffffffffffffffffL,
ExpandableListView.getPackedPositionForChild(Integer.MAX_VALUE, 0xffffffff));
}
diff --git a/tests/tests/widget/src/android/widget/cts/ExpandableListViewWithHeadersTest.java b/tests/tests/widget/src/android/widget/cts/ExpandableListViewWithHeadersTest.java
index 57776a0..fe65f98 100644
--- a/tests/tests/widget/src/android/widget/cts/ExpandableListViewWithHeadersTest.java
+++ b/tests/tests/widget/src/android/widget/cts/ExpandableListViewWithHeadersTest.java
@@ -16,16 +16,16 @@
package android.widget.cts;
+import dalvik.annotation.TestLevel;
+import dalvik.annotation.TestTargetClass;
+import dalvik.annotation.TestTargetNew;
+
import android.test.ActivityInstrumentationTestCase2;
import android.test.suitebuilder.annotation.LargeTest;
import android.test.suitebuilder.annotation.MediumTest;
import android.view.KeyEvent;
import android.widget.ExpandableListView;
import android.widget.cts.util.ListUtil;
-import dalvik.annotation.TestTargets;
-import dalvik.annotation.TestTargetNew;
-import dalvik.annotation.TestLevel;
-import dalvik.annotation.TestTargetClass;
@TestTargetClass(ExpandableListView.class)
public class ExpandableListViewWithHeadersTest extends
@@ -34,7 +34,7 @@
private ListUtil mListUtil;
public ExpandableListViewWithHeadersTest() {
- super("com.android.cts.stub", ExpandableListWithHeaders.class);
+ super(ExpandableListWithHeaders.class);
}
@Override
@@ -78,4 +78,24 @@
getInstrumentation().waitForIdleSync();
assertTrue(mExpandableListView.isGroupExpanded(0));
}
+
+ @MediumTest
+ public void testContextMenus() {
+ ExpandableListTester tester = new ExpandableListTester(mExpandableListView, this);
+ tester.testContextMenus();
+ }
+
+ @MediumTest
+ public void testConvertionBetweenFlatAndPacked() {
+ ExpandableListTester tester = new ExpandableListTester(mExpandableListView, this);
+ tester.testConvertionBetweenFlatAndPackedOnGroups();
+ tester.testConvertionBetweenFlatAndPackedOnChildren();
+ }
+
+ @MediumTest
+ public void testSelectedPosition() {
+ ExpandableListTester tester = new ExpandableListTester(mExpandableListView, this);
+ tester.testSelectedPositionOnGroups();
+ tester.testSelectedPositionOnChildren();
+ }
}
diff --git a/tests/tests/widget/src/android/widget/cts/GridViewTest.java b/tests/tests/widget/src/android/widget/cts/GridViewTest.java
index 65045d8..376c137 100644
--- a/tests/tests/widget/src/android/widget/cts/GridViewTest.java
+++ b/tests/tests/widget/src/android/widget/cts/GridViewTest.java
@@ -531,6 +531,48 @@
assertEquals(0, child.getLeft() - mGridView.getListPaddingLeft());
}
}
+
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ notes = "Test {@link GridView#getNumColumns()}",
+ method = "getNumColumns"
+ )
+ public void testGetNumColumns() {
+ mGridView = new GridView(mActivity);
+
+ assertEquals(mGridView.getNumColumns(), GridView.AUTO_FIT);
+
+ mGridView = findGridViewById(R.id.gridview);
+
+ mActivity.runOnUiThread(new Runnable() {
+ public void run() {
+ mGridView.setAdapter(new MockGridViewAdapter(10));
+ mGridView.setNumColumns(10);
+ }
+ });
+ mInstrumentation.waitForIdleSync();
+
+ assertEquals(mGridView.getNumColumns(), 10);
+
+ mActivity.runOnUiThread(new Runnable() {
+ public void run() {
+ mGridView.setNumColumns(1);
+ }
+ });
+ mInstrumentation.waitForIdleSync();
+
+ assertEquals(mGridView.getNumColumns(), 1);
+
+ mActivity.runOnUiThread(new Runnable() {
+ public void run() {
+ mGridView.setNumColumns(0);
+ }
+ });
+ mInstrumentation.waitForIdleSync();
+
+ //although setNumColumns(0) was called, the number of columns should be 1
+ assertEquals(mGridView.getNumColumns(), 1);
+ }
@TestTargetNew(
level = TestLevel.COMPLETE,
diff --git a/tests/tests/widget/src/android/widget/cts/PositionTesterContextMenuListener.java b/tests/tests/widget/src/android/widget/cts/PositionTesterContextMenuListener.java
new file mode 100644
index 0000000..a1c9bc4
--- /dev/null
+++ b/tests/tests/widget/src/android/widget/cts/PositionTesterContextMenuListener.java
@@ -0,0 +1,111 @@
+/*
+ * 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.widget.cts;
+
+import android.view.ContextMenu;
+import android.view.View;
+import android.view.ContextMenu.ContextMenuInfo;
+import android.view.View.OnCreateContextMenuListener;
+import android.widget.ExpandableListView;
+import android.widget.AdapterView.AdapterContextMenuInfo;
+
+public class PositionTesterContextMenuListener implements OnCreateContextMenuListener {
+
+ private int groupPosition, childPosition;
+
+ // Fake constant to store in testType a test type specific to headers and footers
+ private static final int ADAPTER_TYPE = -1;
+ private int testType; // as returned by getPackedPositionType
+
+ // Will be set to null by each call to onCreateContextMenu, unless an error occurred.
+ private String errorMessage;
+
+ public void expectGroupContextMenu(int groupPosition) {
+ this.groupPosition = groupPosition;
+ testType = ExpandableListView.PACKED_POSITION_TYPE_GROUP;
+ }
+
+ public void expectChildContextMenu(int groupPosition, int childPosition) {
+ this.groupPosition = groupPosition;
+ this.childPosition = childPosition;
+ testType = ExpandableListView.PACKED_POSITION_TYPE_CHILD;
+ }
+
+ public void expectAdapterContextMenu(int flatPosition) {
+ this.groupPosition = flatPosition;
+ testType = ADAPTER_TYPE;
+ }
+
+ public void onCreateContextMenu(ContextMenu menu, View v, ContextMenuInfo menuInfo) {
+ errorMessage = null;
+ if (testType == ADAPTER_TYPE) {
+ if (!isTrue("MenuInfo is not an AdapterContextMenuInfo",
+ menuInfo instanceof AdapterContextMenuInfo)) {
+ return;
+ }
+ AdapterContextMenuInfo adapterContextMenuInfo = (AdapterContextMenuInfo) menuInfo;
+ if (!areEqual("Wrong flat position", groupPosition, adapterContextMenuInfo.position)) {
+ return;
+ }
+ } else {
+ if (!isTrue("MenuInfo is not an ExpandableListContextMenuInfo",
+ menuInfo instanceof ExpandableListView.ExpandableListContextMenuInfo)) {
+ return;
+ }
+ ExpandableListView.ExpandableListContextMenuInfo elvMenuInfo =
+ (ExpandableListView.ExpandableListContextMenuInfo) menuInfo;
+ long packedPosition = elvMenuInfo.packedPosition;
+
+ int packedPositionType = ExpandableListView.getPackedPositionType(packedPosition);
+ if (!areEqual("Wrong packed position type", testType, packedPositionType)) {
+ return;
+ }
+
+ int packedPositionGroup = ExpandableListView.getPackedPositionGroup(packedPosition);
+ if (!areEqual("Wrong group position", groupPosition, packedPositionGroup)) {
+ return;
+ }
+
+ if (testType == ExpandableListView.PACKED_POSITION_TYPE_CHILD) {
+ int packedPositionChild = ExpandableListView.getPackedPositionChild(packedPosition);
+ if (!areEqual("Wrong child position", childPosition, packedPositionChild)) {
+ return;
+ }
+ }
+ }
+ }
+
+ private boolean areEqual(String message, int expected, int actual) {
+ if (expected != actual) {
+ errorMessage = String.format(message + " (%d vs %d", expected, actual);
+ return false;
+ }
+ return true;
+ }
+
+ private boolean isTrue(String message, boolean value) {
+ if (!value) {
+ errorMessage = message;
+ return false;
+ }
+ return true;
+ }
+
+ public String getErrorMessage() {
+ return errorMessage;
+ }
+}