summaryrefslogtreecommitdiffstats
path: root/src/com
diff options
context:
space:
mode:
authorChiao Cheng <chiaocheng@google.com>2012-09-14 12:00:21 -0700
committerChiao Cheng <chiaocheng@google.com>2012-09-17 15:15:21 -0700
commitbf1f360793c466dae12f8bc386161353355f2b28 (patch)
tree426c813c050a9a32a801f5653c3eae0d861309a7 /src/com
parent5a6b519447147a91eda94142c5667e86b2d4456c (diff)
downloadpackages_apps_ContactsCommon-bf1f360793c466dae12f8bc386161353355f2b28.tar.gz
packages_apps_ContactsCommon-bf1f360793c466dae12f8bc386161353355f2b28.tar.bz2
packages_apps_ContactsCommon-bf1f360793c466dae12f8bc386161353355f2b28.zip
Adding custom AsyncQueryHandler to prevent null cursors.
In safe mode, a cursor can come back as null even though our providers never allow for that. NoNullCursorAsyncQueryHandler should be used instead of AsyncQueryHandler from now on. It will return EmptyCursor in place of a null. Bug: 7012260 Change-Id: I5b8ba6fb85ae0f984ee8b0ff2f2f068232a03848
Diffstat (limited to 'src/com')
-rw-r--r--src/com/android/contacts/common/database/EmptyCursor.java84
-rw-r--r--src/com/android/contacts/common/database/NoNullCursorAsyncQueryHandler.java69
2 files changed, 153 insertions, 0 deletions
diff --git a/src/com/android/contacts/common/database/EmptyCursor.java b/src/com/android/contacts/common/database/EmptyCursor.java
new file mode 100644
index 00000000..ad00effe
--- /dev/null
+++ b/src/com/android/contacts/common/database/EmptyCursor.java
@@ -0,0 +1,84 @@
+/*
+* Copyright (C) 2012 The Android Open Source Project
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License
+*/
+
+package com.android.contacts.common.database;
+
+import android.database.AbstractCursor;
+import android.database.CursorIndexOutOfBoundsException;
+
+/**
+ * A cursor that is empty.
+ * <p>
+ * If you want an empty cursor, this class is better than a MatrixCursor because it has less
+ * overhead.
+ */
+final public class EmptyCursor extends AbstractCursor {
+
+ private String[] mColumns;
+
+ public EmptyCursor(String[] columns) {
+ this.mColumns = columns;
+ }
+
+ @Override
+ public int getCount() {
+ return 0;
+ }
+
+ @Override
+ public String[] getColumnNames() {
+ return mColumns;
+ }
+
+ @Override
+ public String getString(int column) {
+ throw cursorException();
+ }
+
+ @Override
+ public short getShort(int column) {
+ throw cursorException();
+ }
+
+ @Override
+ public int getInt(int column) {
+ throw cursorException();
+ }
+
+ @Override
+ public long getLong(int column) {
+ throw cursorException();
+ }
+
+ @Override
+ public float getFloat(int column) {
+ throw cursorException();
+ }
+
+ @Override
+ public double getDouble(int column) {
+ throw cursorException();
+ }
+
+ @Override
+ public boolean isNull(int column) {
+ throw cursorException();
+ }
+
+ private CursorIndexOutOfBoundsException cursorException() {
+ return new CursorIndexOutOfBoundsException("Operation not permitted on an empty cursor.");
+ }
+}
diff --git a/src/com/android/contacts/common/database/NoNullCursorAsyncQueryHandler.java b/src/com/android/contacts/common/database/NoNullCursorAsyncQueryHandler.java
new file mode 100644
index 00000000..aefc0fd8
--- /dev/null
+++ b/src/com/android/contacts/common/database/NoNullCursorAsyncQueryHandler.java
@@ -0,0 +1,69 @@
+/*
+ * Copyright (C) 2012 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License
+ */
+
+package com.android.contacts.common.database;
+
+import android.content.AsyncQueryHandler;
+import android.content.ContentResolver;
+import android.database.Cursor;
+import android.net.Uri;
+
+/**
+ * An {@AsyncQueryHandler} that will never return a null cursor.
+ * <p>
+ * Instead, will return a {@link Cursor} with 0 records.
+ */
+public abstract class NoNullCursorAsyncQueryHandler extends AsyncQueryHandler {
+
+ public NoNullCursorAsyncQueryHandler(ContentResolver cr) {
+ super(cr);
+ }
+
+ @Override
+ public void startQuery(int token, Object cookie, Uri uri, String[] projection, String selection,
+ String[] selectionArgs, String orderBy) {
+ final CookieWithProjection projectionCookie = new CookieWithProjection(cookie, projection);
+ super.startQuery(token, projectionCookie, uri, projection, selection, selectionArgs,
+ orderBy);
+ }
+
+ @Override
+ protected final void onQueryComplete(int token, Object cookie, Cursor cursor) {
+ CookieWithProjection projectionCookie = (CookieWithProjection) cookie;
+
+ super.onQueryComplete(token, projectionCookie.originalCookie, cursor);
+
+ if (cursor == null) {
+ cursor = new EmptyCursor(projectionCookie.projection);
+ }
+ onNotNullableQueryComplete(token, projectionCookie.originalCookie, cursor);
+ }
+
+ protected abstract void onNotNullableQueryComplete(int token, Object cookie, Cursor cursor);
+
+ /**
+ * Class to add projection to an existing cookie.
+ */
+ private static class CookieWithProjection {
+ public final Object originalCookie;
+ public final String[] projection;
+
+ public CookieWithProjection(Object cookie, String[] projection) {
+ this.originalCookie = cookie;
+ this.projection = projection;
+ }
+ }
+}