diff --git a/android/database/AbstractCursor.java b/android/database/AbstractCursor.java
new file mode 100644
index 0000000..3effc5a
--- /dev/null
+++ b/android/database/AbstractCursor.java
@@ -0,0 +1,552 @@
+/*
+ * Copyright (C) 2006 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.database;
+
+import android.annotation.NonNull;
+import android.compat.annotation.UnsupportedAppUsage;
+import android.content.ContentResolver;
+import android.net.Uri;
+import android.os.Build;
+import android.os.Bundle;
+import android.util.Log;
+
+import java.lang.ref.WeakReference;
+import java.util.Arrays;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Objects;
+
+
+/**
+ * This is an abstract cursor class that handles a lot of the common code
+ * that all cursors need to deal with and is provided for convenience reasons.
+ */
+public abstract class AbstractCursor implements CrossProcessCursor {
+    private static final String TAG = "Cursor";
+
+    /**
+     * @removed This field should not be used.
+     */
+    protected HashMap<Long, Map<String, Object>> mUpdatedRows;
+
+    /**
+     * @removed This field should not be used.
+     */
+    protected int mRowIdColumnIndex;
+
+    /**
+     * @removed This field should not be used.
+     */
+    protected Long mCurrentRowID;
+
+    /**
+     * @deprecated Use {@link #getPosition()} instead.
+     */
+    @Deprecated
+    protected int mPos;
+
+    /**
+     * @deprecated Use {@link #isClosed()} instead.
+     */
+    @Deprecated
+    protected boolean mClosed;
+
+    /**
+     * @deprecated Do not use.
+     */
+    @Deprecated
+    protected ContentResolver mContentResolver;
+
+    @UnsupportedAppUsage
+    private Uri mNotifyUri;
+    private List<Uri> mNotifyUris;
+
+    private final Object mSelfObserverLock = new Object();
+    private ContentObserver mSelfObserver;
+    private boolean mSelfObserverRegistered;
+
+    private final DataSetObservable mDataSetObservable = new DataSetObservable();
+    private final ContentObservable mContentObservable = new ContentObservable();
+
+    @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023)
+    private Bundle mExtras = Bundle.EMPTY;
+
+    /* -------------------------------------------------------- */
+    /* These need to be implemented by subclasses */
+    @Override
+    abstract public int getCount();
+
+    @Override
+    abstract public String[] getColumnNames();
+
+    @Override
+    abstract public String getString(int column);
+    @Override
+    abstract public short getShort(int column);
+    @Override
+    abstract public int getInt(int column);
+    @Override
+    abstract public long getLong(int column);
+    @Override
+    abstract public float getFloat(int column);
+    @Override
+    abstract public double getDouble(int column);
+    @Override
+    abstract public boolean isNull(int column);
+
+    @Override
+    public int getType(int column) {
+        // Reflects the assumption that all commonly used field types (meaning everything
+        // but blobs) are convertible to strings so it should be safe to call
+        // getString to retrieve them.
+        return FIELD_TYPE_STRING;
+    }
+
+    // TODO implement getBlob in all cursor types
+    @Override
+    public byte[] getBlob(int column) {
+        throw new UnsupportedOperationException("getBlob is not supported");
+    }
+    /* -------------------------------------------------------- */
+    /* Methods that may optionally be implemented by subclasses */
+
+    /**
+     * If the cursor is backed by a {@link CursorWindow}, returns a pre-filled
+     * window with the contents of the cursor, otherwise null.
+     *
+     * @return The pre-filled window that backs this cursor, or null if none.
+     */
+    @Override
+    public CursorWindow getWindow() {
+        return null;
+    }
+
+    @Override
+    public int getColumnCount() {
+        return getColumnNames().length;
+    }
+
+    @Override
+    public void deactivate() {
+        onDeactivateOrClose();
+    }
+
+    /** @hide */
+    protected void onDeactivateOrClose() {
+        if (mSelfObserver != null) {
+            mContentResolver.unregisterContentObserver(mSelfObserver);
+            mSelfObserverRegistered = false;
+        }
+        mDataSetObservable.notifyInvalidated();
+    }
+
+    @Override
+    public boolean requery() {
+        if (mSelfObserver != null && mSelfObserverRegistered == false) {
+            final int size = mNotifyUris.size();
+            for (int i = 0; i < size; ++i) {
+                final Uri notifyUri = mNotifyUris.get(i);
+                mContentResolver.registerContentObserver(notifyUri, true, mSelfObserver);
+            }
+            mSelfObserverRegistered = true;
+        }
+        mDataSetObservable.notifyChanged();
+        return true;
+    }
+
+    @Override
+    public boolean isClosed() {
+        return mClosed;
+    }
+
+    @Override
+    public void close() {
+        mClosed = true;
+        mContentObservable.unregisterAll();
+        onDeactivateOrClose();
+    }
+
+    /**
+     * This function is called every time the cursor is successfully scrolled
+     * to a new position, giving the subclass a chance to update any state it
+     * may have. If it returns false the move function will also do so and the
+     * cursor will scroll to the beforeFirst position.
+     *
+     * @param oldPosition the position that we're moving from
+     * @param newPosition the position that we're moving to
+     * @return true if the move is successful, false otherwise
+     */
+    @Override
+    public boolean onMove(int oldPosition, int newPosition) {
+        return true;
+    }
+
+
+    @Override
+    public void copyStringToBuffer(int columnIndex, CharArrayBuffer buffer) {
+        // Default implementation, uses getString
+        String result = getString(columnIndex);
+        if (result != null) {
+            char[] data = buffer.data;
+            if (data == null || data.length < result.length()) {
+                buffer.data = result.toCharArray();
+            } else {
+                result.getChars(0, result.length(), data, 0);
+            }
+            buffer.sizeCopied = result.length();
+        } else {
+            buffer.sizeCopied = 0;
+        }
+    }
+
+    /* -------------------------------------------------------- */
+    /* Implementation */
+    public AbstractCursor() {
+        mPos = -1;
+    }
+
+    @Override
+    public final int getPosition() {
+        return mPos;
+    }
+
+    @Override
+    public final boolean moveToPosition(int position) {
+        // Make sure position isn't past the end of the cursor
+        final int count = getCount();
+        if (position >= count) {
+            mPos = count;
+            return false;
+        }
+
+        // Make sure position isn't before the beginning of the cursor
+        if (position < 0) {
+            mPos = -1;
+            return false;
+        }
+
+        // Check for no-op moves, and skip the rest of the work for them
+        if (position == mPos) {
+            return true;
+        }
+
+        boolean result = onMove(mPos, position);
+        if (result == false) {
+            mPos = -1;
+        } else {
+            mPos = position;
+        }
+
+        return result;
+    }
+
+    @Override
+    public void fillWindow(int position, CursorWindow window) {
+        DatabaseUtils.cursorFillWindow(this, position, window);
+    }
+
+    @Override
+    public final boolean move(int offset) {
+        return moveToPosition(mPos + offset);
+    }
+
+    @Override
+    public final boolean moveToFirst() {
+        return moveToPosition(0);
+    }
+
+    @Override
+    public final boolean moveToLast() {
+        return moveToPosition(getCount() - 1);
+    }
+
+    @Override
+    public final boolean moveToNext() {
+        return moveToPosition(mPos + 1);
+    }
+
+    @Override
+    public final boolean moveToPrevious() {
+        return moveToPosition(mPos - 1);
+    }
+
+    @Override
+    public final boolean isFirst() {
+        return mPos == 0 && getCount() != 0;
+    }
+
+    @Override
+    public final boolean isLast() {
+        int cnt = getCount();
+        return mPos == (cnt - 1) && cnt != 0;
+    }
+
+    @Override
+    public final boolean isBeforeFirst() {
+        if (getCount() == 0) {
+            return true;
+        }
+        return mPos == -1;
+    }
+
+    @Override
+    public final boolean isAfterLast() {
+        if (getCount() == 0) {
+            return true;
+        }
+        return mPos == getCount();
+    }
+
+    @Override
+    public int getColumnIndex(String columnName) {
+        // Hack according to bug 903852
+        final int periodIndex = columnName.lastIndexOf('.');
+        if (periodIndex != -1) {
+            Exception e = new Exception();
+            Log.e(TAG, "requesting column name with table name -- " + columnName, e);
+            columnName = columnName.substring(periodIndex + 1);
+        }
+
+        String columnNames[] = getColumnNames();
+        int length = columnNames.length;
+        for (int i = 0; i < length; i++) {
+            if (columnNames[i].equalsIgnoreCase(columnName)) {
+                return i;
+            }
+        }
+
+        if (false) {
+            if (getCount() > 0) {
+                Log.w("AbstractCursor", "Unknown column " + columnName);
+            }
+        }
+        return -1;
+    }
+
+    @Override
+    public int getColumnIndexOrThrow(String columnName) {
+        final int index = getColumnIndex(columnName);
+        if (index < 0) {
+            String availableColumns = "";
+            try {
+                availableColumns = Arrays.toString(getColumnNames());
+            } catch (Exception e) {
+                Log.d(TAG, "Cannot collect column names for debug purposes", e);
+            }
+            throw new IllegalArgumentException("column '" + columnName
+                    + "' does not exist. Available columns: " + availableColumns);
+        }
+        return index;
+    }
+
+    @Override
+    public String getColumnName(int columnIndex) {
+        return getColumnNames()[columnIndex];
+    }
+
+    @Override
+    public void registerContentObserver(ContentObserver observer) {
+        mContentObservable.registerObserver(observer);
+    }
+
+    @Override
+    public void unregisterContentObserver(ContentObserver observer) {
+        // cursor will unregister all observers when it close
+        if (!mClosed) {
+            mContentObservable.unregisterObserver(observer);
+        }
+    }
+
+    @Override
+    public void registerDataSetObserver(DataSetObserver observer) {
+        mDataSetObservable.registerObserver(observer);
+    }
+
+    @Override
+    public void unregisterDataSetObserver(DataSetObserver observer) {
+        mDataSetObservable.unregisterObserver(observer);
+    }
+
+    /**
+     * Subclasses must call this method when they finish committing updates to notify all
+     * observers.
+     *
+     * @param selfChange
+     */
+    protected void onChange(boolean selfChange) {
+        synchronized (mSelfObserverLock) {
+            mContentObservable.dispatchChange(selfChange, null);
+            if (mNotifyUris != null && selfChange) {
+                final int size = mNotifyUris.size();
+                for (int i = 0; i < size; ++i) {
+                    final Uri notifyUri = mNotifyUris.get(i);
+                    mContentResolver.notifyChange(notifyUri, mSelfObserver);
+                }
+            }
+        }
+    }
+
+    /**
+     * Specifies a content URI to watch for changes.
+     *
+     * @param cr The content resolver from the caller's context.
+     * @param notifyUri The URI to watch for changes. This can be a
+     * specific row URI, or a base URI for a whole class of content.
+     */
+    @Override
+    public void setNotificationUri(ContentResolver cr, Uri notifyUri) {
+        setNotificationUris(cr, Arrays.asList(notifyUri));
+    }
+
+    @Override
+    public void setNotificationUris(@NonNull ContentResolver cr, @NonNull List<Uri> notifyUris) {
+        Objects.requireNonNull(cr);
+        Objects.requireNonNull(notifyUris);
+
+        setNotificationUris(cr, notifyUris, cr.getUserId(), true);
+    }
+
+    /**
+     * Set the notification uri but with an observer for a particular user's view. Also allows
+     * disabling the use of a self observer, which is sensible if either
+     * a) the cursor's owner calls {@link #onChange(boolean)} whenever the content changes, or
+     * b) the cursor is known not to have any content observers.
+     * @hide
+     */
+    public void setNotificationUris(ContentResolver cr, List<Uri> notifyUris, int userHandle,
+            boolean registerSelfObserver) {
+        synchronized (mSelfObserverLock) {
+            mNotifyUris = notifyUris;
+            mNotifyUri = mNotifyUris.get(0);
+            mContentResolver = cr;
+            if (mSelfObserver != null) {
+                mContentResolver.unregisterContentObserver(mSelfObserver);
+                mSelfObserverRegistered = false;
+            }
+            if (registerSelfObserver) {
+                mSelfObserver = new SelfContentObserver(this);
+                final int size = mNotifyUris.size();
+                for (int i = 0; i < size; ++i) {
+                    final Uri notifyUri = mNotifyUris.get(i);
+                    mContentResolver.registerContentObserver(
+                            notifyUri, true, mSelfObserver, userHandle);
+                }
+                mSelfObserverRegistered = true;
+            }
+        }
+    }
+
+    @Override
+    public Uri getNotificationUri() {
+        synchronized (mSelfObserverLock) {
+            return mNotifyUri;
+        }
+    }
+
+    @Override
+    public List<Uri> getNotificationUris() {
+        synchronized (mSelfObserverLock) {
+            return mNotifyUris;
+        }
+    }
+
+    @Override
+    public boolean getWantsAllOnMoveCalls() {
+        return false;
+    }
+
+    @Override
+    public void setExtras(Bundle extras) {
+        mExtras = (extras == null) ? Bundle.EMPTY : extras;
+    }
+
+    @Override
+    public Bundle getExtras() {
+        return mExtras;
+    }
+
+    @Override
+    public Bundle respond(Bundle extras) {
+        return Bundle.EMPTY;
+    }
+
+    /**
+     * @deprecated Always returns false since Cursors do not support updating rows
+     */
+    @Deprecated
+    protected boolean isFieldUpdated(int columnIndex) {
+        return false;
+    }
+
+    /**
+     * @deprecated Always returns null since Cursors do not support updating rows
+     */
+    @Deprecated
+    protected Object getUpdatedField(int columnIndex) {
+        return null;
+    }
+
+    /**
+     * This function throws CursorIndexOutOfBoundsException if
+     * the cursor position is out of bounds. Subclass implementations of
+     * the get functions should call this before attempting
+     * to retrieve data.
+     *
+     * @throws CursorIndexOutOfBoundsException
+     */
+    protected void checkPosition() {
+        if (-1 == mPos || getCount() == mPos) {
+            throw new CursorIndexOutOfBoundsException(mPos, getCount());
+        }
+    }
+
+    @Override
+    protected void finalize() {
+        if (mSelfObserver != null && mSelfObserverRegistered == true) {
+            mContentResolver.unregisterContentObserver(mSelfObserver);
+        }
+        try {
+            if (!mClosed) close();
+        } catch(Exception e) { }
+    }
+
+    /**
+     * Cursors use this class to track changes others make to their URI.
+     */
+    protected static class SelfContentObserver extends ContentObserver {
+        WeakReference<AbstractCursor> mCursor;
+
+        public SelfContentObserver(AbstractCursor cursor) {
+            super(null);
+            mCursor = new WeakReference<AbstractCursor>(cursor);
+        }
+
+        @Override
+        public boolean deliverSelfNotifications() {
+            return false;
+        }
+
+        @Override
+        public void onChange(boolean selfChange) {
+            AbstractCursor cursor = mCursor.get();
+            if (cursor != null) {
+                cursor.onChange(false);
+            }
+        }
+    }
+}
diff --git a/android/database/AbstractWindowedCursor.java b/android/database/AbstractWindowedCursor.java
new file mode 100644
index 0000000..daf7d2b
--- /dev/null
+++ b/android/database/AbstractWindowedCursor.java
@@ -0,0 +1,215 @@
+/*
+ * Copyright (C) 2006 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.database;
+
+import android.compat.annotation.UnsupportedAppUsage;
+
+/**
+ * A base class for Cursors that store their data in {@link CursorWindow}s.
+ * <p>
+ * The cursor owns the cursor window it uses.  When the cursor is closed,
+ * its window is also closed.  Likewise, when the window used by the cursor is
+ * changed, its old window is closed.  This policy of strict ownership ensures
+ * that cursor windows are not leaked.
+ * </p><p>
+ * Subclasses are responsible for filling the cursor window with data during
+ * {@link #onMove(int, int)}, allocating a new cursor window if necessary.
+ * During {@link #requery()}, the existing cursor window should be cleared and
+ * filled with new data.
+ * </p><p>
+ * If the contents of the cursor change or become invalid, the old window must be closed
+ * (because it is owned by the cursor) and set to null.
+ * </p>
+ */
+public abstract class AbstractWindowedCursor extends AbstractCursor {
+    /**
+     * The cursor window owned by this cursor.
+     */
+    protected CursorWindow mWindow;
+
+    @Override
+    public byte[] getBlob(int columnIndex) {
+        checkPosition();
+        return mWindow.getBlob(mPos, columnIndex);
+    }
+
+    @Override
+    public String getString(int columnIndex) {
+        checkPosition();
+        return mWindow.getString(mPos, columnIndex);
+    }
+
+    @Override
+    public void copyStringToBuffer(int columnIndex, CharArrayBuffer buffer) {
+        checkPosition();
+        mWindow.copyStringToBuffer(mPos, columnIndex, buffer);
+    }
+
+    @Override
+    public short getShort(int columnIndex) {
+        checkPosition();
+        return mWindow.getShort(mPos, columnIndex);
+    }
+
+    @Override
+    public int getInt(int columnIndex) {
+        checkPosition();
+        return mWindow.getInt(mPos, columnIndex);
+    }
+
+    @Override
+    public long getLong(int columnIndex) {
+        checkPosition();
+        return mWindow.getLong(mPos, columnIndex);
+    }
+
+    @Override
+    public float getFloat(int columnIndex) {
+        checkPosition();
+        return mWindow.getFloat(mPos, columnIndex);
+    }
+
+    @Override
+    public double getDouble(int columnIndex) {
+        checkPosition();
+        return mWindow.getDouble(mPos, columnIndex);
+    }
+
+    @Override
+    public boolean isNull(int columnIndex) {
+        checkPosition();
+        return mWindow.getType(mPos, columnIndex) == Cursor.FIELD_TYPE_NULL;
+    }
+
+    /**
+     * @deprecated Use {@link #getType}
+     */
+    @Deprecated
+    public boolean isBlob(int columnIndex) {
+        return getType(columnIndex) == Cursor.FIELD_TYPE_BLOB;
+    }
+
+    /**
+     * @deprecated Use {@link #getType}
+     */
+    @Deprecated
+    public boolean isString(int columnIndex) {
+        return getType(columnIndex) == Cursor.FIELD_TYPE_STRING;
+    }
+
+    /**
+     * @deprecated Use {@link #getType}
+     */
+    @Deprecated
+    public boolean isLong(int columnIndex) {
+        return getType(columnIndex) == Cursor.FIELD_TYPE_INTEGER;
+    }
+
+    /**
+     * @deprecated Use {@link #getType}
+     */
+    @Deprecated
+    public boolean isFloat(int columnIndex) {
+        return getType(columnIndex) == Cursor.FIELD_TYPE_FLOAT;
+    }
+
+    @Override
+    public int getType(int columnIndex) {
+        checkPosition();
+        return mWindow.getType(mPos, columnIndex);
+    }
+
+    @Override
+    protected void checkPosition() {
+        super.checkPosition();
+        
+        if (mWindow == null) {
+            throw new StaleDataException("Attempting to access a closed CursorWindow." +
+                    "Most probable cause: cursor is deactivated prior to calling this method.");
+        }
+    }
+
+    @Override
+    public CursorWindow getWindow() {
+        return mWindow;
+    }
+
+    /**
+     * Sets a new cursor window for the cursor to use.
+     * <p>
+     * The cursor takes ownership of the provided cursor window; the cursor window
+     * will be closed when the cursor is closed or when the cursor adopts a new
+     * cursor window.
+     * </p><p>
+     * If the cursor previously had a cursor window, then it is closed when the
+     * new cursor window is assigned.
+     * </p>
+     *
+     * @param window The new cursor window, typically a remote cursor window.
+     */
+    public void setWindow(CursorWindow window) {
+        if (window != mWindow) {
+            closeWindow();
+            mWindow = window;
+        }
+    }
+
+    /**
+     * Returns true if the cursor has an associated cursor window.
+     *
+     * @return True if the cursor has an associated cursor window.
+     */
+    public boolean hasWindow() {
+        return mWindow != null;
+    }
+
+    /**
+     * Closes the cursor window and sets {@link #mWindow} to null.
+     * @hide
+     */
+    @UnsupportedAppUsage
+    protected void closeWindow() {
+        if (mWindow != null) {
+            mWindow.close();
+            mWindow = null;
+        }
+    }
+
+    /**
+     * If there is a window, clear it.
+     * Otherwise, creates a new window.
+     *
+     * @param name The window name.
+     * @hide
+     */
+    @UnsupportedAppUsage
+    protected void clearOrCreateWindow(String name) {
+        if (mWindow == null) {
+            mWindow = new CursorWindow(name);
+        } else {
+            mWindow.clear();
+        }
+    }
+
+    /** @hide */
+    @Override
+    @UnsupportedAppUsage
+    protected void onDeactivateOrClose() {
+        super.onDeactivateOrClose();
+        closeWindow();
+    }
+}
diff --git a/android/database/BulkCursorDescriptor.java b/android/database/BulkCursorDescriptor.java
new file mode 100644
index 0000000..80a0319
--- /dev/null
+++ b/android/database/BulkCursorDescriptor.java
@@ -0,0 +1,78 @@
+/*
+ * Copyright (C) 2012 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.database;
+
+import android.os.Parcel;
+import android.os.Parcelable;
+
+/**
+ * Describes the properties of a {@link CursorToBulkCursorAdaptor} that are
+ * needed to initialize its {@link BulkCursorToCursorAdaptor} counterpart on the client's end.
+ *
+ * {@hide}
+ */
+public final class BulkCursorDescriptor implements Parcelable {
+    public static final @android.annotation.NonNull Parcelable.Creator<BulkCursorDescriptor> CREATOR =
+            new Parcelable.Creator<BulkCursorDescriptor>() {
+        @Override
+        public BulkCursorDescriptor createFromParcel(Parcel in) {
+            BulkCursorDescriptor d = new BulkCursorDescriptor();
+            d.readFromParcel(in);
+            return d;
+        }
+
+        @Override
+        public BulkCursorDescriptor[] newArray(int size) {
+            return new BulkCursorDescriptor[size];
+        }
+    };
+
+    public IBulkCursor cursor;
+    public String[] columnNames;
+    public boolean wantsAllOnMoveCalls;
+    public int count;
+    public CursorWindow window;
+
+    @Override
+    public int describeContents() {
+        return 0;
+    }
+
+    @Override
+    public void writeToParcel(Parcel out, int flags) {
+        out.writeStrongBinder(cursor.asBinder());
+        out.writeStringArray(columnNames);
+        out.writeInt(wantsAllOnMoveCalls ? 1 : 0);
+        out.writeInt(count);
+        if (window != null) {
+            out.writeInt(1);
+            window.writeToParcel(out, flags);
+        } else {
+            out.writeInt(0);
+        }
+    }
+
+    public void readFromParcel(Parcel in) {
+        cursor = BulkCursorNative.asInterface(in.readStrongBinder());
+        columnNames = in.readStringArray();
+        wantsAllOnMoveCalls = in.readInt() != 0;
+        count = in.readInt();
+        if (in.readInt() != 0) {
+            window = CursorWindow.CREATOR.createFromParcel(in);
+        }
+    }
+}
diff --git a/android/database/BulkCursorNative.java b/android/database/BulkCursorNative.java
new file mode 100644
index 0000000..8ea450c
--- /dev/null
+++ b/android/database/BulkCursorNative.java
@@ -0,0 +1,285 @@
+/*
+ * Copyright (C) 2006 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.database;
+
+import android.compat.annotation.UnsupportedAppUsage;
+import android.os.Binder;
+import android.os.Bundle;
+import android.os.IBinder;
+import android.os.Parcel;
+import android.os.Parcelable;
+import android.os.RemoteException;
+
+/**
+ * Native implementation of the bulk cursor. This is only for use in implementing
+ * IPC, application code should use the Cursor interface.
+ *
+ * {@hide}
+ */
+public abstract class BulkCursorNative extends Binder implements IBulkCursor
+{
+    public BulkCursorNative()
+    {
+        attachInterface(this, descriptor);
+    }
+
+    /**
+     * Cast a Binder object into a content resolver interface, generating
+     * a proxy if needed.
+     */
+    static public IBulkCursor asInterface(IBinder obj)
+    {
+        if (obj == null) {
+            return null;
+        }
+        IBulkCursor in = (IBulkCursor)obj.queryLocalInterface(descriptor);
+        if (in != null) {
+            return in;
+        }
+
+        return new BulkCursorProxy(obj);
+    }
+    
+    @Override
+    public boolean onTransact(int code, Parcel data, Parcel reply, int flags)
+            throws RemoteException {
+        try {
+            switch (code) {
+                case GET_CURSOR_WINDOW_TRANSACTION: {
+                    data.enforceInterface(IBulkCursor.descriptor);
+                    int startPos = data.readInt();
+                    CursorWindow window = getWindow(startPos);
+                    reply.writeNoException();
+                    if (window == null) {
+                        reply.writeInt(0);
+                    } else {
+                        reply.writeInt(1);
+                        window.writeToParcel(reply, Parcelable.PARCELABLE_WRITE_RETURN_VALUE);
+                    }
+                    return true;
+                }
+
+                case DEACTIVATE_TRANSACTION: {
+                    data.enforceInterface(IBulkCursor.descriptor);
+                    deactivate();
+                    reply.writeNoException();
+                    return true;
+                }
+                
+                case CLOSE_TRANSACTION: {
+                    data.enforceInterface(IBulkCursor.descriptor);
+                    close();
+                    reply.writeNoException();
+                    return true;
+                }
+
+                case REQUERY_TRANSACTION: {
+                    data.enforceInterface(IBulkCursor.descriptor);
+                    IContentObserver observer =
+                            IContentObserver.Stub.asInterface(data.readStrongBinder());
+                    int count = requery(observer);
+                    reply.writeNoException();
+                    reply.writeInt(count);
+                    reply.writeBundle(getExtras());
+                    return true;
+                }
+
+                case ON_MOVE_TRANSACTION: {
+                    data.enforceInterface(IBulkCursor.descriptor);
+                    int position = data.readInt();
+                    onMove(position);
+                    reply.writeNoException();
+                    return true;
+                }
+
+                case GET_EXTRAS_TRANSACTION: {
+                    data.enforceInterface(IBulkCursor.descriptor);
+                    Bundle extras = getExtras();
+                    reply.writeNoException();
+                    reply.writeBundle(extras);
+                    return true;
+                }
+
+                case RESPOND_TRANSACTION: {
+                    data.enforceInterface(IBulkCursor.descriptor);
+                    Bundle extras = data.readBundle();
+                    Bundle returnExtras = respond(extras);
+                    reply.writeNoException();
+                    reply.writeBundle(returnExtras);
+                    return true;
+                }
+            }
+        } catch (Exception e) {
+            DatabaseUtils.writeExceptionToParcel(reply, e);
+            return true;
+        }
+
+        return super.onTransact(code, data, reply, flags);
+    }
+
+    public IBinder asBinder()
+    {
+        return this;
+    }
+}
+
+
+final class BulkCursorProxy implements IBulkCursor {
+    @UnsupportedAppUsage
+    private IBinder mRemote;
+    private Bundle mExtras;
+
+    public BulkCursorProxy(IBinder remote)
+    {
+        mRemote = remote;
+        mExtras = null;
+    }
+
+    public IBinder asBinder()
+    {
+        return mRemote;
+    }
+
+    public CursorWindow getWindow(int position) throws RemoteException
+    {
+        Parcel data = Parcel.obtain();
+        Parcel reply = Parcel.obtain();
+        try {
+            data.writeInterfaceToken(IBulkCursor.descriptor);
+            data.writeInt(position);
+
+            mRemote.transact(GET_CURSOR_WINDOW_TRANSACTION, data, reply, 0);
+            DatabaseUtils.readExceptionFromParcel(reply);
+
+            CursorWindow window = null;
+            if (reply.readInt() == 1) {
+                window = CursorWindow.newFromParcel(reply);
+            }
+            return window;
+        } finally {
+            data.recycle();
+            reply.recycle();
+        }
+    }
+
+    public void onMove(int position) throws RemoteException {
+        Parcel data = Parcel.obtain();
+        Parcel reply = Parcel.obtain();
+        try {
+            data.writeInterfaceToken(IBulkCursor.descriptor);
+            data.writeInt(position);
+
+            mRemote.transact(ON_MOVE_TRANSACTION, data, reply, 0);
+            DatabaseUtils.readExceptionFromParcel(reply);
+        } finally {
+            data.recycle();
+            reply.recycle();
+        }
+    }
+
+    public void deactivate() throws RemoteException
+    {
+        Parcel data = Parcel.obtain();
+        Parcel reply = Parcel.obtain();
+        try {
+            data.writeInterfaceToken(IBulkCursor.descriptor);
+
+            mRemote.transact(DEACTIVATE_TRANSACTION, data, reply, 0);
+            DatabaseUtils.readExceptionFromParcel(reply);
+        } finally {
+            data.recycle();
+            reply.recycle();
+        }
+    }
+
+    public void close() throws RemoteException
+    {
+        Parcel data = Parcel.obtain();
+        Parcel reply = Parcel.obtain();
+        try {
+            data.writeInterfaceToken(IBulkCursor.descriptor);
+
+            mRemote.transact(CLOSE_TRANSACTION, data, reply, 0);
+            DatabaseUtils.readExceptionFromParcel(reply);
+        } finally {
+            data.recycle();
+            reply.recycle();
+        }
+    }
+    
+    public int requery(IContentObserver observer) throws RemoteException {
+        Parcel data = Parcel.obtain();
+        Parcel reply = Parcel.obtain();
+        try {
+            data.writeInterfaceToken(IBulkCursor.descriptor);
+            data.writeStrongInterface(observer);
+
+            boolean result = mRemote.transact(REQUERY_TRANSACTION, data, reply, 0);
+            DatabaseUtils.readExceptionFromParcel(reply);
+
+            int count;
+            if (!result) {
+                count = -1;
+            } else {
+                count = reply.readInt();
+                mExtras = reply.readBundle();
+            }
+            return count;
+        } finally {
+            data.recycle();
+            reply.recycle();
+        }
+    }
+
+    public Bundle getExtras() throws RemoteException {
+        if (mExtras == null) {
+            Parcel data = Parcel.obtain();
+            Parcel reply = Parcel.obtain();
+            try {
+                data.writeInterfaceToken(IBulkCursor.descriptor);
+
+                mRemote.transact(GET_EXTRAS_TRANSACTION, data, reply, 0);
+                DatabaseUtils.readExceptionFromParcel(reply);
+
+                mExtras = reply.readBundle();
+            } finally {
+                data.recycle();
+                reply.recycle();
+            }
+        }
+        return mExtras;
+    }
+
+    public Bundle respond(Bundle extras) throws RemoteException {
+        Parcel data = Parcel.obtain();
+        Parcel reply = Parcel.obtain();
+        try {
+            data.writeInterfaceToken(IBulkCursor.descriptor);
+            data.writeBundle(extras);
+
+            mRemote.transact(RESPOND_TRANSACTION, data, reply, 0);
+            DatabaseUtils.readExceptionFromParcel(reply);
+
+            Bundle returnExtras = reply.readBundle();
+            return returnExtras;
+        } finally {
+            data.recycle();
+            reply.recycle();
+        }
+    }
+}
+
diff --git a/android/database/BulkCursorToCursorAdaptor.java b/android/database/BulkCursorToCursorAdaptor.java
new file mode 100644
index 0000000..8576715
--- /dev/null
+++ b/android/database/BulkCursorToCursorAdaptor.java
@@ -0,0 +1,190 @@
+/*
+ * Copyright (C) 2006 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.database;
+
+import android.os.Bundle;
+import android.os.RemoteException;
+import android.util.Log;
+
+/**
+ * Adapts an {@link IBulkCursor} to a {@link Cursor} for use in the local process.
+ *
+ * {@hide}
+ */
+public final class BulkCursorToCursorAdaptor extends AbstractWindowedCursor {
+    private static final String TAG = "BulkCursor";
+
+    private SelfContentObserver mObserverBridge = new SelfContentObserver(this);
+    private IBulkCursor mBulkCursor;
+    private String[] mColumns;
+    private boolean mWantsAllOnMoveCalls;
+    private int mCount;
+
+    /**
+     * Initializes the adaptor.
+     * Must be called before first use.
+     */
+    public void initialize(BulkCursorDescriptor d) {
+        mBulkCursor = d.cursor;
+        mColumns = d.columnNames;
+        mWantsAllOnMoveCalls = d.wantsAllOnMoveCalls;
+        mCount = d.count;
+        if (d.window != null) {
+            setWindow(d.window);
+        }
+    }
+
+    /**
+     * Gets a SelfDataChangeOberserver that can be sent to a remote
+     * process to receive change notifications over IPC.
+     *
+     * @return A SelfContentObserver hooked up to this Cursor
+     */
+    public IContentObserver getObserver() {
+        return mObserverBridge.getContentObserver();
+    }
+
+    private void throwIfCursorIsClosed() {
+        if (mBulkCursor == null) {
+            throw new StaleDataException("Attempted to access a cursor after it has been closed.");
+        }
+    }
+
+    @Override
+    public int getCount() {
+        throwIfCursorIsClosed();
+        return mCount;
+    }
+
+    @Override
+    public boolean onMove(int oldPosition, int newPosition) {
+        throwIfCursorIsClosed();
+
+        try {
+            // Make sure we have the proper window
+            if (mWindow == null
+                    || newPosition < mWindow.getStartPosition()
+                    || newPosition >= mWindow.getStartPosition() + mWindow.getNumRows()) {
+                setWindow(mBulkCursor.getWindow(newPosition));
+            } else if (mWantsAllOnMoveCalls) {
+                mBulkCursor.onMove(newPosition);
+            }
+        } catch (RemoteException ex) {
+            // We tried to get a window and failed
+            Log.e(TAG, "Unable to get window because the remote process is dead");
+            return false;
+        }
+
+        // Couldn't obtain a window, something is wrong
+        if (mWindow == null) {
+            return false;
+        }
+
+        return true;
+    }
+
+    @Override
+    public void deactivate() {
+        // This will call onInvalidated(), so make sure to do it before calling release,
+        // which is what actually makes the data set invalid.
+        super.deactivate();
+
+        if (mBulkCursor != null) {
+            try {
+                mBulkCursor.deactivate();
+            } catch (RemoteException ex) {
+                Log.w(TAG, "Remote process exception when deactivating");
+            }
+        }
+    }
+    
+    @Override
+    public void close() {
+        super.close();
+
+        if (mBulkCursor != null) {
+            try {
+                mBulkCursor.close();
+            } catch (RemoteException ex) {
+                Log.w(TAG, "Remote process exception when closing");
+            } finally {
+                mBulkCursor = null;
+            }
+        }
+    }
+
+    @Override
+    public boolean requery() {
+        throwIfCursorIsClosed();
+
+        try {
+            mCount = mBulkCursor.requery(getObserver());
+            if (mCount != -1) {
+                mPos = -1;
+                closeWindow();
+
+                // super.requery() will call onChanged. Do it here instead of relying on the
+                // observer from the far side so that observers can see a correct value for mCount
+                // when responding to onChanged.
+                super.requery();
+                return true;
+            } else {
+                deactivate();
+                return false;
+            }
+        } catch (Exception ex) {
+            Log.e(TAG, "Unable to requery because the remote process exception " + ex.getMessage());
+            deactivate();
+            return false;
+        }
+    }
+
+    @Override
+    public String[] getColumnNames() {
+        throwIfCursorIsClosed();
+
+        return mColumns;
+    }
+
+    @Override
+    public Bundle getExtras() {
+        throwIfCursorIsClosed();
+
+        try {
+            return mBulkCursor.getExtras();
+        } catch (RemoteException e) {
+            // This should never happen because the system kills processes that are using remote
+            // cursors when the provider process is killed.
+            throw new RuntimeException(e);
+        }
+    }
+
+    @Override
+    public Bundle respond(Bundle extras) {
+        throwIfCursorIsClosed();
+
+        try {
+            return mBulkCursor.respond(extras);
+        } catch (RemoteException e) {
+            // the system kills processes that are using remote cursors when the provider process
+            // is killed, but this can still happen if this is being called from the system process,
+            // so, better to log and return an empty bundle.
+            Log.w(TAG, "respond() threw RemoteException, returning an empty bundle.", e);
+            return Bundle.EMPTY;
+        }
+    }
+}
diff --git a/android/database/CharArrayBuffer.java b/android/database/CharArrayBuffer.java
new file mode 100644
index 0000000..73781b7
--- /dev/null
+++ b/android/database/CharArrayBuffer.java
@@ -0,0 +1,33 @@
+/*
+ * Copyright (C) 2008 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.database;
+
+/**
+ * This is used for {@link Cursor#copyStringToBuffer}
+ */
+public final class CharArrayBuffer {
+    public CharArrayBuffer(int size) {
+        data = new char[size];
+    }
+    
+    public CharArrayBuffer(char[] buf) {
+        data = buf;
+    }
+    
+    public char[] data; // In and out parameter
+    public int sizeCopied; // Out parameter
+}
diff --git a/android/database/ContentObservable.java b/android/database/ContentObservable.java
new file mode 100644
index 0000000..7692bb3
--- /dev/null
+++ b/android/database/ContentObservable.java
@@ -0,0 +1,91 @@
+/*
+ * 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.database;
+
+import android.net.Uri;
+
+/**
+ * A specialization of {@link Observable} for {@link ContentObserver}
+ * that provides methods for sending notifications to a list of
+ * {@link ContentObserver} objects.
+ */
+public class ContentObservable extends Observable<ContentObserver> {
+    // Even though the generic method defined in Observable would be perfectly
+    // fine on its own, we can't delete this overridden method because it would
+    // potentially break binary compatibility with existing applications.
+    @Override
+    public void registerObserver(ContentObserver observer) {
+        super.registerObserver(observer);
+    }
+
+    /**
+     * Invokes {@link ContentObserver#dispatchChange(boolean)} on each observer.
+     * <p>
+     * If <code>selfChange</code> is true, only delivers the notification
+     * to the observer if it has indicated that it wants to receive self-change
+     * notifications by implementing {@link ContentObserver#deliverSelfNotifications}
+     * to return true.
+     * </p>
+     *
+     * @param selfChange True if this is a self-change notification.
+     *
+     * @deprecated Use {@link #dispatchChange(boolean, Uri)} instead.
+     */
+    @Deprecated
+    public void dispatchChange(boolean selfChange) {
+        dispatchChange(selfChange, null);
+    }
+
+    /**
+     * Invokes {@link ContentObserver#dispatchChange(boolean, Uri)} on each observer.
+     * Includes the changed content Uri when available.
+     * <p>
+     * If <code>selfChange</code> is true, only delivers the notification
+     * to the observer if it has indicated that it wants to receive self-change
+     * notifications by implementing {@link ContentObserver#deliverSelfNotifications}
+     * to return true.
+     * </p>
+     *
+     * @param selfChange True if this is a self-change notification.
+     * @param uri The Uri of the changed content, or null if unknown.
+     */
+    public void dispatchChange(boolean selfChange, Uri uri) {
+        synchronized(mObservers) {
+            for (ContentObserver observer : mObservers) {
+                if (!selfChange || observer.deliverSelfNotifications()) {
+                    observer.dispatchChange(selfChange, uri);
+                }
+            }
+        }
+    }
+
+    /**
+     * Invokes {@link ContentObserver#onChange} on each observer.
+     *
+     * @param selfChange True if this is a self-change notification.
+     *
+     * @deprecated Use {@link #dispatchChange} instead.
+     */
+    @Deprecated
+    public void notifyChange(boolean selfChange) {
+        synchronized(mObservers) {
+            for (ContentObserver observer : mObservers) {
+                observer.onChange(selfChange, null);
+            }
+        }
+    }
+}
diff --git a/android/database/ContentObserver.java b/android/database/ContentObserver.java
new file mode 100644
index 0000000..578d53b
--- /dev/null
+++ b/android/database/ContentObserver.java
@@ -0,0 +1,313 @@
+/*
+ * 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.database;
+
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+import android.annotation.UserIdInt;
+import android.app.compat.CompatChanges;
+import android.compat.annotation.ChangeId;
+import android.compat.annotation.EnabledAfter;
+import android.compat.annotation.UnsupportedAppUsage;
+import android.content.ContentResolver.NotifyFlags;
+import android.net.Uri;
+import android.os.Handler;
+import android.os.UserHandle;
+
+import java.util.Arrays;
+import java.util.Collection;
+
+/**
+ * Receives call backs for changes to content.
+ * Must be implemented by objects which are added to a {@link ContentObservable}.
+ */
+public abstract class ContentObserver {
+    /**
+     * Starting in {@link android.os.Build.VERSION_CODES#R}, there is a new
+     * public API overload {@link #onChange(boolean, Uri, int)} that delivers a
+     * {@code int flags} argument.
+     * <p>
+     * Some apps may be relying on a previous hidden API that delivered a
+     * {@code int userId} argument, and this change is used to control delivery
+     * of the new {@code int flags} argument in its place.
+     */
+    @ChangeId
+    @EnabledAfter(targetSdkVersion=android.os.Build.VERSION_CODES.Q)
+    private static final long ADD_CONTENT_OBSERVER_FLAGS = 150939131L;
+
+    private final Object mLock = new Object();
+    private Transport mTransport; // guarded by mLock
+
+    Handler mHandler;
+
+    /**
+     * Creates a content observer.
+     *
+     * @param handler The handler to run {@link #onChange} on, or null if none.
+     */
+    public ContentObserver(Handler handler) {
+        mHandler = handler;
+    }
+
+    /**
+     * Gets access to the binder transport object. Not for public consumption.
+     *
+     * {@hide}
+     */
+    public IContentObserver getContentObserver() {
+        synchronized (mLock) {
+            if (mTransport == null) {
+                mTransport = new Transport(this);
+            }
+            return mTransport;
+        }
+    }
+
+    /**
+     * Gets access to the binder transport object, and unlinks the transport object
+     * from the ContentObserver. Not for public consumption.
+     *
+     * {@hide}
+     */
+    @UnsupportedAppUsage
+    public IContentObserver releaseContentObserver() {
+        synchronized (mLock) {
+            final Transport oldTransport = mTransport;
+            if (oldTransport != null) {
+                oldTransport.releaseContentObserver();
+                mTransport = null;
+            }
+            return oldTransport;
+        }
+    }
+
+    /**
+     * Returns true if this observer is interested receiving self-change notifications.
+     *
+     * Subclasses should override this method to indicate whether the observer
+     * is interested in receiving notifications for changes that it made to the
+     * content itself.
+     *
+     * @return True if self-change notifications should be delivered to the observer.
+     */
+    public boolean deliverSelfNotifications() {
+        return false;
+    }
+
+    /**
+     * This method is called when a content change occurs.
+     * <p>
+     * Subclasses should override this method to handle content changes.
+     * </p>
+     *
+     * @param selfChange True if this is a self-change notification.
+     */
+    public void onChange(boolean selfChange) {
+        // Do nothing.  Subclass should override.
+    }
+
+    /**
+     * This method is called when a content change occurs.
+     * Includes the changed content Uri when available.
+     * <p>
+     * Subclasses should override this method to handle content changes. To
+     * ensure correct operation on older versions of the framework that did not
+     * provide richer arguments, applications should implement all overloads.
+     * <p>
+     * Example implementation:
+     * <pre><code>
+     * // Implement the onChange(boolean) method to delegate the change notification to
+     * // the onChange(boolean, Uri) method to ensure correct operation on older versions
+     * // of the framework that did not have the onChange(boolean, Uri) method.
+     * {@literal @Override}
+     * public void onChange(boolean selfChange) {
+     *     onChange(selfChange, null);
+     * }
+     *
+     * // Implement the onChange(boolean, Uri) method to take advantage of the new Uri argument.
+     * {@literal @Override}
+     * public void onChange(boolean selfChange, Uri uri) {
+     *     // Handle change.
+     * }
+     * </code></pre>
+     * </p>
+     *
+     * @param selfChange True if this is a self-change notification.
+     * @param uri The Uri of the changed content.
+     */
+    public void onChange(boolean selfChange, @Nullable Uri uri) {
+        onChange(selfChange);
+    }
+
+    /**
+     * This method is called when a content change occurs. Includes the changed
+     * content Uri when available.
+     * <p>
+     * Subclasses should override this method to handle content changes. To
+     * ensure correct operation on older versions of the framework that did not
+     * provide richer arguments, applications should implement all overloads.
+     *
+     * @param selfChange True if this is a self-change notification.
+     * @param uri The Uri of the changed content.
+     * @param flags Flags indicating details about this change.
+     */
+    public void onChange(boolean selfChange, @Nullable Uri uri, @NotifyFlags int flags) {
+        onChange(selfChange, uri);
+    }
+
+    /**
+     * This method is called when a content change occurs. Includes the changed
+     * content Uris when available.
+     * <p>
+     * Subclasses should override this method to handle content changes. To
+     * ensure correct operation on older versions of the framework that did not
+     * provide richer arguments, applications should implement all overloads.
+     *
+     * @param selfChange True if this is a self-change notification.
+     * @param uris The Uris of the changed content.
+     * @param flags Flags indicating details about this change.
+     */
+    public void onChange(boolean selfChange, @NonNull Collection<Uri> uris,
+            @NotifyFlags int flags) {
+        for (Uri uri : uris) {
+            onChange(selfChange, uri, flags);
+        }
+    }
+
+    /** @hide */
+    public void onChange(boolean selfChange, @NonNull Collection<Uri> uris,
+            @NotifyFlags int flags, @UserIdInt int userId) {
+        // There are dozens of people relying on the hidden API inside the
+        // system UID, so hard-code the old behavior for all of them; for
+        // everyone else we gate based on a specific change
+        if (!CompatChanges.isChangeEnabled(ADD_CONTENT_OBSERVER_FLAGS)
+                || android.os.Process.myUid() == android.os.Process.SYSTEM_UID) {
+            // Deliver userId through argument to preserve hidden API behavior
+            onChange(selfChange, uris, userId);
+        } else {
+            onChange(selfChange, uris, flags);
+        }
+    }
+
+    /**
+     * Dispatches a change notification to the observer.
+     * <p>
+     * If a {@link Handler} was supplied to the {@link ContentObserver}
+     * constructor, then a call to the {@link #onChange} method is posted to the
+     * handler's message queue. Otherwise, the {@link #onChange} method is
+     * invoked immediately on this thread.
+     *
+     * @deprecated Callers should migrate towards using a richer overload that
+     *             provides more details about the change, such as
+     *             {@link #dispatchChange(boolean, Collection, int)}.
+     */
+    @Deprecated
+    public final void dispatchChange(boolean selfChange) {
+        dispatchChange(selfChange, null);
+    }
+
+    /**
+     * Dispatches a change notification to the observer. Includes the changed
+     * content Uri when available.
+     * <p>
+     * If a {@link Handler} was supplied to the {@link ContentObserver}
+     * constructor, then a call to the {@link #onChange} method is posted to the
+     * handler's message queue. Otherwise, the {@link #onChange} method is
+     * invoked immediately on this thread.
+     *
+     * @param selfChange True if this is a self-change notification.
+     * @param uri The Uri of the changed content.
+     */
+    public final void dispatchChange(boolean selfChange, @Nullable Uri uri) {
+        dispatchChange(selfChange, uri, 0);
+    }
+
+    /**
+     * Dispatches a change notification to the observer. Includes the changed
+     * content Uri when available.
+     * <p>
+     * If a {@link Handler} was supplied to the {@link ContentObserver}
+     * constructor, then a call to the {@link #onChange} method is posted to the
+     * handler's message queue. Otherwise, the {@link #onChange} method is
+     * invoked immediately on this thread.
+     *
+     * @param selfChange True if this is a self-change notification.
+     * @param uri The Uri of the changed content.
+     * @param flags Flags indicating details about this change.
+     */
+    public final void dispatchChange(boolean selfChange, @Nullable Uri uri,
+            @NotifyFlags int flags) {
+        dispatchChange(selfChange, Arrays.asList(uri), flags);
+    }
+
+    /**
+     * Dispatches a change notification to the observer. Includes the changed
+     * content Uris when available.
+     * <p>
+     * If a {@link Handler} was supplied to the {@link ContentObserver}
+     * constructor, then a call to the {@link #onChange} method is posted to the
+     * handler's message queue. Otherwise, the {@link #onChange} method is
+     * invoked immediately on this thread.
+     *
+     * @param selfChange True if this is a self-change notification.
+     * @param uris The Uri of the changed content.
+     * @param flags Flags indicating details about this change.
+     */
+    public final void dispatchChange(boolean selfChange, @NonNull Collection<Uri> uris,
+            @NotifyFlags int flags) {
+        dispatchChange(selfChange, uris, flags, UserHandle.getCallingUserId());
+    }
+
+    /** @hide */
+    public final void dispatchChange(boolean selfChange, @NonNull Collection<Uri> uris,
+            @NotifyFlags int flags, @UserIdInt int userId) {
+        if (mHandler == null) {
+            onChange(selfChange, uris, flags, userId);
+        } else {
+            mHandler.post(() -> {
+                onChange(selfChange, uris, flags, userId);
+            });
+        }
+    }
+
+    private static final class Transport extends IContentObserver.Stub {
+        private ContentObserver mContentObserver;
+
+        public Transport(ContentObserver contentObserver) {
+            mContentObserver = contentObserver;
+        }
+
+        @Override
+        public void onChange(boolean selfChange, Uri uri, int userId) {
+            // This is kept intact purely for apps using hidden APIs, to
+            // redirect to the updated implementation
+            onChangeEtc(selfChange, new Uri[] { uri }, 0, userId);
+        }
+
+        @Override
+        public void onChangeEtc(boolean selfChange, Uri[] uris, int flags, int userId) {
+            ContentObserver contentObserver = mContentObserver;
+            if (contentObserver != null) {
+                contentObserver.dispatchChange(selfChange, Arrays.asList(uris), flags, userId);
+            }
+        }
+
+        public void releaseContentObserver() {
+            mContentObserver = null;
+        }
+    }
+}
diff --git a/android/database/CrossProcessCursor.java b/android/database/CrossProcessCursor.java
new file mode 100644
index 0000000..26379cc
--- /dev/null
+++ b/android/database/CrossProcessCursor.java
@@ -0,0 +1,78 @@
+/*
+ * Copyright (C) 2008 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.database;
+
+/**
+ * A cross process cursor is an extension of a {@link Cursor} that also supports
+ * usage from remote processes.
+ * <p>
+ * The contents of a cross process cursor are marshalled to the remote process by
+ * filling {@link CursorWindow} objects using {@link #fillWindow}.  As an optimization,
+ * the cursor can provide a pre-filled window to use via {@link #getWindow} thereby
+ * obviating the need to copy the data to yet another cursor window.
+ */
+public interface CrossProcessCursor extends Cursor {
+    /**
+     * Returns a pre-filled window that contains the data within this cursor.
+     * <p>
+     * In particular, the window contains the row indicated by {@link Cursor#getPosition}.
+     * The window's contents are automatically scrolled whenever the current
+     * row moved outside the range covered by the window.
+     * </p>
+     *
+     * @return The pre-filled window, or null if none.
+     */
+    CursorWindow getWindow();
+
+    /**
+     * Copies cursor data into the window.
+     * <p>
+     * Clears the window and fills it with data beginning at the requested
+     * row position until all of the data in the cursor is exhausted
+     * or the window runs out of space.
+     * </p><p>
+     * The filled window uses the same row indices as the original cursor.
+     * For example, if you fill a window starting from row 5 from the cursor,
+     * you can query the contents of row 5 from the window just by asking it
+     * for row 5 because there is a direct correspondence between the row indices
+     * used by the cursor and the window.
+     * </p><p>
+     * The current position of the cursor, as returned by {@link #getPosition},
+     * is not changed by this method.
+     * </p>
+     *
+     * @param position The zero-based index of the first row to copy into the window.
+     * @param window The window to fill.
+     */
+    void fillWindow(int position, CursorWindow window);
+
+    /**
+     * This function is called every time the cursor is successfully scrolled
+     * to a new position, giving the subclass a chance to update any state it
+     * may have.  If it returns false the move function will also do so and the
+     * cursor will scroll to the beforeFirst position.
+     * <p>
+     * This function should be called by methods such as {@link #moveToPosition(int)},
+     * so it will typically not be called from outside of the cursor class itself.
+     * </p>
+     *
+     * @param oldPosition The position that we're moving from.
+     * @param newPosition The position that we're moving to.
+     * @return True if the move is successful, false otherwise.
+     */
+    boolean onMove(int oldPosition, int newPosition); 
+}
diff --git a/android/database/CrossProcessCursorWrapper.java b/android/database/CrossProcessCursorWrapper.java
new file mode 100644
index 0000000..1b77cb9
--- /dev/null
+++ b/android/database/CrossProcessCursorWrapper.java
@@ -0,0 +1,75 @@
+/*
+ * Copyright (C) 2011 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License
+ */
+
+package android.database;
+
+import android.database.CrossProcessCursor;
+import android.database.Cursor;
+import android.database.CursorWindow;
+import android.database.CursorWrapper;
+
+/**
+ * Cursor wrapper that implements {@link CrossProcessCursor}.
+ * <p>
+ * If the wrapped cursor implements {@link CrossProcessCursor}, then the wrapper
+ * delegates {@link #fillWindow}, {@link #getWindow()} and {@link #onMove} to it.
+ * Otherwise, the wrapper provides default implementations of these methods that
+ * traverse the contents of the cursor similar to {@link AbstractCursor#fillWindow}.
+ * </p><p>
+ * This wrapper can be used to adapt an ordinary {@link Cursor} into a
+ * {@link CrossProcessCursor}.
+ * </p>
+ */
+public class CrossProcessCursorWrapper extends CursorWrapper implements CrossProcessCursor {
+    /**
+     * Creates a cross process cursor wrapper.
+     * @param cursor The underlying cursor to wrap.
+     */
+    public CrossProcessCursorWrapper(Cursor cursor) {
+        super(cursor);
+    }
+
+    @Override
+    public void fillWindow(int position, CursorWindow window) {
+        if (mCursor instanceof CrossProcessCursor) {
+            final CrossProcessCursor crossProcessCursor = (CrossProcessCursor)mCursor;
+            crossProcessCursor.fillWindow(position, window);
+            return;
+        }
+
+        DatabaseUtils.cursorFillWindow(mCursor, position, window);
+    }
+
+    @Override
+    public CursorWindow getWindow() {
+        if (mCursor instanceof CrossProcessCursor) {
+            final CrossProcessCursor crossProcessCursor = (CrossProcessCursor)mCursor;
+            return crossProcessCursor.getWindow();
+        }
+
+        return null;
+    }
+
+    @Override
+    public boolean onMove(int oldPosition, int newPosition) {
+        if (mCursor instanceof CrossProcessCursor) {
+            final CrossProcessCursor crossProcessCursor = (CrossProcessCursor)mCursor;
+            return crossProcessCursor.onMove(oldPosition, newPosition);
+        }
+
+        return true;
+    }
+}
diff --git a/android/database/Cursor.java b/android/database/Cursor.java
new file mode 100644
index 0000000..2afb755
--- /dev/null
+++ b/android/database/Cursor.java
@@ -0,0 +1,518 @@
+/*
+ * Copyright (C) 2006 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.database;
+
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+import android.content.ContentResolver;
+import android.net.Uri;
+import android.os.Bundle;
+
+import java.io.Closeable;
+import java.util.Arrays;
+import java.util.List;
+
+/**
+ * This interface provides random read-write access to the result set returned
+ * by a database query.
+ * <p>
+ * Cursor implementations are not required to be synchronized so code using a Cursor from multiple
+ * threads should perform its own synchronization when using the Cursor.
+ * </p><p>
+ * Implementations should subclass {@link AbstractCursor}.
+ * </p>
+ */
+public interface Cursor extends Closeable {
+    /*
+     * Values returned by {@link #getType(int)}.
+     * These should be consistent with the corresponding types defined in CursorWindow.h
+     */
+    /** Value returned by {@link #getType(int)} if the specified column is null */
+    static final int FIELD_TYPE_NULL = 0;
+
+    /** Value returned by {@link #getType(int)} if the specified  column type is integer */
+    static final int FIELD_TYPE_INTEGER = 1;
+
+    /** Value returned by {@link #getType(int)} if the specified column type is float */
+    static final int FIELD_TYPE_FLOAT = 2;
+
+    /** Value returned by {@link #getType(int)} if the specified column type is string */
+    static final int FIELD_TYPE_STRING = 3;
+
+    /** Value returned by {@link #getType(int)} if the specified column type is blob */
+    static final int FIELD_TYPE_BLOB = 4;
+
+    /**
+     * Returns the numbers of rows in the cursor.
+     *
+     * @return the number of rows in the cursor.
+     */
+    int getCount();
+
+    /**
+     * Returns the current position of the cursor in the row set.
+     * The value is zero-based. When the row set is first returned the cursor
+     * will be at positon -1, which is before the first row. After the
+     * last row is returned another call to next() will leave the cursor past
+     * the last entry, at a position of count().
+     *
+     * @return the current cursor position.
+     */
+    int getPosition();
+
+    /**
+     * Move the cursor by a relative amount, forward or backward, from the
+     * current position. Positive offsets move forwards, negative offsets move
+     * backwards. If the final position is outside of the bounds of the result
+     * set then the resultant position will be pinned to -1 or count() depending
+     * on whether the value is off the front or end of the set, respectively.
+     *
+     * <p>This method will return true if the requested destination was
+     * reachable, otherwise, it returns false. For example, if the cursor is at
+     * currently on the second entry in the result set and move(-5) is called,
+     * the position will be pinned at -1, and false will be returned.
+     *
+     * @param offset the offset to be applied from the current position.
+     * @return whether the requested move fully succeeded.
+     */
+    boolean move(int offset);
+
+    /**
+     * Move the cursor to an absolute position. The valid
+     * range of values is -1 &lt;= position &lt;= count.
+     *
+     * <p>This method will return true if the request destination was reachable, 
+     * otherwise, it returns false.
+     *
+     * @param position the zero-based position to move to.
+     * @return whether the requested move fully succeeded.
+     */
+    boolean moveToPosition(int position);
+
+    /**
+     * Move the cursor to the first row.
+     *
+     * <p>This method will return false if the cursor is empty.
+     *
+     * @return whether the move succeeded.
+     */
+    boolean moveToFirst();
+
+    /**
+     * Move the cursor to the last row.
+     *
+     * <p>This method will return false if the cursor is empty.
+     *
+     * @return whether the move succeeded.
+     */
+    boolean moveToLast();
+
+    /**
+     * Move the cursor to the next row.
+     *
+     * <p>This method will return false if the cursor is already past the
+     * last entry in the result set.
+     *
+     * @return whether the move succeeded.
+     */
+    boolean moveToNext();
+
+    /**
+     * Move the cursor to the previous row.
+     *
+     * <p>This method will return false if the cursor is already before the
+     * first entry in the result set.
+     *
+     * @return whether the move succeeded.
+     */
+    boolean moveToPrevious();
+
+    /**
+     * Returns whether the cursor is pointing to the first row.
+     *
+     * @return whether the cursor is pointing at the first entry.
+     */
+    boolean isFirst();
+
+    /**
+     * Returns whether the cursor is pointing to the last row.
+     *
+     * @return whether the cursor is pointing at the last entry.
+     */
+    boolean isLast();
+
+    /**
+     * Returns whether the cursor is pointing to the position before the first
+     * row.
+     *
+     * @return whether the cursor is before the first result.
+     */
+    boolean isBeforeFirst();
+
+    /**
+     * Returns whether the cursor is pointing to the position after the last
+     * row.
+     *
+     * @return whether the cursor is after the last result.
+     */
+    boolean isAfterLast();
+
+    /**
+     * Returns the zero-based index for the given column name, or -1 if the column doesn't exist.
+     * If you expect the column to exist use {@link #getColumnIndexOrThrow(String)} instead, which
+     * will make the error more clear.
+     *
+     * @param columnName the name of the target column.
+     * @return the zero-based column index for the given column name, or -1 if
+     * the column name does not exist.
+     * @see #getColumnIndexOrThrow(String)
+     */
+    int getColumnIndex(String columnName);
+
+    /**
+     * Returns the zero-based index for the given column name, or throws
+     * {@link IllegalArgumentException} if the column doesn't exist. If you're not sure if
+     * a column will exist or not use {@link #getColumnIndex(String)} and check for -1, which
+     * is more efficient than catching the exceptions.
+     *
+     * @param columnName the name of the target column.
+     * @return the zero-based column index for the given column name
+     * @see #getColumnIndex(String)
+     * @throws IllegalArgumentException if the column does not exist
+     */
+    int getColumnIndexOrThrow(String columnName) throws IllegalArgumentException;
+
+    /**
+     * Returns the column name at the given zero-based column index.
+     *
+     * @param columnIndex the zero-based index of the target column.
+     * @return the column name for the given column index.
+     */
+    String getColumnName(int columnIndex);
+
+    /**
+     * Returns a string array holding the names of all of the columns in the
+     * result set in the order in which they were listed in the result.
+     *
+     * @return the names of the columns returned in this query.
+     */
+    String[] getColumnNames();
+
+    /**
+     * Return total number of columns
+     * @return number of columns 
+     */
+    int getColumnCount();
+    
+    /**
+     * Returns the value of the requested column as a byte array.
+     *
+     * <p>The result and whether this method throws an exception when the
+     * column value is null or the column type is not a blob type is
+     * implementation-defined.
+     *
+     * @param columnIndex the zero-based index of the target column.
+     * @return the value of that column as a byte array.
+     */
+    byte[] getBlob(int columnIndex);
+
+    /**
+     * Returns the value of the requested column as a String.
+     *
+     * <p>The result and whether this method throws an exception when the
+     * column value is null or the column type is not a string type is
+     * implementation-defined.
+     *
+     * @param columnIndex the zero-based index of the target column.
+     * @return the value of that column as a String.
+     */
+    String getString(int columnIndex);
+    
+    /**
+     * Retrieves the requested column text and stores it in the buffer provided.
+     * If the buffer size is not sufficient, a new char buffer will be allocated 
+     * and assigned to CharArrayBuffer.data
+     * @param columnIndex the zero-based index of the target column.
+     *        if the target column is null, return buffer
+     * @param buffer the buffer to copy the text into. 
+     */
+    void copyStringToBuffer(int columnIndex, CharArrayBuffer buffer);
+    
+    /**
+     * Returns the value of the requested column as a short.
+     *
+     * <p>The result and whether this method throws an exception when the
+     * column value is null, the column type is not an integral type, or the
+     * integer value is outside the range [<code>Short.MIN_VALUE</code>,
+     * <code>Short.MAX_VALUE</code>] is implementation-defined.
+     *
+     * @param columnIndex the zero-based index of the target column.
+     * @return the value of that column as a short.
+     */
+    short getShort(int columnIndex);
+
+    /**
+     * Returns the value of the requested column as an int.
+     *
+     * <p>The result and whether this method throws an exception when the
+     * column value is null, the column type is not an integral type, or the
+     * integer value is outside the range [<code>Integer.MIN_VALUE</code>,
+     * <code>Integer.MAX_VALUE</code>] is implementation-defined.
+     *
+     * @param columnIndex the zero-based index of the target column.
+     * @return the value of that column as an int.
+     */
+    int getInt(int columnIndex);
+
+    /**
+     * Returns the value of the requested column as a long.
+     *
+     * <p>The result and whether this method throws an exception when the
+     * column value is null, the column type is not an integral type, or the
+     * integer value is outside the range [<code>Long.MIN_VALUE</code>,
+     * <code>Long.MAX_VALUE</code>] is implementation-defined.
+     *
+     * @param columnIndex the zero-based index of the target column.
+     * @return the value of that column as a long.
+     */
+    long getLong(int columnIndex);
+
+    /**
+     * Returns the value of the requested column as a float.
+     *
+     * <p>The result and whether this method throws an exception when the
+     * column value is null, the column type is not a floating-point type, or the
+     * floating-point value is not representable as a <code>float</code> value is
+     * implementation-defined.
+     *
+     * @param columnIndex the zero-based index of the target column.
+     * @return the value of that column as a float.
+     */
+    float getFloat(int columnIndex);
+
+    /**
+     * Returns the value of the requested column as a double.
+     *
+     * <p>The result and whether this method throws an exception when the
+     * column value is null, the column type is not a floating-point type, or the
+     * floating-point value is not representable as a <code>double</code> value is
+     * implementation-defined.
+     *
+     * @param columnIndex the zero-based index of the target column.
+     * @return the value of that column as a double.
+     */
+    double getDouble(int columnIndex);
+
+    /**
+     * Returns data type of the given column's value.
+     * The preferred type of the column is returned but the data may be converted to other types
+     * as documented in the get-type methods such as {@link #getInt(int)}, {@link #getFloat(int)}
+     * etc.
+     *<p>
+     * Returned column types are
+     * <ul>
+     *   <li>{@link #FIELD_TYPE_NULL}</li>
+     *   <li>{@link #FIELD_TYPE_INTEGER}</li>
+     *   <li>{@link #FIELD_TYPE_FLOAT}</li>
+     *   <li>{@link #FIELD_TYPE_STRING}</li>
+     *   <li>{@link #FIELD_TYPE_BLOB}</li>
+     *</ul>
+     *</p>
+     *
+     * @param columnIndex the zero-based index of the target column.
+     * @return column value type
+     */
+    int getType(int columnIndex);
+
+    /**
+     * Returns <code>true</code> if the value in the indicated column is null.
+     *
+     * @param columnIndex the zero-based index of the target column.
+     * @return whether the column value is null.
+     */
+    boolean isNull(int columnIndex);
+
+    /**
+     * Deactivates the Cursor, making all calls on it fail until {@link #requery} is called.
+     * Inactive Cursors use fewer resources than active Cursors.
+     * Calling {@link #requery} will make the cursor active again.
+     * @deprecated Since {@link #requery()} is deprecated, so too is this.
+     */
+    @Deprecated
+    void deactivate();
+
+    /**
+     * Performs the query that created the cursor again, refreshing its 
+     * contents. This may be done at any time, including after a call to {@link
+     * #deactivate}.
+     *
+     * Since this method could execute a query on the database and potentially take
+     * a while, it could cause ANR if it is called on Main (UI) thread.
+     * A warning is printed if this method is being executed on Main thread.
+     *
+     * @return true if the requery succeeded, false if not, in which case the
+     *         cursor becomes invalid.
+     * @deprecated Don't use this. Just request a new cursor, so you can do this
+     * asynchronously and update your list view once the new cursor comes back.
+     */
+    @Deprecated
+    boolean requery();
+
+    /**
+     * Closes the Cursor, releasing all of its resources and making it completely invalid.
+     * Unlike {@link #deactivate()} a call to {@link #requery()} will not make the Cursor valid
+     * again.
+     */
+    void close();
+
+    /**
+     * return true if the cursor is closed
+     * @return true if the cursor is closed.
+     */
+    boolean isClosed();
+    
+    /**
+     * Register an observer that is called when changes happen to the content backing this cursor.
+     * Typically the data set won't change until {@link #requery()} is called.
+     *
+     * @param observer the object that gets notified when the content backing the cursor changes.
+     * @see #unregisterContentObserver(ContentObserver)
+     */
+    void registerContentObserver(ContentObserver observer);
+
+    /**
+     * Unregister an observer that has previously been registered with this
+     * cursor via {@link #registerContentObserver}.
+     *
+     * @param observer the object to unregister.
+     * @see #registerContentObserver(ContentObserver)
+     */
+    void unregisterContentObserver(ContentObserver observer);
+    
+    /**
+     * Register an observer that is called when changes happen to the contents
+     * of the this cursors data set, for example, when the data set is changed via
+     * {@link #requery()}, {@link #deactivate()}, or {@link #close()}.
+     *
+     * @param observer the object that gets notified when the cursors data set changes.
+     * @see #unregisterDataSetObserver(DataSetObserver)
+     */
+    void registerDataSetObserver(DataSetObserver observer);
+
+    /**
+     * Unregister an observer that has previously been registered with this
+     * cursor via {@link #registerContentObserver}.
+     *
+     * @param observer the object to unregister.
+     * @see #registerDataSetObserver(DataSetObserver)
+     */
+    void unregisterDataSetObserver(DataSetObserver observer);
+
+    /**
+     * Register to watch a content URI for changes. This can be the URI of a specific data row (for 
+     * example, "content://my_provider_type/23"), or a a generic URI for a content type.
+     *
+     * <p>Calling this overrides any previous call to
+     * {@link #setNotificationUris(ContentResolver, List)}.
+     *
+     * @param cr The content resolver from the caller's context. The listener attached to 
+     * this resolver will be notified.
+     * @param uri The content URI to watch.
+     */
+    void setNotificationUri(ContentResolver cr, Uri uri);
+
+    /**
+     * Similar to {@link #setNotificationUri(ContentResolver, Uri)}, except this version allows
+     * to watch multiple content URIs for changes.
+     *
+     * <p>If this is not implemented, this is equivalent to calling
+     * {@link #setNotificationUri(ContentResolver, Uri)} with the first URI in {@code uris}.
+     *
+     * <p>Calling this overrides any previous call to
+     * {@link #setNotificationUri(ContentResolver, Uri)}.
+     *
+     * @param cr The content resolver from the caller's context. The listener attached to
+     * this resolver will be notified.
+     * @param uris The content URIs to watch.
+     */
+    default void setNotificationUris(@NonNull ContentResolver cr, @NonNull List<Uri> uris) {
+        setNotificationUri(cr, uris.get(0));
+    }
+
+    /**
+     * Return the URI at which notifications of changes in this Cursor's data
+     * will be delivered, as previously set by {@link #setNotificationUri}.
+     * @return Returns a URI that can be used with
+     * {@link ContentResolver#registerContentObserver(android.net.Uri, boolean, ContentObserver)
+     * ContentResolver.registerContentObserver} to find out about changes to this Cursor's
+     * data.  May be null if no notification URI has been set.
+     */
+    Uri getNotificationUri();
+
+    /**
+     * Return the URIs at which notifications of changes in this Cursor's data
+     * will be delivered, as previously set by {@link #setNotificationUris}.
+     *
+     * <p>If this is not implemented, this is equivalent to calling {@link #getNotificationUri()}.
+     *
+     * @return Returns URIs that can be used with
+     * {@link ContentResolver#registerContentObserver(android.net.Uri, boolean, ContentObserver)
+     * ContentResolver.registerContentObserver} to find out about changes to this Cursor's
+     * data. May be null if no notification URI has been set.
+     */
+    default @Nullable List<Uri> getNotificationUris() {
+        final Uri notifyUri = getNotificationUri();
+        return notifyUri == null ? null : Arrays.asList(notifyUri);
+    }
+
+    /**
+     * onMove() will only be called across processes if this method returns true.
+     * @return whether all cursor movement should result in a call to onMove().
+     */
+    boolean getWantsAllOnMoveCalls();
+
+    /**
+     * Sets a {@link Bundle} that will be returned by {@link #getExtras()}.
+     *
+     * @param extras {@link Bundle} to set, or null to set an empty bundle.
+     */
+    void setExtras(Bundle extras);
+
+    /**
+     * Returns a bundle of extra values. This is an optional way for cursors to provide out-of-band
+     * metadata to their users. One use of this is for reporting on the progress of network requests
+     * that are required to fetch data for the cursor.
+     *
+     * <p>These values may only change when requery is called.
+     * @return cursor-defined values, or {@link android.os.Bundle#EMPTY Bundle.EMPTY} if there
+     *         are no values. Never <code>null</code>.
+     */
+    Bundle getExtras();
+
+    /**
+     * This is an out-of-band way for the the user of a cursor to communicate with the cursor. The
+     * structure of each bundle is entirely defined by the cursor.
+     *
+     * <p>One use of this is to tell a cursor that it should retry its network request after it
+     * reported an error.
+     * @param extras extra values, or {@link android.os.Bundle#EMPTY Bundle.EMPTY}.
+     *         Never <code>null</code>.
+     * @return extra values, or {@link android.os.Bundle#EMPTY Bundle.EMPTY}.
+     *         Never <code>null</code>.
+     */
+    Bundle respond(Bundle extras);
+}
diff --git a/android/database/CursorIndexOutOfBoundsException.java b/android/database/CursorIndexOutOfBoundsException.java
new file mode 100644
index 0000000..1f77d00
--- /dev/null
+++ b/android/database/CursorIndexOutOfBoundsException.java
@@ -0,0 +1,31 @@
+/*
+ * Copyright (C) 2006 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.database;
+
+/**
+ * An exception indicating that a cursor is out of bounds.
+ */
+public class CursorIndexOutOfBoundsException extends IndexOutOfBoundsException {
+
+    public CursorIndexOutOfBoundsException(int index, int size) {
+        super("Index " + index + " requested, with a size of " + size);
+    }
+
+    public CursorIndexOutOfBoundsException(String message) {
+        super(message);
+    }
+}
diff --git a/android/database/CursorJoiner.java b/android/database/CursorJoiner.java
new file mode 100644
index 0000000..a95263b
--- /dev/null
+++ b/android/database/CursorJoiner.java
@@ -0,0 +1,265 @@
+/*
+ * Copyright (C) 2008 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.database;
+
+import java.util.Iterator;
+
+/**
+ * Does a join on two cursors using the specified columns. The cursors must already
+ * be sorted on each of the specified columns in ascending order. This joiner only
+ * supports the case where the tuple of key column values is unique.
+ * <p>
+ * Typical usage:
+ *
+ * <pre>
+ * CursorJoiner joiner = new CursorJoiner(cursorA, keyColumnsofA, cursorB, keyColumnsofB);
+ * for (CursorJoiner.Result joinerResult : joiner) {
+ *     switch (joinerResult) {
+ *         case LEFT:
+ *             // handle case where a row in cursorA is unique
+ *             break;
+ *         case RIGHT:
+ *             // handle case where a row in cursorB is unique
+ *             break;
+ *         case BOTH:
+ *             // handle case where a row with the same key is in both cursors
+ *             break;
+ *     }
+ * }
+ * </pre>
+ */
+public final class CursorJoiner
+        implements Iterator<CursorJoiner.Result>, Iterable<CursorJoiner.Result> {
+    private Cursor mCursorLeft;
+    private Cursor mCursorRight;
+    private boolean mCompareResultIsValid;
+    private Result mCompareResult;
+    private int[] mColumnsLeft;
+    private int[] mColumnsRight;
+    private String[] mValues;
+
+    /**
+     * The result of a call to next().
+     */
+    public enum Result {
+        /** The row currently pointed to by the left cursor is unique */
+        RIGHT,
+        /** The row currently pointed to by the right cursor is unique */
+        LEFT,
+        /** The rows pointed to by both cursors are the same */
+        BOTH
+    }
+
+    /**
+     * Initializes the CursorJoiner and resets the cursors to the first row. The left and right
+     * column name arrays must have the same number of columns.
+     * @param cursorLeft The left cursor to compare
+     * @param columnNamesLeft The column names to compare from the left cursor
+     * @param cursorRight The right cursor to compare
+     * @param columnNamesRight The column names to compare from the right cursor
+     */
+    public CursorJoiner(
+            Cursor cursorLeft, String[] columnNamesLeft,
+            Cursor cursorRight, String[] columnNamesRight) {
+        if (columnNamesLeft.length != columnNamesRight.length) {
+            throw new IllegalArgumentException(
+                    "you must have the same number of columns on the left and right, "
+                            + columnNamesLeft.length + " != " + columnNamesRight.length);
+        }
+
+        mCursorLeft = cursorLeft;
+        mCursorRight = cursorRight;
+
+        mCursorLeft.moveToFirst();
+        mCursorRight.moveToFirst();
+
+        mCompareResultIsValid = false;
+
+        mColumnsLeft = buildColumnIndiciesArray(cursorLeft, columnNamesLeft);
+        mColumnsRight = buildColumnIndiciesArray(cursorRight, columnNamesRight);
+
+        mValues = new String[mColumnsLeft.length * 2];
+    }
+
+    public Iterator<Result> iterator() {
+        return this;
+    }
+
+    /**
+     * Lookup the indicies of the each column name and return them in an array.
+     * @param cursor the cursor that contains the columns
+     * @param columnNames the array of names to lookup
+     * @return an array of column indices
+     */
+    private int[] buildColumnIndiciesArray(Cursor cursor, String[] columnNames) {
+        int[] columns = new int[columnNames.length];
+        for (int i = 0; i < columnNames.length; i++) {
+            columns[i] = cursor.getColumnIndexOrThrow(columnNames[i]);
+        }
+        return columns;
+    }
+
+    /**
+     * Returns whether or not there are more rows to compare using next().
+     * @return true if there are more rows to compare
+     */
+    public boolean hasNext() {
+        if (mCompareResultIsValid) {
+            switch (mCompareResult) {
+                case BOTH:
+                    return !mCursorLeft.isLast() || !mCursorRight.isLast();
+
+                case LEFT:
+                    return !mCursorLeft.isLast() || !mCursorRight.isAfterLast();
+
+                case RIGHT:
+                    return !mCursorLeft.isAfterLast() || !mCursorRight.isLast();
+
+                default:
+                    throw new IllegalStateException("bad value for mCompareResult, "
+                            + mCompareResult);
+            }
+        } else {
+            return !mCursorLeft.isAfterLast() || !mCursorRight.isAfterLast();
+        }
+    }
+
+    /**
+     * Returns the comparison result of the next row from each cursor. If one cursor
+     * has no more rows but the other does then subsequent calls to this will indicate that
+     * the remaining rows are unique.
+     * <p>
+     * The caller must check that hasNext() returns true before calling this.
+     * <p>
+     * Once next() has been called the cursors specified in the result of the call to
+     * next() are guaranteed to point to the row that was indicated. Reading values
+     * from the cursor that was not indicated in the call to next() will result in
+     * undefined behavior.
+     * @return LEFT, if the row pointed to by the left cursor is unique, RIGHT
+     *   if the row pointed to by the right cursor is unique, BOTH if the rows in both
+     *   cursors are the same.
+     */
+    public Result next() {
+        if (!hasNext()) {
+            throw new IllegalStateException("you must only call next() when hasNext() is true");
+        }
+        incrementCursors();
+        assert hasNext();
+
+        boolean hasLeft = !mCursorLeft.isAfterLast();
+        boolean hasRight = !mCursorRight.isAfterLast();
+
+        if (hasLeft && hasRight) {
+            populateValues(mValues, mCursorLeft, mColumnsLeft, 0 /* start filling at index 0 */);
+            populateValues(mValues, mCursorRight, mColumnsRight, 1 /* start filling at index 1 */);
+            switch (compareStrings(mValues)) {
+                case -1:
+                    mCompareResult = Result.LEFT;
+                    break;
+                case 0:
+                    mCompareResult = Result.BOTH;
+                    break;
+                case 1:
+                    mCompareResult = Result.RIGHT;
+                    break;
+            }
+        } else if (hasLeft) {
+            mCompareResult = Result.LEFT;
+        } else  {
+            assert hasRight;
+            mCompareResult = Result.RIGHT;
+        }
+        mCompareResultIsValid = true;
+        return mCompareResult;
+    }
+
+    public void remove() {
+        throw new UnsupportedOperationException("not implemented");
+    }
+
+    /**
+     * Reads the strings from the cursor that are specifed in the columnIndicies
+     * array and saves them in values beginning at startingIndex, skipping a slot
+     * for each value. If columnIndicies has length 3 and startingIndex is 1, the
+     * values will be stored in slots 1, 3, and 5.
+     * @param values the String[] to populate
+     * @param cursor the cursor from which to read
+     * @param columnIndicies the indicies of the values to read from the cursor
+     * @param startingIndex the slot in which to start storing values, and must be either 0 or 1.
+     */
+    private static void populateValues(String[] values, Cursor cursor, int[] columnIndicies,
+            int startingIndex) {
+        assert startingIndex == 0 || startingIndex == 1;
+        for (int i = 0; i < columnIndicies.length; i++) {
+            values[startingIndex + i*2] = cursor.getString(columnIndicies[i]);
+        }
+    }
+
+    /**
+     * Increment the cursors past the rows indicated in the most recent call to next().
+     * This will only have an affect once per call to next().
+     */
+    private void incrementCursors() {
+        if (mCompareResultIsValid) {
+            switch (mCompareResult) {
+                case LEFT:
+                    mCursorLeft.moveToNext();
+                    break;
+                case RIGHT:
+                    mCursorRight.moveToNext();
+                    break;
+                case BOTH:
+                    mCursorLeft.moveToNext();
+                    mCursorRight.moveToNext();
+                    break;
+            }
+            mCompareResultIsValid = false;
+        }
+    }
+
+    /**
+     * Compare the values. Values contains n pairs of strings. If all the pairs of strings match
+     * then returns 0. Otherwise returns the comparison result of the first non-matching pair
+     * of values, -1 if the first of the pair is less than the second of the pair or 1 if it
+     * is greater.
+     * @param values the n pairs of values to compare
+     * @return -1, 0, or 1 as described above.
+     */
+    private static int compareStrings(String... values) {
+        if ((values.length % 2) != 0) {
+            throw new IllegalArgumentException("you must specify an even number of values");
+        }
+
+        for (int index = 0; index < values.length; index+=2) {
+            if (values[index] == null) {
+                if (values[index+1] == null) continue;
+                return -1;
+            }
+
+            if (values[index+1] == null) {
+                return 1;
+            }
+
+            int comp = values[index].compareTo(values[index+1]);
+            if (comp != 0) {
+                return comp < 0 ? -1 : 1;
+            }
+        }
+
+        return 0;
+    }
+}
diff --git a/android/database/CursorToBulkCursorAdaptor.java b/android/database/CursorToBulkCursorAdaptor.java
new file mode 100644
index 0000000..ce86807
--- /dev/null
+++ b/android/database/CursorToBulkCursorAdaptor.java
@@ -0,0 +1,298 @@
+/*
+ * Copyright (C) 2006 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.database;
+
+import android.annotation.NonNull;
+import android.annotation.UserIdInt;
+import android.content.ContentResolver.NotifyFlags;
+import android.net.Uri;
+import android.os.Bundle;
+import android.os.IBinder;
+import android.os.RemoteException;
+
+import java.util.ArrayList;
+import java.util.Collection;
+
+/**
+ * Wraps a BulkCursor around an existing Cursor making it remotable.
+ * <p>
+ * If the wrapped cursor returns non-null from {@link CrossProcessCursor#getWindow}
+ * then it is assumed to own the window.  Otherwise, the adaptor provides a
+ * window to be filled and ensures it gets closed as needed during deactivation
+ * and requeries.
+ * </p>
+ *
+ * {@hide}
+ */
+public final class CursorToBulkCursorAdaptor extends BulkCursorNative
+        implements IBinder.DeathRecipient {
+    private static final String TAG = "Cursor";
+
+    private final Object mLock = new Object();
+    private final String mProviderName;
+    private ContentObserverProxy mObserver;
+
+    /**
+     * The cursor that is being adapted.
+     * This field is set to null when the cursor is closed.
+     */
+    private CrossProcessCursor mCursor;
+
+    /**
+     * The cursor window that was filled by the cross process cursor in the
+     * case where the cursor does not support getWindow.
+     * This field is only ever non-null when the window has actually be filled.
+     */
+    private CursorWindow mFilledWindow;
+
+    private static final class ContentObserverProxy extends ContentObserver {
+        protected IContentObserver mRemote;
+
+        public ContentObserverProxy(IContentObserver remoteObserver, DeathRecipient recipient) {
+            super(null);
+            mRemote = remoteObserver;
+            try {
+                remoteObserver.asBinder().linkToDeath(recipient, 0);
+            } catch (RemoteException e) {
+                // Do nothing, the far side is dead
+            }
+        }
+
+        public boolean unlinkToDeath(DeathRecipient recipient) {
+            return mRemote.asBinder().unlinkToDeath(recipient, 0);
+        }
+
+        @Override
+        public boolean deliverSelfNotifications() {
+            // The far side handles the self notifications.
+            return false;
+        }
+
+        @Override
+        public void onChange(boolean selfChange, @NonNull Collection<Uri> uris,
+                @NotifyFlags int flags, @UserIdInt int userId) {
+            // Since we deliver changes from the most-specific to least-specific
+            // overloads, we only need to redirect from the most-specific local
+            // method to the most-specific remote method
+
+            final ArrayList<Uri> asList = new ArrayList<>();
+            uris.forEach(asList::add);
+            final Uri[] asArray = asList.toArray(new Uri[asList.size()]);
+
+            try {
+                mRemote.onChangeEtc(selfChange, asArray, flags, userId);
+            } catch (RemoteException ex) {
+                // Do nothing, the far side is dead
+            }
+        }
+    }
+
+    public CursorToBulkCursorAdaptor(Cursor cursor, IContentObserver observer,
+            String providerName) {
+        if (cursor instanceof CrossProcessCursor) {
+            mCursor = (CrossProcessCursor)cursor;
+        } else {
+            mCursor = new CrossProcessCursorWrapper(cursor);
+        }
+        mProviderName = providerName;
+
+        synchronized (mLock) {
+            createAndRegisterObserverProxyLocked(observer);
+        }
+    }
+
+    private void closeFilledWindowLocked() {
+        if (mFilledWindow != null) {
+            mFilledWindow.close();
+            mFilledWindow = null;
+        }
+    }
+
+    private void disposeLocked() {
+        if (mCursor != null) {
+            unregisterObserverProxyLocked();
+            mCursor.close();
+            mCursor = null;
+        }
+
+        closeFilledWindowLocked();
+    }
+
+    private void throwIfCursorIsClosed() {
+        if (mCursor == null) {
+            throw new StaleDataException("Attempted to access a cursor after it has been closed.");
+        }
+    }
+
+    @Override
+    public void binderDied() {
+        synchronized (mLock) {
+            disposeLocked();
+        }
+    }
+
+    /**
+     * Returns an object that contains sufficient metadata to reconstruct
+     * the cursor remotely.  May throw if an error occurs when executing the query
+     * and obtaining the row count.
+     */
+    public BulkCursorDescriptor getBulkCursorDescriptor() {
+        synchronized (mLock) {
+            throwIfCursorIsClosed();
+
+            BulkCursorDescriptor d = new BulkCursorDescriptor();
+            d.cursor = this;
+            d.columnNames = mCursor.getColumnNames();
+            d.wantsAllOnMoveCalls = mCursor.getWantsAllOnMoveCalls();
+            d.count = mCursor.getCount();
+            d.window = mCursor.getWindow();
+            if (d.window != null) {
+                // Acquire a reference to the window because its reference count will be
+                // decremented when it is returned as part of the binder call reply parcel.
+                d.window.acquireReference();
+            }
+            return d;
+        }
+    }
+
+    @Override
+    public CursorWindow getWindow(int position) {
+        synchronized (mLock) {
+            throwIfCursorIsClosed();
+
+            if (!mCursor.moveToPosition(position)) {
+                closeFilledWindowLocked();
+                return null;
+            }
+
+            CursorWindow window = mCursor.getWindow();
+            if (window != null) {
+                closeFilledWindowLocked();
+            } else {
+                window = mFilledWindow;
+                if (window == null) {
+                    mFilledWindow = new CursorWindow(mProviderName);
+                    window = mFilledWindow;
+                } else if (position < window.getStartPosition()
+                        || position >= window.getStartPosition() + window.getNumRows()) {
+                    window.clear();
+                }
+                mCursor.fillWindow(position, window);
+            }
+
+            if (window != null) {
+                // Acquire a reference to the window because its reference count will be
+                // decremented when it is returned as part of the binder call reply parcel.
+                window.acquireReference();
+            }
+            return window;
+        }
+    }
+
+    @Override
+    public void onMove(int position) {
+        synchronized (mLock) {
+            throwIfCursorIsClosed();
+
+            mCursor.onMove(mCursor.getPosition(), position);
+        }
+    }
+
+    @Override
+    public void deactivate() {
+        synchronized (mLock) {
+            if (mCursor != null) {
+                unregisterObserverProxyLocked();
+                mCursor.deactivate();
+            }
+
+            closeFilledWindowLocked();
+        }
+    }
+
+    @Override
+    public void close() {
+        synchronized (mLock) {
+            disposeLocked();
+        }
+    }
+
+    @Override
+    public int requery(IContentObserver observer) {
+        synchronized (mLock) {
+            throwIfCursorIsClosed();
+
+            closeFilledWindowLocked();
+
+            try {
+                if (!mCursor.requery()) {
+                    return -1;
+                }
+            } catch (IllegalStateException e) {
+                IllegalStateException leakProgram = new IllegalStateException(
+                        mProviderName + " Requery misuse db, mCursor isClosed:" +
+                        mCursor.isClosed(), e);
+                throw leakProgram;
+            }
+
+            unregisterObserverProxyLocked();
+            createAndRegisterObserverProxyLocked(observer);
+            return mCursor.getCount();
+        }
+    }
+
+    /**
+     * Create a ContentObserver from the observer and register it as an observer on the
+     * underlying cursor.
+     * @param observer the IContentObserver that wants to monitor the cursor
+     * @throws IllegalStateException if an observer is already registered
+     */
+    private void createAndRegisterObserverProxyLocked(IContentObserver observer) {
+        if (mObserver != null) {
+            throw new IllegalStateException("an observer is already registered");
+        }
+        mObserver = new ContentObserverProxy(observer, this);
+        mCursor.registerContentObserver(mObserver);
+    }
+
+    /** Unregister the observer if it is already registered. */
+    private void unregisterObserverProxyLocked() {
+        if (mObserver != null) {
+            mCursor.unregisterContentObserver(mObserver);
+            mObserver.unlinkToDeath(this);
+            mObserver = null;
+        }
+    }
+
+    @Override
+    public Bundle getExtras() {
+        synchronized (mLock) {
+            throwIfCursorIsClosed();
+
+            return mCursor.getExtras();
+        }
+    }
+
+    @Override
+    public Bundle respond(Bundle extras) {
+        synchronized (mLock) {
+            throwIfCursorIsClosed();
+
+            return mCursor.respond(extras);
+        }
+    }
+}
diff --git a/android/database/CursorWindow.java b/android/database/CursorWindow.java
new file mode 100644
index 0000000..063a2d0
--- /dev/null
+++ b/android/database/CursorWindow.java
@@ -0,0 +1,823 @@
+/*
+ * Copyright (C) 2006 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.database;
+
+import android.annotation.BytesLong;
+import android.compat.annotation.UnsupportedAppUsage;
+import android.content.res.Resources;
+import android.database.sqlite.SQLiteClosable;
+import android.database.sqlite.SQLiteException;
+import android.os.Binder;
+import android.os.Parcel;
+import android.os.Parcelable;
+import android.os.Process;
+import android.util.Log;
+import android.util.LongSparseArray;
+import android.util.SparseIntArray;
+
+import dalvik.annotation.optimization.FastNative;
+import dalvik.system.CloseGuard;
+
+/**
+ * A buffer containing multiple cursor rows.
+ * <p>
+ * A {@link CursorWindow} is read-write when initially created and used locally.
+ * When sent to a remote process (by writing it to a {@link Parcel}), the remote process
+ * receives a read-only view of the cursor window.  Typically the cursor window
+ * will be allocated by the producer, filled with data, and then sent to the
+ * consumer for reading.
+ * </p>
+ */
+public class CursorWindow extends SQLiteClosable implements Parcelable {
+    private static final String STATS_TAG = "CursorWindowStats";
+
+    // This static member will be evaluated when first used.
+    @UnsupportedAppUsage
+    private static int sCursorWindowSize = -1;
+
+    /**
+     * The native CursorWindow object pointer.  (FOR INTERNAL USE ONLY)
+     * @hide
+     */
+    @UnsupportedAppUsage
+    public long mWindowPtr;
+
+    private int mStartPos;
+    private final String mName;
+
+    private final CloseGuard mCloseGuard = CloseGuard.get();
+
+    // May throw CursorWindowAllocationException
+    private static native long nativeCreate(String name, int cursorWindowSize);
+
+    // May throw CursorWindowAllocationException
+    private static native long nativeCreateFromParcel(Parcel parcel);
+    private static native void nativeDispose(long windowPtr);
+    private static native void nativeWriteToParcel(long windowPtr, Parcel parcel);
+
+    private static native String nativeGetName(long windowPtr);
+    private static native byte[] nativeGetBlob(long windowPtr, int row, int column);
+    private static native String nativeGetString(long windowPtr, int row, int column);
+    private static native void nativeCopyStringToBuffer(long windowPtr, int row, int column,
+            CharArrayBuffer buffer);
+    private static native boolean nativePutBlob(long windowPtr, byte[] value, int row, int column);
+    private static native boolean nativePutString(long windowPtr, String value,
+            int row, int column);
+
+    // Below native methods don't do unconstrained work, so are FastNative for performance
+
+    @FastNative
+    private static native void nativeClear(long windowPtr);
+
+    @FastNative
+    private static native int nativeGetNumRows(long windowPtr);
+    @FastNative
+    private static native boolean nativeSetNumColumns(long windowPtr, int columnNum);
+    @FastNative
+    private static native boolean nativeAllocRow(long windowPtr);
+    @FastNative
+    private static native void nativeFreeLastRow(long windowPtr);
+
+    @FastNative
+    private static native int nativeGetType(long windowPtr, int row, int column);
+    @FastNative
+    private static native long nativeGetLong(long windowPtr, int row, int column);
+    @FastNative
+    private static native double nativeGetDouble(long windowPtr, int row, int column);
+
+    @FastNative
+    private static native boolean nativePutLong(long windowPtr, long value, int row, int column);
+    @FastNative
+    private static native boolean nativePutDouble(long windowPtr, double value, int row, int column);
+    @FastNative
+    private static native boolean nativePutNull(long windowPtr, int row, int column);
+
+
+    /**
+     * Creates a new empty cursor window and gives it a name.
+     * <p>
+     * The cursor initially has no rows or columns.  Call {@link #setNumColumns(int)} to
+     * set the number of columns before adding any rows to the cursor.
+     * </p>
+     *
+     * @param name The name of the cursor window, or null if none.
+     */
+    public CursorWindow(String name) {
+        this(name, getCursorWindowSize());
+    }
+
+    /**
+     * Creates a new empty cursor window and gives it a name.
+     * <p>
+     * The cursor initially has no rows or columns.  Call {@link #setNumColumns(int)} to
+     * set the number of columns before adding any rows to the cursor.
+     * </p>
+     *
+     * @param name The name of the cursor window, or null if none.
+     * @param windowSizeBytes Size of cursor window in bytes.
+     * <p><strong>Note:</strong> Memory is dynamically allocated as data rows are added to the
+     * window. Depending on the amount of data stored, the actual amount of memory allocated can be
+     * lower than specified size, but cannot exceed it.
+     */
+    public CursorWindow(String name, @BytesLong long windowSizeBytes) {
+        mStartPos = 0;
+        mName = name != null && name.length() != 0 ? name : "<unnamed>";
+        mWindowPtr = nativeCreate(mName, (int) windowSizeBytes);
+        if (mWindowPtr == 0) {
+            throw new AssertionError(); // Not possible, the native code won't return it.
+        }
+        mCloseGuard.open("close");
+        recordNewWindow(Binder.getCallingPid(), mWindowPtr);
+    }
+
+    /**
+     * Creates a new empty cursor window.
+     * <p>
+     * The cursor initially has no rows or columns.  Call {@link #setNumColumns(int)} to
+     * set the number of columns before adding any rows to the cursor.
+     * </p>
+     *
+     * @param localWindow True if this window will be used in this process only,
+     * false if it might be sent to another processes.  This argument is ignored.
+     *
+     * @deprecated There is no longer a distinction between local and remote
+     * cursor windows.  Use the {@link #CursorWindow(String)} constructor instead.
+     */
+    @Deprecated
+    public CursorWindow(boolean localWindow) {
+        this((String)null);
+    }
+
+    private CursorWindow(Parcel source) {
+        mStartPos = source.readInt();
+        mWindowPtr = nativeCreateFromParcel(source);
+        if (mWindowPtr == 0) {
+            throw new AssertionError(); // Not possible, the native code won't return it.
+        }
+        mName = nativeGetName(mWindowPtr);
+        mCloseGuard.open("close");
+    }
+
+    @Override
+    protected void finalize() throws Throwable {
+        try {
+            if (mCloseGuard != null) {
+                mCloseGuard.warnIfOpen();
+            }
+            dispose();
+        } finally {
+            super.finalize();
+        }
+    }
+
+    private void dispose() {
+        if (mCloseGuard != null) {
+            mCloseGuard.close();
+        }
+        if (mWindowPtr != 0) {
+            recordClosingOfWindow(mWindowPtr);
+            nativeDispose(mWindowPtr);
+            mWindowPtr = 0;
+        }
+    }
+
+    /**
+     * Gets the name of this cursor window, never null.
+     * @hide
+     */
+    public String getName() {
+        return mName;
+    }
+
+    /**
+     * Clears out the existing contents of the window, making it safe to reuse
+     * for new data.
+     * <p>
+     * The start position ({@link #getStartPosition()}), number of rows ({@link #getNumRows()}),
+     * and number of columns in the cursor are all reset to zero.
+     * </p>
+     */
+    public void clear() {
+        acquireReference();
+        try {
+            mStartPos = 0;
+            nativeClear(mWindowPtr);
+        } finally {
+            releaseReference();
+        }
+    }
+
+    /**
+     * Gets the start position of this cursor window.
+     * <p>
+     * The start position is the zero-based index of the first row that this window contains
+     * relative to the entire result set of the {@link Cursor}.
+     * </p>
+     *
+     * @return The zero-based start position.
+     */
+    public int getStartPosition() {
+        return mStartPos;
+    }
+
+    /**
+     * Sets the start position of this cursor window.
+     * <p>
+     * The start position is the zero-based index of the first row that this window contains
+     * relative to the entire result set of the {@link Cursor}.
+     * </p>
+     *
+     * @param pos The new zero-based start position.
+     */
+    public void setStartPosition(int pos) {
+        mStartPos = pos;
+    }
+
+    /**
+     * Gets the number of rows in this window.
+     *
+     * @return The number of rows in this cursor window.
+     */
+    public int getNumRows() {
+        acquireReference();
+        try {
+            return nativeGetNumRows(mWindowPtr);
+        } finally {
+            releaseReference();
+        }
+    }
+
+    /**
+     * Sets the number of columns in this window.
+     * <p>
+     * This method must be called before any rows are added to the window, otherwise
+     * it will fail to set the number of columns if it differs from the current number
+     * of columns.
+     * </p>
+     *
+     * @param columnNum The new number of columns.
+     * @return True if successful.
+     */
+    public boolean setNumColumns(int columnNum) {
+        acquireReference();
+        try {
+            return nativeSetNumColumns(mWindowPtr, columnNum);
+        } finally {
+            releaseReference();
+        }
+    }
+
+    /**
+     * Allocates a new row at the end of this cursor window.
+     *
+     * @return True if successful, false if the cursor window is out of memory.
+     */
+    public boolean allocRow(){
+        acquireReference();
+        try {
+            return nativeAllocRow(mWindowPtr);
+        } finally {
+            releaseReference();
+        }
+    }
+
+    /**
+     * Frees the last row in this cursor window.
+     */
+    public void freeLastRow(){
+        acquireReference();
+        try {
+            nativeFreeLastRow(mWindowPtr);
+        } finally {
+            releaseReference();
+        }
+    }
+
+    /**
+     * Returns true if the field at the specified row and column index
+     * has type {@link Cursor#FIELD_TYPE_NULL}.
+     *
+     * @param row The zero-based row index.
+     * @param column The zero-based column index.
+     * @return True if the field has type {@link Cursor#FIELD_TYPE_NULL}.
+     * @deprecated Use {@link #getType(int, int)} instead.
+     */
+    @Deprecated
+    public boolean isNull(int row, int column) {
+        return getType(row, column) == Cursor.FIELD_TYPE_NULL;
+    }
+
+    /**
+     * Returns true if the field at the specified row and column index
+     * has type {@link Cursor#FIELD_TYPE_BLOB} or {@link Cursor#FIELD_TYPE_NULL}.
+     *
+     * @param row The zero-based row index.
+     * @param column The zero-based column index.
+     * @return True if the field has type {@link Cursor#FIELD_TYPE_BLOB} or
+     * {@link Cursor#FIELD_TYPE_NULL}.
+     * @deprecated Use {@link #getType(int, int)} instead.
+     */
+    @Deprecated
+    public boolean isBlob(int row, int column) {
+        int type = getType(row, column);
+        return type == Cursor.FIELD_TYPE_BLOB || type == Cursor.FIELD_TYPE_NULL;
+    }
+
+    /**
+     * Returns true if the field at the specified row and column index
+     * has type {@link Cursor#FIELD_TYPE_INTEGER}.
+     *
+     * @param row The zero-based row index.
+     * @param column The zero-based column index.
+     * @return True if the field has type {@link Cursor#FIELD_TYPE_INTEGER}.
+     * @deprecated Use {@link #getType(int, int)} instead.
+     */
+    @Deprecated
+    public boolean isLong(int row, int column) {
+        return getType(row, column) == Cursor.FIELD_TYPE_INTEGER;
+    }
+
+    /**
+     * Returns true if the field at the specified row and column index
+     * has type {@link Cursor#FIELD_TYPE_FLOAT}.
+     *
+     * @param row The zero-based row index.
+     * @param column The zero-based column index.
+     * @return True if the field has type {@link Cursor#FIELD_TYPE_FLOAT}.
+     * @deprecated Use {@link #getType(int, int)} instead.
+     */
+    @Deprecated
+    public boolean isFloat(int row, int column) {
+        return getType(row, column) == Cursor.FIELD_TYPE_FLOAT;
+    }
+
+    /**
+     * Returns true if the field at the specified row and column index
+     * has type {@link Cursor#FIELD_TYPE_STRING} or {@link Cursor#FIELD_TYPE_NULL}.
+     *
+     * @param row The zero-based row index.
+     * @param column The zero-based column index.
+     * @return True if the field has type {@link Cursor#FIELD_TYPE_STRING}
+     * or {@link Cursor#FIELD_TYPE_NULL}.
+     * @deprecated Use {@link #getType(int, int)} instead.
+     */
+    @Deprecated
+    public boolean isString(int row, int column) {
+        int type = getType(row, column);
+        return type == Cursor.FIELD_TYPE_STRING || type == Cursor.FIELD_TYPE_NULL;
+    }
+
+    /**
+     * Returns the type of the field at the specified row and column index.
+     * <p>
+     * The returned field types are:
+     * <ul>
+     * <li>{@link Cursor#FIELD_TYPE_NULL}</li>
+     * <li>{@link Cursor#FIELD_TYPE_INTEGER}</li>
+     * <li>{@link Cursor#FIELD_TYPE_FLOAT}</li>
+     * <li>{@link Cursor#FIELD_TYPE_STRING}</li>
+     * <li>{@link Cursor#FIELD_TYPE_BLOB}</li>
+     * </ul>
+     * </p>
+     *
+     * @param row The zero-based row index.
+     * @param column The zero-based column index.
+     * @return The field type.
+     */
+    public int getType(int row, int column) {
+        acquireReference();
+        try {
+            return nativeGetType(mWindowPtr, row - mStartPos, column);
+        } finally {
+            releaseReference();
+        }
+    }
+
+    /**
+     * Gets the value of the field at the specified row and column index as a byte array.
+     * <p>
+     * The result is determined as follows:
+     * <ul>
+     * <li>If the field is of type {@link Cursor#FIELD_TYPE_NULL}, then the result
+     * is <code>null</code>.</li>
+     * <li>If the field is of type {@link Cursor#FIELD_TYPE_BLOB}, then the result
+     * is the blob value.</li>
+     * <li>If the field is of type {@link Cursor#FIELD_TYPE_STRING}, then the result
+     * is the array of bytes that make up the internal representation of the
+     * string value.</li>
+     * <li>If the field is of type {@link Cursor#FIELD_TYPE_INTEGER} or
+     * {@link Cursor#FIELD_TYPE_FLOAT}, then a {@link SQLiteException} is thrown.</li>
+     * </ul>
+     * </p>
+     *
+     * @param row The zero-based row index.
+     * @param column The zero-based column index.
+     * @return The value of the field as a byte array.
+     */
+    public byte[] getBlob(int row, int column) {
+        acquireReference();
+        try {
+            return nativeGetBlob(mWindowPtr, row - mStartPos, column);
+        } finally {
+            releaseReference();
+        }
+    }
+
+    /**
+     * Gets the value of the field at the specified row and column index as a string.
+     * <p>
+     * The result is determined as follows:
+     * <ul>
+     * <li>If the field is of type {@link Cursor#FIELD_TYPE_NULL}, then the result
+     * is <code>null</code>.</li>
+     * <li>If the field is of type {@link Cursor#FIELD_TYPE_STRING}, then the result
+     * is the string value.</li>
+     * <li>If the field is of type {@link Cursor#FIELD_TYPE_INTEGER}, then the result
+     * is a string representation of the integer in decimal, obtained by formatting the
+     * value with the <code>printf</code> family of functions using
+     * format specifier <code>%lld</code>.</li>
+     * <li>If the field is of type {@link Cursor#FIELD_TYPE_FLOAT}, then the result
+     * is a string representation of the floating-point value in decimal, obtained by
+     * formatting the value with the <code>printf</code> family of functions using
+     * format specifier <code>%g</code>.</li>
+     * <li>If the field is of type {@link Cursor#FIELD_TYPE_BLOB}, then a
+     * {@link SQLiteException} is thrown.</li>
+     * </ul>
+     * </p>
+     *
+     * @param row The zero-based row index.
+     * @param column The zero-based column index.
+     * @return The value of the field as a string.
+     */
+    public String getString(int row, int column) {
+        acquireReference();
+        try {
+            return nativeGetString(mWindowPtr, row - mStartPos, column);
+        } finally {
+            releaseReference();
+        }
+    }
+
+    /**
+     * Copies the text of the field at the specified row and column index into
+     * a {@link CharArrayBuffer}.
+     * <p>
+     * The buffer is populated as follows:
+     * <ul>
+     * <li>If the buffer is too small for the value to be copied, then it is
+     * automatically resized.</li>
+     * <li>If the field is of type {@link Cursor#FIELD_TYPE_NULL}, then the buffer
+     * is set to an empty string.</li>
+     * <li>If the field is of type {@link Cursor#FIELD_TYPE_STRING}, then the buffer
+     * is set to the contents of the string.</li>
+     * <li>If the field is of type {@link Cursor#FIELD_TYPE_INTEGER}, then the buffer
+     * is set to a string representation of the integer in decimal, obtained by formatting the
+     * value with the <code>printf</code> family of functions using
+     * format specifier <code>%lld</code>.</li>
+     * <li>If the field is of type {@link Cursor#FIELD_TYPE_FLOAT}, then the buffer is
+     * set to a string representation of the floating-point value in decimal, obtained by
+     * formatting the value with the <code>printf</code> family of functions using
+     * format specifier <code>%g</code>.</li>
+     * <li>If the field is of type {@link Cursor#FIELD_TYPE_BLOB}, then a
+     * {@link SQLiteException} is thrown.</li>
+     * </ul>
+     * </p>
+     *
+     * @param row The zero-based row index.
+     * @param column The zero-based column index.
+     * @param buffer The {@link CharArrayBuffer} to hold the string.  It is automatically
+     * resized if the requested string is larger than the buffer's current capacity.
+      */
+    public void copyStringToBuffer(int row, int column, CharArrayBuffer buffer) {
+        if (buffer == null) {
+            throw new IllegalArgumentException("CharArrayBuffer should not be null");
+        }
+        acquireReference();
+        try {
+            nativeCopyStringToBuffer(mWindowPtr, row - mStartPos, column, buffer);
+        } finally {
+            releaseReference();
+        }
+    }
+
+    /**
+     * Gets the value of the field at the specified row and column index as a <code>long</code>.
+     * <p>
+     * The result is determined as follows:
+     * <ul>
+     * <li>If the field is of type {@link Cursor#FIELD_TYPE_NULL}, then the result
+     * is <code>0L</code>.</li>
+     * <li>If the field is of type {@link Cursor#FIELD_TYPE_STRING}, then the result
+     * is the value obtained by parsing the string value with <code>strtoll</code>.
+     * <li>If the field is of type {@link Cursor#FIELD_TYPE_INTEGER}, then the result
+     * is the <code>long</code> value.</li>
+     * <li>If the field is of type {@link Cursor#FIELD_TYPE_FLOAT}, then the result
+     * is the floating-point value converted to a <code>long</code>.</li>
+     * <li>If the field is of type {@link Cursor#FIELD_TYPE_BLOB}, then a
+     * {@link SQLiteException} is thrown.</li>
+     * </ul>
+     * </p>
+     *
+     * @param row The zero-based row index.
+     * @param column The zero-based column index.
+     * @return The value of the field as a <code>long</code>.
+     */
+    public long getLong(int row, int column) {
+        acquireReference();
+        try {
+            return nativeGetLong(mWindowPtr, row - mStartPos, column);
+        } finally {
+            releaseReference();
+        }
+    }
+
+    /**
+     * Gets the value of the field at the specified row and column index as a
+     * <code>double</code>.
+     * <p>
+     * The result is determined as follows:
+     * <ul>
+     * <li>If the field is of type {@link Cursor#FIELD_TYPE_NULL}, then the result
+     * is <code>0.0</code>.</li>
+     * <li>If the field is of type {@link Cursor#FIELD_TYPE_STRING}, then the result
+     * is the value obtained by parsing the string value with <code>strtod</code>.
+     * <li>If the field is of type {@link Cursor#FIELD_TYPE_INTEGER}, then the result
+     * is the integer value converted to a <code>double</code>.</li>
+     * <li>If the field is of type {@link Cursor#FIELD_TYPE_FLOAT}, then the result
+     * is the <code>double</code> value.</li>
+     * <li>If the field is of type {@link Cursor#FIELD_TYPE_BLOB}, then a
+     * {@link SQLiteException} is thrown.</li>
+     * </ul>
+     * </p>
+     *
+     * @param row The zero-based row index.
+     * @param column The zero-based column index.
+     * @return The value of the field as a <code>double</code>.
+     */
+    public double getDouble(int row, int column) {
+        acquireReference();
+        try {
+            return nativeGetDouble(mWindowPtr, row - mStartPos, column);
+        } finally {
+            releaseReference();
+        }
+    }
+
+    /**
+     * Gets the value of the field at the specified row and column index as a
+     * <code>short</code>.
+     * <p>
+     * The result is determined by invoking {@link #getLong} and converting the
+     * result to <code>short</code>.
+     * </p>
+     *
+     * @param row The zero-based row index.
+     * @param column The zero-based column index.
+     * @return The value of the field as a <code>short</code>.
+     */
+    public short getShort(int row, int column) {
+        return (short) getLong(row, column);
+    }
+
+    /**
+     * Gets the value of the field at the specified row and column index as an
+     * <code>int</code>.
+     * <p>
+     * The result is determined by invoking {@link #getLong} and converting the
+     * result to <code>int</code>.
+     * </p>
+     *
+     * @param row The zero-based row index.
+     * @param column The zero-based column index.
+     * @return The value of the field as an <code>int</code>.
+     */
+    public int getInt(int row, int column) {
+        return (int) getLong(row, column);
+    }
+
+    /**
+     * Gets the value of the field at the specified row and column index as a
+     * <code>float</code>.
+     * <p>
+     * The result is determined by invoking {@link #getDouble} and converting the
+     * result to <code>float</code>.
+     * </p>
+     *
+     * @param row The zero-based row index.
+     * @param column The zero-based column index.
+     * @return The value of the field as an <code>float</code>.
+     */
+    public float getFloat(int row, int column) {
+        return (float) getDouble(row, column);
+    }
+
+    /**
+     * Copies a byte array into the field at the specified row and column index.
+     *
+     * @param value The value to store.
+     * @param row The zero-based row index.
+     * @param column The zero-based column index.
+     * @return True if successful.
+     */
+    public boolean putBlob(byte[] value, int row, int column) {
+        acquireReference();
+        try {
+            return nativePutBlob(mWindowPtr, value, row - mStartPos, column);
+        } finally {
+            releaseReference();
+        }
+    }
+
+    /**
+     * Copies a string into the field at the specified row and column index.
+     *
+     * @param value The value to store.
+     * @param row The zero-based row index.
+     * @param column The zero-based column index.
+     * @return True if successful.
+     */
+    public boolean putString(String value, int row, int column) {
+        acquireReference();
+        try {
+            return nativePutString(mWindowPtr, value, row - mStartPos, column);
+        } finally {
+            releaseReference();
+        }
+    }
+
+    /**
+     * Puts a long integer into the field at the specified row and column index.
+     *
+     * @param value The value to store.
+     * @param row The zero-based row index.
+     * @param column The zero-based column index.
+     * @return True if successful.
+     */
+    public boolean putLong(long value, int row, int column) {
+        acquireReference();
+        try {
+            return nativePutLong(mWindowPtr, value, row - mStartPos, column);
+        } finally {
+            releaseReference();
+        }
+    }
+
+    /**
+     * Puts a double-precision floating point value into the field at the
+     * specified row and column index.
+     *
+     * @param value The value to store.
+     * @param row The zero-based row index.
+     * @param column The zero-based column index.
+     * @return True if successful.
+     */
+    public boolean putDouble(double value, int row, int column) {
+        acquireReference();
+        try {
+            return nativePutDouble(mWindowPtr, value, row - mStartPos, column);
+        } finally {
+            releaseReference();
+        }
+    }
+
+    /**
+     * Puts a null value into the field at the specified row and column index.
+     *
+     * @param row The zero-based row index.
+     * @param column The zero-based column index.
+     * @return True if successful.
+     */
+    public boolean putNull(int row, int column) {
+        acquireReference();
+        try {
+            return nativePutNull(mWindowPtr, row - mStartPos, column);
+        } finally {
+            releaseReference();
+        }
+    }
+
+    public static final @android.annotation.NonNull Parcelable.Creator<CursorWindow> CREATOR
+            = new Parcelable.Creator<CursorWindow>() {
+        public CursorWindow createFromParcel(Parcel source) {
+            return new CursorWindow(source);
+        }
+
+        public CursorWindow[] newArray(int size) {
+            return new CursorWindow[size];
+        }
+    };
+
+    public static CursorWindow newFromParcel(Parcel p) {
+        return CREATOR.createFromParcel(p);
+    }
+
+    public int describeContents() {
+        return 0;
+    }
+
+    public void writeToParcel(Parcel dest, int flags) {
+        acquireReference();
+        try {
+            dest.writeInt(mStartPos);
+            nativeWriteToParcel(mWindowPtr, dest);
+        } finally {
+            releaseReference();
+        }
+
+        if ((flags & Parcelable.PARCELABLE_WRITE_RETURN_VALUE) != 0) {
+            releaseReference();
+        }
+    }
+
+    @Override
+    protected void onAllReferencesReleased() {
+        dispose();
+    }
+
+    @UnsupportedAppUsage
+    private static final LongSparseArray<Integer> sWindowToPidMap = new LongSparseArray<Integer>();
+
+    private void recordNewWindow(int pid, long window) {
+        synchronized (sWindowToPidMap) {
+            sWindowToPidMap.put(window, pid);
+            if (Log.isLoggable(STATS_TAG, Log.VERBOSE)) {
+                Log.i(STATS_TAG, "Created a new Cursor. " + printStats());
+            }
+        }
+    }
+
+    private void recordClosingOfWindow(long window) {
+        synchronized (sWindowToPidMap) {
+            if (sWindowToPidMap.size() == 0) {
+                // this means we are not in the ContentProvider.
+                return;
+            }
+            sWindowToPidMap.delete(window);
+        }
+    }
+
+    @UnsupportedAppUsage
+    private String printStats() {
+        StringBuilder buff = new StringBuilder();
+        int myPid = Process.myPid();
+        int total = 0;
+        SparseIntArray pidCounts = new SparseIntArray();
+        synchronized (sWindowToPidMap) {
+            int size = sWindowToPidMap.size();
+            if (size == 0) {
+                // this means we are not in the ContentProvider.
+                return "";
+            }
+            for (int indx = 0; indx < size; indx++) {
+                int pid = sWindowToPidMap.valueAt(indx);
+                int value = pidCounts.get(pid);
+                pidCounts.put(pid, ++value);
+            }
+        }
+        int numPids = pidCounts.size();
+        for (int i = 0; i < numPids;i++) {
+            buff.append(" (# cursors opened by ");
+            int pid = pidCounts.keyAt(i);
+            if (pid == myPid) {
+                buff.append("this proc=");
+            } else {
+                buff.append("pid " + pid + "=");
+            }
+            int num = pidCounts.get(pid);
+            buff.append(num + ")");
+            total += num;
+        }
+        // limit the returned string size to 1000
+        String s = (buff.length() > 980) ? buff.substring(0, 980) : buff.toString();
+        return "# Open Cursors=" + total + s;
+    }
+
+    private static int getCursorWindowSize() {
+        if (sCursorWindowSize < 0) {
+            // The cursor window size. resource xml file specifies the value in kB.
+            // convert it to bytes here by multiplying with 1024.
+            sCursorWindowSize = Resources.getSystem().getInteger(
+                    com.android.internal.R.integer.config_cursorWindowSize) * 1024;
+        }
+        return sCursorWindowSize;
+    }
+
+    @Override
+    public String toString() {
+        return getName() + " {" + Long.toHexString(mWindowPtr) + "}";
+    }
+}
diff --git a/android/database/CursorWindowAllocationException.java b/android/database/CursorWindowAllocationException.java
new file mode 100644
index 0000000..2e3227d
--- /dev/null
+++ b/android/database/CursorWindowAllocationException.java
@@ -0,0 +1,29 @@
+/*
+ * Copyright (C) 2010 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.database;
+
+/**
+ * This exception is thrown when a CursorWindow couldn't be allocated,
+ * most probably due to memory not being available.
+ *
+ * @hide
+ */
+public class CursorWindowAllocationException extends RuntimeException {
+    public CursorWindowAllocationException(String description) {
+        super(description);
+    }
+}
diff --git a/android/database/CursorWindowPerfTest.java b/android/database/CursorWindowPerfTest.java
new file mode 100644
index 0000000..c5ef80d
--- /dev/null
+++ b/android/database/CursorWindowPerfTest.java
@@ -0,0 +1,124 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.database;
+
+import static org.junit.Assert.assertTrue;
+
+import android.content.Context;
+import android.database.sqlite.SQLiteCursor;
+import android.database.sqlite.SQLiteDatabase;
+import android.perftests.utils.BenchmarkState;
+import android.perftests.utils.PerfStatusReporter;
+
+import androidx.test.InstrumentationRegistry;
+import androidx.test.filters.LargeTest;
+import androidx.test.runner.AndroidJUnit4;
+
+import org.junit.AfterClass;
+import org.junit.BeforeClass;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+@RunWith(AndroidJUnit4.class)
+@LargeTest
+public class CursorWindowPerfTest {
+    @Rule
+    public PerfStatusReporter mPerfStatusReporter = new PerfStatusReporter();
+
+    private static Context getContext() {
+        return InstrumentationRegistry.getTargetContext();
+    }
+
+    private static final String DB_NAME = CursorWindowPerfTest.class.toString();
+
+    private static SQLiteDatabase sDatabase;
+
+    @BeforeClass
+    public static void setup() {
+        getContext().deleteDatabase(DB_NAME);
+        sDatabase = getContext().openOrCreateDatabase(DB_NAME, Context.MODE_PRIVATE, null);
+
+        for (TableHelper helper : TableHelper.TABLE_HELPERS) {
+            sDatabase.execSQL(helper.createSql());
+            final String insert = helper.insertSql();
+
+            // this test only needs 1 row
+            sDatabase.execSQL(insert, helper.createItem(0));
+        }
+
+    }
+
+    @AfterClass
+    public static void teardown() {
+        getContext().deleteDatabase(DB_NAME);
+    }
+
+    @Test
+    public void loadInt() {
+        loadRowFromCursorWindow(TableHelper.INT_1, false);
+    }
+
+    @Test
+    public void loadInt_doubleRef() {
+        loadRowFromCursorWindow(TableHelper.INT_1, true);
+    }
+
+    @Test
+    public void load10Ints() {
+        loadRowFromCursorWindow(TableHelper.INT_10, false);
+    }
+
+    @Test
+    public void loadUser() {
+        loadRowFromCursorWindow(TableHelper.USER, false);
+    }
+
+    private void loadRowFromCursorWindow(TableHelper helper, boolean doubleRef) {
+        try (Cursor cursor = sDatabase.rawQuery(helper.readSql(), new String[0])) {
+            TableHelper.CursorReader reader = helper.createReader(cursor);
+
+            SQLiteCursor sqLiteCursor = (SQLiteCursor) cursor;
+
+            sqLiteCursor.getCount(); // load one window
+            CursorWindow window = sqLiteCursor.getWindow();
+            assertTrue("must have enough rows", window.getNumRows() >= 1);
+            int start = window.getStartPosition();
+
+            BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+
+            if (!doubleRef) {
+                // normal access
+                while (state.keepRunning()) {
+                    cursor.moveToPosition(start);
+                    reader.read();
+                }
+            } else {
+                // add an extra window acquire/release to measure overhead
+                while (state.keepRunning()) {
+                    cursor.moveToPosition(start);
+                    try {
+                        window.acquireReference();
+                        reader.read();
+                    } finally {
+                        window.releaseReference();
+                    }
+                }
+            }
+        }
+    }
+}
diff --git a/android/database/CursorWrapper.java b/android/database/CursorWrapper.java
new file mode 100644
index 0000000..4496f80
--- /dev/null
+++ b/android/database/CursorWrapper.java
@@ -0,0 +1,270 @@
+/*
+ * Copyright (C) 2006 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.database;
+
+import android.compat.annotation.UnsupportedAppUsage;
+import android.content.ContentResolver;
+import android.net.Uri;
+import android.os.Bundle;
+
+import java.util.List;
+
+/**
+ * Wrapper class for Cursor that delegates all calls to the actual cursor object.  The primary
+ * use for this class is to extend a cursor while overriding only a subset of its methods.
+ */
+public class CursorWrapper implements Cursor {
+    /** @hide */
+    @UnsupportedAppUsage
+    protected final Cursor mCursor;
+
+    /**
+     * Creates a cursor wrapper.
+     * @param cursor The underlying cursor to wrap.
+     */
+    public CursorWrapper(Cursor cursor) {
+        mCursor = cursor;
+    }
+
+    /**
+     * Gets the underlying cursor that is wrapped by this instance.
+     *
+     * @return The wrapped cursor.
+     */
+    public Cursor getWrappedCursor() {
+        return mCursor;
+    }
+
+    @Override
+    public void close() {
+        mCursor.close(); 
+    }
+ 
+    @Override
+    public boolean isClosed() {
+        return mCursor.isClosed();
+    }
+
+    @Override
+    public int getCount() {
+        return mCursor.getCount();
+    }
+
+    @Override
+    @Deprecated
+    public void deactivate() {
+        mCursor.deactivate();
+    }
+
+    @Override
+    public boolean moveToFirst() {
+        return mCursor.moveToFirst();
+    }
+
+    @Override
+    public int getColumnCount() {
+        return mCursor.getColumnCount();
+    }
+
+    @Override
+    public int getColumnIndex(String columnName) {
+        return mCursor.getColumnIndex(columnName);
+    }
+
+    @Override
+    public int getColumnIndexOrThrow(String columnName)
+            throws IllegalArgumentException {
+        return mCursor.getColumnIndexOrThrow(columnName);
+    }
+
+    @Override
+    public String getColumnName(int columnIndex) {
+         return mCursor.getColumnName(columnIndex);
+    }
+
+    @Override
+    public String[] getColumnNames() {
+        return mCursor.getColumnNames();
+    }
+
+    @Override
+    public double getDouble(int columnIndex) {
+        return mCursor.getDouble(columnIndex);
+    }
+
+    @Override
+    public void setExtras(Bundle extras) {
+        mCursor.setExtras(extras);
+    }
+
+    @Override
+    public Bundle getExtras() {
+        return mCursor.getExtras();
+    }
+
+    @Override
+    public float getFloat(int columnIndex) {
+        return mCursor.getFloat(columnIndex);
+    }
+
+    @Override
+    public int getInt(int columnIndex) {
+        return mCursor.getInt(columnIndex);
+    }
+
+    @Override
+    public long getLong(int columnIndex) {
+        return mCursor.getLong(columnIndex);
+    }
+
+    @Override
+    public short getShort(int columnIndex) {
+        return mCursor.getShort(columnIndex);
+    }
+
+    @Override
+    public String getString(int columnIndex) {
+        return mCursor.getString(columnIndex);
+    }
+    
+    @Override
+    public void copyStringToBuffer(int columnIndex, CharArrayBuffer buffer) {
+        mCursor.copyStringToBuffer(columnIndex, buffer);
+    }
+
+    @Override
+    public byte[] getBlob(int columnIndex) {
+        return mCursor.getBlob(columnIndex);
+    }
+    
+    @Override
+    public boolean getWantsAllOnMoveCalls() {
+        return mCursor.getWantsAllOnMoveCalls();
+    }
+
+    @Override
+    public boolean isAfterLast() {
+        return mCursor.isAfterLast();
+    }
+
+    @Override
+    public boolean isBeforeFirst() {
+        return mCursor.isBeforeFirst();
+    }
+
+    @Override
+    public boolean isFirst() {
+        return mCursor.isFirst();
+    }
+
+    @Override
+    public boolean isLast() {
+        return mCursor.isLast();
+    }
+
+    @Override
+    public int getType(int columnIndex) {
+        return mCursor.getType(columnIndex);
+    }
+
+    @Override
+    public boolean isNull(int columnIndex) {
+        return mCursor.isNull(columnIndex);
+    }
+
+    @Override
+    public boolean moveToLast() {
+        return mCursor.moveToLast();
+    }
+
+    @Override
+    public boolean move(int offset) {
+        return mCursor.move(offset);
+    }
+
+    @Override
+    public boolean moveToPosition(int position) {
+        return mCursor.moveToPosition(position);
+    }
+
+    @Override
+    public boolean moveToNext() {
+        return mCursor.moveToNext();
+    }
+
+    @Override
+    public int getPosition() {
+        return mCursor.getPosition();
+    }
+
+    @Override
+    public boolean moveToPrevious() {
+        return mCursor.moveToPrevious();
+    }
+
+    @Override
+    public void registerContentObserver(ContentObserver observer) {
+        mCursor.registerContentObserver(observer);
+    }
+
+    @Override
+    public void registerDataSetObserver(DataSetObserver observer) {
+        mCursor.registerDataSetObserver(observer);
+    }
+
+    @Override
+    @Deprecated
+    public boolean requery() {
+        return mCursor.requery();
+    }
+
+    @Override
+    public Bundle respond(Bundle extras) {
+        return mCursor.respond(extras);
+    }
+
+    @Override
+    public void setNotificationUri(ContentResolver cr, Uri uri) {
+        mCursor.setNotificationUri(cr, uri);
+    }
+
+    @Override
+    public void setNotificationUris(ContentResolver cr, List<Uri> uris) {
+        mCursor.setNotificationUris(cr, uris);
+    }
+
+    @Override
+    public Uri getNotificationUri() {
+        return mCursor.getNotificationUri();
+    }
+
+    @Override
+    public List<Uri> getNotificationUris() {
+        return mCursor.getNotificationUris();
+    }
+
+    @Override
+    public void unregisterContentObserver(ContentObserver observer) {
+        mCursor.unregisterContentObserver(observer);
+    }
+
+    @Override
+    public void unregisterDataSetObserver(DataSetObserver observer) {
+        mCursor.unregisterDataSetObserver(observer);
+    }
+}
+
diff --git a/android/database/DataSetObservable.java b/android/database/DataSetObservable.java
new file mode 100644
index 0000000..ca77a13
--- /dev/null
+++ b/android/database/DataSetObservable.java
@@ -0,0 +1,54 @@
+/*
+ * 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.database;
+
+/**
+ * A specialization of {@link Observable} for {@link DataSetObserver}
+ * that provides methods for sending notifications to a list of
+ * {@link DataSetObserver} objects.
+ */
+public class DataSetObservable extends Observable<DataSetObserver> {
+    /**
+     * Invokes {@link DataSetObserver#onChanged} on each observer.
+     * Called when the contents of the data set have changed.  The recipient
+     * will obtain the new contents the next time it queries the data set.
+     */
+    public void notifyChanged() {
+        synchronized(mObservers) {
+            // since onChanged() is implemented by the app, it could do anything, including
+            // removing itself from {@link mObservers} - and that could cause problems if
+            // an iterator is used on the ArrayList {@link mObservers}.
+            // to avoid such problems, just march thru the list in the reverse order.
+            for (int i = mObservers.size() - 1; i >= 0; i--) {
+                mObservers.get(i).onChanged();
+            }
+        }
+    }
+
+    /**
+     * Invokes {@link DataSetObserver#onInvalidated} on each observer.
+     * Called when the data set is no longer valid and cannot be queried again,
+     * such as when the data set has been closed.
+     */
+    public void notifyInvalidated() {
+        synchronized (mObservers) {
+            for (int i = mObservers.size() - 1; i >= 0; i--) {
+                mObservers.get(i).onInvalidated();
+            }
+        }
+    }
+}
diff --git a/android/database/DataSetObserver.java b/android/database/DataSetObserver.java
new file mode 100644
index 0000000..28616c8
--- /dev/null
+++ b/android/database/DataSetObserver.java
@@ -0,0 +1,41 @@
+/*
+ * 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.database;
+
+/**
+ * Receives call backs when a data set has been changed, or made invalid. The typically data sets
+ * that are observed are {@link Cursor}s or {@link android.widget.Adapter}s.
+ * DataSetObserver must be implemented by objects which are added to a DataSetObservable.
+ */
+public abstract class DataSetObserver {
+    /**
+     * This method is called when the entire data set has changed,
+     * most likely through a call to {@link Cursor#requery()} on a {@link Cursor}.
+     */
+    public void onChanged() {
+        // Do nothing
+    }
+
+    /**
+     * This method is called when the entire data becomes invalid,
+     * most likely through a call to {@link Cursor#deactivate()} or {@link Cursor#close()} on a
+     * {@link Cursor}.
+     */
+    public void onInvalidated() {
+        // Do nothing
+    }
+}
diff --git a/android/database/DatabaseErrorHandler.java b/android/database/DatabaseErrorHandler.java
new file mode 100644
index 0000000..55ad921
--- /dev/null
+++ b/android/database/DatabaseErrorHandler.java
@@ -0,0 +1,32 @@
+/*
+ * 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.database;
+
+import android.database.sqlite.SQLiteDatabase;
+
+/**
+ * An interface to let apps define an action to take when database corruption is detected.
+ */
+public interface DatabaseErrorHandler {
+
+    /**
+     * The method invoked when database corruption is detected.
+     * @param dbObj the {@link SQLiteDatabase} object representing the database on which corruption
+     * is detected.
+     */
+    void onCorruption(SQLiteDatabase dbObj);
+}
diff --git a/android/database/DatabaseUtils.java b/android/database/DatabaseUtils.java
new file mode 100644
index 0000000..9b809b8
--- /dev/null
+++ b/android/database/DatabaseUtils.java
@@ -0,0 +1,1601 @@
+/*
+ * Copyright (C) 2006 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.database;
+
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+import android.compat.annotation.UnsupportedAppUsage;
+import android.content.ContentValues;
+import android.content.Context;
+import android.content.OperationApplicationException;
+import android.database.sqlite.SQLiteAbortException;
+import android.database.sqlite.SQLiteConstraintException;
+import android.database.sqlite.SQLiteDatabase;
+import android.database.sqlite.SQLiteDatabaseCorruptException;
+import android.database.sqlite.SQLiteDiskIOException;
+import android.database.sqlite.SQLiteException;
+import android.database.sqlite.SQLiteFullException;
+import android.database.sqlite.SQLiteProgram;
+import android.database.sqlite.SQLiteStatement;
+import android.os.Build;
+import android.os.OperationCanceledException;
+import android.os.Parcel;
+import android.os.ParcelFileDescriptor;
+import android.text.TextUtils;
+import android.util.Log;
+
+import com.android.internal.util.ArrayUtils;
+
+import java.io.FileNotFoundException;
+import java.io.PrintStream;
+import java.text.Collator;
+import java.util.Arrays;
+import java.util.HashMap;
+import java.util.Locale;
+import java.util.Map;
+
+/**
+ * Static utility methods for dealing with databases and {@link Cursor}s.
+ */
+public class DatabaseUtils {
+    private static final String TAG = "DatabaseUtils";
+
+    private static final boolean DEBUG = false;
+
+    /** One of the values returned by {@link #getSqlStatementType(String)}. */
+    public static final int STATEMENT_SELECT = 1;
+    /** One of the values returned by {@link #getSqlStatementType(String)}. */
+    public static final int STATEMENT_UPDATE = 2;
+    /** One of the values returned by {@link #getSqlStatementType(String)}. */
+    public static final int STATEMENT_ATTACH = 3;
+    /** One of the values returned by {@link #getSqlStatementType(String)}. */
+    public static final int STATEMENT_BEGIN = 4;
+    /** One of the values returned by {@link #getSqlStatementType(String)}. */
+    public static final int STATEMENT_COMMIT = 5;
+    /** One of the values returned by {@link #getSqlStatementType(String)}. */
+    public static final int STATEMENT_ABORT = 6;
+    /** One of the values returned by {@link #getSqlStatementType(String)}. */
+    public static final int STATEMENT_PRAGMA = 7;
+    /** One of the values returned by {@link #getSqlStatementType(String)}. */
+    public static final int STATEMENT_DDL = 8;
+    /** One of the values returned by {@link #getSqlStatementType(String)}. */
+    public static final int STATEMENT_UNPREPARED = 9;
+    /** One of the values returned by {@link #getSqlStatementType(String)}. */
+    public static final int STATEMENT_OTHER = 99;
+
+    /**
+     * Special function for writing an exception result at the header of
+     * a parcel, to be used when returning an exception from a transaction.
+     * exception will be re-thrown by the function in another process
+     * @param reply Parcel to write to
+     * @param e The Exception to be written.
+     * @see Parcel#writeNoException
+     * @see Parcel#writeException
+     */
+    public static final void writeExceptionToParcel(Parcel reply, Exception e) {
+        int code = 0;
+        boolean logException = true;
+        if (e instanceof FileNotFoundException) {
+            code = 1;
+            logException = false;
+        } else if (e instanceof IllegalArgumentException) {
+            code = 2;
+        } else if (e instanceof UnsupportedOperationException) {
+            code = 3;
+        } else if (e instanceof SQLiteAbortException) {
+            code = 4;
+        } else if (e instanceof SQLiteConstraintException) {
+            code = 5;
+        } else if (e instanceof SQLiteDatabaseCorruptException) {
+            code = 6;
+        } else if (e instanceof SQLiteFullException) {
+            code = 7;
+        } else if (e instanceof SQLiteDiskIOException) {
+            code = 8;
+        } else if (e instanceof SQLiteException) {
+            code = 9;
+        } else if (e instanceof OperationApplicationException) {
+            code = 10;
+        } else if (e instanceof OperationCanceledException) {
+            code = 11;
+            logException = false;
+        } else {
+            reply.writeException(e);
+            Log.e(TAG, "Writing exception to parcel", e);
+            return;
+        }
+        reply.writeInt(code);
+        reply.writeString(e.getMessage());
+
+        if (logException) {
+            Log.e(TAG, "Writing exception to parcel", e);
+        }
+    }
+
+    /**
+     * Special function for reading an exception result from the header of
+     * a parcel, to be used after receiving the result of a transaction.  This
+     * will throw the exception for you if it had been written to the Parcel,
+     * otherwise return and let you read the normal result data from the Parcel.
+     * @param reply Parcel to read from
+     * @see Parcel#writeNoException
+     * @see Parcel#readException
+     */
+    public static final void readExceptionFromParcel(Parcel reply) {
+        int code = reply.readExceptionCode();
+        if (code == 0) return;
+        String msg = reply.readString();
+        DatabaseUtils.readExceptionFromParcel(reply, msg, code);
+    }
+
+    public static void readExceptionWithFileNotFoundExceptionFromParcel(
+            Parcel reply) throws FileNotFoundException {
+        int code = reply.readExceptionCode();
+        if (code == 0) return;
+        String msg = reply.readString();
+        if (code == 1) {
+            throw new FileNotFoundException(msg);
+        } else {
+            DatabaseUtils.readExceptionFromParcel(reply, msg, code);
+        }
+    }
+
+    public static void readExceptionWithOperationApplicationExceptionFromParcel(
+            Parcel reply) throws OperationApplicationException {
+        int code = reply.readExceptionCode();
+        if (code == 0) return;
+        String msg = reply.readString();
+        if (code == 10) {
+            throw new OperationApplicationException(msg);
+        } else {
+            DatabaseUtils.readExceptionFromParcel(reply, msg, code);
+        }
+    }
+
+    private static final void readExceptionFromParcel(Parcel reply, String msg, int code) {
+        switch (code) {
+            case 2:
+                throw new IllegalArgumentException(msg);
+            case 3:
+                throw new UnsupportedOperationException(msg);
+            case 4:
+                throw new SQLiteAbortException(msg);
+            case 5:
+                throw new SQLiteConstraintException(msg);
+            case 6:
+                throw new SQLiteDatabaseCorruptException(msg);
+            case 7:
+                throw new SQLiteFullException(msg);
+            case 8:
+                throw new SQLiteDiskIOException(msg);
+            case 9:
+                throw new SQLiteException(msg);
+            case 11:
+                throw new OperationCanceledException(msg);
+            default:
+                reply.readException(code, msg);
+        }
+    }
+
+    /**
+     * Binds the given Object to the given SQLiteProgram using the proper
+     * typing. For example, bind numbers as longs/doubles, and everything else
+     * as a string by call toString() on it.
+     *
+     * @param prog the program to bind the object to
+     * @param index the 1-based index to bind at
+     * @param value the value to bind
+     */
+    public static void bindObjectToProgram(SQLiteProgram prog, int index,
+            Object value) {
+        if (value == null) {
+            prog.bindNull(index);
+        } else if (value instanceof Double || value instanceof Float) {
+            prog.bindDouble(index, ((Number)value).doubleValue());
+        } else if (value instanceof Number) {
+            prog.bindLong(index, ((Number)value).longValue());
+        } else if (value instanceof Boolean) {
+            Boolean bool = (Boolean)value;
+            if (bool) {
+                prog.bindLong(index, 1);
+            } else {
+                prog.bindLong(index, 0);
+            }
+        } else if (value instanceof byte[]){
+            prog.bindBlob(index, (byte[]) value);
+        } else {
+            prog.bindString(index, value.toString());
+        }
+    }
+
+    /**
+     * Bind the given selection with the given selection arguments.
+     * <p>
+     * Internally assumes that '?' is only ever used for arguments, and doesn't
+     * appear as a literal or escaped value.
+     * <p>
+     * This method is typically useful for trusted code that needs to cook up a
+     * fully-bound selection.
+     *
+     * @hide
+     */
+    public static @Nullable String bindSelection(@Nullable String selection,
+            @Nullable Object... selectionArgs) {
+        if (selection == null) return null;
+        // If no arguments provided, so we can't bind anything
+        if (ArrayUtils.isEmpty(selectionArgs)) return selection;
+        // If no bindings requested, so we can shortcut
+        if (selection.indexOf('?') == -1) return selection;
+
+        // Track the chars immediately before and after each bind request, to
+        // decide if it needs additional whitespace added
+        char before = ' ';
+        char after = ' ';
+
+        int argIndex = 0;
+        final int len = selection.length();
+        final StringBuilder res = new StringBuilder(len);
+        for (int i = 0; i < len; ) {
+            char c = selection.charAt(i++);
+            if (c == '?') {
+                // Assume this bind request is guarded until we find a specific
+                // trailing character below
+                after = ' ';
+
+                // Sniff forward to see if the selection is requesting a
+                // specific argument index
+                int start = i;
+                for (; i < len; i++) {
+                    c = selection.charAt(i);
+                    if (c < '0' || c > '9') {
+                        after = c;
+                        break;
+                    }
+                }
+                if (start != i) {
+                    argIndex = Integer.parseInt(selection.substring(start, i)) - 1;
+                }
+
+                // Manually bind the argument into the selection, adding
+                // whitespace when needed for clarity
+                final Object arg = selectionArgs[argIndex++];
+                if (before != ' ' && before != '=') res.append(' ');
+                switch (DatabaseUtils.getTypeOfObject(arg)) {
+                    case Cursor.FIELD_TYPE_NULL:
+                        res.append("NULL");
+                        break;
+                    case Cursor.FIELD_TYPE_INTEGER:
+                        res.append(((Number) arg).longValue());
+                        break;
+                    case Cursor.FIELD_TYPE_FLOAT:
+                        res.append(((Number) arg).doubleValue());
+                        break;
+                    case Cursor.FIELD_TYPE_BLOB:
+                        throw new IllegalArgumentException("Blobs not supported");
+                    case Cursor.FIELD_TYPE_STRING:
+                    default:
+                        if (arg instanceof Boolean) {
+                            // Provide compatibility with legacy applications which may pass
+                            // Boolean values in bind args.
+                            res.append(((Boolean) arg).booleanValue() ? 1 : 0);
+                        } else {
+                            res.append('\'');
+                            res.append(arg.toString());
+                            res.append('\'');
+                        }
+                        break;
+                }
+                if (after != ' ') res.append(' ');
+            } else {
+                res.append(c);
+                before = c;
+            }
+        }
+        return res.toString();
+    }
+
+    /**
+     * Make a deep copy of the given argument list, ensuring that the returned
+     * value is completely isolated from any changes to the original arguments.
+     *
+     * @hide
+     */
+    public static @Nullable Object[] deepCopyOf(@Nullable Object[] args) {
+        if (args == null) return null;
+
+        final Object[] res = new Object[args.length];
+        for (int i = 0; i < args.length; i++) {
+            final Object arg = args[i];
+
+            if ((arg == null) || (arg instanceof Number) || (arg instanceof String)) {
+                // When the argument is immutable, we can copy by reference
+                res[i] = arg;
+            } else if (arg instanceof byte[]) {
+                // Need to deep copy blobs
+                final byte[] castArg = (byte[]) arg;
+                res[i] = Arrays.copyOf(castArg, castArg.length);
+            } else {
+                // Convert everything else to string, making it immutable
+                res[i] = String.valueOf(arg);
+            }
+        }
+        return res;
+    }
+
+    /**
+     * Returns data type of the given object's value.
+     *<p>
+     * Returned values are
+     * <ul>
+     *   <li>{@link Cursor#FIELD_TYPE_NULL}</li>
+     *   <li>{@link Cursor#FIELD_TYPE_INTEGER}</li>
+     *   <li>{@link Cursor#FIELD_TYPE_FLOAT}</li>
+     *   <li>{@link Cursor#FIELD_TYPE_STRING}</li>
+     *   <li>{@link Cursor#FIELD_TYPE_BLOB}</li>
+     *</ul>
+     *</p>
+     *
+     * @param obj the object whose value type is to be returned
+     * @return object value type
+     * @hide
+     */
+    @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023)
+    public static int getTypeOfObject(Object obj) {
+        if (obj == null) {
+            return Cursor.FIELD_TYPE_NULL;
+        } else if (obj instanceof byte[]) {
+            return Cursor.FIELD_TYPE_BLOB;
+        } else if (obj instanceof Float || obj instanceof Double) {
+            return Cursor.FIELD_TYPE_FLOAT;
+        } else if (obj instanceof Long || obj instanceof Integer
+                || obj instanceof Short || obj instanceof Byte) {
+            return Cursor.FIELD_TYPE_INTEGER;
+        } else {
+            return Cursor.FIELD_TYPE_STRING;
+        }
+    }
+
+    /**
+     * Fills the specified cursor window by iterating over the contents of the cursor.
+     * The window is filled until the cursor is exhausted or the window runs out
+     * of space.
+     *
+     * The original position of the cursor is left unchanged by this operation.
+     *
+     * @param cursor The cursor that contains the data to put in the window.
+     * @param position The start position for filling the window.
+     * @param window The window to fill.
+     * @hide
+     */
+    public static void cursorFillWindow(final Cursor cursor,
+            int position, final CursorWindow window) {
+        if (position < 0 || position >= cursor.getCount()) {
+            return;
+        }
+        final int oldPos = cursor.getPosition();
+        final int numColumns = cursor.getColumnCount();
+        window.clear();
+        window.setStartPosition(position);
+        window.setNumColumns(numColumns);
+        if (cursor.moveToPosition(position)) {
+            rowloop: do {
+                if (!window.allocRow()) {
+                    break;
+                }
+                for (int i = 0; i < numColumns; i++) {
+                    final int type = cursor.getType(i);
+                    final boolean success;
+                    switch (type) {
+                        case Cursor.FIELD_TYPE_NULL:
+                            success = window.putNull(position, i);
+                            break;
+
+                        case Cursor.FIELD_TYPE_INTEGER:
+                            success = window.putLong(cursor.getLong(i), position, i);
+                            break;
+
+                        case Cursor.FIELD_TYPE_FLOAT:
+                            success = window.putDouble(cursor.getDouble(i), position, i);
+                            break;
+
+                        case Cursor.FIELD_TYPE_BLOB: {
+                            final byte[] value = cursor.getBlob(i);
+                            success = value != null ? window.putBlob(value, position, i)
+                                    : window.putNull(position, i);
+                            break;
+                        }
+
+                        default: // assume value is convertible to String
+                        case Cursor.FIELD_TYPE_STRING: {
+                            final String value = cursor.getString(i);
+                            success = value != null ? window.putString(value, position, i)
+                                    : window.putNull(position, i);
+                            break;
+                        }
+                    }
+                    if (!success) {
+                        window.freeLastRow();
+                        break rowloop;
+                    }
+                }
+                position += 1;
+            } while (cursor.moveToNext());
+        }
+        cursor.moveToPosition(oldPos);
+    }
+
+    /**
+     * Appends an SQL string to the given StringBuilder, including the opening
+     * and closing single quotes. Any single quotes internal to sqlString will
+     * be escaped.
+     *
+     * This method is deprecated because we want to encourage everyone
+     * to use the "?" binding form.  However, when implementing a
+     * ContentProvider, one may want to add WHERE clauses that were
+     * not provided by the caller.  Since "?" is a positional form,
+     * using it in this case could break the caller because the
+     * indexes would be shifted to accomodate the ContentProvider's
+     * internal bindings.  In that case, it may be necessary to
+     * construct a WHERE clause manually.  This method is useful for
+     * those cases.
+     *
+     * @param sb the StringBuilder that the SQL string will be appended to
+     * @param sqlString the raw string to be appended, which may contain single
+     *                  quotes
+     */
+    public static void appendEscapedSQLString(StringBuilder sb, String sqlString) {
+        sb.append('\'');
+        if (sqlString.indexOf('\'') != -1) {
+            int length = sqlString.length();
+            for (int i = 0; i < length; i++) {
+                char c = sqlString.charAt(i);
+                if (c == '\'') {
+                    sb.append('\'');
+                }
+                sb.append(c);
+            }
+        } else
+            sb.append(sqlString);
+        sb.append('\'');
+    }
+
+    /**
+     * SQL-escape a string.
+     */
+    public static String sqlEscapeString(String value) {
+        StringBuilder escaper = new StringBuilder();
+
+        DatabaseUtils.appendEscapedSQLString(escaper, value);
+
+        return escaper.toString();
+    }
+
+    /**
+     * Appends an Object to an SQL string with the proper escaping, etc.
+     */
+    public static final void appendValueToSql(StringBuilder sql, Object value) {
+        if (value == null) {
+            sql.append("NULL");
+        } else if (value instanceof Boolean) {
+            Boolean bool = (Boolean)value;
+            if (bool) {
+                sql.append('1');
+            } else {
+                sql.append('0');
+            }
+        } else {
+            appendEscapedSQLString(sql, value.toString());
+        }
+    }
+
+    /**
+     * Concatenates two SQL WHERE clauses, handling empty or null values.
+     */
+    public static String concatenateWhere(String a, String b) {
+        if (TextUtils.isEmpty(a)) {
+            return b;
+        }
+        if (TextUtils.isEmpty(b)) {
+            return a;
+        }
+
+        return "(" + a + ") AND (" + b + ")";
+    }
+
+    /**
+     * return the collation key
+     * @param name
+     * @return the collation key
+     */
+    public static String getCollationKey(String name) {
+        byte [] arr = getCollationKeyInBytes(name);
+        try {
+            return new String(arr, 0, getKeyLen(arr), "ISO8859_1");
+        } catch (Exception ex) {
+            return "";
+        }
+    }
+
+    /**
+     * return the collation key in hex format
+     * @param name
+     * @return the collation key in hex format
+     */
+    public static String getHexCollationKey(String name) {
+        byte[] arr = getCollationKeyInBytes(name);
+        char[] keys = encodeHex(arr);
+        return new String(keys, 0, getKeyLen(arr) * 2);
+    }
+
+
+    /**
+     * Used building output as Hex
+     */
+    private static final char[] DIGITS = {
+            '0', '1', '2', '3', '4', '5', '6', '7',
+            '8', '9', 'a', 'b', 'c', 'd', 'e', 'f'
+    };
+
+    private static char[] encodeHex(byte[] input) {
+        int l = input.length;
+        char[] out = new char[l << 1];
+
+        // two characters form the hex value.
+        for (int i = 0, j = 0; i < l; i++) {
+            out[j++] = DIGITS[(0xF0 & input[i]) >>> 4 ];
+            out[j++] = DIGITS[ 0x0F & input[i] ];
+        }
+
+        return out;
+    }
+
+    private static int getKeyLen(byte[] arr) {
+        if (arr[arr.length - 1] != 0) {
+            return arr.length;
+        } else {
+            // remove zero "termination"
+            return arr.length-1;
+        }
+    }
+
+    private static byte[] getCollationKeyInBytes(String name) {
+        if (mColl == null) {
+            mColl = Collator.getInstance();
+            mColl.setStrength(Collator.PRIMARY);
+        }
+        return mColl.getCollationKey(name).toByteArray();
+    }
+
+    private static Collator mColl = null;
+    /**
+     * Prints the contents of a Cursor to System.out. The position is restored
+     * after printing.
+     *
+     * @param cursor the cursor to print
+     */
+    public static void dumpCursor(Cursor cursor) {
+        dumpCursor(cursor, System.out);
+    }
+
+    /**
+     * Prints the contents of a Cursor to a PrintSteam. The position is restored
+     * after printing.
+     *
+     * @param cursor the cursor to print
+     * @param stream the stream to print to
+     */
+    public static void dumpCursor(Cursor cursor, PrintStream stream) {
+        stream.println(">>>>> Dumping cursor " + cursor);
+        if (cursor != null) {
+            int startPos = cursor.getPosition();
+
+            cursor.moveToPosition(-1);
+            while (cursor.moveToNext()) {
+                dumpCurrentRow(cursor, stream);
+            }
+            cursor.moveToPosition(startPos);
+        }
+        stream.println("<<<<<");
+    }
+
+    /**
+     * Prints the contents of a Cursor to a StringBuilder. The position
+     * is restored after printing.
+     *
+     * @param cursor the cursor to print
+     * @param sb the StringBuilder to print to
+     */
+    public static void dumpCursor(Cursor cursor, StringBuilder sb) {
+        sb.append(">>>>> Dumping cursor " + cursor + "\n");
+        if (cursor != null) {
+            int startPos = cursor.getPosition();
+
+            cursor.moveToPosition(-1);
+            while (cursor.moveToNext()) {
+                dumpCurrentRow(cursor, sb);
+            }
+            cursor.moveToPosition(startPos);
+        }
+        sb.append("<<<<<\n");
+    }
+
+    /**
+     * Prints the contents of a Cursor to a String. The position is restored
+     * after printing.
+     *
+     * @param cursor the cursor to print
+     * @return a String that contains the dumped cursor
+     */
+    public static String dumpCursorToString(Cursor cursor) {
+        StringBuilder sb = new StringBuilder();
+        dumpCursor(cursor, sb);
+        return sb.toString();
+    }
+
+    /**
+     * Prints the contents of a Cursor's current row to System.out.
+     *
+     * @param cursor the cursor to print from
+     */
+    public static void dumpCurrentRow(Cursor cursor) {
+        dumpCurrentRow(cursor, System.out);
+    }
+
+    /**
+     * Prints the contents of a Cursor's current row to a PrintSteam.
+     *
+     * @param cursor the cursor to print
+     * @param stream the stream to print to
+     */
+    public static void dumpCurrentRow(Cursor cursor, PrintStream stream) {
+        String[] cols = cursor.getColumnNames();
+        stream.println("" + cursor.getPosition() + " {");
+        int length = cols.length;
+        for (int i = 0; i< length; i++) {
+            String value;
+            try {
+                value = cursor.getString(i);
+            } catch (SQLiteException e) {
+                // assume that if the getString threw this exception then the column is not
+                // representable by a string, e.g. it is a BLOB.
+                value = "<unprintable>";
+            }
+            stream.println("   " + cols[i] + '=' + value);
+        }
+        stream.println("}");
+    }
+
+    /**
+     * Prints the contents of a Cursor's current row to a StringBuilder.
+     *
+     * @param cursor the cursor to print
+     * @param sb the StringBuilder to print to
+     */
+    public static void dumpCurrentRow(Cursor cursor, StringBuilder sb) {
+        String[] cols = cursor.getColumnNames();
+        sb.append("" + cursor.getPosition() + " {\n");
+        int length = cols.length;
+        for (int i = 0; i < length; i++) {
+            String value;
+            try {
+                value = cursor.getString(i);
+            } catch (SQLiteException e) {
+                // assume that if the getString threw this exception then the column is not
+                // representable by a string, e.g. it is a BLOB.
+                value = "<unprintable>";
+            }
+            sb.append("   " + cols[i] + '=' + value + "\n");
+        }
+        sb.append("}\n");
+    }
+
+    /**
+     * Dump the contents of a Cursor's current row to a String.
+     *
+     * @param cursor the cursor to print
+     * @return a String that contains the dumped cursor row
+     */
+    public static String dumpCurrentRowToString(Cursor cursor) {
+        StringBuilder sb = new StringBuilder();
+        dumpCurrentRow(cursor, sb);
+        return sb.toString();
+    }
+
+    /**
+     * Reads a String out of a field in a Cursor and writes it to a Map.
+     *
+     * @param cursor The cursor to read from
+     * @param field The TEXT field to read
+     * @param values The {@link ContentValues} to put the value into, with the field as the key
+     */
+    public static void cursorStringToContentValues(Cursor cursor, String field,
+            ContentValues values) {
+        cursorStringToContentValues(cursor, field, values, field);
+    }
+
+    /**
+     * Reads a String out of a field in a Cursor and writes it to an InsertHelper.
+     *
+     * @param cursor The cursor to read from
+     * @param field The TEXT field to read
+     * @param inserter The InsertHelper to bind into
+     * @param index the index of the bind entry in the InsertHelper
+     */
+    public static void cursorStringToInsertHelper(Cursor cursor, String field,
+            InsertHelper inserter, int index) {
+        inserter.bind(index, cursor.getString(cursor.getColumnIndexOrThrow(field)));
+    }
+
+    /**
+     * Reads a String out of a field in a Cursor and writes it to a Map.
+     *
+     * @param cursor The cursor to read from
+     * @param field The TEXT field to read
+     * @param values The {@link ContentValues} to put the value into, with the field as the key
+     * @param key The key to store the value with in the map
+     */
+    public static void cursorStringToContentValues(Cursor cursor, String field,
+            ContentValues values, String key) {
+        values.put(key, cursor.getString(cursor.getColumnIndexOrThrow(field)));
+    }
+
+    /**
+     * Reads an Integer out of a field in a Cursor and writes it to a Map.
+     *
+     * @param cursor The cursor to read from
+     * @param field The INTEGER field to read
+     * @param values The {@link ContentValues} to put the value into, with the field as the key
+     */
+    public static void cursorIntToContentValues(Cursor cursor, String field, ContentValues values) {
+        cursorIntToContentValues(cursor, field, values, field);
+    }
+
+    /**
+     * Reads a Integer out of a field in a Cursor and writes it to a Map.
+     *
+     * @param cursor The cursor to read from
+     * @param field The INTEGER field to read
+     * @param values The {@link ContentValues} to put the value into, with the field as the key
+     * @param key The key to store the value with in the map
+     */
+    public static void cursorIntToContentValues(Cursor cursor, String field, ContentValues values,
+            String key) {
+        int colIndex = cursor.getColumnIndex(field);
+        if (!cursor.isNull(colIndex)) {
+            values.put(key, cursor.getInt(colIndex));
+        } else {
+            values.put(key, (Integer) null);
+        }
+    }
+
+    /**
+     * Reads a Long out of a field in a Cursor and writes it to a Map.
+     *
+     * @param cursor The cursor to read from
+     * @param field The INTEGER field to read
+     * @param values The {@link ContentValues} to put the value into, with the field as the key
+     */
+    public static void cursorLongToContentValues(Cursor cursor, String field, ContentValues values)
+    {
+        cursorLongToContentValues(cursor, field, values, field);
+    }
+
+    /**
+     * Reads a Long out of a field in a Cursor and writes it to a Map.
+     *
+     * @param cursor The cursor to read from
+     * @param field The INTEGER field to read
+     * @param values The {@link ContentValues} to put the value into
+     * @param key The key to store the value with in the map
+     */
+    public static void cursorLongToContentValues(Cursor cursor, String field, ContentValues values,
+            String key) {
+        int colIndex = cursor.getColumnIndex(field);
+        if (!cursor.isNull(colIndex)) {
+            Long value = Long.valueOf(cursor.getLong(colIndex));
+            values.put(key, value);
+        } else {
+            values.put(key, (Long) null);
+        }
+    }
+
+    /**
+     * Reads a Double out of a field in a Cursor and writes it to a Map.
+     *
+     * @param cursor The cursor to read from
+     * @param field The REAL field to read
+     * @param values The {@link ContentValues} to put the value into
+     */
+    public static void cursorDoubleToCursorValues(Cursor cursor, String field, ContentValues values)
+    {
+        cursorDoubleToContentValues(cursor, field, values, field);
+    }
+
+    /**
+     * Reads a Double out of a field in a Cursor and writes it to a Map.
+     *
+     * @param cursor The cursor to read from
+     * @param field The REAL field to read
+     * @param values The {@link ContentValues} to put the value into
+     * @param key The key to store the value with in the map
+     */
+    public static void cursorDoubleToContentValues(Cursor cursor, String field,
+            ContentValues values, String key) {
+        int colIndex = cursor.getColumnIndex(field);
+        if (!cursor.isNull(colIndex)) {
+            values.put(key, cursor.getDouble(colIndex));
+        } else {
+            values.put(key, (Double) null);
+        }
+    }
+
+    /**
+     * Read the entire contents of a cursor row and store them in a ContentValues.
+     *
+     * @param cursor the cursor to read from.
+     * @param values the {@link ContentValues} to put the row into.
+     */
+    public static void cursorRowToContentValues(Cursor cursor, ContentValues values) {
+        String[] columns = cursor.getColumnNames();
+        int length = columns.length;
+        for (int i = 0; i < length; i++) {
+            if (cursor.getType(i) == Cursor.FIELD_TYPE_BLOB) {
+                values.put(columns[i], cursor.getBlob(i));
+            } else {
+                values.put(columns[i], cursor.getString(i));
+            }
+        }
+    }
+
+    /**
+     * Picks a start position for {@link Cursor#fillWindow} such that the
+     * window will contain the requested row and a useful range of rows
+     * around it.
+     *
+     * When the data set is too large to fit in a cursor window, seeking the
+     * cursor can become a very expensive operation since we have to run the
+     * query again when we move outside the bounds of the current window.
+     *
+     * We try to choose a start position for the cursor window such that
+     * 1/3 of the window's capacity is used to hold rows before the requested
+     * position and 2/3 of the window's capacity is used to hold rows after the
+     * requested position.
+     *
+     * @param cursorPosition The row index of the row we want to get.
+     * @param cursorWindowCapacity The estimated number of rows that can fit in
+     * a cursor window, or 0 if unknown.
+     * @return The recommended start position, always less than or equal to
+     * the requested row.
+     * @hide
+     */
+    @UnsupportedAppUsage
+    public static int cursorPickFillWindowStartPosition(
+            int cursorPosition, int cursorWindowCapacity) {
+        return Math.max(cursorPosition - cursorWindowCapacity / 3, 0);
+    }
+
+    /**
+     * Query the table for the number of rows in the table.
+     * @param db the database the table is in
+     * @param table the name of the table to query
+     * @return the number of rows in the table
+     */
+    public static long queryNumEntries(SQLiteDatabase db, String table) {
+        return queryNumEntries(db, table, null, null);
+    }
+
+    /**
+     * Query the table for the number of rows in the table.
+     * @param db the database the table is in
+     * @param table the name of the table to query
+     * @param selection A filter declaring which rows to return,
+     *              formatted as an SQL WHERE clause (excluding the WHERE itself).
+     *              Passing null will count all rows for the given table
+     * @return the number of rows in the table filtered by the selection
+     */
+    public static long queryNumEntries(SQLiteDatabase db, String table, String selection) {
+        return queryNumEntries(db, table, selection, null);
+    }
+
+    /**
+     * Query the table for the number of rows in the table.
+     * @param db the database the table is in
+     * @param table the name of the table to query
+     * @param selection A filter declaring which rows to return,
+     *              formatted as an SQL WHERE clause (excluding the WHERE itself).
+     *              Passing null will count all rows for the given table
+     * @param selectionArgs You may include ?s in selection,
+     *              which will be replaced by the values from selectionArgs,
+     *              in order that they appear in the selection.
+     *              The values will be bound as Strings.
+     * @return the number of rows in the table filtered by the selection
+     */
+    public static long queryNumEntries(SQLiteDatabase db, String table, String selection,
+            String[] selectionArgs) {
+        String s = (!TextUtils.isEmpty(selection)) ? " where " + selection : "";
+        return longForQuery(db, "select count(*) from " + table + s,
+                    selectionArgs);
+    }
+
+    /**
+     * Query the table to check whether a table is empty or not
+     * @param db the database the table is in
+     * @param table the name of the table to query
+     * @return True if the table is empty
+     * @hide
+     */
+    public static boolean queryIsEmpty(SQLiteDatabase db, String table) {
+        long isEmpty = longForQuery(db, "select exists(select 1 from " + table + ")", null);
+        return isEmpty == 0;
+    }
+
+    /**
+     * Utility method to run the query on the db and return the value in the
+     * first column of the first row.
+     */
+    public static long longForQuery(SQLiteDatabase db, String query, String[] selectionArgs) {
+        SQLiteStatement prog = db.compileStatement(query);
+        try {
+            return longForQuery(prog, selectionArgs);
+        } finally {
+            prog.close();
+        }
+    }
+
+    /**
+     * Utility method to run the pre-compiled query and return the value in the
+     * first column of the first row.
+     */
+    public static long longForQuery(SQLiteStatement prog, String[] selectionArgs) {
+        prog.bindAllArgsAsStrings(selectionArgs);
+        return prog.simpleQueryForLong();
+    }
+
+    /**
+     * Utility method to run the query on the db and return the value in the
+     * first column of the first row.
+     */
+    public static String stringForQuery(SQLiteDatabase db, String query, String[] selectionArgs) {
+        SQLiteStatement prog = db.compileStatement(query);
+        try {
+            return stringForQuery(prog, selectionArgs);
+        } finally {
+            prog.close();
+        }
+    }
+
+    /**
+     * Utility method to run the pre-compiled query and return the value in the
+     * first column of the first row.
+     */
+    public static String stringForQuery(SQLiteStatement prog, String[] selectionArgs) {
+        prog.bindAllArgsAsStrings(selectionArgs);
+        return prog.simpleQueryForString();
+    }
+
+    /**
+     * Utility method to run the query on the db and return the blob value in the
+     * first column of the first row.
+     *
+     * @return A read-only file descriptor for a copy of the blob value.
+     */
+    public static ParcelFileDescriptor blobFileDescriptorForQuery(SQLiteDatabase db,
+            String query, String[] selectionArgs) {
+        SQLiteStatement prog = db.compileStatement(query);
+        try {
+            return blobFileDescriptorForQuery(prog, selectionArgs);
+        } finally {
+            prog.close();
+        }
+    }
+
+    /**
+     * Utility method to run the pre-compiled query and return the blob value in the
+     * first column of the first row.
+     *
+     * @return A read-only file descriptor for a copy of the blob value.
+     */
+    public static ParcelFileDescriptor blobFileDescriptorForQuery(SQLiteStatement prog,
+            String[] selectionArgs) {
+        prog.bindAllArgsAsStrings(selectionArgs);
+        return prog.simpleQueryForBlobFileDescriptor();
+    }
+
+    /**
+     * Reads a String out of a column in a Cursor and writes it to a ContentValues.
+     * Adds nothing to the ContentValues if the column isn't present or if its value is null.
+     *
+     * @param cursor The cursor to read from
+     * @param column The column to read
+     * @param values The {@link ContentValues} to put the value into
+     */
+    public static void cursorStringToContentValuesIfPresent(Cursor cursor, ContentValues values,
+            String column) {
+        final int index = cursor.getColumnIndex(column);
+        if (index != -1 && !cursor.isNull(index)) {
+            values.put(column, cursor.getString(index));
+        }
+    }
+
+    /**
+     * Reads a Long out of a column in a Cursor and writes it to a ContentValues.
+     * Adds nothing to the ContentValues if the column isn't present or if its value is null.
+     *
+     * @param cursor The cursor to read from
+     * @param column The column to read
+     * @param values The {@link ContentValues} to put the value into
+     */
+    public static void cursorLongToContentValuesIfPresent(Cursor cursor, ContentValues values,
+            String column) {
+        final int index = cursor.getColumnIndex(column);
+        if (index != -1 && !cursor.isNull(index)) {
+            values.put(column, cursor.getLong(index));
+        }
+    }
+
+    /**
+     * Reads a Short out of a column in a Cursor and writes it to a ContentValues.
+     * Adds nothing to the ContentValues if the column isn't present or if its value is null.
+     *
+     * @param cursor The cursor to read from
+     * @param column The column to read
+     * @param values The {@link ContentValues} to put the value into
+     */
+    public static void cursorShortToContentValuesIfPresent(Cursor cursor, ContentValues values,
+            String column) {
+        final int index = cursor.getColumnIndex(column);
+        if (index != -1 && !cursor.isNull(index)) {
+            values.put(column, cursor.getShort(index));
+        }
+    }
+
+    /**
+     * Reads a Integer out of a column in a Cursor and writes it to a ContentValues.
+     * Adds nothing to the ContentValues if the column isn't present or if its value is null.
+     *
+     * @param cursor The cursor to read from
+     * @param column The column to read
+     * @param values The {@link ContentValues} to put the value into
+     */
+    public static void cursorIntToContentValuesIfPresent(Cursor cursor, ContentValues values,
+            String column) {
+        final int index = cursor.getColumnIndex(column);
+        if (index != -1 && !cursor.isNull(index)) {
+            values.put(column, cursor.getInt(index));
+        }
+    }
+
+    /**
+     * Reads a Float out of a column in a Cursor and writes it to a ContentValues.
+     * Adds nothing to the ContentValues if the column isn't present or if its value is null.
+     *
+     * @param cursor The cursor to read from
+     * @param column The column to read
+     * @param values The {@link ContentValues} to put the value into
+     */
+    public static void cursorFloatToContentValuesIfPresent(Cursor cursor, ContentValues values,
+            String column) {
+        final int index = cursor.getColumnIndex(column);
+        if (index != -1 && !cursor.isNull(index)) {
+            values.put(column, cursor.getFloat(index));
+        }
+    }
+
+    /**
+     * Reads a Double out of a column in a Cursor and writes it to a ContentValues.
+     * Adds nothing to the ContentValues if the column isn't present or if its value is null.
+     *
+     * @param cursor The cursor to read from
+     * @param column The column to read
+     * @param values The {@link ContentValues} to put the value into
+     */
+    public static void cursorDoubleToContentValuesIfPresent(Cursor cursor, ContentValues values,
+            String column) {
+        final int index = cursor.getColumnIndex(column);
+        if (index != -1 && !cursor.isNull(index)) {
+            values.put(column, cursor.getDouble(index));
+        }
+    }
+
+    /**
+     * This class allows users to do multiple inserts into a table using
+     * the same statement.
+     * <p>
+     * This class is not thread-safe.
+     * </p>
+     *
+     * @deprecated Use {@link SQLiteStatement} instead.
+     */
+    @Deprecated
+    public static class InsertHelper {
+        private final SQLiteDatabase mDb;
+        private final String mTableName;
+        private HashMap<String, Integer> mColumns;
+        private String mInsertSQL = null;
+        private SQLiteStatement mInsertStatement = null;
+        private SQLiteStatement mReplaceStatement = null;
+        private SQLiteStatement mPreparedStatement = null;
+
+        /**
+         * {@hide}
+         *
+         * These are the columns returned by sqlite's "PRAGMA
+         * table_info(...)" command that we depend on.
+         */
+        public static final int TABLE_INFO_PRAGMA_COLUMNNAME_INDEX = 1;
+
+        /**
+         * This field was accidentally exposed in earlier versions of the platform
+         * so we can hide it but we can't remove it.
+         *
+         * @hide
+         */
+        public static final int TABLE_INFO_PRAGMA_DEFAULT_INDEX = 4;
+
+        /**
+         * @param db the SQLiteDatabase to insert into
+         * @param tableName the name of the table to insert into
+         */
+        public InsertHelper(SQLiteDatabase db, String tableName) {
+            mDb = db;
+            mTableName = tableName;
+        }
+
+        private void buildSQL() throws SQLException {
+            StringBuilder sb = new StringBuilder(128);
+            sb.append("INSERT INTO ");
+            sb.append(mTableName);
+            sb.append(" (");
+
+            StringBuilder sbv = new StringBuilder(128);
+            sbv.append("VALUES (");
+
+            int i = 1;
+            Cursor cur = null;
+            try {
+                cur = mDb.rawQuery("PRAGMA table_info(" + mTableName + ")", null);
+                mColumns = new HashMap<String, Integer>(cur.getCount());
+                while (cur.moveToNext()) {
+                    String columnName = cur.getString(TABLE_INFO_PRAGMA_COLUMNNAME_INDEX);
+                    String defaultValue = cur.getString(TABLE_INFO_PRAGMA_DEFAULT_INDEX);
+
+                    mColumns.put(columnName, i);
+                    sb.append("'");
+                    sb.append(columnName);
+                    sb.append("'");
+
+                    if (defaultValue == null) {
+                        sbv.append("?");
+                    } else {
+                        sbv.append("COALESCE(?, ");
+                        sbv.append(defaultValue);
+                        sbv.append(")");
+                    }
+
+                    sb.append(i == cur.getCount() ? ") " : ", ");
+                    sbv.append(i == cur.getCount() ? ");" : ", ");
+                    ++i;
+                }
+            } finally {
+                if (cur != null) cur.close();
+            }
+
+            sb.append(sbv);
+
+            mInsertSQL = sb.toString();
+            if (DEBUG) Log.v(TAG, "insert statement is " + mInsertSQL);
+        }
+
+        private SQLiteStatement getStatement(boolean allowReplace) throws SQLException {
+            if (allowReplace) {
+                if (mReplaceStatement == null) {
+                    if (mInsertSQL == null) buildSQL();
+                    // chop "INSERT" off the front and prepend "INSERT OR REPLACE" instead.
+                    String replaceSQL = "INSERT OR REPLACE" + mInsertSQL.substring(6);
+                    mReplaceStatement = mDb.compileStatement(replaceSQL);
+                }
+                return mReplaceStatement;
+            } else {
+                if (mInsertStatement == null) {
+                    if (mInsertSQL == null) buildSQL();
+                    mInsertStatement = mDb.compileStatement(mInsertSQL);
+                }
+                return mInsertStatement;
+            }
+        }
+
+        /**
+         * Performs an insert, adding a new row with the given values.
+         *
+         * @param values the set of values with which  to populate the
+         * new row
+         * @param allowReplace if true, the statement does "INSERT OR
+         *   REPLACE" instead of "INSERT", silently deleting any
+         *   previously existing rows that would cause a conflict
+         *
+         * @return the row ID of the newly inserted row, or -1 if an
+         * error occurred
+         */
+        private long insertInternal(ContentValues values, boolean allowReplace) {
+            // Start a transaction even though we don't really need one.
+            // This is to help maintain compatibility with applications that
+            // access InsertHelper from multiple threads even though they never should have.
+            // The original code used to lock the InsertHelper itself which was prone
+            // to deadlocks.  Starting a transaction achieves the same mutual exclusion
+            // effect as grabbing a lock but without the potential for deadlocks.
+            mDb.beginTransactionNonExclusive();
+            try {
+                SQLiteStatement stmt = getStatement(allowReplace);
+                stmt.clearBindings();
+                if (DEBUG) Log.v(TAG, "--- inserting in table " + mTableName);
+                for (Map.Entry<String, Object> e: values.valueSet()) {
+                    final String key = e.getKey();
+                    int i = getColumnIndex(key);
+                    DatabaseUtils.bindObjectToProgram(stmt, i, e.getValue());
+                    if (DEBUG) {
+                        Log.v(TAG, "binding " + e.getValue() + " to column " +
+                              i + " (" + key + ")");
+                    }
+                }
+                long result = stmt.executeInsert();
+                mDb.setTransactionSuccessful();
+                return result;
+            } catch (SQLException e) {
+                Log.e(TAG, "Error inserting " + values + " into table  " + mTableName, e);
+                return -1;
+            } finally {
+                mDb.endTransaction();
+            }
+        }
+
+        /**
+         * Returns the index of the specified column. This is index is suitagble for use
+         * in calls to bind().
+         * @param key the column name
+         * @return the index of the column
+         */
+        public int getColumnIndex(String key) {
+            getStatement(false);
+            final Integer index = mColumns.get(key);
+            if (index == null) {
+                throw new IllegalArgumentException("column '" + key + "' is invalid");
+            }
+            return index;
+        }
+
+        /**
+         * Bind the value to an index. A prepareForInsert() or prepareForReplace()
+         * without a matching execute() must have already have been called.
+         * @param index the index of the slot to which to bind
+         * @param value the value to bind
+         */
+        public void bind(int index, double value) {
+            mPreparedStatement.bindDouble(index, value);
+        }
+
+        /**
+         * Bind the value to an index. A prepareForInsert() or prepareForReplace()
+         * without a matching execute() must have already have been called.
+         * @param index the index of the slot to which to bind
+         * @param value the value to bind
+         */
+        public void bind(int index, float value) {
+            mPreparedStatement.bindDouble(index, value);
+        }
+
+        /**
+         * Bind the value to an index. A prepareForInsert() or prepareForReplace()
+         * without a matching execute() must have already have been called.
+         * @param index the index of the slot to which to bind
+         * @param value the value to bind
+         */
+        public void bind(int index, long value) {
+            mPreparedStatement.bindLong(index, value);
+        }
+
+        /**
+         * Bind the value to an index. A prepareForInsert() or prepareForReplace()
+         * without a matching execute() must have already have been called.
+         * @param index the index of the slot to which to bind
+         * @param value the value to bind
+         */
+        public void bind(int index, int value) {
+            mPreparedStatement.bindLong(index, value);
+        }
+
+        /**
+         * Bind the value to an index. A prepareForInsert() or prepareForReplace()
+         * without a matching execute() must have already have been called.
+         * @param index the index of the slot to which to bind
+         * @param value the value to bind
+         */
+        public void bind(int index, boolean value) {
+            mPreparedStatement.bindLong(index, value ? 1 : 0);
+        }
+
+        /**
+         * Bind null to an index. A prepareForInsert() or prepareForReplace()
+         * without a matching execute() must have already have been called.
+         * @param index the index of the slot to which to bind
+         */
+        public void bindNull(int index) {
+            mPreparedStatement.bindNull(index);
+        }
+
+        /**
+         * Bind the value to an index. A prepareForInsert() or prepareForReplace()
+         * without a matching execute() must have already have been called.
+         * @param index the index of the slot to which to bind
+         * @param value the value to bind
+         */
+        public void bind(int index, byte[] value) {
+            if (value == null) {
+                mPreparedStatement.bindNull(index);
+            } else {
+                mPreparedStatement.bindBlob(index, value);
+            }
+        }
+
+        /**
+         * Bind the value to an index. A prepareForInsert() or prepareForReplace()
+         * without a matching execute() must have already have been called.
+         * @param index the index of the slot to which to bind
+         * @param value the value to bind
+         */
+        public void bind(int index, String value) {
+            if (value == null) {
+                mPreparedStatement.bindNull(index);
+            } else {
+                mPreparedStatement.bindString(index, value);
+            }
+        }
+
+        /**
+         * Performs an insert, adding a new row with the given values.
+         * If the table contains conflicting rows, an error is
+         * returned.
+         *
+         * @param values the set of values with which to populate the
+         * new row
+         *
+         * @return the row ID of the newly inserted row, or -1 if an
+         * error occurred
+         */
+        public long insert(ContentValues values) {
+            return insertInternal(values, false);
+        }
+
+        /**
+         * Execute the previously prepared insert or replace using the bound values
+         * since the last call to prepareForInsert or prepareForReplace.
+         *
+         * <p>Note that calling bind() and then execute() is not thread-safe. The only thread-safe
+         * way to use this class is to call insert() or replace().
+         *
+         * @return the row ID of the newly inserted row, or -1 if an
+         * error occurred
+         */
+        public long execute() {
+            if (mPreparedStatement == null) {
+                throw new IllegalStateException("you must prepare this inserter before calling "
+                        + "execute");
+            }
+            try {
+                if (DEBUG) Log.v(TAG, "--- doing insert or replace in table " + mTableName);
+                return mPreparedStatement.executeInsert();
+            } catch (SQLException e) {
+                Log.e(TAG, "Error executing InsertHelper with table " + mTableName, e);
+                return -1;
+            } finally {
+                // you can only call this once per prepare
+                mPreparedStatement = null;
+            }
+        }
+
+        /**
+         * Prepare the InsertHelper for an insert. The pattern for this is:
+         * <ul>
+         * <li>prepareForInsert()
+         * <li>bind(index, value);
+         * <li>bind(index, value);
+         * <li>...
+         * <li>bind(index, value);
+         * <li>execute();
+         * </ul>
+         */
+        public void prepareForInsert() {
+            mPreparedStatement = getStatement(false);
+            mPreparedStatement.clearBindings();
+        }
+
+        /**
+         * Prepare the InsertHelper for a replace. The pattern for this is:
+         * <ul>
+         * <li>prepareForReplace()
+         * <li>bind(index, value);
+         * <li>bind(index, value);
+         * <li>...
+         * <li>bind(index, value);
+         * <li>execute();
+         * </ul>
+         */
+        public void prepareForReplace() {
+            mPreparedStatement = getStatement(true);
+            mPreparedStatement.clearBindings();
+        }
+
+        /**
+         * Performs an insert, adding a new row with the given values.
+         * If the table contains conflicting rows, they are deleted
+         * and replaced with the new row.
+         *
+         * @param values the set of values with which to populate the
+         * new row
+         *
+         * @return the row ID of the newly inserted row, or -1 if an
+         * error occurred
+         */
+        public long replace(ContentValues values) {
+            return insertInternal(values, true);
+        }
+
+        /**
+         * Close this object and release any resources associated with
+         * it.  The behavior of calling <code>insert()</code> after
+         * calling this method is undefined.
+         */
+        public void close() {
+            if (mInsertStatement != null) {
+                mInsertStatement.close();
+                mInsertStatement = null;
+            }
+            if (mReplaceStatement != null) {
+                mReplaceStatement.close();
+                mReplaceStatement = null;
+            }
+            mInsertSQL = null;
+            mColumns = null;
+        }
+    }
+
+    /**
+     * Creates a db and populates it with the sql statements in sqlStatements.
+     *
+     * @param context the context to use to create the db
+     * @param dbName the name of the db to create
+     * @param dbVersion the version to set on the db
+     * @param sqlStatements the statements to use to populate the db. This should be a single string
+     *   of the form returned by sqlite3's <tt>.dump</tt> command (statements separated by
+     *   semicolons)
+     */
+    static public void createDbFromSqlStatements(
+            Context context, String dbName, int dbVersion, String sqlStatements) {
+        SQLiteDatabase db = context.openOrCreateDatabase(dbName, 0, null);
+        // TODO: this is not quite safe since it assumes that all semicolons at the end of a line
+        // terminate statements. It is possible that a text field contains ;\n. We will have to fix
+        // this if that turns out to be a problem.
+        String[] statements = TextUtils.split(sqlStatements, ";\n");
+        for (String statement : statements) {
+            if (TextUtils.isEmpty(statement)) continue;
+            db.execSQL(statement);
+        }
+        db.setVersion(dbVersion);
+        db.close();
+    }
+
+    /**
+     * Returns one of the following which represent the type of the given SQL statement.
+     * <ol>
+     *   <li>{@link #STATEMENT_SELECT}</li>
+     *   <li>{@link #STATEMENT_UPDATE}</li>
+     *   <li>{@link #STATEMENT_ATTACH}</li>
+     *   <li>{@link #STATEMENT_BEGIN}</li>
+     *   <li>{@link #STATEMENT_COMMIT}</li>
+     *   <li>{@link #STATEMENT_ABORT}</li>
+     *   <li>{@link #STATEMENT_OTHER}</li>
+     * </ol>
+     * @param sql the SQL statement whose type is returned by this method
+     * @return one of the values listed above
+     */
+    public static int getSqlStatementType(String sql) {
+        sql = sql.trim();
+        if (sql.length() < 3) {
+            return STATEMENT_OTHER;
+        }
+        String prefixSql = sql.substring(0, 3).toUpperCase(Locale.ROOT);
+        if (prefixSql.equals("SEL")) {
+            return STATEMENT_SELECT;
+        } else if (prefixSql.equals("INS") ||
+                prefixSql.equals("UPD") ||
+                prefixSql.equals("REP") ||
+                prefixSql.equals("DEL")) {
+            return STATEMENT_UPDATE;
+        } else if (prefixSql.equals("ATT")) {
+            return STATEMENT_ATTACH;
+        } else if (prefixSql.equals("COM")) {
+            return STATEMENT_COMMIT;
+        } else if (prefixSql.equals("END")) {
+            return STATEMENT_COMMIT;
+        } else if (prefixSql.equals("ROL")) {
+            boolean isRollbackToSavepoint = sql.toUpperCase(Locale.ROOT).contains(" TO ");
+            if (isRollbackToSavepoint) {
+                Log.w(TAG, "Statement '" + sql
+                        + "' may not work on API levels 16-27, use ';" + sql + "' instead");
+                return STATEMENT_OTHER;
+            }
+            return STATEMENT_ABORT;
+        } else if (prefixSql.equals("BEG")) {
+            return STATEMENT_BEGIN;
+        } else if (prefixSql.equals("PRA")) {
+            return STATEMENT_PRAGMA;
+        } else if (prefixSql.equals("CRE") || prefixSql.equals("DRO") ||
+                prefixSql.equals("ALT")) {
+            return STATEMENT_DDL;
+        } else if (prefixSql.equals("ANA") || prefixSql.equals("DET")) {
+            return STATEMENT_UNPREPARED;
+        }
+        return STATEMENT_OTHER;
+    }
+
+    /**
+     * Appends one set of selection args to another. This is useful when adding a selection
+     * argument to a user provided set.
+     */
+    public static String[] appendSelectionArgs(String[] originalValues, String[] newValues) {
+        if (originalValues == null || originalValues.length == 0) {
+            return newValues;
+        }
+        String[] result = new String[originalValues.length + newValues.length ];
+        System.arraycopy(originalValues, 0, result, 0, originalValues.length);
+        System.arraycopy(newValues, 0, result, originalValues.length, newValues.length);
+        return result;
+    }
+
+    /**
+     * Returns column index of "_id" column, or -1 if not found.
+     * @hide
+     */
+    public static int findRowIdColumnIndex(String[] columnNames) {
+        int length = columnNames.length;
+        for (int i = 0; i < length; i++) {
+            if (columnNames[i].equals("_id")) {
+                return i;
+            }
+        }
+        return -1;
+    }
+
+    /**
+     * Escape the given argument for use in a {@code LIKE} statement.
+     * @hide
+     */
+    public static String escapeForLike(@NonNull String arg) {
+        // Shamelessly borrowed from com.android.providers.media.util.DatabaseUtils
+        final StringBuilder sb = new StringBuilder();
+        for (int i = 0; i < arg.length(); i++) {
+            final char c = arg.charAt(i);
+            switch (c) {
+                case '%': sb.append('\\');
+                    break;
+                case '_': sb.append('\\');
+                    break;
+            }
+            sb.append(c);
+        }
+        return sb.toString();
+    }
+}
diff --git a/android/database/DefaultDatabaseErrorHandler.java b/android/database/DefaultDatabaseErrorHandler.java
new file mode 100644
index 0000000..cf019e1
--- /dev/null
+++ b/android/database/DefaultDatabaseErrorHandler.java
@@ -0,0 +1,109 @@
+/*
+ * 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.database;
+
+import android.database.sqlite.SQLiteDatabase;
+import android.database.sqlite.SQLiteException;
+import android.util.Log;
+import android.util.Pair;
+
+import java.io.File;
+import java.util.List;
+
+/**
+ * Default class used to define the action to take when database corruption is reported
+ * by sqlite.
+ * <p>
+ * An application can specify an implementation of {@link DatabaseErrorHandler} on the
+ * following:
+ * <ul>
+ *   <li>{@link SQLiteDatabase#openOrCreateDatabase(String,
+ *      android.database.sqlite.SQLiteDatabase.CursorFactory, DatabaseErrorHandler)}</li>
+ *   <li>{@link SQLiteDatabase#openDatabase(String,
+ *      android.database.sqlite.SQLiteDatabase.CursorFactory, int, DatabaseErrorHandler)}</li>
+ * </ul>
+ * The specified {@link DatabaseErrorHandler} is used to handle database corruption errors, if they
+ * occur.
+ * <p>
+ * If null is specified for the DatabaseErrorHandler param in the above calls, this class is used
+ * as the default {@link DatabaseErrorHandler}.
+ */
+public final class DefaultDatabaseErrorHandler implements DatabaseErrorHandler {
+
+    private static final String TAG = "DefaultDatabaseErrorHandler";
+
+    /**
+     * defines the default method to be invoked when database corruption is detected.
+     * @param dbObj the {@link SQLiteDatabase} object representing the database on which corruption
+     * is detected.
+     */
+    public void onCorruption(SQLiteDatabase dbObj) {
+        Log.e(TAG, "Corruption reported by sqlite on database: " + dbObj.getPath());
+        SQLiteDatabase.wipeDetected(dbObj.getPath(), "corruption");
+
+        // is the corruption detected even before database could be 'opened'?
+        if (!dbObj.isOpen()) {
+            // database files are not even openable. delete this database file.
+            // NOTE if the database has attached databases, then any of them could be corrupt.
+            // and not deleting all of them could cause corrupted database file to remain and 
+            // make the application crash on database open operation. To avoid this problem,
+            // the application should provide its own {@link DatabaseErrorHandler} impl class
+            // to delete ALL files of the database (including the attached databases).
+            deleteDatabaseFile(dbObj.getPath());
+            return;
+        }
+
+        List<Pair<String, String>> attachedDbs = null;
+        try {
+            // Close the database, which will cause subsequent operations to fail.
+            // before that, get the attached database list first.
+            try {
+                attachedDbs = dbObj.getAttachedDbs();
+            } catch (SQLiteException e) {
+                /* ignore */
+            }
+            try {
+                dbObj.close();
+            } catch (SQLiteException e) {
+                /* ignore */
+            }
+        } finally {
+            // Delete all files of this corrupt database and/or attached databases
+            if (attachedDbs != null) {
+                for (Pair<String, String> p : attachedDbs) {
+                    deleteDatabaseFile(p.second);
+                }
+            } else {
+                // attachedDbs = null is possible when the database is so corrupt that even
+                // "PRAGMA database_list;" also fails. delete the main database file
+                deleteDatabaseFile(dbObj.getPath());
+            }
+        }
+    }
+
+    private void deleteDatabaseFile(String fileName) {
+        if (fileName.equalsIgnoreCase(":memory:") || fileName.trim().length() == 0) {
+            return;
+        }
+        Log.e(TAG, "deleting the database file: " + fileName);
+        try {
+            SQLiteDatabase.deleteDatabase(new File(fileName), /*removeCheckFile=*/ false);
+        } catch (Exception e) {
+            /* print warning and ignore exception */
+            Log.w(TAG, "delete failed: " + e.getMessage());
+        }
+    }
+}
diff --git a/android/database/IBulkCursor.java b/android/database/IBulkCursor.java
new file mode 100644
index 0000000..b551116
--- /dev/null
+++ b/android/database/IBulkCursor.java
@@ -0,0 +1,66 @@
+/*
+ * Copyright (C) 2006 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.database;
+
+import android.os.Bundle;
+import android.os.IBinder;
+import android.os.IInterface;
+import android.os.RemoteException;
+
+/**
+ * This interface provides a low-level way to pass bulk cursor data across
+ * both process and language boundaries. Application code should use the Cursor
+ * interface directly.
+ *
+ * {@hide}
+ */
+public interface IBulkCursor extends IInterface  {
+    /**
+     * Gets a cursor window that contains the specified position.
+     * The window will contain a range of rows around the specified position.
+     */
+    public CursorWindow getWindow(int position) throws RemoteException;
+
+    /**
+     * Notifies the cursor that the position has changed.
+     * Only called when {@link #getWantsAllOnMoveCalls()} returns true.
+     *
+     * @param position The new position
+     */
+    public void onMove(int position) throws RemoteException;
+
+    public void deactivate() throws RemoteException;
+
+    public void close() throws RemoteException;
+
+    public int requery(IContentObserver observer) throws RemoteException;
+
+    Bundle getExtras() throws RemoteException;
+
+    Bundle respond(Bundle extras) throws RemoteException;
+
+    /* IPC constants */
+    static final String descriptor = "android.content.IBulkCursor";
+
+    static final int GET_CURSOR_WINDOW_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION;
+    static final int DEACTIVATE_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION + 1;
+    static final int REQUERY_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION + 2;
+    static final int ON_MOVE_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION + 3;
+    static final int GET_EXTRAS_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION + 4;
+    static final int RESPOND_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION + 5;
+    static final int CLOSE_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION + 6;
+}
diff --git a/android/database/MatrixCursor.java b/android/database/MatrixCursor.java
new file mode 100644
index 0000000..050a49a
--- /dev/null
+++ b/android/database/MatrixCursor.java
@@ -0,0 +1,326 @@
+/*
+ * 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.database;
+
+import android.compat.annotation.UnsupportedAppUsage;
+import android.os.Build;
+
+import java.util.ArrayList;
+
+/**
+ * A mutable cursor implementation backed by an array of {@code Object}s. Use
+ * {@link #newRow()} to add rows. Automatically expands internal capacity
+ * as needed.
+ */
+public class MatrixCursor extends AbstractCursor {
+
+    private final String[] columnNames;
+    @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023)
+    private Object[] data;
+    @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023)
+    private int rowCount = 0;
+    private final int columnCount;
+
+    /**
+     * Constructs a new cursor with the given initial capacity.
+     *
+     * @param columnNames names of the columns, the ordering of which
+     *  determines column ordering elsewhere in this cursor
+     * @param initialCapacity in rows
+     */
+    public MatrixCursor(String[] columnNames, int initialCapacity) {
+        this.columnNames = columnNames;
+        this.columnCount = columnNames.length;
+
+        if (initialCapacity < 1) {
+            initialCapacity = 1;
+        }
+
+        this.data = new Object[columnCount * initialCapacity];
+    }
+
+    /**
+     * Constructs a new cursor.
+     *
+     * @param columnNames names of the columns, the ordering of which
+     *  determines column ordering elsewhere in this cursor
+     */
+    public MatrixCursor(String[] columnNames) {
+        this(columnNames, 16);
+    }
+
+    /**
+     * Gets value at the given column for the current row.
+     */
+    @UnsupportedAppUsage
+    private Object get(int column) {
+        if (column < 0 || column >= columnCount) {
+            throw new CursorIndexOutOfBoundsException("Requested column: "
+                    + column + ", # of columns: " +  columnCount);
+        }
+        if (mPos < 0) {
+            throw new CursorIndexOutOfBoundsException("Before first row.");
+        }
+        if (mPos >= rowCount) {
+            throw new CursorIndexOutOfBoundsException("After last row.");
+        }
+        return data[mPos * columnCount + column];
+    }
+
+    /**
+     * Adds a new row to the end and returns a builder for that row. Not safe
+     * for concurrent use.
+     *
+     * @return builder which can be used to set the column values for the new
+     *  row
+     */
+    public RowBuilder newRow() {
+        final int row = rowCount++;
+        final int endIndex = rowCount * columnCount;
+        ensureCapacity(endIndex);
+        return new RowBuilder(row);
+    }
+
+    /**
+     * Adds a new row to the end with the given column values. Not safe
+     * for concurrent use.
+     *
+     * @throws IllegalArgumentException if {@code columnValues.length !=
+     *  columnNames.length}
+     * @param columnValues in the same order as the the column names specified
+     *  at cursor construction time
+     */
+    public void addRow(Object[] columnValues) {
+        if (columnValues.length != columnCount) {
+            throw new IllegalArgumentException("columnNames.length = "
+                    + columnCount + ", columnValues.length = "
+                    + columnValues.length);
+        }
+
+        int start = rowCount++ * columnCount;
+        ensureCapacity(start + columnCount);
+        System.arraycopy(columnValues, 0, data, start, columnCount);
+    }
+
+    /**
+     * Adds a new row to the end with the given column values. Not safe
+     * for concurrent use.
+     *
+     * @throws IllegalArgumentException if {@code columnValues.size() !=
+     *  columnNames.length}
+     * @param columnValues in the same order as the the column names specified
+     *  at cursor construction time
+     */
+    public void addRow(Iterable<?> columnValues) {
+        int start = rowCount * columnCount;
+        int end = start + columnCount;
+        ensureCapacity(end);
+
+        if (columnValues instanceof ArrayList<?>) {
+            addRow((ArrayList<?>) columnValues, start);
+            return;
+        }
+
+        int current = start;
+        Object[] localData = data;
+        for (Object columnValue : columnValues) {
+            if (current == end) {
+                // TODO: null out row?
+                throw new IllegalArgumentException(
+                        "columnValues.size() > columnNames.length");
+            }
+            localData[current++] = columnValue;
+        }
+
+        if (current != end) {
+            // TODO: null out row?
+            throw new IllegalArgumentException(
+                    "columnValues.size() < columnNames.length");
+        }
+
+        // Increase row count here in case we encounter an exception.
+        rowCount++;
+    }
+
+    /** Optimization for {@link ArrayList}. */
+    private void addRow(ArrayList<?> columnValues, int start) {
+        int size = columnValues.size();
+        if (size != columnCount) {
+            throw new IllegalArgumentException("columnNames.length = "
+                    + columnCount + ", columnValues.size() = " + size);
+        }
+
+        rowCount++;
+        Object[] localData = data;
+        for (int i = 0; i < size; i++) {
+            localData[start + i] = columnValues.get(i);
+        }
+    }
+
+    /** Ensures that this cursor has enough capacity. */
+    private void ensureCapacity(int size) {
+        if (size > data.length) {
+            Object[] oldData = this.data;
+            int newSize = data.length * 2;
+            if (newSize < size) {
+                newSize = size;
+            }
+            this.data = new Object[newSize];
+            System.arraycopy(oldData, 0, this.data, 0, oldData.length);
+        }
+    }
+
+    /**
+     * Builds a row of values using either of these approaches:
+     * <ul>
+     * <li>Values can be added with explicit column ordering using
+     * {@link #add(Object)}, which starts from the left-most column and adds one
+     * column value at a time. This follows the same ordering as the column
+     * names specified at cursor construction time.
+     * <li>Column and value pairs can be offered for possible inclusion using
+     * {@link #add(String, Object)}. If the cursor includes the given column,
+     * the value will be set for that column, otherwise the value is ignored.
+     * This approach is useful when matching data to a custom projection.
+     * </ul>
+     * Undefined values are left as {@code null}.
+     */
+    public class RowBuilder {
+        private final int row;
+        private final int endIndex;
+
+        private int index;
+
+        RowBuilder(int row) {
+            this.row = row;
+            this.index = row * columnCount;
+            this.endIndex = index + columnCount;
+        }
+
+        /**
+         * Sets the next column value in this row.
+         *
+         * @throws CursorIndexOutOfBoundsException if you try to add too many
+         *  values
+         * @return this builder to support chaining
+         */
+        public RowBuilder add(Object columnValue) {
+            if (index == endIndex) {
+                throw new CursorIndexOutOfBoundsException(
+                        "No more columns left.");
+            }
+
+            data[index++] = columnValue;
+            return this;
+        }
+
+        /**
+         * Offer value for possible inclusion if this cursor defines the given
+         * column. Columns not defined by the cursor are silently ignored.
+         *
+         * @return this builder to support chaining
+         */
+        public RowBuilder add(String columnName, Object value) {
+            for (int i = 0; i < columnNames.length; i++) {
+                if (columnName.equals(columnNames[i])) {
+                    data[(row * columnCount) + i] = value;
+                }
+            }
+            return this;
+        }
+
+        /** @hide */
+        public final RowBuilder add(int columnIndex, Object value) {
+            data[(row * columnCount) + columnIndex] = value;
+            return this;
+        }
+    }
+
+    // AbstractCursor implementation.
+
+    @Override
+    public int getCount() {
+        return rowCount;
+    }
+
+    @Override
+    public String[] getColumnNames() {
+        return columnNames;
+    }
+
+    @Override
+    public String getString(int column) {
+        Object value = get(column);
+        if (value == null) return null;
+        return value.toString();
+    }
+
+    @Override
+    public short getShort(int column) {
+        Object value = get(column);
+        if (value == null) return 0;
+        if (value instanceof Number) return ((Number) value).shortValue();
+        return Short.parseShort(value.toString());
+    }
+
+    @Override
+    public int getInt(int column) {
+        Object value = get(column);
+        if (value == null) return 0;
+        if (value instanceof Number) return ((Number) value).intValue();
+        return Integer.parseInt(value.toString());
+    }
+
+    @Override
+    public long getLong(int column) {
+        Object value = get(column);
+        if (value == null) return 0;
+        if (value instanceof Number) return ((Number) value).longValue();
+        return Long.parseLong(value.toString());
+    }
+
+    @Override
+    public float getFloat(int column) {
+        Object value = get(column);
+        if (value == null) return 0.0f;
+        if (value instanceof Number) return ((Number) value).floatValue();
+        return Float.parseFloat(value.toString());
+    }
+
+    @Override
+    public double getDouble(int column) {
+        Object value = get(column);
+        if (value == null) return 0.0d;
+        if (value instanceof Number) return ((Number) value).doubleValue();
+        return Double.parseDouble(value.toString());
+    }
+
+    @Override
+    public byte[] getBlob(int column) {
+        Object value = get(column);
+        return (byte[]) value;
+    }
+
+    @Override
+    public int getType(int column) {
+        return DatabaseUtils.getTypeOfObject(get(column));
+    }
+
+    @Override
+    public boolean isNull(int column) {
+        return get(column) == null;
+    }
+}
diff --git a/android/database/MergeCursor.java b/android/database/MergeCursor.java
new file mode 100644
index 0000000..272cfa2
--- /dev/null
+++ b/android/database/MergeCursor.java
@@ -0,0 +1,238 @@
+/*
+ * Copyright (C) 2006 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.database;
+
+/**
+ * A convenience class that lets you present an array of Cursors as a single linear Cursor.
+ * The schema of the cursors presented is entirely up to the creator of the MergeCursor, and
+ * may be different if that is desired. Calls to getColumns, getColumnIndex, etc will return the
+ * value for the row that the MergeCursor is currently pointing at.
+ */
+public class MergeCursor extends AbstractCursor
+{
+    private DataSetObserver mObserver = new DataSetObserver() {
+
+        @Override
+        public void onChanged() {
+            // Reset our position so the optimizations in move-related code
+            // don't screw us over
+            mPos = -1;
+        }
+
+        @Override
+        public void onInvalidated() {
+            mPos = -1;
+        }
+    };
+    
+    public MergeCursor(Cursor[] cursors)
+    {
+        mCursors = cursors;
+        mCursor = cursors[0];
+        
+        for (int i = 0; i < mCursors.length; i++) {
+            if (mCursors[i] == null) continue;
+            
+            mCursors[i].registerDataSetObserver(mObserver);
+        }
+    }
+    
+    @Override
+    public int getCount()
+    {
+        int count = 0;
+        int length = mCursors.length;
+        for (int i = 0 ; i < length ; i++) {
+            if (mCursors[i] != null) {
+                count += mCursors[i].getCount();
+            }
+        }
+        return count;
+    }
+
+    @Override
+    public boolean onMove(int oldPosition, int newPosition)
+    {
+        /* Find the right cursor */
+        mCursor = null;
+        int cursorStartPos = 0;
+        int length = mCursors.length;
+        for (int i = 0 ; i < length; i++) {
+            if (mCursors[i] == null) {
+                continue;
+            }
+            
+            if (newPosition < (cursorStartPos + mCursors[i].getCount())) {
+                mCursor = mCursors[i];
+                break;
+            }
+
+            cursorStartPos += mCursors[i].getCount();
+        }
+
+        /* Move it to the right position */
+        if (mCursor != null) {
+            boolean ret = mCursor.moveToPosition(newPosition - cursorStartPos);
+            return ret;
+        }
+        return false;
+    }
+
+    @Override
+    public String getString(int column)
+    {
+        return mCursor.getString(column);
+    }
+
+    @Override
+    public short getShort(int column)
+    {
+        return mCursor.getShort(column);
+    }
+
+    @Override
+    public int getInt(int column)
+    {
+        return mCursor.getInt(column);
+    }
+
+    @Override
+    public long getLong(int column)
+    {
+        return mCursor.getLong(column);
+    }
+
+    @Override
+    public float getFloat(int column)
+    {
+        return mCursor.getFloat(column);
+    }
+
+    @Override
+    public double getDouble(int column)
+    {
+        return mCursor.getDouble(column);
+    }
+
+    @Override
+    public int getType(int column) {
+        return mCursor.getType(column);
+    }
+
+    @Override
+    public boolean isNull(int column)
+    {
+        return mCursor.isNull(column);
+    }
+
+    @Override
+    public byte[] getBlob(int column)
+    {
+        return mCursor.getBlob(column);   
+    }
+
+    @Override
+    public String[] getColumnNames()
+    {
+        if (mCursor != null) {
+            return mCursor.getColumnNames();
+        } else {
+            return new String[0];
+        }
+    }
+    
+    @Override
+    public void deactivate()
+    {
+        int length = mCursors.length;
+        for (int i = 0 ; i < length ; i++) {
+            if (mCursors[i] != null) {
+                mCursors[i].deactivate();
+            }
+        }
+        super.deactivate();
+    }
+
+    @Override
+    public void close() {
+        int length = mCursors.length;
+        for (int i = 0 ; i < length ; i++) {
+            if (mCursors[i] == null) continue;
+            mCursors[i].close();
+        }
+        super.close();
+    }
+
+    @Override
+    public void registerContentObserver(ContentObserver observer) {
+        int length = mCursors.length;
+        for (int i = 0 ; i < length ; i++) {
+            if (mCursors[i] != null) {
+                mCursors[i].registerContentObserver(observer);
+            }
+        }
+    }
+    @Override
+    public void unregisterContentObserver(ContentObserver observer) {
+        int length = mCursors.length;
+        for (int i = 0 ; i < length ; i++) {
+            if (mCursors[i] != null) {
+                mCursors[i].unregisterContentObserver(observer);
+            }
+        }
+    }
+    
+    @Override
+    public void registerDataSetObserver(DataSetObserver observer) {
+        int length = mCursors.length;
+        for (int i = 0 ; i < length ; i++) {
+            if (mCursors[i] != null) {
+                mCursors[i].registerDataSetObserver(observer);
+            }
+        }
+    }
+    
+    @Override
+    public void unregisterDataSetObserver(DataSetObserver observer) {
+        int length = mCursors.length;
+        for (int i = 0 ; i < length ; i++) {
+            if (mCursors[i] != null) {
+                mCursors[i].unregisterDataSetObserver(observer);
+            }
+        }
+    }
+
+    @Override
+    public boolean requery()
+    {
+        int length = mCursors.length;
+        for (int i = 0 ; i < length ; i++) {
+            if (mCursors[i] == null) {
+                continue;
+            }
+
+            if (mCursors[i].requery() == false) {
+                return false;
+            }
+        }
+
+        return true;
+    }
+
+    private Cursor mCursor; // updated in onMove
+    private Cursor[] mCursors;
+}
diff --git a/android/database/Observable.java b/android/database/Observable.java
new file mode 100644
index 0000000..aff32db
--- /dev/null
+++ b/android/database/Observable.java
@@ -0,0 +1,83 @@
+/*
+ * 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.database;
+
+import java.util.ArrayList;
+
+/**
+ * Provides methods for registering or unregistering arbitrary observers in an {@link ArrayList}.
+ *
+ * This abstract class is intended to be subclassed and specialized to maintain
+ * a registry of observers of specific types and dispatch notifications to them.
+ *
+ * @param T The observer type.
+ */
+public abstract class Observable<T> {
+    /**
+     * The list of observers.  An observer can be in the list at most
+     * once and will never be null.
+     */
+    protected final ArrayList<T> mObservers = new ArrayList<T>();
+
+    /**
+     * Adds an observer to the list. The observer cannot be null and it must not already
+     * be registered.
+     * @param observer the observer to register
+     * @throws IllegalArgumentException the observer is null
+     * @throws IllegalStateException the observer is already registered
+     */
+    public void registerObserver(T observer) {
+        if (observer == null) {
+            throw new IllegalArgumentException("The observer is null.");
+        }
+        synchronized(mObservers) {
+            if (mObservers.contains(observer)) {
+                throw new IllegalStateException("Observer " + observer + " is already registered.");
+            }
+            mObservers.add(observer);
+        }
+    }
+
+    /**
+     * Removes a previously registered observer. The observer must not be null and it
+     * must already have been registered.
+     * @param observer the observer to unregister
+     * @throws IllegalArgumentException the observer is null
+     * @throws IllegalStateException the observer is not yet registered
+     */
+    public void unregisterObserver(T observer) {
+        if (observer == null) {
+            throw new IllegalArgumentException("The observer is null.");
+        }
+        synchronized(mObservers) {
+            int index = mObservers.indexOf(observer);
+            if (index == -1) {
+                throw new IllegalStateException("Observer " + observer + " was not registered.");
+            }
+            mObservers.remove(index);
+        }
+    }
+
+    /**
+     * Remove all registered observers.
+     */
+    public void unregisterAll() {
+        synchronized(mObservers) {
+            mObservers.clear();
+        }
+    }
+}
diff --git a/android/database/RedactingCursor.java b/android/database/RedactingCursor.java
new file mode 100644
index 0000000..6322d56
--- /dev/null
+++ b/android/database/RedactingCursor.java
@@ -0,0 +1,181 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.database;
+
+import android.annotation.NonNull;
+import android.util.SparseArray;
+
+import java.util.Map;
+
+/**
+ * Cursor that offers to redact values of requested columns.
+ *
+ * @hide
+ */
+public class RedactingCursor extends CrossProcessCursorWrapper {
+    private final SparseArray<Object> mRedactions;
+
+    private RedactingCursor(@NonNull Cursor cursor, SparseArray<Object> redactions) {
+        super(cursor);
+        mRedactions = redactions;
+    }
+
+    /**
+     * Create a wrapped instance of the given {@link Cursor} which redacts the
+     * requested columns so they always return specific values when accessed.
+     * <p>
+     * If a redacted column appears multiple times in the underlying cursor, all
+     * instances will be redacted. If none of the redacted columns appear in the
+     * given cursor, the given cursor will be returned untouched to improve
+     * performance.
+     */
+    public static Cursor create(@NonNull Cursor cursor, @NonNull Map<String, Object> redactions) {
+        final SparseArray<Object> internalRedactions = new SparseArray<>();
+
+        final String[] columns = cursor.getColumnNames();
+        for (int i = 0; i < columns.length; i++) {
+            if (redactions.containsKey(columns[i])) {
+                internalRedactions.put(i, redactions.get(columns[i]));
+            }
+        }
+
+        if (internalRedactions.size() == 0) {
+            return cursor;
+        } else {
+            return new RedactingCursor(cursor, internalRedactions);
+        }
+    }
+
+    @Override
+    public void fillWindow(int position, CursorWindow window) {
+        // Fill window directly to ensure data is redacted
+        DatabaseUtils.cursorFillWindow(this, position, window);
+    }
+
+    @Override
+    public CursorWindow getWindow() {
+        // Returning underlying window risks leaking redacted data
+        return null;
+    }
+
+    @Override
+    public Cursor getWrappedCursor() {
+        throw new UnsupportedOperationException(
+                "Returning underlying cursor risks leaking redacted data");
+    }
+
+    @Override
+    public double getDouble(int columnIndex) {
+        final int i = mRedactions.indexOfKey(columnIndex);
+        if (i >= 0) {
+            return (double) mRedactions.valueAt(i);
+        } else {
+            return super.getDouble(columnIndex);
+        }
+    }
+
+    @Override
+    public float getFloat(int columnIndex) {
+        final int i = mRedactions.indexOfKey(columnIndex);
+        if (i >= 0) {
+            return (float) mRedactions.valueAt(i);
+        } else {
+            return super.getFloat(columnIndex);
+        }
+    }
+
+    @Override
+    public int getInt(int columnIndex) {
+        final int i = mRedactions.indexOfKey(columnIndex);
+        if (i >= 0) {
+            return (int) mRedactions.valueAt(i);
+        } else {
+            return super.getInt(columnIndex);
+        }
+    }
+
+    @Override
+    public long getLong(int columnIndex) {
+        final int i = mRedactions.indexOfKey(columnIndex);
+        if (i >= 0) {
+            return (long) mRedactions.valueAt(i);
+        } else {
+            return super.getLong(columnIndex);
+        }
+    }
+
+    @Override
+    public short getShort(int columnIndex) {
+        final int i = mRedactions.indexOfKey(columnIndex);
+        if (i >= 0) {
+            return (short) mRedactions.valueAt(i);
+        } else {
+            return super.getShort(columnIndex);
+        }
+    }
+
+    @Override
+    public String getString(int columnIndex) {
+        final int i = mRedactions.indexOfKey(columnIndex);
+        if (i >= 0) {
+            return (String) mRedactions.valueAt(i);
+        } else {
+            return super.getString(columnIndex);
+        }
+    }
+
+    @Override
+    public void copyStringToBuffer(int columnIndex, CharArrayBuffer buffer) {
+        final int i = mRedactions.indexOfKey(columnIndex);
+        if (i >= 0) {
+            buffer.data = ((String) mRedactions.valueAt(i)).toCharArray();
+            buffer.sizeCopied = buffer.data.length;
+        } else {
+            super.copyStringToBuffer(columnIndex, buffer);
+        }
+    }
+
+    @Override
+    public byte[] getBlob(int columnIndex) {
+        final int i = mRedactions.indexOfKey(columnIndex);
+        if (i >= 0) {
+            return (byte[]) mRedactions.valueAt(i);
+        } else {
+            return super.getBlob(columnIndex);
+        }
+    }
+
+    @Override
+    public int getType(int columnIndex) {
+        final int i = mRedactions.indexOfKey(columnIndex);
+        if (i >= 0) {
+            return DatabaseUtils.getTypeOfObject(mRedactions.valueAt(i));
+        } else {
+            return super.getType(columnIndex);
+        }
+    }
+
+    @Override
+    public boolean isNull(int columnIndex) {
+        final int i = mRedactions.indexOfKey(columnIndex);
+        if (i >= 0) {
+            return mRedactions.valueAt(i) == null;
+        } else {
+            return super.isNull(columnIndex);
+        }
+    }
+}
diff --git a/android/database/SQLException.java b/android/database/SQLException.java
new file mode 100644
index 0000000..3402026
--- /dev/null
+++ b/android/database/SQLException.java
@@ -0,0 +1,33 @@
+/*
+ * Copyright (C) 2006 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.database;
+
+/**
+ * An exception that indicates there was an error with SQL parsing or execution.
+ */
+public class SQLException extends RuntimeException {
+    public SQLException() {
+    }
+
+    public SQLException(String error) {
+        super(error);
+    }
+
+    public SQLException(String error, Throwable cause) {
+        super(error, cause);
+    }
+}
diff --git a/android/database/SQLiteDatabaseIoPerfTest.java b/android/database/SQLiteDatabaseIoPerfTest.java
new file mode 100644
index 0000000..830302e
--- /dev/null
+++ b/android/database/SQLiteDatabaseIoPerfTest.java
@@ -0,0 +1,177 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License
+ */
+
+package android.database;
+
+import static org.junit.Assert.assertEquals;
+
+import android.app.Activity;
+import android.content.ContentValues;
+import android.content.Context;
+import android.database.sqlite.SQLiteDatabase;
+import android.os.Bundle;
+import android.util.ArrayMap;
+import android.util.Log;
+
+import androidx.test.InstrumentationRegistry;
+import androidx.test.filters.LargeTest;
+import androidx.test.runner.AndroidJUnit4;
+
+import com.android.internal.util.Preconditions;
+
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import java.io.File;
+import java.io.IOException;
+import java.nio.file.Files;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * Performance tests for measuring amount of data written during typical DB operations
+ *
+ * <p>To run: bit CorePerfTests:android.database.SQLiteDatabaseIoPerfTest
+ */
+@RunWith(AndroidJUnit4.class)
+@LargeTest
+public class SQLiteDatabaseIoPerfTest {
+    private static final String TAG = "SQLiteDatabaseIoPerfTest";
+    private static final String DB_NAME = "db_io_perftest";
+    private static final int DEFAULT_DATASET_SIZE = 500;
+
+    private Long mWriteBytes;
+
+    private SQLiteDatabase mDatabase;
+    private Context mContext;
+
+    @Before
+    public void setUp() {
+        mContext = InstrumentationRegistry.getTargetContext();
+        mContext.deleteDatabase(DB_NAME);
+        mDatabase = mContext.openOrCreateDatabase(DB_NAME, Context.MODE_PRIVATE, null);
+        mDatabase.execSQL("CREATE TABLE T1 "
+                + "(_ID INTEGER PRIMARY KEY, COL_A INTEGER, COL_B VARCHAR(100), COL_C REAL)");
+    }
+
+    @After
+    public void tearDown() {
+        mDatabase.close();
+        mContext.deleteDatabase(DB_NAME);
+    }
+
+    @Test
+    public void testDatabaseModifications() {
+        startMeasuringWrites();
+        ContentValues cv = new ContentValues();
+        String[] whereArg = new String[1];
+        for (int i = 0; i < DEFAULT_DATASET_SIZE; i++) {
+            cv.put("_ID", i);
+            cv.put("COL_A", i);
+            cv.put("COL_B", "NewValue");
+            cv.put("COL_C", 1.0);
+            assertEquals(i, mDatabase.insert("T1", null, cv));
+        }
+        cv = new ContentValues();
+        for (int i = 0; i < DEFAULT_DATASET_SIZE; i++) {
+            cv.put("COL_B", "UpdatedValue");
+            cv.put("COL_C", 1.1);
+            whereArg[0] = String.valueOf(i);
+            assertEquals(1, mDatabase.update("T1", cv, "_ID=?", whereArg));
+        }
+        for (int i = 0; i < DEFAULT_DATASET_SIZE; i++) {
+            whereArg[0] = String.valueOf(i);
+            assertEquals(1, mDatabase.delete("T1", "_ID=?", whereArg));
+        }
+        // Make sure all changes are written to disk
+        mDatabase.close();
+        long bytes = endMeasuringWrites();
+        sendResults("testDatabaseModifications" , bytes);
+    }
+
+    @Test
+    public void testInsertsWithTransactions() {
+        startMeasuringWrites();
+        final int txSize = 10;
+        ContentValues cv = new ContentValues();
+        for (int i = 0; i < DEFAULT_DATASET_SIZE * 5; i++) {
+            if (i % txSize == 0) {
+                mDatabase.beginTransaction();
+            }
+            if (i % txSize == txSize-1) {
+                mDatabase.setTransactionSuccessful();
+                mDatabase.endTransaction();
+
+            }
+            cv.put("_ID", i);
+            cv.put("COL_A", i);
+            cv.put("COL_B", "NewValue");
+            cv.put("COL_C", 1.0);
+            assertEquals(i, mDatabase.insert("T1", null, cv));
+        }
+        // Make sure all changes are written to disk
+        mDatabase.close();
+        long bytes = endMeasuringWrites();
+        sendResults("testInsertsWithTransactions" , bytes);
+    }
+
+    private void startMeasuringWrites() {
+        Preconditions.checkState(mWriteBytes == null, "Measurement already started");
+        mWriteBytes = getIoStats().get("write_bytes");
+    }
+
+    private long endMeasuringWrites() {
+        Preconditions.checkState(mWriteBytes != null, "Measurement wasn't started");
+        Long newWriteBytes = getIoStats().get("write_bytes");
+        return newWriteBytes - mWriteBytes;
+    }
+
+    private void sendResults(String testName, long writeBytes) {
+        Log.i(TAG, testName + " write_bytes: " + writeBytes);
+        Bundle status = new Bundle();
+        status.putLong("write_bytes", writeBytes);
+        InstrumentationRegistry.getInstrumentation().sendStatus(Activity.RESULT_OK, status);
+    }
+
+    private static Map<String, Long> getIoStats() {
+        String ioStat = "/proc/self/io";
+        Map<String, Long> results = new ArrayMap<>();
+        try {
+            List<String> lines = Files.readAllLines(new File(ioStat).toPath());
+            for (String line : lines) {
+                line = line.trim();
+                String[] split = line.split(":");
+                if (split.length == 2) {
+                    try {
+                        String key = split[0].trim();
+                        Long value = Long.valueOf(split[1].trim());
+                        results.put(key, value);
+                    } catch (NumberFormatException e) {
+                        Log.e(TAG, "Cannot parse number from " + line);
+                    }
+                } else if (line.isEmpty()) {
+                    Log.e(TAG, "Cannot parse line " + line);
+                }
+            }
+        } catch (IOException e) {
+            Log.e(TAG, "Can't read: " + ioStat, e);
+        }
+        return results;
+    }
+
+}
diff --git a/android/database/SQLiteDatabasePerfTest.java b/android/database/SQLiteDatabasePerfTest.java
new file mode 100644
index 0000000..973e996
--- /dev/null
+++ b/android/database/SQLiteDatabasePerfTest.java
@@ -0,0 +1,274 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License
+ */
+
+package android.database;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+
+import android.content.ContentValues;
+import android.content.Context;
+import android.database.sqlite.SQLiteDatabase;
+import android.perftests.utils.BenchmarkState;
+import android.perftests.utils.PerfStatusReporter;
+
+import androidx.test.InstrumentationRegistry;
+import androidx.test.filters.LargeTest;
+import androidx.test.runner.AndroidJUnit4;
+
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import java.util.Random;
+
+/**
+ * Performance tests for typical CRUD operations and loading rows into the Cursor
+ *
+ * <p>To run: bit CorePerfTests:android.database.SQLiteDatabasePerfTest
+ */
+@RunWith(AndroidJUnit4.class)
+@LargeTest
+public class SQLiteDatabasePerfTest {
+    // TODO b/64262688 Add Concurrency tests to compare WAL vs DELETE read/write
+    private static final String DB_NAME = "dbperftest";
+    private static final int DEFAULT_DATASET_SIZE = 1000;
+
+    @Rule
+    public PerfStatusReporter mPerfStatusReporter = new PerfStatusReporter();
+    private SQLiteDatabase mDatabase;
+    private Context mContext;
+
+    @Before
+    public void setUp() {
+        mContext = InstrumentationRegistry.getTargetContext();
+        mContext.deleteDatabase(DB_NAME);
+        mDatabase = mContext.openOrCreateDatabase(DB_NAME, Context.MODE_PRIVATE, null);
+        mDatabase.execSQL("CREATE TABLE T1 "
+                + "(_ID INTEGER PRIMARY KEY, COL_A INTEGER, COL_B VARCHAR(100), COL_C REAL)");
+        mDatabase.execSQL("CREATE TABLE T2 ("
+                + "_ID INTEGER PRIMARY KEY, COL_A VARCHAR(100), T1_ID INTEGER,"
+                + "FOREIGN KEY(T1_ID) REFERENCES T1 (_ID))");
+    }
+
+    @After
+    public void tearDown() {
+        mDatabase.close();
+        mContext.deleteDatabase(DB_NAME);
+    }
+
+    @Test
+    public void testSelect() {
+        insertT1TestDataSet();
+
+        BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+
+        Random rnd = new Random(0);
+        while (state.keepRunning()) {
+            int index = rnd.nextInt(DEFAULT_DATASET_SIZE);
+            try (Cursor cursor = mDatabase.rawQuery("SELECT _ID, COL_A, COL_B, COL_C FROM T1 "
+                    + "WHERE _ID=?", new String[]{String.valueOf(index)})) {
+                assertTrue(cursor.moveToNext());
+                assertEquals(index, cursor.getInt(0));
+                assertEquals(index, cursor.getInt(1));
+                assertEquals("T1Value" + index, cursor.getString(2));
+                assertEquals(1.1 * index, cursor.getDouble(3), 0.0000001d);
+            }
+        }
+    }
+
+    @Test
+    public void testSelectMultipleRows() {
+        insertT1TestDataSet();
+
+        BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+        Random rnd = new Random(0);
+        final int querySize = 50;
+        while (state.keepRunning()) {
+            int index = rnd.nextInt(DEFAULT_DATASET_SIZE - querySize - 1);
+            try (Cursor cursor = mDatabase.rawQuery("SELECT _ID, COL_A, COL_B, COL_C FROM T1 "
+                            + "WHERE _ID BETWEEN ? and ? ORDER BY _ID",
+                    new String[]{String.valueOf(index), String.valueOf(index + querySize - 1)})) {
+                int i = 0;
+                while(cursor.moveToNext()) {
+                    assertEquals(index, cursor.getInt(0));
+                    assertEquals(index, cursor.getInt(1));
+                    assertEquals("T1Value" + index, cursor.getString(2));
+                    assertEquals(1.1 * index, cursor.getDouble(3), 0.0000001d);
+                    index++;
+                    i++;
+                }
+                assertEquals(querySize, i);
+            }
+        }
+    }
+
+    @Test
+    public void testCursorIterateForward() {
+        // A larger dataset is needed to exceed default CursorWindow size
+        int datasetSize = DEFAULT_DATASET_SIZE * 50;
+        insertT1TestDataSet(datasetSize);
+
+        BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+        while (state.keepRunning()) {
+            try (Cursor cursor = mDatabase
+                    .rawQuery("SELECT _ID, COL_A, COL_B, COL_C FROM T1 ORDER BY _ID", null)) {
+                int i = 0;
+                while(cursor.moveToNext()) {
+                    assertEquals(i, cursor.getInt(0));
+                    assertEquals(i, cursor.getInt(1));
+                    assertEquals("T1Value" + i, cursor.getString(2));
+                    assertEquals(1.1 * i, cursor.getDouble(3), 0.0000001d);
+                    i++;
+                }
+                assertEquals(datasetSize, i);
+            }
+        }
+    }
+
+    @Test
+    public void testCursorIterateBackwards() {
+        // A larger dataset is needed to exceed default CursorWindow size
+        int datasetSize = DEFAULT_DATASET_SIZE * 50;
+        insertT1TestDataSet(datasetSize);
+
+        BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+        while (state.keepRunning()) {
+            try (Cursor cursor = mDatabase
+                    .rawQuery("SELECT _ID, COL_A, COL_B, COL_C FROM T1 ORDER BY _ID", null)) {
+                int i = datasetSize - 1;
+                while(cursor.moveToPosition(i)) {
+                    assertEquals(i, cursor.getInt(0));
+                    assertEquals(i, cursor.getInt(1));
+                    assertEquals("T1Value" + i, cursor.getString(2));
+                    assertEquals(1.1 * i, cursor.getDouble(3), 0.0000001d);
+                    i--;
+                }
+                assertEquals(-1, i);
+            }
+        }
+    }
+
+    @Test
+    public void testInnerJoin() {
+        mDatabase.setForeignKeyConstraintsEnabled(true);
+        mDatabase.beginTransaction();
+        insertT1TestDataSet();
+        insertT2TestDataSet();
+        mDatabase.setTransactionSuccessful();
+        mDatabase.endTransaction();
+
+        BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+
+        Random rnd = new Random(0);
+        while (state.keepRunning()) {
+            int index = rnd.nextInt(1000);
+            try (Cursor cursor = mDatabase.rawQuery(
+                    "SELECT T1._ID, T1.COL_A, T1.COL_B, T1.COL_C, T2.COL_A FROM T1 "
+                    + "INNER JOIN T2 on T2.T1_ID=T1._ID WHERE T1._ID = ?",
+                    new String[]{String.valueOf(index)})) {
+                assertTrue(cursor.moveToNext());
+                assertEquals(index, cursor.getInt(0));
+                assertEquals(index, cursor.getInt(1));
+                assertEquals("T1Value" + index, cursor.getString(2));
+                assertEquals(1.1 * index, cursor.getDouble(3), 0.0000001d);
+                assertEquals("T2Value" + index, cursor.getString(4));
+            }
+        }
+    }
+
+    @Test
+    public void testInsert() {
+        insertT1TestDataSet();
+
+        BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+
+        ContentValues cv = new ContentValues();
+        cv.put("_ID", DEFAULT_DATASET_SIZE);
+        cv.put("COL_B", "NewValue");
+        cv.put("COL_C", 1.1);
+        String[] deleteArgs = new String[]{String.valueOf(DEFAULT_DATASET_SIZE)};
+        while (state.keepRunning()) {
+            assertEquals(DEFAULT_DATASET_SIZE, mDatabase.insert("T1", null, cv));
+            state.pauseTiming();
+            assertEquals(1, mDatabase.delete("T1", "_ID=?", deleteArgs));
+            state.resumeTiming();
+        }
+    }
+
+    @Test
+    public void testDelete() {
+        insertT1TestDataSet();
+        BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+        String[] deleteArgs = new String[]{String.valueOf(DEFAULT_DATASET_SIZE)};
+        Object[] insertsArgs = new Object[]{DEFAULT_DATASET_SIZE, DEFAULT_DATASET_SIZE,
+                "ValueToDelete", 1.1};
+
+        while (state.keepRunning()) {
+            state.pauseTiming();
+            mDatabase.execSQL("INSERT INTO T1 VALUES (?, ?, ?, ?)", insertsArgs);
+            state.resumeTiming();
+            assertEquals(1, mDatabase.delete("T1", "_ID=?", deleteArgs));
+        }
+    }
+
+    @Test
+    public void testUpdate() {
+        insertT1TestDataSet();
+        BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+
+        Random rnd = new Random(0);
+        int i = 0;
+        ContentValues cv = new ContentValues();
+        String[] argArray = new String[1];
+        while (state.keepRunning()) {
+            int id = rnd.nextInt(DEFAULT_DATASET_SIZE);
+            cv.put("COL_A", i);
+            cv.put("COL_B", "UpdatedValue");
+            cv.put("COL_C", i);
+            argArray[0] = String.valueOf(id);
+            assertEquals(1, mDatabase.update("T1", cv, "_ID=?", argArray));
+            i++;
+        }
+    }
+
+    private void insertT1TestDataSet() {
+        insertT1TestDataSet(DEFAULT_DATASET_SIZE);
+    }
+
+    private void insertT1TestDataSet(int size) {
+        mDatabase.beginTransaction();
+        for (int i = 0; i < size; i++) {
+            mDatabase.execSQL("INSERT INTO T1 VALUES (?, ?, ?, ?)",
+                    new Object[]{i, i, "T1Value" + i, i * 1.1});
+        }
+        mDatabase.setTransactionSuccessful();
+        mDatabase.endTransaction();
+    }
+
+    private void insertT2TestDataSet() {
+        mDatabase.beginTransaction();
+        for (int i = 0; i < DEFAULT_DATASET_SIZE; i++) {
+            mDatabase.execSQL("INSERT INTO T2 VALUES (?, ?, ?)",
+                    new Object[]{i, "T2Value" + i, i});
+        }
+        mDatabase.setTransactionSuccessful();
+        mDatabase.endTransaction();
+    }
+}
+
diff --git a/android/database/StaleDataException.java b/android/database/StaleDataException.java
new file mode 100644
index 0000000..ee70beb
--- /dev/null
+++ b/android/database/StaleDataException.java
@@ -0,0 +1,34 @@
+/*
+ * Copyright (C) 2006 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.database;
+
+/**
+ * This exception is thrown when a Cursor contains stale data and must be
+ * requeried before being used again.
+ */
+public class StaleDataException extends java.lang.RuntimeException
+{
+    public StaleDataException()
+    {
+        super();
+    }
+
+    public StaleDataException(String description)
+    {
+        super(description);
+    }
+}
diff --git a/android/database/TableHelper.java b/android/database/TableHelper.java
new file mode 100644
index 0000000..48f3781
--- /dev/null
+++ b/android/database/TableHelper.java
@@ -0,0 +1,223 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.database;
+
+import java.util.Date;
+import java.util.UUID;
+
+/**
+ * Helper class for creating and querying data from a database in performance tests.
+ *
+ * Subclasses can define different table/query formats.
+ */
+public abstract class TableHelper {
+
+    public interface CursorReader {
+        void read();
+    }
+
+    public abstract String createSql();
+    public abstract String insertSql();
+    public abstract Object[] createItem(int id);
+    public abstract String readSql();
+    public abstract CursorReader createReader(Cursor cursor);
+
+    /**
+     * 1 column, single integer
+     */
+    public static TableHelper INT_1 = new TableHelper() {
+        @Override
+        public String createSql() {
+            return "CREATE TABLE `Int1` ("
+                    + "`a` INTEGER,"
+                    + " PRIMARY KEY(`a`))";
+        }
+
+        @Override
+        public String insertSql() {
+            return "INSERT INTO `Int1`(`a`)"
+                    + " VALUES (?)";
+        }
+
+        @Override
+        public Object[] createItem(int id) {
+            return new Object[] {
+                    id,
+            };
+        }
+
+        @Override
+        public String readSql() {
+            return "SELECT * from Int1";
+        }
+
+        @Override
+        public CursorReader createReader(final Cursor cursor) {
+            final int cursorIndexOfA = cursor.getColumnIndexOrThrow("a");
+            return () -> {
+                cursor.getInt(cursorIndexOfA);
+            };
+        }
+    };
+    /**
+     * 10 columns of integers
+     */
+    public static TableHelper INT_10 = new TableHelper() {
+        @Override
+        public String createSql() {
+            return "CREATE TABLE `Int10` ("
+                    + "`a` INTEGER,"
+                    + " `b` INTEGER,"
+                    + " `c` INTEGER,"
+                    + " `d` INTEGER,"
+                    + " `e` INTEGER,"
+                    + " `f` INTEGER,"
+                    + " `g` INTEGER,"
+                    + " `h` INTEGER,"
+                    + " `i` INTEGER,"
+                    + " `j` INTEGER,"
+                    + " PRIMARY KEY(`a`))";
+        }
+
+        @Override
+        public String insertSql() {
+            return "INSERT INTO `Int10`(`a`,`b`,`c`,`d`,`e`,`f`,`g`,`h`,`i`,`j`)"
+                    + " VALUES (?,?,?,?,?,?,?,?,?,?)";
+        }
+
+        @Override
+        public Object[] createItem(int id) {
+            return new Object[] {
+                    id,
+                    id + 1,
+                    id + 2,
+                    id + 3,
+                    id + 4,
+                    id + 5,
+                    id + 6,
+                    id + 7,
+                    id + 8,
+                    id + 9,
+            };
+        }
+
+        @Override
+        public String readSql() {
+            return "SELECT * from Int10";
+        }
+
+        @Override
+        public CursorReader createReader(final Cursor cursor) {
+            final int cursorIndexOfA = cursor.getColumnIndexOrThrow("a");
+            final int cursorIndexOfB = cursor.getColumnIndexOrThrow("b");
+            final int cursorIndexOfC = cursor.getColumnIndexOrThrow("c");
+            final int cursorIndexOfD = cursor.getColumnIndexOrThrow("d");
+            final int cursorIndexOfE = cursor.getColumnIndexOrThrow("e");
+            final int cursorIndexOfF = cursor.getColumnIndexOrThrow("f");
+            final int cursorIndexOfG = cursor.getColumnIndexOrThrow("g");
+            final int cursorIndexOfH = cursor.getColumnIndexOrThrow("h");
+            final int cursorIndexOfI = cursor.getColumnIndexOrThrow("i");
+            final int cursorIndexOfJ = cursor.getColumnIndexOrThrow("j");
+            return () -> {
+                cursor.getInt(cursorIndexOfA);
+                cursor.getInt(cursorIndexOfB);
+                cursor.getInt(cursorIndexOfC);
+                cursor.getInt(cursorIndexOfD);
+                cursor.getInt(cursorIndexOfE);
+                cursor.getInt(cursorIndexOfF);
+                cursor.getInt(cursorIndexOfG);
+                cursor.getInt(cursorIndexOfH);
+                cursor.getInt(cursorIndexOfI);
+                cursor.getInt(cursorIndexOfJ);
+            };
+        }
+    };
+
+    /**
+     * Mock up of 'user' table with various ints/strings
+     */
+    public static TableHelper USER = new TableHelper() {
+        @Override
+        public String createSql() {
+            return "CREATE TABLE `User` ("
+                    + "`mId` INTEGER,"
+                    + " `mName` TEXT,"
+                    + " `mLastName` TEXT,"
+                    + " `mAge` INTEGER,"
+                    + " `mAdmin` INTEGER,"
+                    + " `mWeight` DOUBLE,"
+                    + " `mBirthday` INTEGER,"
+                    + " `mMoreText` TEXT,"
+                    + " PRIMARY KEY(`mId`))";
+        }
+
+        @Override
+        public String insertSql() {
+            return "INSERT INTO `User`(`mId`,`mName`,`mLastName`,`mAge`,"
+                    + "`mAdmin`,`mWeight`,`mBirthday`,`mMoreText`) VALUES (?,?,?,?,?,?,?,?)";
+        }
+
+        @Override
+        public Object[] createItem(int id) {
+            return new Object[] {
+                    id,
+                    UUID.randomUUID().toString(),
+                    UUID.randomUUID().toString(),
+                    (int) (10 + Math.random() * 50),
+                    0,
+                    (float)0,
+                    new Date().getTime(),
+                    UUID.randomUUID().toString(),
+            };
+        }
+
+        @Override
+        public String readSql() {
+            return "SELECT * from User";
+        }
+
+        @Override
+        public CursorReader createReader(final Cursor cursor) {
+            final int cursorIndexOfMId = cursor.getColumnIndexOrThrow("mId");
+            final int cursorIndexOfMName = cursor.getColumnIndexOrThrow("mName");
+            final int cursorIndexOfMLastName = cursor.getColumnIndexOrThrow("mLastName");
+            final int cursorIndexOfMAge = cursor.getColumnIndexOrThrow("mAge");
+            final int cursorIndexOfMAdmin = cursor.getColumnIndexOrThrow("mAdmin");
+            final int cursorIndexOfMWeight = cursor.getColumnIndexOrThrow("mWeight");
+            final int cursorIndexOfMBirthday = cursor.getColumnIndexOrThrow("mBirthday");
+            final int cursorIndexOfMMoreTextField = cursor.getColumnIndexOrThrow("mMoreText");
+            return () -> {
+                cursor.getInt(cursorIndexOfMId);
+                cursor.getString(cursorIndexOfMName);
+                cursor.getString(cursorIndexOfMLastName);
+                cursor.getInt(cursorIndexOfMAge);
+                cursor.getInt(cursorIndexOfMAdmin);
+                cursor.getFloat(cursorIndexOfMWeight);
+                if (!cursor.isNull(cursorIndexOfMBirthday)) {
+                    cursor.getLong(cursorIndexOfMBirthday);
+                }
+                cursor.getString(cursorIndexOfMMoreTextField);
+            };
+        }
+    };
+
+    public static TableHelper[] TABLE_HELPERS = new TableHelper[] {
+            INT_1,
+            INT_10,
+            USER,
+    };
+}
diff --git a/android/database/TranslatingCursor.java b/android/database/TranslatingCursor.java
new file mode 100644
index 0000000..35cbdc7
--- /dev/null
+++ b/android/database/TranslatingCursor.java
@@ -0,0 +1,236 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.database;
+
+import android.annotation.NonNull;
+import android.content.ContentResolver;
+import android.database.sqlite.SQLiteDatabase;
+import android.database.sqlite.SQLiteQueryBuilder;
+import android.net.Uri;
+import android.os.CancellationSignal;
+import android.util.ArraySet;
+
+import com.android.internal.util.ArrayUtils;
+
+import java.util.Arrays;
+import java.util.Objects;
+
+/**
+ * Cursor that supports deprecation of {@code _data} like columns which represent raw filepaths,
+ * typically by replacing values with fake paths that the OS then offers to redirect to
+ * {@link ContentResolver#openFileDescriptor(Uri, String)}, which developers
+ * should be using directly.
+ *
+ * @hide
+ */
+public class TranslatingCursor extends CrossProcessCursorWrapper {
+    public static class Config {
+        public final Uri baseUri;
+        public final String auxiliaryColumn;
+        public final String[] translateColumns;
+
+        public Config(Uri baseUri, String auxiliaryColumn, String... translateColumns) {
+            this.baseUri = baseUri;
+            this.auxiliaryColumn = auxiliaryColumn;
+            this.translateColumns = translateColumns;
+        }
+    }
+
+    public interface Translator {
+        String translate(String data, int auxiliaryColumnIndex,
+                String matchingColumn, Cursor cursor);
+    }
+
+    private final @NonNull Config mConfig;
+    private final @NonNull Translator mTranslator;
+    private final boolean mDropLast;
+
+    private final int mAuxiliaryColumnIndex;
+    private final ArraySet<Integer> mTranslateColumnIndices;
+
+    public TranslatingCursor(@NonNull Cursor cursor, @NonNull Config config,
+            @NonNull Translator translator, boolean dropLast) {
+        super(cursor);
+
+        mConfig = Objects.requireNonNull(config);
+        mTranslator = Objects.requireNonNull(translator);
+        mDropLast = dropLast;
+
+        mAuxiliaryColumnIndex = cursor.getColumnIndexOrThrow(config.auxiliaryColumn);
+        mTranslateColumnIndices = new ArraySet<>();
+        for (int i = 0; i < cursor.getColumnCount(); ++i) {
+            String columnName = cursor.getColumnName(i);
+            if (ArrayUtils.contains(config.translateColumns, columnName)) {
+                mTranslateColumnIndices.add(i);
+            }
+        }
+    }
+
+    @Override
+    public int getColumnCount() {
+        if (mDropLast) {
+            return super.getColumnCount() - 1;
+        } else {
+            return super.getColumnCount();
+        }
+    }
+
+    @Override
+    public String[] getColumnNames() {
+        if (mDropLast) {
+            return Arrays.copyOfRange(super.getColumnNames(), 0, super.getColumnCount() - 1);
+        } else {
+            return super.getColumnNames();
+        }
+    }
+
+    public static Cursor query(@NonNull Config config, @NonNull Translator translator,
+            SQLiteQueryBuilder qb, SQLiteDatabase db, String[] projectionIn, String selection,
+            String[] selectionArgs, String groupBy, String having, String sortOrder, String limit,
+            CancellationSignal signal) {
+        final boolean requestedAuxiliaryColumn = ArrayUtils.isEmpty(projectionIn)
+                || ArrayUtils.contains(projectionIn, config.auxiliaryColumn);
+        final boolean requestedTranslateColumns = ArrayUtils.isEmpty(projectionIn)
+                || ArrayUtils.containsAny(projectionIn, config.translateColumns);
+
+        // If caller didn't request any columns that need to be translated,
+        // we have nothing to redirect
+        if (!requestedTranslateColumns) {
+            return qb.query(db, projectionIn, selection, selectionArgs,
+                    groupBy, having, sortOrder, limit, signal);
+        }
+
+        // If caller didn't request auxiliary column, we need to splice it in
+        if (!requestedAuxiliaryColumn) {
+            projectionIn = ArrayUtils.appendElement(String.class, projectionIn,
+                    config.auxiliaryColumn);
+        }
+
+        final Cursor c = qb.query(db, projectionIn, selection, selectionArgs,
+                groupBy, having, sortOrder);
+        return new TranslatingCursor(c, config, translator, !requestedAuxiliaryColumn);
+    }
+
+    @Override
+    public void fillWindow(int position, CursorWindow window) {
+        // Fill window directly to ensure data is rewritten
+        DatabaseUtils.cursorFillWindow(this, position, window);
+    }
+
+    @Override
+    public CursorWindow getWindow() {
+        // Returning underlying window risks leaking data
+        return null;
+    }
+
+    @Override
+    public Cursor getWrappedCursor() {
+        throw new UnsupportedOperationException(
+                "Returning underlying cursor risks leaking data");
+    }
+
+    @Override
+    public double getDouble(int columnIndex) {
+        if (ArrayUtils.contains(mTranslateColumnIndices, columnIndex)) {
+            throw new IllegalArgumentException();
+        } else {
+            return super.getDouble(columnIndex);
+        }
+    }
+
+    @Override
+    public float getFloat(int columnIndex) {
+        if (ArrayUtils.contains(mTranslateColumnIndices, columnIndex)) {
+            throw new IllegalArgumentException();
+        } else {
+            return super.getFloat(columnIndex);
+        }
+    }
+
+    @Override
+    public int getInt(int columnIndex) {
+        if (ArrayUtils.contains(mTranslateColumnIndices, columnIndex)) {
+            throw new IllegalArgumentException();
+        } else {
+            return super.getInt(columnIndex);
+        }
+    }
+
+    @Override
+    public long getLong(int columnIndex) {
+        if (ArrayUtils.contains(mTranslateColumnIndices, columnIndex)) {
+            throw new IllegalArgumentException();
+        } else {
+            return super.getLong(columnIndex);
+        }
+    }
+
+    @Override
+    public short getShort(int columnIndex) {
+        if (ArrayUtils.contains(mTranslateColumnIndices, columnIndex)) {
+            throw new IllegalArgumentException();
+        } else {
+            return super.getShort(columnIndex);
+        }
+    }
+
+    @Override
+    public String getString(int columnIndex) {
+        if (ArrayUtils.contains(mTranslateColumnIndices, columnIndex)) {
+            return mTranslator.translate(super.getString(columnIndex),
+                    mAuxiliaryColumnIndex, getColumnName(columnIndex), this);
+        } else {
+            return super.getString(columnIndex);
+        }
+    }
+
+    @Override
+    public void copyStringToBuffer(int columnIndex, CharArrayBuffer buffer) {
+        if (ArrayUtils.contains(mTranslateColumnIndices, columnIndex)) {
+            throw new IllegalArgumentException();
+        } else {
+            super.copyStringToBuffer(columnIndex, buffer);
+        }
+    }
+
+    @Override
+    public byte[] getBlob(int columnIndex) {
+        if (ArrayUtils.contains(mTranslateColumnIndices, columnIndex)) {
+            throw new IllegalArgumentException();
+        } else {
+            return super.getBlob(columnIndex);
+        }
+    }
+
+    @Override
+    public int getType(int columnIndex) {
+        if (ArrayUtils.contains(mTranslateColumnIndices, columnIndex)) {
+            return Cursor.FIELD_TYPE_STRING;
+        } else {
+            return super.getType(columnIndex);
+        }
+    }
+
+    @Override
+    public boolean isNull(int columnIndex) {
+        if (ArrayUtils.contains(mTranslateColumnIndices, columnIndex)) {
+            return getString(columnIndex) == null;
+        } else {
+            return super.isNull(columnIndex);
+        }
+    }
+}
diff --git a/android/database/sqlite/DatabaseObjectNotClosedException.java b/android/database/sqlite/DatabaseObjectNotClosedException.java
new file mode 100644
index 0000000..ba546f3
--- /dev/null
+++ b/android/database/sqlite/DatabaseObjectNotClosedException.java
@@ -0,0 +1,34 @@
+/*
+ * Copyright (C) 2006 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.database.sqlite;
+
+import android.compat.annotation.UnsupportedAppUsage;
+
+/**
+ * An exception that indicates that garbage-collector is finalizing a database object
+ * that is not explicitly closed
+ * @hide
+ */
+public class DatabaseObjectNotClosedException extends RuntimeException {
+    private static final String s = "Application did not close the cursor or database object " +
+            "that was opened here";
+
+    @UnsupportedAppUsage
+    public DatabaseObjectNotClosedException() {
+        super(s);
+    }
+}
diff --git a/android/database/sqlite/SQLiteAbortException.java b/android/database/sqlite/SQLiteAbortException.java
new file mode 100644
index 0000000..64dc4b7
--- /dev/null
+++ b/android/database/sqlite/SQLiteAbortException.java
@@ -0,0 +1,30 @@
+/*
+ * Copyright (C) 2008 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.database.sqlite;
+
+/**
+ * An exception that indicates that the SQLite program was aborted.
+ * This can happen either through a call to ABORT in a trigger,
+ * or as the result of using the ABORT conflict clause.
+ */
+public class SQLiteAbortException extends SQLiteException {
+    public SQLiteAbortException() {}
+
+    public SQLiteAbortException(String error) {
+        super(error);
+    }
+}
diff --git a/android/database/sqlite/SQLiteAccessPermException.java b/android/database/sqlite/SQLiteAccessPermException.java
new file mode 100644
index 0000000..238da4b
--- /dev/null
+++ b/android/database/sqlite/SQLiteAccessPermException.java
@@ -0,0 +1,29 @@
+/*
+ * Copyright (C) 2010 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.database.sqlite;
+
+/**
+ * This exception class is used when sqlite can't access the database file
+ * due to lack of permissions on the file.
+ */
+public class SQLiteAccessPermException extends SQLiteException {
+    public SQLiteAccessPermException() {}
+
+    public SQLiteAccessPermException(String error) {
+        super(error);
+    }
+}
diff --git a/android/database/sqlite/SQLiteBindOrColumnIndexOutOfRangeException.java b/android/database/sqlite/SQLiteBindOrColumnIndexOutOfRangeException.java
new file mode 100644
index 0000000..41f2f9c
--- /dev/null
+++ b/android/database/sqlite/SQLiteBindOrColumnIndexOutOfRangeException.java
@@ -0,0 +1,28 @@
+/*
+ * 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.database.sqlite;
+
+/**
+ * Thrown if the the bind or column parameter index is out of range
+ */
+public class SQLiteBindOrColumnIndexOutOfRangeException extends SQLiteException {
+    public SQLiteBindOrColumnIndexOutOfRangeException() {}
+
+    public SQLiteBindOrColumnIndexOutOfRangeException(String error) {
+        super(error);
+    }
+}
diff --git a/android/database/sqlite/SQLiteBlobTooBigException.java b/android/database/sqlite/SQLiteBlobTooBigException.java
new file mode 100644
index 0000000..a82676b
--- /dev/null
+++ b/android/database/sqlite/SQLiteBlobTooBigException.java
@@ -0,0 +1,25 @@
+/*
+ * 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.database.sqlite;
+
+public class SQLiteBlobTooBigException extends SQLiteException {
+    public SQLiteBlobTooBigException() {}
+
+    public SQLiteBlobTooBigException(String error) {
+        super(error);
+    }
+}
diff --git a/android/database/sqlite/SQLiteCantOpenDatabaseException.java b/android/database/sqlite/SQLiteCantOpenDatabaseException.java
new file mode 100644
index 0000000..5d4b48d
--- /dev/null
+++ b/android/database/sqlite/SQLiteCantOpenDatabaseException.java
@@ -0,0 +1,30 @@
+/*
+ * 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.database.sqlite;
+
+public class SQLiteCantOpenDatabaseException extends SQLiteException {
+    public SQLiteCantOpenDatabaseException() {}
+
+    public SQLiteCantOpenDatabaseException(String error) {
+        super(error);
+    }
+
+    /** @hide */
+    public SQLiteCantOpenDatabaseException(String error, Throwable cause) {
+        super(error, cause);
+    }
+}
diff --git a/android/database/sqlite/SQLiteClosable.java b/android/database/sqlite/SQLiteClosable.java
new file mode 100644
index 0000000..2fca729
--- /dev/null
+++ b/android/database/sqlite/SQLiteClosable.java
@@ -0,0 +1,111 @@
+/*
+ * 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.database.sqlite;
+
+import android.compat.annotation.UnsupportedAppUsage;
+
+import java.io.Closeable;
+
+/**
+ * An object created from a SQLiteDatabase that can be closed.
+ *
+ * This class implements a primitive reference counting scheme for database objects.
+ */
+public abstract class SQLiteClosable implements Closeable {
+    @UnsupportedAppUsage
+    private int mReferenceCount = 1;
+
+    /**
+     * Called when the last reference to the object was released by
+     * a call to {@link #releaseReference()} or {@link #close()}.
+     */
+    protected abstract void onAllReferencesReleased();
+
+    /**
+     * Called when the last reference to the object was released by
+     * a call to {@link #releaseReferenceFromContainer()}.
+     *
+     * @deprecated Do not use.
+     */
+    @Deprecated
+    protected void onAllReferencesReleasedFromContainer() {
+        onAllReferencesReleased();
+    }
+
+    /**
+     * Acquires a reference to the object.
+     *
+     * @throws IllegalStateException if the last reference to the object has already
+     * been released.
+     */
+    public void acquireReference() {
+        synchronized(this) {
+            if (mReferenceCount <= 0) {
+                throw new IllegalStateException(
+                        "attempt to re-open an already-closed object: " + this);
+            }
+            mReferenceCount++;
+        }
+    }
+
+    /**
+     * Releases a reference to the object, closing the object if the last reference
+     * was released.
+     *
+     * @see #onAllReferencesReleased()
+     */
+    public void releaseReference() {
+        boolean refCountIsZero = false;
+        synchronized(this) {
+            refCountIsZero = --mReferenceCount == 0;
+        }
+        if (refCountIsZero) {
+            onAllReferencesReleased();
+        }
+    }
+
+    /**
+     * Releases a reference to the object that was owned by the container of the object,
+     * closing the object if the last reference was released.
+     *
+     * @see #onAllReferencesReleasedFromContainer()
+     * @deprecated Do not use.
+     */
+    @Deprecated
+    public void releaseReferenceFromContainer() {
+        boolean refCountIsZero = false;
+        synchronized(this) {
+            refCountIsZero = --mReferenceCount == 0;
+        }
+        if (refCountIsZero) {
+            onAllReferencesReleasedFromContainer();
+        }
+    }
+
+    /**
+     * Releases a reference to the object, closing the object if the last reference
+     * was released.
+     *
+     * Calling this method is equivalent to calling {@link #releaseReference}.
+     *
+     * @see #releaseReference()
+     * @see #onAllReferencesReleased()
+     */
+    public void close() {
+        releaseReference();
+    }
+}
diff --git a/android/database/sqlite/SQLiteCompatibilityWalFlags.java b/android/database/sqlite/SQLiteCompatibilityWalFlags.java
new file mode 100644
index 0000000..a269072
--- /dev/null
+++ b/android/database/sqlite/SQLiteCompatibilityWalFlags.java
@@ -0,0 +1,151 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.database.sqlite;
+
+import android.annotation.TestApi;
+import android.app.ActivityThread;
+import android.app.Application;
+import android.provider.Settings;
+import android.text.TextUtils;
+import android.util.KeyValueListParser;
+import android.util.Log;
+
+import com.android.internal.annotations.VisibleForTesting;
+
+/**
+ * Helper class for accessing
+ * {@link Settings.Global#SQLITE_COMPATIBILITY_WAL_FLAGS global compatibility WAL settings}.
+ *
+ * <p>The value of {@link Settings.Global#SQLITE_COMPATIBILITY_WAL_FLAGS} is cached on first access
+ * for consistent behavior across all connections opened in the process.
+ * @hide
+ */
+@TestApi
+public class SQLiteCompatibilityWalFlags {
+
+    private static final String TAG = "SQLiteCompatibilityWalFlags";
+
+    private static volatile boolean sInitialized;
+    private static volatile boolean sLegacyCompatibilityWalEnabled;
+    private static volatile String sWALSyncMode;
+    private static volatile long sTruncateSize = -1;
+    // This flag is used to avoid recursive initialization due to circular dependency on Settings
+    private static volatile boolean sCallingGlobalSettings;
+
+    private SQLiteCompatibilityWalFlags() {
+    }
+
+    /**
+     * @hide
+     */
+    @VisibleForTesting
+    public static boolean isLegacyCompatibilityWalEnabled() {
+        initIfNeeded();
+        return sLegacyCompatibilityWalEnabled;
+    }
+
+    /**
+     * @hide
+     */
+    @VisibleForTesting
+    public static String getWALSyncMode() {
+        initIfNeeded();
+        // The configurable WAL sync mode should only ever be used if the legacy compatibility
+        // WAL is enabled. It should *not* have any effect if app developers explicitly turn on
+        // WAL for their database using setWriteAheadLoggingEnabled. Throwing an exception here
+        // adds an extra layer of checking that we never use it in the wrong place.
+        if (!sLegacyCompatibilityWalEnabled) {
+            throw new IllegalStateException("isLegacyCompatibilityWalEnabled() == false");
+        }
+
+        return sWALSyncMode;
+    }
+
+    /**
+     * Override {@link com.android.internal.R.integer#db_wal_truncate_size}.
+     *
+     * @return the value set in the global setting, or -1 if a value is not set.
+     *
+     * @hide
+     */
+    @VisibleForTesting
+    public static long getTruncateSize() {
+        initIfNeeded();
+        return sTruncateSize;
+    }
+
+    private static void initIfNeeded() {
+        if (sInitialized || sCallingGlobalSettings) {
+            return;
+        }
+        ActivityThread activityThread = ActivityThread.currentActivityThread();
+        Application app = activityThread == null ? null : activityThread.getApplication();
+        String flags = null;
+        if (app == null) {
+            Log.w(TAG, "Cannot read global setting "
+                    + Settings.Global.SQLITE_COMPATIBILITY_WAL_FLAGS + " - "
+                    + "Application state not available");
+        } else {
+            try {
+                sCallingGlobalSettings = true;
+                flags = Settings.Global.getString(app.getContentResolver(),
+                        Settings.Global.SQLITE_COMPATIBILITY_WAL_FLAGS);
+            } finally {
+                sCallingGlobalSettings = false;
+            }
+        }
+
+        init(flags);
+    }
+
+    /**
+     * @hide
+     */
+    @VisibleForTesting
+    public static void init(String flags) {
+        if (TextUtils.isEmpty(flags)) {
+            sInitialized = true;
+            return;
+        }
+        KeyValueListParser parser = new KeyValueListParser(',');
+        try {
+            parser.setString(flags);
+        } catch (IllegalArgumentException e) {
+            Log.e(TAG, "Setting has invalid format: " + flags, e);
+            sInitialized = true;
+            return;
+        }
+        sLegacyCompatibilityWalEnabled = parser.getBoolean(
+                "legacy_compatibility_wal_enabled", false);
+        sWALSyncMode = parser.getString("wal_syncmode", SQLiteGlobal.getWALSyncMode());
+        sTruncateSize = parser.getInt("truncate_size", -1);
+        Log.i(TAG, "Read compatibility WAL flags: legacy_compatibility_wal_enabled="
+                + sLegacyCompatibilityWalEnabled + ", wal_syncmode=" + sWALSyncMode);
+        sInitialized = true;
+    }
+
+    /**
+     * @hide
+     */
+    @VisibleForTesting
+    @TestApi
+    public static void reset() {
+        sInitialized = false;
+        sLegacyCompatibilityWalEnabled = false;
+        sWALSyncMode = null;
+    }
+}
diff --git a/android/database/sqlite/SQLiteConnection.java b/android/database/sqlite/SQLiteConnection.java
new file mode 100644
index 0000000..2f67f6d
--- /dev/null
+++ b/android/database/sqlite/SQLiteConnection.java
@@ -0,0 +1,1719 @@
+/*
+ * Copyright (C) 2011 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.database.sqlite;
+
+import android.database.Cursor;
+import android.database.CursorWindow;
+import android.database.DatabaseUtils;
+import android.database.sqlite.SQLiteDebug.DbStats;
+import android.database.sqlite.SQLiteDebug.NoPreloadHolder;
+import android.os.CancellationSignal;
+import android.os.OperationCanceledException;
+import android.os.ParcelFileDescriptor;
+import android.os.SystemClock;
+import android.os.Trace;
+import android.util.Log;
+import android.util.LruCache;
+import android.util.Pair;
+import android.util.Printer;
+
+import dalvik.system.BlockGuard;
+import dalvik.system.CloseGuard;
+
+import java.io.File;
+import java.io.IOException;
+import java.nio.file.FileSystems;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.text.SimpleDateFormat;
+import java.util.ArrayList;
+import java.util.Date;
+import java.util.Map;
+import java.util.function.BinaryOperator;
+import java.util.function.UnaryOperator;
+
+/**
+ * Represents a SQLite database connection.
+ * Each connection wraps an instance of a native <code>sqlite3</code> object.
+ * <p>
+ * When database connection pooling is enabled, there can be multiple active
+ * connections to the same database.  Otherwise there is typically only one
+ * connection per database.
+ * </p><p>
+ * When the SQLite WAL feature is enabled, multiple readers and one writer
+ * can concurrently access the database.  Without WAL, readers and writers
+ * are mutually exclusive.
+ * </p>
+ *
+ * <h2>Ownership and concurrency guarantees</h2>
+ * <p>
+ * Connection objects are not thread-safe.  They are acquired as needed to
+ * perform a database operation and are then returned to the pool.  At any
+ * given time, a connection is either owned and used by a {@link SQLiteSession}
+ * object or the {@link SQLiteConnectionPool}.  Those classes are
+ * responsible for serializing operations to guard against concurrent
+ * use of a connection.
+ * </p><p>
+ * The guarantee of having a single owner allows this class to be implemented
+ * without locks and greatly simplifies resource management.
+ * </p>
+ *
+ * <h2>Encapsulation guarantees</h2>
+ * <p>
+ * The connection object object owns *all* of the SQLite related native
+ * objects that are associated with the connection.  What's more, there are
+ * no other objects in the system that are capable of obtaining handles to
+ * those native objects.  Consequently, when the connection is closed, we do
+ * not have to worry about what other components might have references to
+ * its associated SQLite state -- there are none.
+ * </p><p>
+ * Encapsulation is what ensures that the connection object's
+ * lifecycle does not become a tortured mess of finalizers and reference
+ * queues.
+ * </p>
+ *
+ * <h2>Reentrance</h2>
+ * <p>
+ * This class must tolerate reentrant execution of SQLite operations because
+ * triggers may call custom SQLite functions that perform additional queries.
+ * </p>
+ *
+ * @hide
+ */
+public final class SQLiteConnection implements CancellationSignal.OnCancelListener {
+    private static final String TAG = "SQLiteConnection";
+    private static final boolean DEBUG = false;
+
+    private static final String[] EMPTY_STRING_ARRAY = new String[0];
+    private static final byte[] EMPTY_BYTE_ARRAY = new byte[0];
+
+    private final CloseGuard mCloseGuard = CloseGuard.get();
+
+    private final SQLiteConnectionPool mPool;
+    private final SQLiteDatabaseConfiguration mConfiguration;
+    private final int mConnectionId;
+    private final boolean mIsPrimaryConnection;
+    private final boolean mIsReadOnlyConnection;
+    private final PreparedStatementCache mPreparedStatementCache;
+    private PreparedStatement mPreparedStatementPool;
+
+    // The recent operations log.
+    private final OperationLog mRecentOperations;
+
+    // The native SQLiteConnection pointer.  (FOR INTERNAL USE ONLY)
+    private long mConnectionPtr;
+
+    private boolean mOnlyAllowReadOnlyOperations;
+
+    // The number of times attachCancellationSignal has been called.
+    // Because SQLite statement execution can be reentrant, we keep track of how many
+    // times we have attempted to attach a cancellation signal to the connection so that
+    // we can ensure that we detach the signal at the right time.
+    private int mCancellationSignalAttachCount;
+
+    private static native long nativeOpen(String path, int openFlags, String label,
+            boolean enableTrace, boolean enableProfile, int lookasideSlotSize,
+            int lookasideSlotCount);
+    private static native void nativeClose(long connectionPtr);
+    private static native void nativeRegisterCustomScalarFunction(long connectionPtr,
+            String name, UnaryOperator<String> function);
+    private static native void nativeRegisterCustomAggregateFunction(long connectionPtr,
+            String name, BinaryOperator<String> function);
+    private static native void nativeRegisterLocalizedCollators(long connectionPtr, String locale);
+    private static native long nativePrepareStatement(long connectionPtr, String sql);
+    private static native void nativeFinalizeStatement(long connectionPtr, long statementPtr);
+    private static native int nativeGetParameterCount(long connectionPtr, long statementPtr);
+    private static native boolean nativeIsReadOnly(long connectionPtr, long statementPtr);
+    private static native int nativeGetColumnCount(long connectionPtr, long statementPtr);
+    private static native String nativeGetColumnName(long connectionPtr, long statementPtr,
+            int index);
+    private static native void nativeBindNull(long connectionPtr, long statementPtr,
+            int index);
+    private static native void nativeBindLong(long connectionPtr, long statementPtr,
+            int index, long value);
+    private static native void nativeBindDouble(long connectionPtr, long statementPtr,
+            int index, double value);
+    private static native void nativeBindString(long connectionPtr, long statementPtr,
+            int index, String value);
+    private static native void nativeBindBlob(long connectionPtr, long statementPtr,
+            int index, byte[] value);
+    private static native void nativeResetStatementAndClearBindings(
+            long connectionPtr, long statementPtr);
+    private static native void nativeExecute(long connectionPtr, long statementPtr);
+    private static native long nativeExecuteForLong(long connectionPtr, long statementPtr);
+    private static native String nativeExecuteForString(long connectionPtr, long statementPtr);
+    private static native int nativeExecuteForBlobFileDescriptor(
+            long connectionPtr, long statementPtr);
+    private static native int nativeExecuteForChangedRowCount(long connectionPtr, long statementPtr);
+    private static native long nativeExecuteForLastInsertedRowId(
+            long connectionPtr, long statementPtr);
+    private static native long nativeExecuteForCursorWindow(
+            long connectionPtr, long statementPtr, long windowPtr,
+            int startPos, int requiredPos, boolean countAllRows);
+    private static native int nativeGetDbLookaside(long connectionPtr);
+    private static native void nativeCancel(long connectionPtr);
+    private static native void nativeResetCancel(long connectionPtr, boolean cancelable);
+
+    private SQLiteConnection(SQLiteConnectionPool pool,
+            SQLiteDatabaseConfiguration configuration,
+            int connectionId, boolean primaryConnection) {
+        mPool = pool;
+        mRecentOperations = new OperationLog(mPool);
+        mConfiguration = new SQLiteDatabaseConfiguration(configuration);
+        mConnectionId = connectionId;
+        mIsPrimaryConnection = primaryConnection;
+        mIsReadOnlyConnection = (configuration.openFlags & SQLiteDatabase.OPEN_READONLY) != 0;
+        mPreparedStatementCache = new PreparedStatementCache(
+                mConfiguration.maxSqlCacheSize);
+        mCloseGuard.open("close");
+    }
+
+    @Override
+    protected void finalize() throws Throwable {
+        try {
+            if (mPool != null && mConnectionPtr != 0) {
+                mPool.onConnectionLeaked();
+            }
+
+            dispose(true);
+        } finally {
+            super.finalize();
+        }
+    }
+
+    // Called by SQLiteConnectionPool only.
+    static SQLiteConnection open(SQLiteConnectionPool pool,
+            SQLiteDatabaseConfiguration configuration,
+            int connectionId, boolean primaryConnection) {
+        SQLiteConnection connection = new SQLiteConnection(pool, configuration,
+                connectionId, primaryConnection);
+        try {
+            connection.open();
+            return connection;
+        } catch (SQLiteException ex) {
+            connection.dispose(false);
+            throw ex;
+        }
+    }
+
+    // Called by SQLiteConnectionPool only.
+    // Closes the database closes and releases all of its associated resources.
+    // Do not call methods on the connection after it is closed.  It will probably crash.
+    void close() {
+        dispose(false);
+    }
+
+    private void open() {
+        final String file = mConfiguration.path;
+        final int cookie = mRecentOperations.beginOperation("open", null, null);
+        try {
+            mConnectionPtr = nativeOpen(file, mConfiguration.openFlags,
+                    mConfiguration.label,
+                    NoPreloadHolder.DEBUG_SQL_STATEMENTS, NoPreloadHolder.DEBUG_SQL_TIME,
+                    mConfiguration.lookasideSlotSize, mConfiguration.lookasideSlotCount);
+        } catch (SQLiteCantOpenDatabaseException e) {
+            String message = String.format("Cannot open database '%s'", file);
+
+            try {
+                // Try to diagnose for common reasons. If something fails in here, that's fine;
+                // just swallow the exception.
+
+                final Path path = FileSystems.getDefault().getPath(file);
+                final Path dir = path.getParent();
+
+                if (!Files.isDirectory(dir)) {
+                    message += ": Directory " + dir + " doesn't exist";
+                } else if (!Files.exists(path)) {
+                    message += ": File " + path + " doesn't exist";
+                } else if (!Files.isReadable(path)) {
+                    message += ": File " + path + " is not readable";
+                } else if (Files.isDirectory(path)) {
+                    message += ": Path " + path + " is a directory";
+                } else {
+                    message += ": Unknown reason";
+                }
+            } catch (Throwable th) {
+                message += ": Unknown reason; cannot examine filesystem: " + th.getMessage();
+            }
+            throw new SQLiteCantOpenDatabaseException(message, e);
+        } finally {
+            mRecentOperations.endOperation(cookie);
+        }
+        setPageSize();
+        setForeignKeyModeFromConfiguration();
+        setWalModeFromConfiguration();
+        setJournalSizeLimit();
+        setAutoCheckpointInterval();
+        setLocaleFromConfiguration();
+        setCustomFunctionsFromConfiguration();
+        executePerConnectionSqlFromConfiguration(0);
+    }
+
+    private void dispose(boolean finalized) {
+        if (mCloseGuard != null) {
+            if (finalized) {
+                mCloseGuard.warnIfOpen();
+            }
+            mCloseGuard.close();
+        }
+
+        if (mConnectionPtr != 0) {
+            final int cookie = mRecentOperations.beginOperation("close", null, null);
+            try {
+                mPreparedStatementCache.evictAll();
+                nativeClose(mConnectionPtr);
+                mConnectionPtr = 0;
+            } finally {
+                mRecentOperations.endOperation(cookie);
+            }
+        }
+    }
+
+    private void setPageSize() {
+        if (!mConfiguration.isInMemoryDb() && !mIsReadOnlyConnection) {
+            final long newValue = SQLiteGlobal.getDefaultPageSize();
+            long value = executeForLong("PRAGMA page_size", null, null);
+            if (value != newValue) {
+                execute("PRAGMA page_size=" + newValue, null, null);
+            }
+        }
+    }
+
+    private void setAutoCheckpointInterval() {
+        if (!mConfiguration.isInMemoryDb() && !mIsReadOnlyConnection) {
+            final long newValue = SQLiteGlobal.getWALAutoCheckpoint();
+            long value = executeForLong("PRAGMA wal_autocheckpoint", null, null);
+            if (value != newValue) {
+                executeForLong("PRAGMA wal_autocheckpoint=" + newValue, null, null);
+            }
+        }
+    }
+
+    private void setJournalSizeLimit() {
+        if (!mConfiguration.isInMemoryDb() && !mIsReadOnlyConnection) {
+            final long newValue = SQLiteGlobal.getJournalSizeLimit();
+            long value = executeForLong("PRAGMA journal_size_limit", null, null);
+            if (value != newValue) {
+                executeForLong("PRAGMA journal_size_limit=" + newValue, null, null);
+            }
+        }
+    }
+
+    private void setForeignKeyModeFromConfiguration() {
+        if (!mIsReadOnlyConnection) {
+            final long newValue = mConfiguration.foreignKeyConstraintsEnabled ? 1 : 0;
+            long value = executeForLong("PRAGMA foreign_keys", null, null);
+            if (value != newValue) {
+                execute("PRAGMA foreign_keys=" + newValue, null, null);
+            }
+        }
+    }
+
+    private void setWalModeFromConfiguration() {
+        if (!mConfiguration.isInMemoryDb() && !mIsReadOnlyConnection) {
+            final boolean walEnabled =
+                    (mConfiguration.openFlags & SQLiteDatabase.ENABLE_WRITE_AHEAD_LOGGING) != 0;
+            // Use compatibility WAL unless an app explicitly set journal/synchronous mode
+            // or DISABLE_COMPATIBILITY_WAL flag is set
+            final boolean isCompatibilityWalEnabled =
+                    mConfiguration.isLegacyCompatibilityWalEnabled();
+            if (walEnabled || isCompatibilityWalEnabled) {
+                setJournalMode("WAL");
+                if (mConfiguration.syncMode != null) {
+                    setSyncMode(mConfiguration.syncMode);
+                } else if (isCompatibilityWalEnabled) {
+                    setSyncMode(SQLiteCompatibilityWalFlags.getWALSyncMode());
+                } else {
+                    setSyncMode(SQLiteGlobal.getWALSyncMode());
+                }
+                maybeTruncateWalFile();
+            } else {
+                setJournalMode(mConfiguration.journalMode == null
+                        ? SQLiteGlobal.getDefaultJournalMode() : mConfiguration.journalMode);
+                setSyncMode(mConfiguration.syncMode == null
+                        ? SQLiteGlobal.getDefaultSyncMode() : mConfiguration.syncMode);
+            }
+        }
+    }
+
+    /**
+     * If the WAL file exists and larger than a threshold, truncate it by executing
+     * PRAGMA wal_checkpoint.
+     */
+    private void maybeTruncateWalFile() {
+        final long threshold = SQLiteGlobal.getWALTruncateSize();
+        if (DEBUG) {
+            Log.d(TAG, "Truncate threshold=" + threshold);
+        }
+        if (threshold == 0) {
+            return;
+        }
+
+        final File walFile = new File(mConfiguration.path + "-wal");
+        if (!walFile.isFile()) {
+            return;
+        }
+        final long size = walFile.length();
+        if (size < threshold) {
+            if (DEBUG) {
+                Log.d(TAG, walFile.getAbsolutePath() + " " + size + " bytes: No need to truncate");
+            }
+            return;
+        }
+
+        Log.i(TAG, walFile.getAbsolutePath() + " " + size + " bytes: Bigger than "
+                + threshold + "; truncating");
+        try {
+            executeForString("PRAGMA wal_checkpoint(TRUNCATE)", null, null);
+        } catch (SQLiteException e) {
+            Log.w(TAG, "Failed to truncate the -wal file", e);
+        }
+    }
+
+    private void setSyncMode(String newValue) {
+        String value = executeForString("PRAGMA synchronous", null, null);
+        if (!canonicalizeSyncMode(value).equalsIgnoreCase(
+                canonicalizeSyncMode(newValue))) {
+            execute("PRAGMA synchronous=" + newValue, null, null);
+        }
+    }
+
+    private static String canonicalizeSyncMode(String value) {
+        switch (value) {
+            case "0": return "OFF";
+            case "1": return "NORMAL";
+            case "2": return "FULL";
+        }
+        return value;
+    }
+
+    private void setJournalMode(String newValue) {
+        String value = executeForString("PRAGMA journal_mode", null, null);
+        if (!value.equalsIgnoreCase(newValue)) {
+            try {
+                String result = executeForString("PRAGMA journal_mode=" + newValue, null, null);
+                if (result.equalsIgnoreCase(newValue)) {
+                    return;
+                }
+                // PRAGMA journal_mode silently fails and returns the original journal
+                // mode in some cases if the journal mode could not be changed.
+            } catch (SQLiteDatabaseLockedException ex) {
+                // This error (SQLITE_BUSY) occurs if one connection has the database
+                // open in WAL mode and another tries to change it to non-WAL.
+            }
+            // Because we always disable WAL mode when a database is first opened
+            // (even if we intend to re-enable it), we can encounter problems if
+            // there is another open connection to the database somewhere.
+            // This can happen for a variety of reasons such as an application opening
+            // the same database in multiple processes at the same time or if there is a
+            // crashing content provider service that the ActivityManager has
+            // removed from its registry but whose process hasn't quite died yet
+            // by the time it is restarted in a new process.
+            //
+            // If we don't change the journal mode, nothing really bad happens.
+            // In the worst case, an application that enables WAL might not actually
+            // get it, although it can still use connection pooling.
+            Log.w(TAG, "Could not change the database journal mode of '"
+                    + mConfiguration.label + "' from '" + value + "' to '" + newValue
+                    + "' because the database is locked.  This usually means that "
+                    + "there are other open connections to the database which prevents "
+                    + "the database from enabling or disabling write-ahead logging mode.  "
+                    + "Proceeding without changing the journal mode.");
+        }
+    }
+
+    private void setLocaleFromConfiguration() {
+        if ((mConfiguration.openFlags & SQLiteDatabase.NO_LOCALIZED_COLLATORS) != 0) {
+            return;
+        }
+
+        // Register the localized collators.
+        final String newLocale = mConfiguration.locale.toString();
+        nativeRegisterLocalizedCollators(mConnectionPtr, newLocale);
+
+        if (!mConfiguration.isInMemoryDb()) {
+            checkDatabaseWiped();
+        }
+
+        // If the database is read-only, we cannot modify the android metadata table
+        // or existing indexes.
+        if (mIsReadOnlyConnection) {
+            return;
+        }
+
+        try {
+            // Ensure the android metadata table exists.
+            execute("CREATE TABLE IF NOT EXISTS android_metadata (locale TEXT)", null, null);
+
+            // Check whether the locale was actually changed.
+            final String oldLocale = executeForString("SELECT locale FROM android_metadata "
+                    + "UNION SELECT NULL ORDER BY locale DESC LIMIT 1", null, null);
+            if (oldLocale != null && oldLocale.equals(newLocale)) {
+                return;
+            }
+
+            // Go ahead and update the indexes using the new locale.
+            execute("BEGIN", null, null);
+            boolean success = false;
+            try {
+                execute("DELETE FROM android_metadata", null, null);
+                execute("INSERT INTO android_metadata (locale) VALUES(?)",
+                        new Object[] { newLocale }, null);
+                execute("REINDEX LOCALIZED", null, null);
+                success = true;
+            } finally {
+                execute(success ? "COMMIT" : "ROLLBACK", null, null);
+            }
+        } catch (SQLiteException ex) {
+            throw ex;
+        } catch (RuntimeException ex) {
+            throw new SQLiteException("Failed to change locale for db '" + mConfiguration.label
+                    + "' to '" + newLocale + "'.", ex);
+        }
+    }
+
+    private void setCustomFunctionsFromConfiguration() {
+        for (int i = 0; i < mConfiguration.customScalarFunctions.size(); i++) {
+            nativeRegisterCustomScalarFunction(mConnectionPtr,
+                    mConfiguration.customScalarFunctions.keyAt(i),
+                    mConfiguration.customScalarFunctions.valueAt(i));
+        }
+        for (int i = 0; i < mConfiguration.customAggregateFunctions.size(); i++) {
+            nativeRegisterCustomAggregateFunction(mConnectionPtr,
+                    mConfiguration.customAggregateFunctions.keyAt(i),
+                    mConfiguration.customAggregateFunctions.valueAt(i));
+        }
+    }
+
+    private void executePerConnectionSqlFromConfiguration(int startIndex) {
+        for (int i = startIndex; i < mConfiguration.perConnectionSql.size(); i++) {
+            final Pair<String, Object[]> statement = mConfiguration.perConnectionSql.get(i);
+            final int type = DatabaseUtils.getSqlStatementType(statement.first);
+            switch (type) {
+                case DatabaseUtils.STATEMENT_SELECT:
+                    executeForString(statement.first, statement.second, null);
+                    break;
+                case DatabaseUtils.STATEMENT_PRAGMA:
+                    execute(statement.first, statement.second, null);
+                    break;
+                default:
+                    throw new IllegalArgumentException(
+                            "Unsupported configuration statement: " + statement);
+            }
+        }
+    }
+
+    private void checkDatabaseWiped() {
+        if (!SQLiteGlobal.checkDbWipe()) {
+            return;
+        }
+        try {
+            final File checkFile = new File(mConfiguration.path
+                    + SQLiteGlobal.WIPE_CHECK_FILE_SUFFIX);
+
+            final boolean hasMetadataTable = executeForLong(
+                    "SELECT count(*) FROM sqlite_master"
+                            + " WHERE type='table' AND name='android_metadata'", null, null) > 0;
+            final boolean hasCheckFile = checkFile.exists();
+
+            if (!mIsReadOnlyConnection && !hasCheckFile) {
+                // Create the check file, unless it's a readonly connection,
+                // in which case we can't create the metadata table anyway.
+                checkFile.createNewFile();
+            }
+
+            if (!hasMetadataTable && hasCheckFile) {
+                // Bad. The DB is gone unexpectedly.
+                SQLiteDatabase.wipeDetected(mConfiguration.path, "unknown");
+            }
+
+        } catch (RuntimeException | IOException ex) {
+            SQLiteDatabase.wtfAsSystemServer(TAG,
+                    "Unexpected exception while checking for wipe", ex);
+        }
+    }
+
+    // Called by SQLiteConnectionPool only.
+    void reconfigure(SQLiteDatabaseConfiguration configuration) {
+        mOnlyAllowReadOnlyOperations = false;
+
+        // Remember what changed.
+        boolean foreignKeyModeChanged = configuration.foreignKeyConstraintsEnabled
+                != mConfiguration.foreignKeyConstraintsEnabled;
+        boolean walModeChanged = ((configuration.openFlags ^ mConfiguration.openFlags)
+                & (SQLiteDatabase.ENABLE_WRITE_AHEAD_LOGGING
+                | SQLiteDatabase.ENABLE_LEGACY_COMPATIBILITY_WAL)) != 0;
+        boolean localeChanged = !configuration.locale.equals(mConfiguration.locale);
+        boolean customScalarFunctionsChanged = !configuration.customScalarFunctions
+                .equals(mConfiguration.customScalarFunctions);
+        boolean customAggregateFunctionsChanged = !configuration.customAggregateFunctions
+                .equals(mConfiguration.customAggregateFunctions);
+        final int oldSize = mConfiguration.perConnectionSql.size();
+        final int newSize = configuration.perConnectionSql.size();
+        boolean perConnectionSqlChanged = newSize > oldSize;
+
+        // Update configuration parameters.
+        mConfiguration.updateParametersFrom(configuration);
+
+        // Update prepared statement cache size.
+        mPreparedStatementCache.resize(configuration.maxSqlCacheSize);
+
+        if (foreignKeyModeChanged) {
+            setForeignKeyModeFromConfiguration();
+        }
+        if (walModeChanged) {
+            setWalModeFromConfiguration();
+        }
+        if (localeChanged) {
+            setLocaleFromConfiguration();
+        }
+        if (customScalarFunctionsChanged || customAggregateFunctionsChanged) {
+            setCustomFunctionsFromConfiguration();
+        }
+        if (perConnectionSqlChanged) {
+            executePerConnectionSqlFromConfiguration(oldSize);
+        }
+    }
+
+    // Called by SQLiteConnectionPool only.
+    // When set to true, executing write operations will throw SQLiteException.
+    // Preparing statements that might write is ok, just don't execute them.
+    void setOnlyAllowReadOnlyOperations(boolean readOnly) {
+        mOnlyAllowReadOnlyOperations = readOnly;
+    }
+
+    // Called by SQLiteConnectionPool only.
+    // Returns true if the prepared statement cache contains the specified SQL.
+    boolean isPreparedStatementInCache(String sql) {
+        return mPreparedStatementCache.get(sql) != null;
+    }
+
+    /**
+     * Gets the unique id of this connection.
+     * @return The connection id.
+     */
+    public int getConnectionId() {
+        return mConnectionId;
+    }
+
+    /**
+     * Returns true if this is the primary database connection.
+     * @return True if this is the primary database connection.
+     */
+    public boolean isPrimaryConnection() {
+        return mIsPrimaryConnection;
+    }
+
+    /**
+     * Prepares a statement for execution but does not bind its parameters or execute it.
+     * <p>
+     * This method can be used to check for syntax errors during compilation
+     * prior to execution of the statement.  If the {@code outStatementInfo} argument
+     * is not null, the provided {@link SQLiteStatementInfo} object is populated
+     * with information about the statement.
+     * </p><p>
+     * A prepared statement makes no reference to the arguments that may eventually
+     * be bound to it, consequently it it possible to cache certain prepared statements
+     * such as SELECT or INSERT/UPDATE statements.  If the statement is cacheable,
+     * then it will be stored in the cache for later.
+     * </p><p>
+     * To take advantage of this behavior as an optimization, the connection pool
+     * provides a method to acquire a connection that already has a given SQL statement
+     * in its prepared statement cache so that it is ready for execution.
+     * </p>
+     *
+     * @param sql The SQL statement to prepare.
+     * @param outStatementInfo The {@link SQLiteStatementInfo} object to populate
+     * with information about the statement, or null if none.
+     *
+     * @throws SQLiteException if an error occurs, such as a syntax error.
+     */
+    public void prepare(String sql, SQLiteStatementInfo outStatementInfo) {
+        if (sql == null) {
+            throw new IllegalArgumentException("sql must not be null.");
+        }
+
+        final int cookie = mRecentOperations.beginOperation("prepare", sql, null);
+        try {
+            final PreparedStatement statement = acquirePreparedStatement(sql);
+            try {
+                if (outStatementInfo != null) {
+                    outStatementInfo.numParameters = statement.mNumParameters;
+                    outStatementInfo.readOnly = statement.mReadOnly;
+
+                    final int columnCount = nativeGetColumnCount(
+                            mConnectionPtr, statement.mStatementPtr);
+                    if (columnCount == 0) {
+                        outStatementInfo.columnNames = EMPTY_STRING_ARRAY;
+                    } else {
+                        outStatementInfo.columnNames = new String[columnCount];
+                        for (int i = 0; i < columnCount; i++) {
+                            outStatementInfo.columnNames[i] = nativeGetColumnName(
+                                    mConnectionPtr, statement.mStatementPtr, i);
+                        }
+                    }
+                }
+            } finally {
+                releasePreparedStatement(statement);
+            }
+        } catch (RuntimeException ex) {
+            mRecentOperations.failOperation(cookie, ex);
+            throw ex;
+        } finally {
+            mRecentOperations.endOperation(cookie);
+        }
+    }
+
+    /**
+     * Executes a statement that does not return a result.
+     *
+     * @param sql The SQL statement to execute.
+     * @param bindArgs The arguments to bind, or null if none.
+     * @param cancellationSignal A signal to cancel the operation in progress, or null if none.
+     *
+     * @throws SQLiteException if an error occurs, such as a syntax error
+     * or invalid number of bind arguments.
+     * @throws OperationCanceledException if the operation was canceled.
+     */
+    public void execute(String sql, Object[] bindArgs,
+            CancellationSignal cancellationSignal) {
+        if (sql == null) {
+            throw new IllegalArgumentException("sql must not be null.");
+        }
+
+        final int cookie = mRecentOperations.beginOperation("execute", sql, bindArgs);
+        try {
+            final PreparedStatement statement = acquirePreparedStatement(sql);
+            try {
+                throwIfStatementForbidden(statement);
+                bindArguments(statement, bindArgs);
+                applyBlockGuardPolicy(statement);
+                attachCancellationSignal(cancellationSignal);
+                try {
+                    nativeExecute(mConnectionPtr, statement.mStatementPtr);
+                } finally {
+                    detachCancellationSignal(cancellationSignal);
+                }
+            } finally {
+                releasePreparedStatement(statement);
+            }
+        } catch (RuntimeException ex) {
+            mRecentOperations.failOperation(cookie, ex);
+            throw ex;
+        } finally {
+            mRecentOperations.endOperation(cookie);
+        }
+    }
+
+    /**
+     * Executes a statement that returns a single <code>long</code> result.
+     *
+     * @param sql The SQL statement to execute.
+     * @param bindArgs The arguments to bind, or null if none.
+     * @param cancellationSignal A signal to cancel the operation in progress, or null if none.
+     * @return The value of the first column in the first row of the result set
+     * as a <code>long</code>, or zero if none.
+     *
+     * @throws SQLiteException if an error occurs, such as a syntax error
+     * or invalid number of bind arguments.
+     * @throws OperationCanceledException if the operation was canceled.
+     */
+    public long executeForLong(String sql, Object[] bindArgs,
+            CancellationSignal cancellationSignal) {
+        if (sql == null) {
+            throw new IllegalArgumentException("sql must not be null.");
+        }
+
+        final int cookie = mRecentOperations.beginOperation("executeForLong", sql, bindArgs);
+        try {
+            final PreparedStatement statement = acquirePreparedStatement(sql);
+            try {
+                throwIfStatementForbidden(statement);
+                bindArguments(statement, bindArgs);
+                applyBlockGuardPolicy(statement);
+                attachCancellationSignal(cancellationSignal);
+                try {
+                    long ret = nativeExecuteForLong(mConnectionPtr, statement.mStatementPtr);
+                    mRecentOperations.setResult(ret);
+                    return ret;
+                } finally {
+                    detachCancellationSignal(cancellationSignal);
+                }
+            } finally {
+                releasePreparedStatement(statement);
+            }
+        } catch (RuntimeException ex) {
+            mRecentOperations.failOperation(cookie, ex);
+            throw ex;
+        } finally {
+            mRecentOperations.endOperation(cookie);
+        }
+    }
+
+    /**
+     * Executes a statement that returns a single {@link String} result.
+     *
+     * @param sql The SQL statement to execute.
+     * @param bindArgs The arguments to bind, or null if none.
+     * @param cancellationSignal A signal to cancel the operation in progress, or null if none.
+     * @return The value of the first column in the first row of the result set
+     * as a <code>String</code>, or null if none.
+     *
+     * @throws SQLiteException if an error occurs, such as a syntax error
+     * or invalid number of bind arguments.
+     * @throws OperationCanceledException if the operation was canceled.
+     */
+    public String executeForString(String sql, Object[] bindArgs,
+            CancellationSignal cancellationSignal) {
+        if (sql == null) {
+            throw new IllegalArgumentException("sql must not be null.");
+        }
+
+        final int cookie = mRecentOperations.beginOperation("executeForString", sql, bindArgs);
+        try {
+            final PreparedStatement statement = acquirePreparedStatement(sql);
+            try {
+                throwIfStatementForbidden(statement);
+                bindArguments(statement, bindArgs);
+                applyBlockGuardPolicy(statement);
+                attachCancellationSignal(cancellationSignal);
+                try {
+                    String ret = nativeExecuteForString(mConnectionPtr, statement.mStatementPtr);
+                    mRecentOperations.setResult(ret);
+                    return ret;
+                } finally {
+                    detachCancellationSignal(cancellationSignal);
+                }
+            } finally {
+                releasePreparedStatement(statement);
+            }
+        } catch (RuntimeException ex) {
+            mRecentOperations.failOperation(cookie, ex);
+            throw ex;
+        } finally {
+            mRecentOperations.endOperation(cookie);
+        }
+    }
+
+    /**
+     * Executes a statement that returns a single BLOB result as a
+     * file descriptor to a shared memory region.
+     *
+     * @param sql The SQL statement to execute.
+     * @param bindArgs The arguments to bind, or null if none.
+     * @param cancellationSignal A signal to cancel the operation in progress, or null if none.
+     * @return The file descriptor for a shared memory region that contains
+     * the value of the first column in the first row of the result set as a BLOB,
+     * or null if none.
+     *
+     * @throws SQLiteException if an error occurs, such as a syntax error
+     * or invalid number of bind arguments.
+     * @throws OperationCanceledException if the operation was canceled.
+     */
+    public ParcelFileDescriptor executeForBlobFileDescriptor(String sql, Object[] bindArgs,
+            CancellationSignal cancellationSignal) {
+        if (sql == null) {
+            throw new IllegalArgumentException("sql must not be null.");
+        }
+
+        final int cookie = mRecentOperations.beginOperation("executeForBlobFileDescriptor",
+                sql, bindArgs);
+        try {
+            final PreparedStatement statement = acquirePreparedStatement(sql);
+            try {
+                throwIfStatementForbidden(statement);
+                bindArguments(statement, bindArgs);
+                applyBlockGuardPolicy(statement);
+                attachCancellationSignal(cancellationSignal);
+                try {
+                    int fd = nativeExecuteForBlobFileDescriptor(
+                            mConnectionPtr, statement.mStatementPtr);
+                    return fd >= 0 ? ParcelFileDescriptor.adoptFd(fd) : null;
+                } finally {
+                    detachCancellationSignal(cancellationSignal);
+                }
+            } finally {
+                releasePreparedStatement(statement);
+            }
+        } catch (RuntimeException ex) {
+            mRecentOperations.failOperation(cookie, ex);
+            throw ex;
+        } finally {
+            mRecentOperations.endOperation(cookie);
+        }
+    }
+
+    /**
+     * Executes a statement that returns a count of the number of rows
+     * that were changed.  Use for UPDATE or DELETE SQL statements.
+     *
+     * @param sql The SQL statement to execute.
+     * @param bindArgs The arguments to bind, or null if none.
+     * @param cancellationSignal A signal to cancel the operation in progress, or null if none.
+     * @return The number of rows that were changed.
+     *
+     * @throws SQLiteException if an error occurs, such as a syntax error
+     * or invalid number of bind arguments.
+     * @throws OperationCanceledException if the operation was canceled.
+     */
+    public int executeForChangedRowCount(String sql, Object[] bindArgs,
+            CancellationSignal cancellationSignal) {
+        if (sql == null) {
+            throw new IllegalArgumentException("sql must not be null.");
+        }
+
+        int changedRows = 0;
+        final int cookie = mRecentOperations.beginOperation("executeForChangedRowCount",
+                sql, bindArgs);
+        try {
+            final PreparedStatement statement = acquirePreparedStatement(sql);
+            try {
+                throwIfStatementForbidden(statement);
+                bindArguments(statement, bindArgs);
+                applyBlockGuardPolicy(statement);
+                attachCancellationSignal(cancellationSignal);
+                try {
+                    changedRows = nativeExecuteForChangedRowCount(
+                            mConnectionPtr, statement.mStatementPtr);
+                    return changedRows;
+                } finally {
+                    detachCancellationSignal(cancellationSignal);
+                }
+            } finally {
+                releasePreparedStatement(statement);
+            }
+        } catch (RuntimeException ex) {
+            mRecentOperations.failOperation(cookie, ex);
+            throw ex;
+        } finally {
+            if (mRecentOperations.endOperationDeferLog(cookie)) {
+                mRecentOperations.logOperation(cookie, "changedRows=" + changedRows);
+            }
+        }
+    }
+
+    /**
+     * Executes a statement that returns the row id of the last row inserted
+     * by the statement.  Use for INSERT SQL statements.
+     *
+     * @param sql The SQL statement to execute.
+     * @param bindArgs The arguments to bind, or null if none.
+     * @param cancellationSignal A signal to cancel the operation in progress, or null if none.
+     * @return The row id of the last row that was inserted, or 0 if none.
+     *
+     * @throws SQLiteException if an error occurs, such as a syntax error
+     * or invalid number of bind arguments.
+     * @throws OperationCanceledException if the operation was canceled.
+     */
+    public long executeForLastInsertedRowId(String sql, Object[] bindArgs,
+            CancellationSignal cancellationSignal) {
+        if (sql == null) {
+            throw new IllegalArgumentException("sql must not be null.");
+        }
+
+        final int cookie = mRecentOperations.beginOperation("executeForLastInsertedRowId",
+                sql, bindArgs);
+        try {
+            final PreparedStatement statement = acquirePreparedStatement(sql);
+            try {
+                throwIfStatementForbidden(statement);
+                bindArguments(statement, bindArgs);
+                applyBlockGuardPolicy(statement);
+                attachCancellationSignal(cancellationSignal);
+                try {
+                    return nativeExecuteForLastInsertedRowId(
+                            mConnectionPtr, statement.mStatementPtr);
+                } finally {
+                    detachCancellationSignal(cancellationSignal);
+                }
+            } finally {
+                releasePreparedStatement(statement);
+            }
+        } catch (RuntimeException ex) {
+            mRecentOperations.failOperation(cookie, ex);
+            throw ex;
+        } finally {
+            mRecentOperations.endOperation(cookie);
+        }
+    }
+
+    /**
+     * Executes a statement and populates the specified {@link CursorWindow}
+     * with a range of results.  Returns the number of rows that were counted
+     * during query execution.
+     *
+     * @param sql The SQL statement to execute.
+     * @param bindArgs The arguments to bind, or null if none.
+     * @param window The cursor window to clear and fill.
+     * @param startPos The start position for filling the window.
+     * @param requiredPos The position of a row that MUST be in the window.
+     * If it won't fit, then the query should discard part of what it filled
+     * so that it does.  Must be greater than or equal to <code>startPos</code>.
+     * @param countAllRows True to count all rows that the query would return
+     * regagless of whether they fit in the window.
+     * @param cancellationSignal A signal to cancel the operation in progress, or null if none.
+     * @return The number of rows that were counted during query execution.  Might
+     * not be all rows in the result set unless <code>countAllRows</code> is true.
+     *
+     * @throws SQLiteException if an error occurs, such as a syntax error
+     * or invalid number of bind arguments.
+     * @throws OperationCanceledException if the operation was canceled.
+     */
+    public int executeForCursorWindow(String sql, Object[] bindArgs,
+            CursorWindow window, int startPos, int requiredPos, boolean countAllRows,
+            CancellationSignal cancellationSignal) {
+        if (sql == null) {
+            throw new IllegalArgumentException("sql must not be null.");
+        }
+        if (window == null) {
+            throw new IllegalArgumentException("window must not be null.");
+        }
+
+        window.acquireReference();
+        try {
+            int actualPos = -1;
+            int countedRows = -1;
+            int filledRows = -1;
+            final int cookie = mRecentOperations.beginOperation("executeForCursorWindow",
+                    sql, bindArgs);
+            try {
+                final PreparedStatement statement = acquirePreparedStatement(sql);
+                try {
+                    throwIfStatementForbidden(statement);
+                    bindArguments(statement, bindArgs);
+                    applyBlockGuardPolicy(statement);
+                    attachCancellationSignal(cancellationSignal);
+                    try {
+                        final long result = nativeExecuteForCursorWindow(
+                                mConnectionPtr, statement.mStatementPtr, window.mWindowPtr,
+                                startPos, requiredPos, countAllRows);
+                        actualPos = (int)(result >> 32);
+                        countedRows = (int)result;
+                        filledRows = window.getNumRows();
+                        window.setStartPosition(actualPos);
+                        return countedRows;
+                    } finally {
+                        detachCancellationSignal(cancellationSignal);
+                    }
+                } finally {
+                    releasePreparedStatement(statement);
+                }
+            } catch (RuntimeException ex) {
+                mRecentOperations.failOperation(cookie, ex);
+                throw ex;
+            } finally {
+                if (mRecentOperations.endOperationDeferLog(cookie)) {
+                    mRecentOperations.logOperation(cookie, "window='" + window
+                            + "', startPos=" + startPos
+                            + ", actualPos=" + actualPos
+                            + ", filledRows=" + filledRows
+                            + ", countedRows=" + countedRows);
+                }
+            }
+        } finally {
+            window.releaseReference();
+        }
+    }
+
+    private PreparedStatement acquirePreparedStatement(String sql) {
+        PreparedStatement statement = mPreparedStatementCache.get(sql);
+        boolean skipCache = false;
+        if (statement != null) {
+            if (!statement.mInUse) {
+                return statement;
+            }
+            // The statement is already in the cache but is in use (this statement appears
+            // to be not only re-entrant but recursive!).  So prepare a new copy of the
+            // statement but do not cache it.
+            skipCache = true;
+        }
+
+        final long statementPtr = nativePrepareStatement(mConnectionPtr, sql);
+        try {
+            final int numParameters = nativeGetParameterCount(mConnectionPtr, statementPtr);
+            final int type = DatabaseUtils.getSqlStatementType(sql);
+            final boolean readOnly = nativeIsReadOnly(mConnectionPtr, statementPtr);
+            statement = obtainPreparedStatement(sql, statementPtr, numParameters, type, readOnly);
+            if (!skipCache && isCacheable(type)) {
+                mPreparedStatementCache.put(sql, statement);
+                statement.mInCache = true;
+            }
+        } catch (RuntimeException ex) {
+            // Finalize the statement if an exception occurred and we did not add
+            // it to the cache.  If it is already in the cache, then leave it there.
+            if (statement == null || !statement.mInCache) {
+                nativeFinalizeStatement(mConnectionPtr, statementPtr);
+            }
+            throw ex;
+        }
+        statement.mInUse = true;
+        return statement;
+    }
+
+    private void releasePreparedStatement(PreparedStatement statement) {
+        statement.mInUse = false;
+        if (statement.mInCache) {
+            try {
+                nativeResetStatementAndClearBindings(mConnectionPtr, statement.mStatementPtr);
+            } catch (SQLiteException ex) {
+                // The statement could not be reset due to an error.  Remove it from the cache.
+                // When remove() is called, the cache will invoke its entryRemoved() callback,
+                // which will in turn call finalizePreparedStatement() to finalize and
+                // recycle the statement.
+                if (DEBUG) {
+                    Log.d(TAG, "Could not reset prepared statement due to an exception.  "
+                            + "Removing it from the cache.  SQL: "
+                            + trimSqlForDisplay(statement.mSql), ex);
+                }
+
+                mPreparedStatementCache.remove(statement.mSql);
+            }
+        } else {
+            finalizePreparedStatement(statement);
+        }
+    }
+
+    private void finalizePreparedStatement(PreparedStatement statement) {
+        nativeFinalizeStatement(mConnectionPtr, statement.mStatementPtr);
+        recyclePreparedStatement(statement);
+    }
+
+    private void attachCancellationSignal(CancellationSignal cancellationSignal) {
+        if (cancellationSignal != null) {
+            cancellationSignal.throwIfCanceled();
+
+            mCancellationSignalAttachCount += 1;
+            if (mCancellationSignalAttachCount == 1) {
+                // Reset cancellation flag before executing the statement.
+                nativeResetCancel(mConnectionPtr, true /*cancelable*/);
+
+                // After this point, onCancel() may be called concurrently.
+                cancellationSignal.setOnCancelListener(this);
+            }
+        }
+    }
+
+    private void detachCancellationSignal(CancellationSignal cancellationSignal) {
+        if (cancellationSignal != null) {
+            assert mCancellationSignalAttachCount > 0;
+
+            mCancellationSignalAttachCount -= 1;
+            if (mCancellationSignalAttachCount == 0) {
+                // After this point, onCancel() cannot be called concurrently.
+                cancellationSignal.setOnCancelListener(null);
+
+                // Reset cancellation flag after executing the statement.
+                nativeResetCancel(mConnectionPtr, false /*cancelable*/);
+            }
+        }
+    }
+
+    // CancellationSignal.OnCancelListener callback.
+    // This method may be called on a different thread than the executing statement.
+    // However, it will only be called between calls to attachCancellationSignal and
+    // detachCancellationSignal, while a statement is executing.  We can safely assume
+    // that the SQLite connection is still alive.
+    @Override
+    public void onCancel() {
+        nativeCancel(mConnectionPtr);
+    }
+
+    private void bindArguments(PreparedStatement statement, Object[] bindArgs) {
+        final int count = bindArgs != null ? bindArgs.length : 0;
+        if (count != statement.mNumParameters) {
+            throw new SQLiteBindOrColumnIndexOutOfRangeException(
+                    "Expected " + statement.mNumParameters + " bind arguments but "
+                    + count + " were provided.");
+        }
+        if (count == 0) {
+            return;
+        }
+
+        final long statementPtr = statement.mStatementPtr;
+        for (int i = 0; i < count; i++) {
+            final Object arg = bindArgs[i];
+            switch (DatabaseUtils.getTypeOfObject(arg)) {
+                case Cursor.FIELD_TYPE_NULL:
+                    nativeBindNull(mConnectionPtr, statementPtr, i + 1);
+                    break;
+                case Cursor.FIELD_TYPE_INTEGER:
+                    nativeBindLong(mConnectionPtr, statementPtr, i + 1,
+                            ((Number)arg).longValue());
+                    break;
+                case Cursor.FIELD_TYPE_FLOAT:
+                    nativeBindDouble(mConnectionPtr, statementPtr, i + 1,
+                            ((Number)arg).doubleValue());
+                    break;
+                case Cursor.FIELD_TYPE_BLOB:
+                    nativeBindBlob(mConnectionPtr, statementPtr, i + 1, (byte[])arg);
+                    break;
+                case Cursor.FIELD_TYPE_STRING:
+                default:
+                    if (arg instanceof Boolean) {
+                        // Provide compatibility with legacy applications which may pass
+                        // Boolean values in bind args.
+                        nativeBindLong(mConnectionPtr, statementPtr, i + 1,
+                                ((Boolean)arg).booleanValue() ? 1 : 0);
+                    } else {
+                        nativeBindString(mConnectionPtr, statementPtr, i + 1, arg.toString());
+                    }
+                    break;
+            }
+        }
+    }
+
+    private void throwIfStatementForbidden(PreparedStatement statement) {
+        if (mOnlyAllowReadOnlyOperations && !statement.mReadOnly) {
+            throw new SQLiteException("Cannot execute this statement because it "
+                    + "might modify the database but the connection is read-only.");
+        }
+    }
+
+    private static boolean isCacheable(int statementType) {
+        if (statementType == DatabaseUtils.STATEMENT_UPDATE
+                || statementType == DatabaseUtils.STATEMENT_SELECT) {
+            return true;
+        }
+        return false;
+    }
+
+    private void applyBlockGuardPolicy(PreparedStatement statement) {
+        if (!mConfiguration.isInMemoryDb()) {
+            if (statement.mReadOnly) {
+                BlockGuard.getThreadPolicy().onReadFromDisk();
+            } else {
+                BlockGuard.getThreadPolicy().onWriteToDisk();
+            }
+        }
+    }
+
+    /**
+     * Dumps debugging information about this connection.
+     *
+     * @param printer The printer to receive the dump, not null.
+     * @param verbose True to dump more verbose information.
+     */
+    public void dump(Printer printer, boolean verbose) {
+        dumpUnsafe(printer, verbose);
+    }
+
+    /**
+     * Dumps debugging information about this connection, in the case where the
+     * caller might not actually own the connection.
+     *
+     * This function is written so that it may be called by a thread that does not
+     * own the connection.  We need to be very careful because the connection state is
+     * not synchronized.
+     *
+     * At worst, the method may return stale or slightly wrong data, however
+     * it should not crash.  This is ok as it is only used for diagnostic purposes.
+     *
+     * @param printer The printer to receive the dump, not null.
+     * @param verbose True to dump more verbose information.
+     */
+    void dumpUnsafe(Printer printer, boolean verbose) {
+        printer.println("Connection #" + mConnectionId + ":");
+        if (verbose) {
+            printer.println("  connectionPtr: 0x" + Long.toHexString(mConnectionPtr));
+        }
+        printer.println("  isPrimaryConnection: " + mIsPrimaryConnection);
+        printer.println("  onlyAllowReadOnlyOperations: " + mOnlyAllowReadOnlyOperations);
+
+        mRecentOperations.dump(printer);
+
+        if (verbose) {
+            mPreparedStatementCache.dump(printer);
+        }
+    }
+
+    /**
+     * Describes the currently executing operation, in the case where the
+     * caller might not actually own the connection.
+     *
+     * This function is written so that it may be called by a thread that does not
+     * own the connection.  We need to be very careful because the connection state is
+     * not synchronized.
+     *
+     * At worst, the method may return stale or slightly wrong data, however
+     * it should not crash.  This is ok as it is only used for diagnostic purposes.
+     *
+     * @return A description of the current operation including how long it has been running,
+     * or null if none.
+     */
+    String describeCurrentOperationUnsafe() {
+        return mRecentOperations.describeCurrentOperation();
+    }
+
+    /**
+     * Collects statistics about database connection memory usage.
+     *
+     * @param dbStatsList The list to populate.
+     */
+    void collectDbStats(ArrayList<DbStats> dbStatsList) {
+        // Get information about the main database.
+        int lookaside = nativeGetDbLookaside(mConnectionPtr);
+        long pageCount = 0;
+        long pageSize = 0;
+        try {
+            pageCount = executeForLong("PRAGMA page_count;", null, null);
+            pageSize = executeForLong("PRAGMA page_size;", null, null);
+        } catch (SQLiteException ex) {
+            // Ignore.
+        }
+        dbStatsList.add(getMainDbStatsUnsafe(lookaside, pageCount, pageSize));
+
+        // Get information about attached databases.
+        // We ignore the first row in the database list because it corresponds to
+        // the main database which we have already described.
+        CursorWindow window = new CursorWindow("collectDbStats");
+        try {
+            executeForCursorWindow("PRAGMA database_list;", null, window, 0, 0, false, null);
+            for (int i = 1; i < window.getNumRows(); i++) {
+                String name = window.getString(i, 1);
+                String path = window.getString(i, 2);
+                pageCount = 0;
+                pageSize = 0;
+                try {
+                    pageCount = executeForLong("PRAGMA " + name + ".page_count;", null, null);
+                    pageSize = executeForLong("PRAGMA " + name + ".page_size;", null, null);
+                } catch (SQLiteException ex) {
+                    // Ignore.
+                }
+                String label = "  (attached) " + name;
+                if (!path.isEmpty()) {
+                    label += ": " + path;
+                }
+                dbStatsList.add(new DbStats(label, pageCount, pageSize, 0, 0, 0, 0));
+            }
+        } catch (SQLiteException ex) {
+            // Ignore.
+        } finally {
+            window.close();
+        }
+    }
+
+    /**
+     * Collects statistics about database connection memory usage, in the case where the
+     * caller might not actually own the connection.
+     *
+     * @return The statistics object, never null.
+     */
+    void collectDbStatsUnsafe(ArrayList<DbStats> dbStatsList) {
+        dbStatsList.add(getMainDbStatsUnsafe(0, 0, 0));
+    }
+
+    private DbStats getMainDbStatsUnsafe(int lookaside, long pageCount, long pageSize) {
+        // The prepared statement cache is thread-safe so we can access its statistics
+        // even if we do not own the database connection.
+        String label = mConfiguration.path;
+        if (!mIsPrimaryConnection) {
+            label += " (" + mConnectionId + ")";
+        }
+        return new DbStats(label, pageCount, pageSize, lookaside,
+                mPreparedStatementCache.hitCount(),
+                mPreparedStatementCache.missCount(),
+                mPreparedStatementCache.size());
+    }
+
+    @Override
+    public String toString() {
+        return "SQLiteConnection: " + mConfiguration.path + " (" + mConnectionId + ")";
+    }
+
+    private PreparedStatement obtainPreparedStatement(String sql, long statementPtr,
+            int numParameters, int type, boolean readOnly) {
+        PreparedStatement statement = mPreparedStatementPool;
+        if (statement != null) {
+            mPreparedStatementPool = statement.mPoolNext;
+            statement.mPoolNext = null;
+            statement.mInCache = false;
+        } else {
+            statement = new PreparedStatement();
+        }
+        statement.mSql = sql;
+        statement.mStatementPtr = statementPtr;
+        statement.mNumParameters = numParameters;
+        statement.mType = type;
+        statement.mReadOnly = readOnly;
+        return statement;
+    }
+
+    private void recyclePreparedStatement(PreparedStatement statement) {
+        statement.mSql = null;
+        statement.mPoolNext = mPreparedStatementPool;
+        mPreparedStatementPool = statement;
+    }
+
+    private static String trimSqlForDisplay(String sql) {
+        // Note: Creating and caching a regular expression is expensive at preload-time
+        //       and stops compile-time initialization. This pattern is only used when
+        //       dumping the connection, which is a rare (mainly error) case. So:
+        //       DO NOT CACHE.
+        return sql.replaceAll("[\\s]*\\n+[\\s]*", " ");
+    }
+
+    /**
+     * Holder type for a prepared statement.
+     *
+     * Although this object holds a pointer to a native statement object, it
+     * does not have a finalizer.  This is deliberate.  The {@link SQLiteConnection}
+     * owns the statement object and will take care of freeing it when needed.
+     * In particular, closing the connection requires a guarantee of deterministic
+     * resource disposal because all native statement objects must be freed before
+     * the native database object can be closed.  So no finalizers here.
+     */
+    private static final class PreparedStatement {
+        // Next item in pool.
+        public PreparedStatement mPoolNext;
+
+        // The SQL from which the statement was prepared.
+        public String mSql;
+
+        // The native sqlite3_stmt object pointer.
+        // Lifetime is managed explicitly by the connection.
+        public long mStatementPtr;
+
+        // The number of parameters that the prepared statement has.
+        public int mNumParameters;
+
+        // The statement type.
+        public int mType;
+
+        // True if the statement is read-only.
+        public boolean mReadOnly;
+
+        // True if the statement is in the cache.
+        public boolean mInCache;
+
+        // True if the statement is in use (currently executing).
+        // We need this flag because due to the use of custom functions in triggers, it's
+        // possible for SQLite calls to be re-entrant.  Consequently we need to prevent
+        // in use statements from being finalized until they are no longer in use.
+        public boolean mInUse;
+    }
+
+    private final class PreparedStatementCache
+            extends LruCache<String, PreparedStatement> {
+        public PreparedStatementCache(int size) {
+            super(size);
+        }
+
+        @Override
+        protected void entryRemoved(boolean evicted, String key,
+                PreparedStatement oldValue, PreparedStatement newValue) {
+            oldValue.mInCache = false;
+            if (!oldValue.mInUse) {
+                finalizePreparedStatement(oldValue);
+            }
+        }
+
+        public void dump(Printer printer) {
+            printer.println("  Prepared statement cache:");
+            Map<String, PreparedStatement> cache = snapshot();
+            if (!cache.isEmpty()) {
+                int i = 0;
+                for (Map.Entry<String, PreparedStatement> entry : cache.entrySet()) {
+                    PreparedStatement statement = entry.getValue();
+                    if (statement.mInCache) { // might be false due to a race with entryRemoved
+                        String sql = entry.getKey();
+                        printer.println("    " + i + ": statementPtr=0x"
+                                + Long.toHexString(statement.mStatementPtr)
+                                + ", numParameters=" + statement.mNumParameters
+                                + ", type=" + statement.mType
+                                + ", readOnly=" + statement.mReadOnly
+                                + ", sql=\"" + trimSqlForDisplay(sql) + "\"");
+                    }
+                    i += 1;
+                }
+            } else {
+                printer.println("    <none>");
+            }
+        }
+    }
+
+    private static final class OperationLog {
+        private static final int MAX_RECENT_OPERATIONS = 20;
+        private static final int COOKIE_GENERATION_SHIFT = 8;
+        private static final int COOKIE_INDEX_MASK = 0xff;
+
+        private final Operation[] mOperations = new Operation[MAX_RECENT_OPERATIONS];
+        private int mIndex;
+        private int mGeneration;
+        private final SQLiteConnectionPool mPool;
+        private long mResultLong = Long.MIN_VALUE;
+        private String mResultString;
+
+        OperationLog(SQLiteConnectionPool pool) {
+            mPool = pool;
+        }
+
+        public int beginOperation(String kind, String sql, Object[] bindArgs) {
+            mResultLong = Long.MIN_VALUE;
+            mResultString = null;
+
+            synchronized (mOperations) {
+                final int index = (mIndex + 1) % MAX_RECENT_OPERATIONS;
+                Operation operation = mOperations[index];
+                if (operation == null) {
+                    operation = new Operation();
+                    mOperations[index] = operation;
+                } else {
+                    operation.mFinished = false;
+                    operation.mException = null;
+                    if (operation.mBindArgs != null) {
+                        operation.mBindArgs.clear();
+                    }
+                }
+                operation.mStartWallTime = System.currentTimeMillis();
+                operation.mStartTime = SystemClock.uptimeMillis();
+                operation.mKind = kind;
+                operation.mSql = sql;
+                operation.mPath = mPool.getPath();
+                operation.mResultLong = Long.MIN_VALUE;
+                operation.mResultString = null;
+                if (bindArgs != null) {
+                    if (operation.mBindArgs == null) {
+                        operation.mBindArgs = new ArrayList<Object>();
+                    } else {
+                        operation.mBindArgs.clear();
+                    }
+                    for (int i = 0; i < bindArgs.length; i++) {
+                        final Object arg = bindArgs[i];
+                        if (arg != null && arg instanceof byte[]) {
+                            // Don't hold onto the real byte array longer than necessary.
+                            operation.mBindArgs.add(EMPTY_BYTE_ARRAY);
+                        } else {
+                            operation.mBindArgs.add(arg);
+                        }
+                    }
+                }
+                operation.mCookie = newOperationCookieLocked(index);
+                if (Trace.isTagEnabled(Trace.TRACE_TAG_DATABASE)) {
+                    Trace.asyncTraceBegin(Trace.TRACE_TAG_DATABASE, operation.getTraceMethodName(),
+                            operation.mCookie);
+                }
+                mIndex = index;
+                return operation.mCookie;
+            }
+        }
+
+        public void failOperation(int cookie, Exception ex) {
+            synchronized (mOperations) {
+                final Operation operation = getOperationLocked(cookie);
+                if (operation != null) {
+                    operation.mException = ex;
+                }
+            }
+        }
+
+        public void endOperation(int cookie) {
+            synchronized (mOperations) {
+                if (endOperationDeferLogLocked(cookie)) {
+                    logOperationLocked(cookie, null);
+                }
+            }
+        }
+
+        public boolean endOperationDeferLog(int cookie) {
+            synchronized (mOperations) {
+                return endOperationDeferLogLocked(cookie);
+            }
+        }
+
+        public void logOperation(int cookie, String detail) {
+            synchronized (mOperations) {
+                logOperationLocked(cookie, detail);
+            }
+        }
+
+        public void setResult(long longResult) {
+            mResultLong = longResult;
+        }
+
+        public void setResult(String stringResult) {
+            mResultString = stringResult;
+        }
+
+        private boolean endOperationDeferLogLocked(int cookie) {
+            final Operation operation = getOperationLocked(cookie);
+            if (operation != null) {
+                if (Trace.isTagEnabled(Trace.TRACE_TAG_DATABASE)) {
+                    Trace.asyncTraceEnd(Trace.TRACE_TAG_DATABASE, operation.getTraceMethodName(),
+                            operation.mCookie);
+                }
+                operation.mEndTime = SystemClock.uptimeMillis();
+                operation.mFinished = true;
+                final long execTime = operation.mEndTime - operation.mStartTime;
+                mPool.onStatementExecuted(execTime);
+                return NoPreloadHolder.DEBUG_LOG_SLOW_QUERIES && SQLiteDebug.shouldLogSlowQuery(
+                        execTime);
+            }
+            return false;
+        }
+
+        private void logOperationLocked(int cookie, String detail) {
+            final Operation operation = getOperationLocked(cookie);
+            operation.mResultLong = mResultLong;
+            operation.mResultString = mResultString;
+            StringBuilder msg = new StringBuilder();
+            operation.describe(msg, true);
+            if (detail != null) {
+                msg.append(", ").append(detail);
+            }
+            Log.d(TAG, msg.toString());
+        }
+
+        private int newOperationCookieLocked(int index) {
+            final int generation = mGeneration++;
+            return generation << COOKIE_GENERATION_SHIFT | index;
+        }
+
+        private Operation getOperationLocked(int cookie) {
+            final int index = cookie & COOKIE_INDEX_MASK;
+            final Operation operation = mOperations[index];
+            return operation.mCookie == cookie ? operation : null;
+        }
+
+        public String describeCurrentOperation() {
+            synchronized (mOperations) {
+                final Operation operation = mOperations[mIndex];
+                if (operation != null && !operation.mFinished) {
+                    StringBuilder msg = new StringBuilder();
+                    operation.describe(msg, false);
+                    return msg.toString();
+                }
+                return null;
+            }
+        }
+
+        public void dump(Printer printer) {
+            synchronized (mOperations) {
+                printer.println("  Most recently executed operations:");
+                int index = mIndex;
+                Operation operation = mOperations[index];
+                if (operation != null) {
+                    // Note: SimpleDateFormat is not thread-safe, cannot be compile-time created,
+                    // and is relatively expensive to create during preloading. This method is only
+                    // used when dumping a connection, which is a rare (mainly error) case.
+                    SimpleDateFormat opDF = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS");
+                    int n = 0;
+                    do {
+                        StringBuilder msg = new StringBuilder();
+                        msg.append("    ").append(n).append(": [");
+                        String formattedStartTime = opDF.format(new Date(operation.mStartWallTime));
+                        msg.append(formattedStartTime);
+                        msg.append("] ");
+                        operation.describe(msg, false); // Never dump bingargs in a bugreport
+                        printer.println(msg.toString());
+
+                        if (index > 0) {
+                            index -= 1;
+                        } else {
+                            index = MAX_RECENT_OPERATIONS - 1;
+                        }
+                        n += 1;
+                        operation = mOperations[index];
+                    } while (operation != null && n < MAX_RECENT_OPERATIONS);
+                } else {
+                    printer.println("    <none>");
+                }
+            }
+        }
+    }
+
+    private static final class Operation {
+        // Trim all SQL statements to 256 characters inside the trace marker.
+        // This limit gives plenty of context while leaving space for other
+        // entries in the trace buffer (and ensures atrace doesn't truncate the
+        // marker for us, potentially losing metadata in the process).
+        private static final int MAX_TRACE_METHOD_NAME_LEN = 256;
+
+        public long mStartWallTime; // in System.currentTimeMillis()
+        public long mStartTime; // in SystemClock.uptimeMillis();
+        public long mEndTime; // in SystemClock.uptimeMillis();
+        public String mKind;
+        public String mSql;
+        public ArrayList<Object> mBindArgs;
+        public boolean mFinished;
+        public Exception mException;
+        public int mCookie;
+        public String mPath;
+        public long mResultLong; // MIN_VALUE means "value not set".
+        public String mResultString;
+
+        public void describe(StringBuilder msg, boolean allowDetailedLog) {
+            msg.append(mKind);
+            if (mFinished) {
+                msg.append(" took ").append(mEndTime - mStartTime).append("ms");
+            } else {
+                msg.append(" started ").append(System.currentTimeMillis() - mStartWallTime)
+                        .append("ms ago");
+            }
+            msg.append(" - ").append(getStatus());
+            if (mSql != null) {
+                msg.append(", sql=\"").append(trimSqlForDisplay(mSql)).append("\"");
+            }
+            final boolean dumpDetails = allowDetailedLog && NoPreloadHolder.DEBUG_LOG_DETAILED
+                    && mBindArgs != null && mBindArgs.size() != 0;
+            if (dumpDetails) {
+                msg.append(", bindArgs=[");
+                final int count = mBindArgs.size();
+                for (int i = 0; i < count; i++) {
+                    final Object arg = mBindArgs.get(i);
+                    if (i != 0) {
+                        msg.append(", ");
+                    }
+                    if (arg == null) {
+                        msg.append("null");
+                    } else if (arg instanceof byte[]) {
+                        msg.append("<byte[]>");
+                    } else if (arg instanceof String) {
+                        msg.append("\"").append((String)arg).append("\"");
+                    } else {
+                        msg.append(arg);
+                    }
+                }
+                msg.append("]");
+            }
+            msg.append(", path=").append(mPath);
+            if (mException != null) {
+                msg.append(", exception=\"").append(mException.getMessage()).append("\"");
+            }
+            if (mResultLong != Long.MIN_VALUE) {
+                msg.append(", result=").append(mResultLong);
+            }
+            if (mResultString != null) {
+                msg.append(", result=\"").append(mResultString).append("\"");
+            }
+        }
+
+        private String getStatus() {
+            if (!mFinished) {
+                return "running";
+            }
+            return mException != null ? "failed" : "succeeded";
+        }
+
+        private String getTraceMethodName() {
+            String methodName = mKind + " " + mSql;
+            if (methodName.length() > MAX_TRACE_METHOD_NAME_LEN)
+                return methodName.substring(0, MAX_TRACE_METHOD_NAME_LEN);
+            return methodName;
+        }
+
+    }
+}
diff --git a/android/database/sqlite/SQLiteConnectionPool.java b/android/database/sqlite/SQLiteConnectionPool.java
new file mode 100644
index 0000000..852f8f2
--- /dev/null
+++ b/android/database/sqlite/SQLiteConnectionPool.java
@@ -0,0 +1,1244 @@
+/*
+ * Copyright (C) 2011 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.database.sqlite;
+
+import android.database.sqlite.SQLiteDebug.DbStats;
+import android.os.CancellationSignal;
+import android.os.Handler;
+import android.os.Looper;
+import android.os.Message;
+import android.os.OperationCanceledException;
+import android.os.SystemClock;
+import android.text.TextUtils;
+import android.util.ArraySet;
+import android.util.Log;
+import android.util.PrefixPrinter;
+import android.util.Printer;
+
+import com.android.internal.annotations.GuardedBy;
+import com.android.internal.annotations.VisibleForTesting;
+
+import dalvik.system.CloseGuard;
+
+import java.io.Closeable;
+import java.io.File;
+import java.util.ArrayList;
+import java.util.Map;
+import java.util.WeakHashMap;
+import java.util.concurrent.atomic.AtomicBoolean;
+import java.util.concurrent.atomic.AtomicLong;
+import java.util.concurrent.locks.LockSupport;
+
+/**
+ * Maintains a pool of active SQLite database connections.
+ * <p>
+ * At any given time, a connection is either owned by the pool, or it has been
+ * acquired by a {@link SQLiteSession}.  When the {@link SQLiteSession} is
+ * finished with the connection it is using, it must return the connection
+ * back to the pool.
+ * </p><p>
+ * The pool holds strong references to the connections it owns.  However,
+ * it only holds <em>weak references</em> to the connections that sessions
+ * have acquired from it.  Using weak references in the latter case ensures
+ * that the connection pool can detect when connections have been improperly
+ * abandoned so that it can create new connections to replace them if needed.
+ * </p><p>
+ * The connection pool is thread-safe (but the connections themselves are not).
+ * </p>
+ *
+ * <h2>Exception safety</h2>
+ * <p>
+ * This code attempts to maintain the invariant that opened connections are
+ * always owned.  Unfortunately that means it needs to handle exceptions
+ * all over to ensure that broken connections get cleaned up.  Most
+ * operations invokving SQLite can throw {@link SQLiteException} or other
+ * runtime exceptions.  This is a bit of a pain to deal with because the compiler
+ * cannot help us catch missing exception handling code.
+ * </p><p>
+ * The general rule for this file: If we are making calls out to
+ * {@link SQLiteConnection} then we must be prepared to handle any
+ * runtime exceptions it might throw at us.  Note that out-of-memory
+ * is an {@link Error}, not a {@link RuntimeException}.  We don't trouble ourselves
+ * handling out of memory because it is hard to do anything at all sensible then
+ * and most likely the VM is about to crash.
+ * </p>
+ *
+ * @hide
+ */
+public final class SQLiteConnectionPool implements Closeable {
+    private static final String TAG = "SQLiteConnectionPool";
+
+    // Amount of time to wait in milliseconds before unblocking acquireConnection
+    // and logging a message about the connection pool being busy.
+    private static final long CONNECTION_POOL_BUSY_MILLIS = 30 * 1000; // 30 seconds
+
+    private final CloseGuard mCloseGuard = CloseGuard.get();
+
+    private final Object mLock = new Object();
+    private final AtomicBoolean mConnectionLeaked = new AtomicBoolean();
+    private final SQLiteDatabaseConfiguration mConfiguration;
+    private int mMaxConnectionPoolSize;
+    private boolean mIsOpen;
+    private int mNextConnectionId;
+
+    private ConnectionWaiter mConnectionWaiterPool;
+    private ConnectionWaiter mConnectionWaiterQueue;
+
+    // Strong references to all available connections.
+    private final ArrayList<SQLiteConnection> mAvailableNonPrimaryConnections =
+            new ArrayList<SQLiteConnection>();
+    private SQLiteConnection mAvailablePrimaryConnection;
+
+    @GuardedBy("mLock")
+    private IdleConnectionHandler mIdleConnectionHandler;
+
+    private final AtomicLong mTotalExecutionTimeCounter = new AtomicLong(0);
+
+    // Describes what should happen to an acquired connection when it is returned to the pool.
+    enum AcquiredConnectionStatus {
+        // The connection should be returned to the pool as usual.
+        NORMAL,
+
+        // The connection must be reconfigured before being returned.
+        RECONFIGURE,
+
+        // The connection must be closed and discarded.
+        DISCARD,
+    }
+
+    // Weak references to all acquired connections.  The associated value
+    // indicates whether the connection must be reconfigured before being
+    // returned to the available connection list or discarded.
+    // For example, the prepared statement cache size may have changed and
+    // need to be updated in preparation for the next client.
+    private final WeakHashMap<SQLiteConnection, AcquiredConnectionStatus> mAcquiredConnections =
+            new WeakHashMap<SQLiteConnection, AcquiredConnectionStatus>();
+
+    /**
+     * Connection flag: Read-only.
+     * <p>
+     * This flag indicates that the connection will only be used to
+     * perform read-only operations.
+     * </p>
+     */
+    public static final int CONNECTION_FLAG_READ_ONLY = 1 << 0;
+
+    /**
+     * Connection flag: Primary connection affinity.
+     * <p>
+     * This flag indicates that the primary connection is required.
+     * This flag helps support legacy applications that expect most data modifying
+     * operations to be serialized by locking the primary database connection.
+     * Setting this flag essentially implements the old "db lock" concept by preventing
+     * an operation from being performed until it can obtain exclusive access to
+     * the primary connection.
+     * </p>
+     */
+    public static final int CONNECTION_FLAG_PRIMARY_CONNECTION_AFFINITY = 1 << 1;
+
+    /**
+     * Connection flag: Connection is being used interactively.
+     * <p>
+     * This flag indicates that the connection is needed by the UI thread.
+     * The connection pool can use this flag to elevate the priority
+     * of the database connection request.
+     * </p>
+     */
+    public static final int CONNECTION_FLAG_INTERACTIVE = 1 << 2;
+
+    private SQLiteConnectionPool(SQLiteDatabaseConfiguration configuration) {
+        mConfiguration = new SQLiteDatabaseConfiguration(configuration);
+        setMaxConnectionPoolSizeLocked();
+        // If timeout is set, setup idle connection handler
+        // In case of MAX_VALUE - idle connections are never closed
+        if (mConfiguration.idleConnectionTimeoutMs != Long.MAX_VALUE) {
+            setupIdleConnectionHandler(Looper.getMainLooper(),
+                    mConfiguration.idleConnectionTimeoutMs);
+        }
+    }
+
+    @Override
+    protected void finalize() throws Throwable {
+        try {
+            dispose(true);
+        } finally {
+            super.finalize();
+        }
+    }
+
+    /**
+     * Opens a connection pool for the specified database.
+     *
+     * @param configuration The database configuration.
+     * @return The connection pool.
+     *
+     * @throws SQLiteException if a database error occurs.
+     */
+    public static SQLiteConnectionPool open(SQLiteDatabaseConfiguration configuration) {
+        if (configuration == null) {
+            throw new IllegalArgumentException("configuration must not be null.");
+        }
+
+        // Create the pool.
+        SQLiteConnectionPool pool = new SQLiteConnectionPool(configuration);
+        pool.open(); // might throw
+        return pool;
+    }
+
+    // Might throw
+    private void open() {
+        // Open the primary connection.
+        // This might throw if the database is corrupt.
+        mAvailablePrimaryConnection = openConnectionLocked(mConfiguration,
+                true /*primaryConnection*/); // might throw
+        // Mark it released so it can be closed after idle timeout
+        synchronized (mLock) {
+            if (mIdleConnectionHandler != null) {
+                mIdleConnectionHandler.connectionReleased(mAvailablePrimaryConnection);
+            }
+        }
+
+        // Mark the pool as being open for business.
+        mIsOpen = true;
+        mCloseGuard.open("close");
+    }
+
+    /**
+     * Closes the connection pool.
+     * <p>
+     * When the connection pool is closed, it will refuse all further requests
+     * to acquire connections.  All connections that are currently available in
+     * the pool are closed immediately.  Any connections that are still in use
+     * will be closed as soon as they are returned to the pool.
+     * </p>
+     *
+     * @throws IllegalStateException if the pool has been closed.
+     */
+    public void close() {
+        dispose(false);
+    }
+
+    private void dispose(boolean finalized) {
+        if (mCloseGuard != null) {
+            if (finalized) {
+                mCloseGuard.warnIfOpen();
+            }
+            mCloseGuard.close();
+        }
+
+        if (!finalized) {
+            // Close all connections.  We don't need (or want) to do this
+            // when finalized because we don't know what state the connections
+            // themselves will be in.  The finalizer is really just here for CloseGuard.
+            // The connections will take care of themselves when their own finalizers run.
+            synchronized (mLock) {
+                throwIfClosedLocked();
+
+                mIsOpen = false;
+
+                closeAvailableConnectionsAndLogExceptionsLocked();
+
+                final int pendingCount = mAcquiredConnections.size();
+                if (pendingCount != 0) {
+                    Log.i(TAG, "The connection pool for " + mConfiguration.label
+                            + " has been closed but there are still "
+                            + pendingCount + " connections in use.  They will be closed "
+                            + "as they are released back to the pool.");
+                }
+
+                wakeConnectionWaitersLocked();
+            }
+        }
+    }
+
+    /**
+     * Reconfigures the database configuration of the connection pool and all of its
+     * connections.
+     * <p>
+     * Configuration changes are propagated down to connections immediately if
+     * they are available or as soon as they are released.  This includes changes
+     * that affect the size of the pool.
+     * </p>
+     *
+     * @param configuration The new configuration.
+     *
+     * @throws IllegalStateException if the pool has been closed.
+     */
+    public void reconfigure(SQLiteDatabaseConfiguration configuration) {
+        if (configuration == null) {
+            throw new IllegalArgumentException("configuration must not be null.");
+        }
+
+        synchronized (mLock) {
+            throwIfClosedLocked();
+
+            boolean walModeChanged = ((configuration.openFlags ^ mConfiguration.openFlags)
+                    & SQLiteDatabase.ENABLE_WRITE_AHEAD_LOGGING) != 0;
+            if (walModeChanged) {
+                // WAL mode can only be changed if there are no acquired connections
+                // because we need to close all but the primary connection first.
+                if (!mAcquiredConnections.isEmpty()) {
+                    throw new IllegalStateException("Write Ahead Logging (WAL) mode cannot "
+                            + "be enabled or disabled while there are transactions in "
+                            + "progress.  Finish all transactions and release all active "
+                            + "database connections first.");
+                }
+
+                // Close all non-primary connections.  This should happen immediately
+                // because none of them are in use.
+                closeAvailableNonPrimaryConnectionsAndLogExceptionsLocked();
+                assert mAvailableNonPrimaryConnections.isEmpty();
+            }
+
+            boolean foreignKeyModeChanged = configuration.foreignKeyConstraintsEnabled
+                    != mConfiguration.foreignKeyConstraintsEnabled;
+            if (foreignKeyModeChanged) {
+                // Foreign key constraints can only be changed if there are no transactions
+                // in progress.  To make this clear, we throw an exception if there are
+                // any acquired connections.
+                if (!mAcquiredConnections.isEmpty()) {
+                    throw new IllegalStateException("Foreign Key Constraints cannot "
+                            + "be enabled or disabled while there are transactions in "
+                            + "progress.  Finish all transactions and release all active "
+                            + "database connections first.");
+                }
+            }
+
+            // We should do in-place switching when transitioning from compatibility WAL
+            // to rollback journal. Otherwise transient connection state will be lost
+            boolean onlyCompatWalChanged = (mConfiguration.openFlags ^ configuration.openFlags)
+                    == SQLiteDatabase.ENABLE_LEGACY_COMPATIBILITY_WAL;
+
+            if (!onlyCompatWalChanged && mConfiguration.openFlags != configuration.openFlags) {
+                // If we are changing open flags and WAL mode at the same time, then
+                // we have no choice but to close the primary connection beforehand
+                // because there can only be one connection open when we change WAL mode.
+                if (walModeChanged) {
+                    closeAvailableConnectionsAndLogExceptionsLocked();
+                }
+
+                // Try to reopen the primary connection using the new open flags then
+                // close and discard all existing connections.
+                // This might throw if the database is corrupt or cannot be opened in
+                // the new mode in which case existing connections will remain untouched.
+                SQLiteConnection newPrimaryConnection = openConnectionLocked(configuration,
+                        true /*primaryConnection*/); // might throw
+
+                closeAvailableConnectionsAndLogExceptionsLocked();
+                discardAcquiredConnectionsLocked();
+
+                mAvailablePrimaryConnection = newPrimaryConnection;
+                mConfiguration.updateParametersFrom(configuration);
+                setMaxConnectionPoolSizeLocked();
+            } else {
+                // Reconfigure the database connections in place.
+                mConfiguration.updateParametersFrom(configuration);
+                setMaxConnectionPoolSizeLocked();
+
+                closeExcessConnectionsAndLogExceptionsLocked();
+                reconfigureAllConnectionsLocked();
+            }
+
+            wakeConnectionWaitersLocked();
+        }
+    }
+
+    /**
+     * Acquires a connection from the pool.
+     * <p>
+     * The caller must call {@link #releaseConnection} to release the connection
+     * back to the pool when it is finished.  Failure to do so will result
+     * in much unpleasantness.
+     * </p>
+     *
+     * @param sql If not null, try to find a connection that already has
+     * the specified SQL statement in its prepared statement cache.
+     * @param connectionFlags The connection request flags.
+     * @param cancellationSignal A signal to cancel the operation in progress, or null if none.
+     * @return The connection that was acquired, never null.
+     *
+     * @throws IllegalStateException if the pool has been closed.
+     * @throws SQLiteException if a database error occurs.
+     * @throws OperationCanceledException if the operation was canceled.
+     */
+    public SQLiteConnection acquireConnection(String sql, int connectionFlags,
+            CancellationSignal cancellationSignal) {
+        SQLiteConnection con = waitForConnection(sql, connectionFlags, cancellationSignal);
+        synchronized (mLock) {
+            if (mIdleConnectionHandler != null) {
+                mIdleConnectionHandler.connectionAcquired(con);
+            }
+        }
+        return con;
+    }
+
+    /**
+     * Releases a connection back to the pool.
+     * <p>
+     * It is ok to call this method after the pool has closed, to release
+     * connections that were still in use at the time of closure.
+     * </p>
+     *
+     * @param connection The connection to release.  Must not be null.
+     *
+     * @throws IllegalStateException if the connection was not acquired
+     * from this pool or if it has already been released.
+     */
+    public void releaseConnection(SQLiteConnection connection) {
+        synchronized (mLock) {
+            if (mIdleConnectionHandler != null) {
+                mIdleConnectionHandler.connectionReleased(connection);
+            }
+            AcquiredConnectionStatus status = mAcquiredConnections.remove(connection);
+            if (status == null) {
+                throw new IllegalStateException("Cannot perform this operation "
+                        + "because the specified connection was not acquired "
+                        + "from this pool or has already been released.");
+            }
+
+            if (!mIsOpen) {
+                closeConnectionAndLogExceptionsLocked(connection);
+            } else if (connection.isPrimaryConnection()) {
+                if (recycleConnectionLocked(connection, status)) {
+                    assert mAvailablePrimaryConnection == null;
+                    mAvailablePrimaryConnection = connection;
+                }
+                wakeConnectionWaitersLocked();
+            } else if (mAvailableNonPrimaryConnections.size() >= mMaxConnectionPoolSize - 1) {
+                closeConnectionAndLogExceptionsLocked(connection);
+            } else {
+                if (recycleConnectionLocked(connection, status)) {
+                    mAvailableNonPrimaryConnections.add(connection);
+                }
+                wakeConnectionWaitersLocked();
+            }
+        }
+    }
+
+    // Can't throw.
+    @GuardedBy("mLock")
+    private boolean recycleConnectionLocked(SQLiteConnection connection,
+            AcquiredConnectionStatus status) {
+        if (status == AcquiredConnectionStatus.RECONFIGURE) {
+            try {
+                connection.reconfigure(mConfiguration); // might throw
+            } catch (RuntimeException ex) {
+                Log.e(TAG, "Failed to reconfigure released connection, closing it: "
+                        + connection, ex);
+                status = AcquiredConnectionStatus.DISCARD;
+            }
+        }
+        if (status == AcquiredConnectionStatus.DISCARD) {
+            closeConnectionAndLogExceptionsLocked(connection);
+            return false;
+        }
+        return true;
+    }
+
+    /**
+     * Returns true if the session should yield the connection due to
+     * contention over available database connections.
+     *
+     * @param connection The connection owned by the session.
+     * @param connectionFlags The connection request flags.
+     * @return True if the session should yield its connection.
+     *
+     * @throws IllegalStateException if the connection was not acquired
+     * from this pool or if it has already been released.
+     */
+    public boolean shouldYieldConnection(SQLiteConnection connection, int connectionFlags) {
+        synchronized (mLock) {
+            if (!mAcquiredConnections.containsKey(connection)) {
+                throw new IllegalStateException("Cannot perform this operation "
+                        + "because the specified connection was not acquired "
+                        + "from this pool or has already been released.");
+            }
+
+            if (!mIsOpen) {
+                return false;
+            }
+
+            return isSessionBlockingImportantConnectionWaitersLocked(
+                    connection.isPrimaryConnection(), connectionFlags);
+        }
+    }
+
+    /**
+     * Collects statistics about database connection memory usage.
+     *
+     * @param dbStatsList The list to populate.
+     */
+    public void collectDbStats(ArrayList<DbStats> dbStatsList) {
+        synchronized (mLock) {
+            if (mAvailablePrimaryConnection != null) {
+                mAvailablePrimaryConnection.collectDbStats(dbStatsList);
+            }
+
+            for (SQLiteConnection connection : mAvailableNonPrimaryConnections) {
+                connection.collectDbStats(dbStatsList);
+            }
+
+            for (SQLiteConnection connection : mAcquiredConnections.keySet()) {
+                connection.collectDbStatsUnsafe(dbStatsList);
+            }
+        }
+    }
+
+    // Might throw.
+    private SQLiteConnection openConnectionLocked(SQLiteDatabaseConfiguration configuration,
+            boolean primaryConnection) {
+        final int connectionId = mNextConnectionId++;
+        return SQLiteConnection.open(this, configuration,
+                connectionId, primaryConnection); // might throw
+    }
+
+    void onConnectionLeaked() {
+        // This code is running inside of the SQLiteConnection finalizer.
+        //
+        // We don't know whether it is just the connection that has been finalized (and leaked)
+        // or whether the connection pool has also been or is about to be finalized.
+        // Consequently, it would be a bad idea to try to grab any locks or to
+        // do any significant work here.  So we do the simplest possible thing and
+        // set a flag.  waitForConnection() periodically checks this flag (when it
+        // times out) so that it can recover from leaked connections and wake
+        // itself or other threads up if necessary.
+        //
+        // You might still wonder why we don't try to do more to wake up the waiters
+        // immediately.  First, as explained above, it would be hard to do safely
+        // unless we started an extra Thread to function as a reference queue.  Second,
+        // this is never supposed to happen in normal operation.  Third, there is no
+        // guarantee that the GC will actually detect the leak in a timely manner so
+        // it's not all that important that we recover from the leak in a timely manner
+        // either.  Fourth, if a badly behaved application finds itself hung waiting for
+        // several seconds while waiting for a leaked connection to be detected and recreated,
+        // then perhaps its authors will have added incentive to fix the problem!
+
+        Log.w(TAG, "A SQLiteConnection object for database '"
+                + mConfiguration.label + "' was leaked!  Please fix your application "
+                + "to end transactions in progress properly and to close the database "
+                + "when it is no longer needed.");
+
+        mConnectionLeaked.set(true);
+    }
+
+    void onStatementExecuted(long executionTimeMs) {
+        mTotalExecutionTimeCounter.addAndGet(executionTimeMs);
+    }
+
+    // Can't throw.
+    @GuardedBy("mLock")
+    private void closeAvailableConnectionsAndLogExceptionsLocked() {
+        closeAvailableNonPrimaryConnectionsAndLogExceptionsLocked();
+
+        if (mAvailablePrimaryConnection != null) {
+            closeConnectionAndLogExceptionsLocked(mAvailablePrimaryConnection);
+            mAvailablePrimaryConnection = null;
+        }
+    }
+
+    // Can't throw.
+    @GuardedBy("mLock")
+    private boolean closeAvailableConnectionLocked(int connectionId) {
+        final int count = mAvailableNonPrimaryConnections.size();
+        for (int i = count - 1; i >= 0; i--) {
+            SQLiteConnection c = mAvailableNonPrimaryConnections.get(i);
+            if (c.getConnectionId() == connectionId) {
+                closeConnectionAndLogExceptionsLocked(c);
+                mAvailableNonPrimaryConnections.remove(i);
+                return true;
+            }
+        }
+
+        if (mAvailablePrimaryConnection != null
+                && mAvailablePrimaryConnection.getConnectionId() == connectionId) {
+            closeConnectionAndLogExceptionsLocked(mAvailablePrimaryConnection);
+            mAvailablePrimaryConnection = null;
+            return true;
+        }
+        return false;
+    }
+
+    // Can't throw.
+    @GuardedBy("mLock")
+    private void closeAvailableNonPrimaryConnectionsAndLogExceptionsLocked() {
+        final int count = mAvailableNonPrimaryConnections.size();
+        for (int i = 0; i < count; i++) {
+            closeConnectionAndLogExceptionsLocked(mAvailableNonPrimaryConnections.get(i));
+        }
+        mAvailableNonPrimaryConnections.clear();
+    }
+
+    /**
+     * Close non-primary connections that are not currently in use. This method is safe to use
+     * in finalize block as it doesn't throw RuntimeExceptions.
+     */
+    void closeAvailableNonPrimaryConnectionsAndLogExceptions() {
+        synchronized (mLock) {
+            closeAvailableNonPrimaryConnectionsAndLogExceptionsLocked();
+        }
+    }
+
+    // Can't throw.
+    @GuardedBy("mLock")
+    private void closeExcessConnectionsAndLogExceptionsLocked() {
+        int availableCount = mAvailableNonPrimaryConnections.size();
+        while (availableCount-- > mMaxConnectionPoolSize - 1) {
+            SQLiteConnection connection =
+                    mAvailableNonPrimaryConnections.remove(availableCount);
+            closeConnectionAndLogExceptionsLocked(connection);
+        }
+    }
+
+    // Can't throw.
+    @GuardedBy("mLock")
+    private void closeConnectionAndLogExceptionsLocked(SQLiteConnection connection) {
+        try {
+            connection.close(); // might throw
+            if (mIdleConnectionHandler != null) {
+                mIdleConnectionHandler.connectionClosed(connection);
+            }
+        } catch (RuntimeException ex) {
+            Log.e(TAG, "Failed to close connection, its fate is now in the hands "
+                    + "of the merciful GC: " + connection, ex);
+        }
+    }
+
+    // Can't throw.
+    private void discardAcquiredConnectionsLocked() {
+        markAcquiredConnectionsLocked(AcquiredConnectionStatus.DISCARD);
+    }
+
+    // Can't throw.
+    @GuardedBy("mLock")
+    private void reconfigureAllConnectionsLocked() {
+        if (mAvailablePrimaryConnection != null) {
+            try {
+                mAvailablePrimaryConnection.reconfigure(mConfiguration); // might throw
+            } catch (RuntimeException ex) {
+                Log.e(TAG, "Failed to reconfigure available primary connection, closing it: "
+                        + mAvailablePrimaryConnection, ex);
+                closeConnectionAndLogExceptionsLocked(mAvailablePrimaryConnection);
+                mAvailablePrimaryConnection = null;
+            }
+        }
+
+        int count = mAvailableNonPrimaryConnections.size();
+        for (int i = 0; i < count; i++) {
+            final SQLiteConnection connection = mAvailableNonPrimaryConnections.get(i);
+            try {
+                connection.reconfigure(mConfiguration); // might throw
+            } catch (RuntimeException ex) {
+                Log.e(TAG, "Failed to reconfigure available non-primary connection, closing it: "
+                        + connection, ex);
+                closeConnectionAndLogExceptionsLocked(connection);
+                mAvailableNonPrimaryConnections.remove(i--);
+                count -= 1;
+            }
+        }
+
+        markAcquiredConnectionsLocked(AcquiredConnectionStatus.RECONFIGURE);
+    }
+
+    // Can't throw.
+    private void markAcquiredConnectionsLocked(AcquiredConnectionStatus status) {
+        if (!mAcquiredConnections.isEmpty()) {
+            ArrayList<SQLiteConnection> keysToUpdate = new ArrayList<SQLiteConnection>(
+                    mAcquiredConnections.size());
+            for (Map.Entry<SQLiteConnection, AcquiredConnectionStatus> entry
+                    : mAcquiredConnections.entrySet()) {
+                AcquiredConnectionStatus oldStatus = entry.getValue();
+                if (status != oldStatus
+                        && oldStatus != AcquiredConnectionStatus.DISCARD) {
+                    keysToUpdate.add(entry.getKey());
+                }
+            }
+            final int updateCount = keysToUpdate.size();
+            for (int i = 0; i < updateCount; i++) {
+                mAcquiredConnections.put(keysToUpdate.get(i), status);
+            }
+        }
+    }
+
+    // Might throw.
+    private SQLiteConnection waitForConnection(String sql, int connectionFlags,
+            CancellationSignal cancellationSignal) {
+        final boolean wantPrimaryConnection =
+                (connectionFlags & CONNECTION_FLAG_PRIMARY_CONNECTION_AFFINITY) != 0;
+
+        final ConnectionWaiter waiter;
+        final int nonce;
+        synchronized (mLock) {
+            throwIfClosedLocked();
+
+            // Abort if canceled.
+            if (cancellationSignal != null) {
+                cancellationSignal.throwIfCanceled();
+            }
+
+            // Try to acquire a connection.
+            SQLiteConnection connection = null;
+            if (!wantPrimaryConnection) {
+                connection = tryAcquireNonPrimaryConnectionLocked(
+                        sql, connectionFlags); // might throw
+            }
+            if (connection == null) {
+                connection = tryAcquirePrimaryConnectionLocked(connectionFlags); // might throw
+            }
+            if (connection != null) {
+                return connection;
+            }
+
+            // No connections available.  Enqueue a waiter in priority order.
+            final int priority = getPriority(connectionFlags);
+            final long startTime = SystemClock.uptimeMillis();
+            waiter = obtainConnectionWaiterLocked(Thread.currentThread(), startTime,
+                    priority, wantPrimaryConnection, sql, connectionFlags);
+            ConnectionWaiter predecessor = null;
+            ConnectionWaiter successor = mConnectionWaiterQueue;
+            while (successor != null) {
+                if (priority > successor.mPriority) {
+                    waiter.mNext = successor;
+                    break;
+                }
+                predecessor = successor;
+                successor = successor.mNext;
+            }
+            if (predecessor != null) {
+                predecessor.mNext = waiter;
+            } else {
+                mConnectionWaiterQueue = waiter;
+            }
+
+            nonce = waiter.mNonce;
+        }
+
+        // Set up the cancellation listener.
+        if (cancellationSignal != null) {
+            cancellationSignal.setOnCancelListener(new CancellationSignal.OnCancelListener() {
+                @Override
+                public void onCancel() {
+                    synchronized (mLock) {
+                        if (waiter.mNonce == nonce) {
+                            cancelConnectionWaiterLocked(waiter);
+                        }
+                    }
+                }
+            });
+        }
+        try {
+            // Park the thread until a connection is assigned or the pool is closed.
+            // Rethrow an exception from the wait, if we got one.
+            long busyTimeoutMillis = CONNECTION_POOL_BUSY_MILLIS;
+            long nextBusyTimeoutTime = waiter.mStartTime + busyTimeoutMillis;
+            for (;;) {
+                // Detect and recover from connection leaks.
+                if (mConnectionLeaked.compareAndSet(true, false)) {
+                    synchronized (mLock) {
+                        wakeConnectionWaitersLocked();
+                    }
+                }
+
+                // Wait to be unparked (may already have happened), a timeout, or interruption.
+                LockSupport.parkNanos(this, busyTimeoutMillis * 1000000L);
+
+                // Clear the interrupted flag, just in case.
+                Thread.interrupted();
+
+                // Check whether we are done waiting yet.
+                synchronized (mLock) {
+                    throwIfClosedLocked();
+
+                    final SQLiteConnection connection = waiter.mAssignedConnection;
+                    final RuntimeException ex = waiter.mException;
+                    if (connection != null || ex != null) {
+                        recycleConnectionWaiterLocked(waiter);
+                        if (connection != null) {
+                            return connection;
+                        }
+                        throw ex; // rethrow!
+                    }
+
+                    final long now = SystemClock.uptimeMillis();
+                    if (now < nextBusyTimeoutTime) {
+                        busyTimeoutMillis = now - nextBusyTimeoutTime;
+                    } else {
+                        logConnectionPoolBusyLocked(now - waiter.mStartTime, connectionFlags);
+                        busyTimeoutMillis = CONNECTION_POOL_BUSY_MILLIS;
+                        nextBusyTimeoutTime = now + busyTimeoutMillis;
+                    }
+                }
+            }
+        } finally {
+            // Remove the cancellation listener.
+            if (cancellationSignal != null) {
+                cancellationSignal.setOnCancelListener(null);
+            }
+        }
+    }
+
+    // Can't throw.
+    @GuardedBy("mLock")
+    private void cancelConnectionWaiterLocked(ConnectionWaiter waiter) {
+        if (waiter.mAssignedConnection != null || waiter.mException != null) {
+            // Waiter is done waiting but has not woken up yet.
+            return;
+        }
+
+        // Waiter must still be waiting.  Dequeue it.
+        ConnectionWaiter predecessor = null;
+        ConnectionWaiter current = mConnectionWaiterQueue;
+        while (current != waiter) {
+            assert current != null;
+            predecessor = current;
+            current = current.mNext;
+        }
+        if (predecessor != null) {
+            predecessor.mNext = waiter.mNext;
+        } else {
+            mConnectionWaiterQueue = waiter.mNext;
+        }
+
+        // Send the waiter an exception and unpark it.
+        waiter.mException = new OperationCanceledException();
+        LockSupport.unpark(waiter.mThread);
+
+        // Check whether removing this waiter will enable other waiters to make progress.
+        wakeConnectionWaitersLocked();
+    }
+
+    // Can't throw.
+    private void logConnectionPoolBusyLocked(long waitMillis, int connectionFlags) {
+        final Thread thread = Thread.currentThread();
+        StringBuilder msg = new StringBuilder();
+        msg.append("The connection pool for database '").append(mConfiguration.label);
+        msg.append("' has been unable to grant a connection to thread ");
+        msg.append(thread.getId()).append(" (").append(thread.getName()).append(") ");
+        msg.append("with flags 0x").append(Integer.toHexString(connectionFlags));
+        msg.append(" for ").append(waitMillis * 0.001f).append(" seconds.\n");
+
+        ArrayList<String> requests = new ArrayList<String>();
+        int activeConnections = 0;
+        int idleConnections = 0;
+        if (!mAcquiredConnections.isEmpty()) {
+            for (SQLiteConnection connection : mAcquiredConnections.keySet()) {
+                String description = connection.describeCurrentOperationUnsafe();
+                if (description != null) {
+                    requests.add(description);
+                    activeConnections += 1;
+                } else {
+                    idleConnections += 1;
+                }
+            }
+        }
+        int availableConnections = mAvailableNonPrimaryConnections.size();
+        if (mAvailablePrimaryConnection != null) {
+            availableConnections += 1;
+        }
+
+        msg.append("Connections: ").append(activeConnections).append(" active, ");
+        msg.append(idleConnections).append(" idle, ");
+        msg.append(availableConnections).append(" available.\n");
+
+        if (!requests.isEmpty()) {
+            msg.append("\nRequests in progress:\n");
+            for (String request : requests) {
+                msg.append("  ").append(request).append("\n");
+            }
+        }
+
+        Log.w(TAG, msg.toString());
+    }
+
+    // Can't throw.
+    @GuardedBy("mLock")
+    private void wakeConnectionWaitersLocked() {
+        // Unpark all waiters that have requests that we can fulfill.
+        // This method is designed to not throw runtime exceptions, although we might send
+        // a waiter an exception for it to rethrow.
+        ConnectionWaiter predecessor = null;
+        ConnectionWaiter waiter = mConnectionWaiterQueue;
+        boolean primaryConnectionNotAvailable = false;
+        boolean nonPrimaryConnectionNotAvailable = false;
+        while (waiter != null) {
+            boolean unpark = false;
+            if (!mIsOpen) {
+                unpark = true;
+            } else {
+                try {
+                    SQLiteConnection connection = null;
+                    if (!waiter.mWantPrimaryConnection && !nonPrimaryConnectionNotAvailable) {
+                        connection = tryAcquireNonPrimaryConnectionLocked(
+                                waiter.mSql, waiter.mConnectionFlags); // might throw
+                        if (connection == null) {
+                            nonPrimaryConnectionNotAvailable = true;
+                        }
+                    }
+                    if (connection == null && !primaryConnectionNotAvailable) {
+                        connection = tryAcquirePrimaryConnectionLocked(
+                                waiter.mConnectionFlags); // might throw
+                        if (connection == null) {
+                            primaryConnectionNotAvailable = true;
+                        }
+                    }
+                    if (connection != null) {
+                        waiter.mAssignedConnection = connection;
+                        unpark = true;
+                    } else if (nonPrimaryConnectionNotAvailable && primaryConnectionNotAvailable) {
+                        // There are no connections available and the pool is still open.
+                        // We cannot fulfill any more connection requests, so stop here.
+                        break;
+                    }
+                } catch (RuntimeException ex) {
+                    // Let the waiter handle the exception from acquiring a connection.
+                    waiter.mException = ex;
+                    unpark = true;
+                }
+            }
+
+            final ConnectionWaiter successor = waiter.mNext;
+            if (unpark) {
+                if (predecessor != null) {
+                    predecessor.mNext = successor;
+                } else {
+                    mConnectionWaiterQueue = successor;
+                }
+                waiter.mNext = null;
+
+                LockSupport.unpark(waiter.mThread);
+            } else {
+                predecessor = waiter;
+            }
+            waiter = successor;
+        }
+    }
+
+    // Might throw.
+    @GuardedBy("mLock")
+    private SQLiteConnection tryAcquirePrimaryConnectionLocked(int connectionFlags) {
+        // If the primary connection is available, acquire it now.
+        SQLiteConnection connection = mAvailablePrimaryConnection;
+        if (connection != null) {
+            mAvailablePrimaryConnection = null;
+            finishAcquireConnectionLocked(connection, connectionFlags); // might throw
+            return connection;
+        }
+
+        // Make sure that the primary connection actually exists and has just been acquired.
+        for (SQLiteConnection acquiredConnection : mAcquiredConnections.keySet()) {
+            if (acquiredConnection.isPrimaryConnection()) {
+                return null;
+            }
+        }
+
+        // Uhoh.  No primary connection!  Either this is the first time we asked
+        // for it, or maybe it leaked?
+        connection = openConnectionLocked(mConfiguration,
+                true /*primaryConnection*/); // might throw
+        finishAcquireConnectionLocked(connection, connectionFlags); // might throw
+        return connection;
+    }
+
+    // Might throw.
+    @GuardedBy("mLock")
+    private SQLiteConnection tryAcquireNonPrimaryConnectionLocked(
+            String sql, int connectionFlags) {
+        // Try to acquire the next connection in the queue.
+        SQLiteConnection connection;
+        final int availableCount = mAvailableNonPrimaryConnections.size();
+        if (availableCount > 1 && sql != null) {
+            // If we have a choice, then prefer a connection that has the
+            // prepared statement in its cache.
+            for (int i = 0; i < availableCount; i++) {
+                connection = mAvailableNonPrimaryConnections.get(i);
+                if (connection.isPreparedStatementInCache(sql)) {
+                    mAvailableNonPrimaryConnections.remove(i);
+                    finishAcquireConnectionLocked(connection, connectionFlags); // might throw
+                    return connection;
+                }
+            }
+        }
+        if (availableCount > 0) {
+            // Otherwise, just grab the next one.
+            connection = mAvailableNonPrimaryConnections.remove(availableCount - 1);
+            finishAcquireConnectionLocked(connection, connectionFlags); // might throw
+            return connection;
+        }
+
+        // Expand the pool if needed.
+        int openConnections = mAcquiredConnections.size();
+        if (mAvailablePrimaryConnection != null) {
+            openConnections += 1;
+        }
+        if (openConnections >= mMaxConnectionPoolSize) {
+            return null;
+        }
+        connection = openConnectionLocked(mConfiguration,
+                false /*primaryConnection*/); // might throw
+        finishAcquireConnectionLocked(connection, connectionFlags); // might throw
+        return connection;
+    }
+
+    // Might throw.
+    @GuardedBy("mLock")
+    private void finishAcquireConnectionLocked(SQLiteConnection connection, int connectionFlags) {
+        try {
+            final boolean readOnly = (connectionFlags & CONNECTION_FLAG_READ_ONLY) != 0;
+            connection.setOnlyAllowReadOnlyOperations(readOnly);
+
+            mAcquiredConnections.put(connection, AcquiredConnectionStatus.NORMAL);
+        } catch (RuntimeException ex) {
+            Log.e(TAG, "Failed to prepare acquired connection for session, closing it: "
+                    + connection +", connectionFlags=" + connectionFlags);
+            closeConnectionAndLogExceptionsLocked(connection);
+            throw ex; // rethrow!
+        }
+    }
+
+    private boolean isSessionBlockingImportantConnectionWaitersLocked(
+            boolean holdingPrimaryConnection, int connectionFlags) {
+        ConnectionWaiter waiter = mConnectionWaiterQueue;
+        if (waiter != null) {
+            final int priority = getPriority(connectionFlags);
+            do {
+                // Only worry about blocked connections that have same or lower priority.
+                if (priority > waiter.mPriority) {
+                    break;
+                }
+
+                // If we are holding the primary connection then we are blocking the waiter.
+                // Likewise, if we are holding a non-primary connection and the waiter
+                // would accept a non-primary connection, then we are blocking the waier.
+                if (holdingPrimaryConnection || !waiter.mWantPrimaryConnection) {
+                    return true;
+                }
+
+                waiter = waiter.mNext;
+            } while (waiter != null);
+        }
+        return false;
+    }
+
+    private static int getPriority(int connectionFlags) {
+        return (connectionFlags & CONNECTION_FLAG_INTERACTIVE) != 0 ? 1 : 0;
+    }
+
+    private void setMaxConnectionPoolSizeLocked() {
+        if (!mConfiguration.isInMemoryDb()
+                && (mConfiguration.openFlags & SQLiteDatabase.ENABLE_WRITE_AHEAD_LOGGING) != 0) {
+            mMaxConnectionPoolSize = SQLiteGlobal.getWALConnectionPoolSize();
+        } else {
+            // We don't actually need to always restrict the connection pool size to 1
+            // for non-WAL databases.  There might be reasons to use connection pooling
+            // with other journal modes. However, we should always keep pool size of 1 for in-memory
+            // databases since every :memory: db is separate from another.
+            // For now, enabling connection pooling and using WAL are the same thing in the API.
+            mMaxConnectionPoolSize = 1;
+        }
+    }
+
+    /**
+     * Set up the handler based on the provided looper and timeout.
+     */
+    @VisibleForTesting
+    public void setupIdleConnectionHandler(Looper looper, long timeoutMs) {
+        synchronized (mLock) {
+            mIdleConnectionHandler = new IdleConnectionHandler(looper, timeoutMs);
+        }
+    }
+
+    void disableIdleConnectionHandler() {
+        synchronized (mLock) {
+            mIdleConnectionHandler = null;
+        }
+    }
+
+    private void throwIfClosedLocked() {
+        if (!mIsOpen) {
+            throw new IllegalStateException("Cannot perform this operation "
+                    + "because the connection pool has been closed.");
+        }
+    }
+
+    private ConnectionWaiter obtainConnectionWaiterLocked(Thread thread, long startTime,
+            int priority, boolean wantPrimaryConnection, String sql, int connectionFlags) {
+        ConnectionWaiter waiter = mConnectionWaiterPool;
+        if (waiter != null) {
+            mConnectionWaiterPool = waiter.mNext;
+            waiter.mNext = null;
+        } else {
+            waiter = new ConnectionWaiter();
+        }
+        waiter.mThread = thread;
+        waiter.mStartTime = startTime;
+        waiter.mPriority = priority;
+        waiter.mWantPrimaryConnection = wantPrimaryConnection;
+        waiter.mSql = sql;
+        waiter.mConnectionFlags = connectionFlags;
+        return waiter;
+    }
+
+    private void recycleConnectionWaiterLocked(ConnectionWaiter waiter) {
+        waiter.mNext = mConnectionWaiterPool;
+        waiter.mThread = null;
+        waiter.mSql = null;
+        waiter.mAssignedConnection = null;
+        waiter.mException = null;
+        waiter.mNonce += 1;
+        mConnectionWaiterPool = waiter;
+    }
+
+    /**
+     * Dumps debugging information about this connection pool.
+     *
+     * @param printer The printer to receive the dump, not null.
+     * @param verbose True to dump more verbose information.
+     */
+    public void dump(Printer printer, boolean verbose, ArraySet<String> directories) {
+        Printer indentedPrinter = PrefixPrinter.create(printer, "    ");
+        synchronized (mLock) {
+            if (directories != null) {
+                directories.add(new File(mConfiguration.path).getParent());
+            }
+            boolean isCompatibilityWalEnabled = mConfiguration.isLegacyCompatibilityWalEnabled();
+            printer.println("Connection pool for " + mConfiguration.path + ":");
+            printer.println("  Open: " + mIsOpen);
+            printer.println("  Max connections: " + mMaxConnectionPoolSize);
+            printer.println("  Total execution time: " + mTotalExecutionTimeCounter);
+            printer.println("  Configuration: openFlags=" + mConfiguration.openFlags
+                    + ", isLegacyCompatibilityWalEnabled=" + isCompatibilityWalEnabled
+                    + ", journalMode=" + TextUtils.emptyIfNull(mConfiguration.journalMode)
+                    + ", syncMode=" + TextUtils.emptyIfNull(mConfiguration.syncMode));
+
+            if (isCompatibilityWalEnabled) {
+                printer.println("  Compatibility WAL enabled: wal_syncmode="
+                        + SQLiteCompatibilityWalFlags.getWALSyncMode());
+            }
+            if (mConfiguration.isLookasideConfigSet()) {
+                printer.println("  Lookaside config: sz=" + mConfiguration.lookasideSlotSize
+                        + " cnt=" + mConfiguration.lookasideSlotCount);
+            }
+            if (mConfiguration.idleConnectionTimeoutMs != Long.MAX_VALUE) {
+                printer.println(
+                        "  Idle connection timeout: " + mConfiguration.idleConnectionTimeoutMs);
+            }
+            printer.println("  Available primary connection:");
+            if (mAvailablePrimaryConnection != null) {
+                mAvailablePrimaryConnection.dump(indentedPrinter, verbose);
+            } else {
+                indentedPrinter.println("<none>");
+            }
+
+            printer.println("  Available non-primary connections:");
+            if (!mAvailableNonPrimaryConnections.isEmpty()) {
+                final int count = mAvailableNonPrimaryConnections.size();
+                for (int i = 0; i < count; i++) {
+                    mAvailableNonPrimaryConnections.get(i).dump(indentedPrinter, verbose);
+                }
+            } else {
+                indentedPrinter.println("<none>");
+            }
+
+            printer.println("  Acquired connections:");
+            if (!mAcquiredConnections.isEmpty()) {
+                for (Map.Entry<SQLiteConnection, AcquiredConnectionStatus> entry :
+                        mAcquiredConnections.entrySet()) {
+                    final SQLiteConnection connection = entry.getKey();
+                    connection.dumpUnsafe(indentedPrinter, verbose);
+                    indentedPrinter.println("  Status: " + entry.getValue());
+                }
+            } else {
+                indentedPrinter.println("<none>");
+            }
+
+            printer.println("  Connection waiters:");
+            if (mConnectionWaiterQueue != null) {
+                int i = 0;
+                final long now = SystemClock.uptimeMillis();
+                for (ConnectionWaiter waiter = mConnectionWaiterQueue; waiter != null;
+                        waiter = waiter.mNext, i++) {
+                    indentedPrinter.println(i + ": waited for "
+                            + ((now - waiter.mStartTime) * 0.001f)
+                            + " ms - thread=" + waiter.mThread
+                            + ", priority=" + waiter.mPriority
+                            + ", sql='" + waiter.mSql + "'");
+                }
+            } else {
+                indentedPrinter.println("<none>");
+            }
+        }
+    }
+
+    @Override
+    public String toString() {
+        return "SQLiteConnectionPool: " + mConfiguration.path;
+    }
+
+    public String getPath() {
+        return mConfiguration.path;
+    }
+
+    private static final class ConnectionWaiter {
+        public ConnectionWaiter mNext;
+        public Thread mThread;
+        public long mStartTime;
+        public int mPriority;
+        public boolean mWantPrimaryConnection;
+        public String mSql;
+        public int mConnectionFlags;
+        public SQLiteConnection mAssignedConnection;
+        public RuntimeException mException;
+        public int mNonce;
+    }
+
+    private class IdleConnectionHandler extends Handler {
+        private final long mTimeout;
+
+        IdleConnectionHandler(Looper looper, long timeout) {
+            super(looper);
+            mTimeout = timeout;
+        }
+
+        @Override
+        public void handleMessage(Message msg) {
+            // Skip the (obsolete) message if the handler has changed
+            synchronized (mLock) {
+                if (this != mIdleConnectionHandler) {
+                    return;
+                }
+                if (closeAvailableConnectionLocked(msg.what)) {
+                    if (Log.isLoggable(TAG, Log.DEBUG)) {
+                        Log.d(TAG, "Closed idle connection " + mConfiguration.label + " " + msg.what
+                                + " after " + mTimeout);
+                    }
+                }
+            }
+        }
+
+        void connectionReleased(SQLiteConnection con) {
+            sendEmptyMessageDelayed(con.getConnectionId(), mTimeout);
+        }
+
+        void connectionAcquired(SQLiteConnection con) {
+            // Remove any pending close operations
+            removeMessages(con.getConnectionId());
+        }
+
+        void connectionClosed(SQLiteConnection con) {
+            removeMessages(con.getConnectionId());
+        }
+    }
+}
diff --git a/android/database/sqlite/SQLiteConstraintException.java b/android/database/sqlite/SQLiteConstraintException.java
new file mode 100644
index 0000000..e3119eb
--- /dev/null
+++ b/android/database/sqlite/SQLiteConstraintException.java
@@ -0,0 +1,28 @@
+/*
+ * Copyright (C) 2008 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.database.sqlite;
+
+/**
+ * An exception that indicates that an integrity constraint was violated.
+ */
+public class SQLiteConstraintException extends SQLiteException {
+    public SQLiteConstraintException() {}
+
+    public SQLiteConstraintException(String error) {
+        super(error);
+    }
+}
diff --git a/android/database/sqlite/SQLiteCursor.java b/android/database/sqlite/SQLiteCursor.java
new file mode 100644
index 0000000..4559e91
--- /dev/null
+++ b/android/database/sqlite/SQLiteCursor.java
@@ -0,0 +1,302 @@
+/*
+ * Copyright (C) 2006 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.database.sqlite;
+
+import android.compat.annotation.UnsupportedAppUsage;
+import android.database.AbstractWindowedCursor;
+import android.database.CursorWindow;
+import android.database.DatabaseUtils;
+import android.os.StrictMode;
+import android.util.Log;
+
+import com.android.internal.util.Preconditions;
+
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ * A Cursor implementation that exposes results from a query on a
+ * {@link SQLiteDatabase}.
+ *
+ * SQLiteCursor is not internally synchronized so code using a SQLiteCursor from multiple
+ * threads should perform its own synchronization when using the SQLiteCursor.
+ */
+public class SQLiteCursor extends AbstractWindowedCursor {
+    static final String TAG = "SQLiteCursor";
+    static final int NO_COUNT = -1;
+
+    /** The name of the table to edit */
+    @UnsupportedAppUsage
+    private final String mEditTable;
+
+    /** The names of the columns in the rows */
+    private final String[] mColumns;
+
+    /** The query object for the cursor */
+    @UnsupportedAppUsage
+    private final SQLiteQuery mQuery;
+
+    /** The compiled query this cursor came from */
+    private final SQLiteCursorDriver mDriver;
+
+    /** The number of rows in the cursor */
+    private int mCount = NO_COUNT;
+
+    /** The number of rows that can fit in the cursor window, 0 if unknown */
+    private int mCursorWindowCapacity;
+
+    /** A mapping of column names to column indices, to speed up lookups */
+    private Map<String, Integer> mColumnNameMap;
+
+    /** Used to find out where a cursor was allocated in case it never got released. */
+    private final Throwable mStackTrace;
+
+    /** Controls fetching of rows relative to requested position **/
+    private boolean mFillWindowForwardOnly;
+
+    /**
+     * Execute a query and provide access to its result set through a Cursor
+     * interface. For a query such as: {@code SELECT name, birth, phone FROM
+     * myTable WHERE ... LIMIT 1,20 ORDER BY...} the column names (name, birth,
+     * phone) would be in the projection argument and everything from
+     * {@code FROM} onward would be in the params argument.
+     *
+     * @param db a reference to a Database object that is already constructed
+     *     and opened. This param is not used any longer
+     * @param editTable the name of the table used for this query
+     * @param query the rest of the query terms
+     *     cursor is finalized
+     * @deprecated use {@link #SQLiteCursor(SQLiteCursorDriver, String, SQLiteQuery)} instead
+     */
+    @Deprecated
+    public SQLiteCursor(SQLiteDatabase db, SQLiteCursorDriver driver,
+            String editTable, SQLiteQuery query) {
+        this(driver, editTable, query);
+    }
+
+    /**
+     * Execute a query and provide access to its result set through a Cursor
+     * interface. For a query such as: {@code SELECT name, birth, phone FROM
+     * myTable WHERE ... LIMIT 1,20 ORDER BY...} the column names (name, birth,
+     * phone) would be in the projection argument and everything from
+     * {@code FROM} onward would be in the params argument.
+     *
+     * @param editTable the name of the table used for this query
+     * @param query the {@link SQLiteQuery} object associated with this cursor object.
+     */
+    public SQLiteCursor(SQLiteCursorDriver driver, String editTable, SQLiteQuery query) {
+        if (query == null) {
+            throw new IllegalArgumentException("query object cannot be null");
+        }
+        if (StrictMode.vmSqliteObjectLeaksEnabled()) {
+            mStackTrace = new DatabaseObjectNotClosedException().fillInStackTrace();
+        } else {
+            mStackTrace = null;
+        }
+        mDriver = driver;
+        mEditTable = editTable;
+        mColumnNameMap = null;
+        mQuery = query;
+
+        mColumns = query.getColumnNames();
+    }
+
+    /**
+     * Get the database that this cursor is associated with.
+     * @return the SQLiteDatabase that this cursor is associated with.
+     */
+    public SQLiteDatabase getDatabase() {
+        return mQuery.getDatabase();
+    }
+
+    @Override
+    public boolean onMove(int oldPosition, int newPosition) {
+        // Make sure the row at newPosition is present in the window
+        if (mWindow == null || newPosition < mWindow.getStartPosition() ||
+                newPosition >= (mWindow.getStartPosition() + mWindow.getNumRows())) {
+            fillWindow(newPosition);
+        }
+
+        return true;
+    }
+
+    @Override
+    public int getCount() {
+        if (mCount == NO_COUNT) {
+            fillWindow(0);
+        }
+        return mCount;
+    }
+
+    @UnsupportedAppUsage
+    private void fillWindow(int requiredPos) {
+        clearOrCreateWindow(getDatabase().getPath());
+        try {
+            Preconditions.checkArgumentNonnegative(requiredPos,
+                    "requiredPos cannot be negative, but was " + requiredPos);
+
+            if (mCount == NO_COUNT) {
+                mCount = mQuery.fillWindow(mWindow, requiredPos, requiredPos, true);
+                mCursorWindowCapacity = mWindow.getNumRows();
+                if (Log.isLoggable(TAG, Log.DEBUG)) {
+                    Log.d(TAG, "received count(*) from native_fill_window: " + mCount);
+                }
+            } else {
+                int startPos = mFillWindowForwardOnly ? requiredPos : DatabaseUtils
+                        .cursorPickFillWindowStartPosition(requiredPos, mCursorWindowCapacity);
+                mQuery.fillWindow(mWindow, startPos, requiredPos, false);
+            }
+        } catch (RuntimeException ex) {
+            // Close the cursor window if the query failed and therefore will
+            // not produce any results.  This helps to avoid accidentally leaking
+            // the cursor window if the client does not correctly handle exceptions
+            // and fails to close the cursor.
+            closeWindow();
+            throw ex;
+        }
+    }
+
+    @Override
+    public int getColumnIndex(String columnName) {
+        // Create mColumnNameMap on demand
+        if (mColumnNameMap == null) {
+            String[] columns = mColumns;
+            int columnCount = columns.length;
+            HashMap<String, Integer> map = new HashMap<String, Integer>(columnCount, 1);
+            for (int i = 0; i < columnCount; i++) {
+                map.put(columns[i], i);
+            }
+            mColumnNameMap = map;
+        }
+
+        // Hack according to bug 903852
+        final int periodIndex = columnName.lastIndexOf('.');
+        if (periodIndex != -1) {
+            Exception e = new Exception();
+            Log.e(TAG, "requesting column name with table name -- " + columnName, e);
+            columnName = columnName.substring(periodIndex + 1);
+        }
+
+        Integer i = mColumnNameMap.get(columnName);
+        if (i != null) {
+            return i.intValue();
+        } else {
+            return -1;
+        }
+    }
+
+    @Override
+    public String[] getColumnNames() {
+        return mColumns;
+    }
+
+    @Override
+    public void deactivate() {
+        super.deactivate();
+        mDriver.cursorDeactivated();
+    }
+
+    @Override
+    public void close() {
+        super.close();
+        synchronized (this) {
+            mQuery.close();
+            mDriver.cursorClosed();
+        }
+    }
+
+    @Override
+    public boolean requery() {
+        if (isClosed()) {
+            return false;
+        }
+
+        synchronized (this) {
+            if (!mQuery.getDatabase().isOpen()) {
+                return false;
+            }
+
+            if (mWindow != null) {
+                mWindow.clear();
+            }
+            mPos = -1;
+            mCount = NO_COUNT;
+
+            mDriver.cursorRequeried(this);
+        }
+
+        try {
+            return super.requery();
+        } catch (IllegalStateException e) {
+            // for backwards compatibility, just return false
+            Log.w(TAG, "requery() failed " + e.getMessage(), e);
+            return false;
+        }
+    }
+
+    @Override
+    public void setWindow(CursorWindow window) {
+        super.setWindow(window);
+        mCount = NO_COUNT;
+    }
+
+    /**
+     * Changes the selection arguments. The new values take effect after a call to requery().
+     */
+    public void setSelectionArguments(String[] selectionArgs) {
+        mDriver.setBindArguments(selectionArgs);
+    }
+
+    /**
+     * Controls fetching of rows relative to requested position.
+     *
+     * <p>Calling this method defines how rows will be loaded, but it doesn't affect rows that
+     * are already in the window. This setting is preserved if a new window is
+     * {@link #setWindow(CursorWindow) set}
+     *
+     * @param fillWindowForwardOnly if true, rows will be fetched starting from requested position
+     * up to the window's capacity. Default value is false.
+     */
+    public void setFillWindowForwardOnly(boolean fillWindowForwardOnly) {
+        mFillWindowForwardOnly = fillWindowForwardOnly;
+    }
+
+    /**
+     * Release the native resources, if they haven't been released yet.
+     */
+    @Override
+    protected void finalize() {
+        try {
+            // if the cursor hasn't been closed yet, close it first
+            if (mWindow != null) {
+                if (mStackTrace != null) {
+                    String sql = mQuery.getSql();
+                    int len = sql.length();
+                    StrictMode.onSqliteObjectLeaked(
+                        "Finalizing a Cursor that has not been deactivated or closed. " +
+                        "database = " + mQuery.getDatabase().getLabel() +
+                        ", table = " + mEditTable +
+                        ", query = " + sql.substring(0, (len > 1000) ? 1000 : len),
+                        mStackTrace);
+                }
+                close();
+            }
+        } finally {
+            super.finalize();
+        }
+    }
+}
diff --git a/android/database/sqlite/SQLiteCursorDriver.java b/android/database/sqlite/SQLiteCursorDriver.java
new file mode 100644
index 0000000..ad2cdd2
--- /dev/null
+++ b/android/database/sqlite/SQLiteCursorDriver.java
@@ -0,0 +1,56 @@
+/*
+ * 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.database.sqlite;
+
+import android.database.Cursor;
+import android.database.sqlite.SQLiteDatabase.CursorFactory;
+
+/**
+ * A driver for SQLiteCursors that is used to create them and gets notified
+ * by the cursors it creates on significant events in their lifetimes.
+ */
+public interface SQLiteCursorDriver {
+    /**
+     * Executes the query returning a Cursor over the result set.
+     * 
+     * @param factory The CursorFactory to use when creating the Cursors, or
+     *         null if standard SQLiteCursors should be returned.
+     * @return a Cursor over the result set
+     */
+    Cursor query(CursorFactory factory, String[] bindArgs);
+
+    /**
+     * Called by a SQLiteCursor when it is released.
+     */
+    void cursorDeactivated();
+
+    /**
+     * Called by a SQLiteCursor when it is requeried.
+     */
+    void cursorRequeried(Cursor cursor);
+
+    /**
+     * Called by a SQLiteCursor when it it closed to destroy this object as well.
+     */
+    void cursorClosed();
+
+    /**
+     * Set new bind arguments. These will take effect in cursorRequeried().
+     * @param bindArgs the new arguments
+     */
+    public void setBindArguments(String[] bindArgs);
+}
diff --git a/android/database/sqlite/SQLiteCustomFunction.java b/android/database/sqlite/SQLiteCustomFunction.java
new file mode 100644
index 0000000..1ace40d
--- /dev/null
+++ b/android/database/sqlite/SQLiteCustomFunction.java
@@ -0,0 +1,59 @@
+/*
+ * Copyright (C) 2011 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.database.sqlite;
+
+import android.compat.annotation.UnsupportedAppUsage;
+import android.os.Build;
+
+/**
+ * Describes a custom SQL function.
+ *
+ * @hide
+ */
+public final class SQLiteCustomFunction {
+    @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023)
+    public final String name;
+    @UnsupportedAppUsage
+    public final int numArgs;
+    public final SQLiteDatabase.CustomFunction callback;
+
+    /**
+     * Create custom function.
+     *
+     * @param name The name of the sqlite3 function.
+     * @param numArgs The number of arguments for the function, or -1 to
+     * support any number of arguments.
+     * @param callback The callback to invoke when the function is executed.
+     */
+    public SQLiteCustomFunction(String name, int numArgs,
+            SQLiteDatabase.CustomFunction callback) {
+        if (name == null) {
+            throw new IllegalArgumentException("name must not be null.");
+        }
+
+        this.name = name;
+        this.numArgs = numArgs;
+        this.callback = callback;
+    }
+
+    // Called from native.
+    @SuppressWarnings("unused")
+    @UnsupportedAppUsage
+    private void dispatchCallback(String[] args) {
+        callback.callback(args);
+    }
+}
diff --git a/android/database/sqlite/SQLiteDatabase.java b/android/database/sqlite/SQLiteDatabase.java
new file mode 100644
index 0000000..7c4692c
--- /dev/null
+++ b/android/database/sqlite/SQLiteDatabase.java
@@ -0,0 +1,2878 @@
+/*
+ * Copyright (C) 2006 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.database.sqlite;
+
+import android.annotation.IntDef;
+import android.annotation.IntRange;
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+import android.app.ActivityManager;
+import android.app.ActivityThread;
+import android.compat.annotation.UnsupportedAppUsage;
+import android.content.ContentResolver;
+import android.content.ContentValues;
+import android.database.Cursor;
+import android.database.DatabaseErrorHandler;
+import android.database.DatabaseUtils;
+import android.database.DefaultDatabaseErrorHandler;
+import android.database.SQLException;
+import android.database.sqlite.SQLiteDebug.DbStats;
+import android.os.CancellationSignal;
+import android.os.Looper;
+import android.os.OperationCanceledException;
+import android.os.SystemProperties;
+import android.text.TextUtils;
+import android.util.ArraySet;
+import android.util.EventLog;
+import android.util.Log;
+import android.util.Pair;
+import android.util.Printer;
+
+import com.android.internal.util.Preconditions;
+
+import dalvik.system.CloseGuard;
+
+import java.io.File;
+import java.io.FileFilter;
+import java.io.IOException;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.nio.file.FileSystems;
+import java.nio.file.Files;
+import java.nio.file.attribute.BasicFileAttributes;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Locale;
+import java.util.Map;
+import java.util.Objects;
+import java.util.WeakHashMap;
+import java.util.function.BinaryOperator;
+import java.util.function.UnaryOperator;
+
+/**
+ * Exposes methods to manage a SQLite database.
+ *
+ * <p>
+ * SQLiteDatabase has methods to create, delete, execute SQL commands, and
+ * perform other common database management tasks.
+ * </p><p>
+ * See the Notepad sample application in the SDK for an example of creating
+ * and managing a database.
+ * </p><p>
+ * Database names must be unique within an application, not across all applications.
+ * </p>
+ *
+ * <h3>Localized Collation - ORDER BY</h3>
+ * <p>
+ * In addition to SQLite's default <code>BINARY</code> collator, Android supplies
+ * two more, <code>LOCALIZED</code>, which changes with the system's current locale,
+ * and <code>UNICODE</code>, which is the Unicode Collation Algorithm and not tailored
+ * to the current locale.
+ * </p>
+ */
+public final class SQLiteDatabase extends SQLiteClosable {
+    private static final String TAG = "SQLiteDatabase";
+
+    private static final int EVENT_DB_CORRUPT = 75004;
+
+    // By default idle connections are not closed
+    private static final boolean DEBUG_CLOSE_IDLE_CONNECTIONS = SystemProperties
+            .getBoolean("persist.debug.sqlite.close_idle_connections", false);
+
+    // Stores reference to all databases opened in the current process.
+    // (The referent Object is not used at this time.)
+    // INVARIANT: Guarded by sActiveDatabases.
+    private static WeakHashMap<SQLiteDatabase, Object> sActiveDatabases = new WeakHashMap<>();
+
+    // Thread-local for database sessions that belong to this database.
+    // Each thread has its own database session.
+    // INVARIANT: Immutable.
+    @UnsupportedAppUsage
+    private final ThreadLocal<SQLiteSession> mThreadSession = ThreadLocal
+            .withInitial(this::createSession);
+
+    // The optional factory to use when creating new Cursors.  May be null.
+    // INVARIANT: Immutable.
+    private final CursorFactory mCursorFactory;
+
+    // Error handler to be used when SQLite returns corruption errors.
+    // INVARIANT: Immutable.
+    private final DatabaseErrorHandler mErrorHandler;
+
+    // Shared database state lock.
+    // This lock guards all of the shared state of the database, such as its
+    // configuration, whether it is open or closed, and so on.  This lock should
+    // be held for as little time as possible.
+    //
+    // The lock MUST NOT be held while attempting to acquire database connections or
+    // while executing SQL statements on behalf of the client as it can lead to deadlock.
+    //
+    // It is ok to hold the lock while reconfiguring the connection pool or dumping
+    // statistics because those operations are non-reentrant and do not try to acquire
+    // connections that might be held by other threads.
+    //
+    // Basic rule: grab the lock, access or modify global state, release the lock, then
+    // do the required SQL work.
+    private final Object mLock = new Object();
+
+    // Warns if the database is finalized without being closed properly.
+    // INVARIANT: Guarded by mLock.
+    private final CloseGuard mCloseGuardLocked = CloseGuard.get();
+
+    // The database configuration.
+    // INVARIANT: Guarded by mLock.
+    @UnsupportedAppUsage
+    private final SQLiteDatabaseConfiguration mConfigurationLocked;
+
+    // The connection pool for the database, null when closed.
+    // The pool itself is thread-safe, but the reference to it can only be acquired
+    // when the lock is held.
+    // INVARIANT: Guarded by mLock.
+    @UnsupportedAppUsage
+    private SQLiteConnectionPool mConnectionPoolLocked;
+
+    // True if the database has attached databases.
+    // INVARIANT: Guarded by mLock.
+    private boolean mHasAttachedDbsLocked;
+
+    /**
+     * When a constraint violation occurs, an immediate ROLLBACK occurs,
+     * thus ending the current transaction, and the command aborts with a
+     * return code of SQLITE_CONSTRAINT. If no transaction is active
+     * (other than the implied transaction that is created on every command)
+     * then this algorithm works the same as ABORT.
+     */
+    public static final int CONFLICT_ROLLBACK = 1;
+
+    /**
+     * When a constraint violation occurs,no ROLLBACK is executed
+     * so changes from prior commands within the same transaction
+     * are preserved. This is the default behavior.
+     */
+    public static final int CONFLICT_ABORT = 2;
+
+    /**
+     * When a constraint violation occurs, the command aborts with a return
+     * code SQLITE_CONSTRAINT. But any changes to the database that
+     * the command made prior to encountering the constraint violation
+     * are preserved and are not backed out.
+     */
+    public static final int CONFLICT_FAIL = 3;
+
+    /**
+     * When a constraint violation occurs, the one row that contains
+     * the constraint violation is not inserted or changed.
+     * But the command continues executing normally. Other rows before and
+     * after the row that contained the constraint violation continue to be
+     * inserted or updated normally. No error is returned.
+     */
+    public static final int CONFLICT_IGNORE = 4;
+
+    /**
+     * When a UNIQUE constraint violation occurs, the pre-existing rows that
+     * are causing the constraint violation are removed prior to inserting
+     * or updating the current row. Thus the insert or update always occurs.
+     * The command continues executing normally. No error is returned.
+     * If a NOT NULL constraint violation occurs, the NULL value is replaced
+     * by the default value for that column. If the column has no default
+     * value, then the ABORT algorithm is used. If a CHECK constraint
+     * violation occurs then the IGNORE algorithm is used. When this conflict
+     * resolution strategy deletes rows in order to satisfy a constraint,
+     * it does not invoke delete triggers on those rows.
+     * This behavior might change in a future release.
+     */
+    public static final int CONFLICT_REPLACE = 5;
+
+    /**
+     * Use the following when no conflict action is specified.
+     */
+    public static final int CONFLICT_NONE = 0;
+
+    /** {@hide} */
+    @UnsupportedAppUsage
+    public static final String[] CONFLICT_VALUES = new String[]
+            {"", " OR ROLLBACK ", " OR ABORT ", " OR FAIL ", " OR IGNORE ", " OR REPLACE "};
+
+    /**
+     * Maximum Length Of A LIKE Or GLOB Pattern
+     * The pattern matching algorithm used in the default LIKE and GLOB implementation
+     * of SQLite can exhibit O(N^2) performance (where N is the number of characters in
+     * the pattern) for certain pathological cases. To avoid denial-of-service attacks
+     * the length of the LIKE or GLOB pattern is limited to SQLITE_MAX_LIKE_PATTERN_LENGTH bytes.
+     * The default value of this limit is 50000. A modern workstation can evaluate
+     * even a pathological LIKE or GLOB pattern of 50000 bytes relatively quickly.
+     * The denial of service problem only comes into play when the pattern length gets
+     * into millions of bytes. Nevertheless, since most useful LIKE or GLOB patterns
+     * are at most a few dozen bytes in length, paranoid application developers may
+     * want to reduce this parameter to something in the range of a few hundred
+     * if they know that external users are able to generate arbitrary patterns.
+     */
+    public static final int SQLITE_MAX_LIKE_PATTERN_LENGTH = 50000;
+
+    /**
+     * Open flag: Flag for {@link #openDatabase} to open the database for reading and writing.
+     * If the disk is full, this may fail even before you actually write anything.
+     *
+     * {@more} Note that the value of this flag is 0, so it is the default.
+     */
+    public static final int OPEN_READWRITE = 0x00000000;          // update native code if changing
+
+    /**
+     * Open flag: Flag for {@link #openDatabase} to open the database for reading only.
+     * This is the only reliable way to open a database if the disk may be full.
+     */
+    public static final int OPEN_READONLY = 0x00000001;           // update native code if changing
+
+    private static final int OPEN_READ_MASK = 0x00000001;         // update native code if changing
+
+    /**
+     * Open flag: Flag for {@link #openDatabase} to open the database without support for
+     * localized collators.
+     *
+     * {@more} This causes the collator <code>LOCALIZED</code> not to be created.
+     * You must be consistent when using this flag to use the setting the database was
+     * created with.  If this is set, {@link #setLocale} will do nothing.
+     */
+    public static final int NO_LOCALIZED_COLLATORS = 0x00000010;  // update native code if changing
+
+    /**
+     * Open flag: Flag for {@link #openDatabase} to create the database file if it does not
+     * already exist.
+     */
+    public static final int CREATE_IF_NECESSARY = 0x10000000;     // update native code if changing
+
+    /**
+     * Open flag: Flag for {@link #openDatabase} to open the database file with
+     * write-ahead logging enabled by default.  Using this flag is more efficient
+     * than calling {@link #enableWriteAheadLogging}.
+     *
+     * Write-ahead logging cannot be used with read-only databases so the value of
+     * this flag is ignored if the database is opened read-only.
+     *
+     * @see #enableWriteAheadLogging
+     */
+    public static final int ENABLE_WRITE_AHEAD_LOGGING = 0x20000000;
+
+
+    // Note: The below value was only used on Android Pie.
+    // public static final int DISABLE_COMPATIBILITY_WAL = 0x40000000;
+
+    /**
+     * Open flag: Flag for {@link #openDatabase} to enable the legacy Compatibility WAL when opening
+     * database.
+     *
+     * @hide
+     */
+    public static final int ENABLE_LEGACY_COMPATIBILITY_WAL = 0x80000000;
+
+    /**
+     * Absolute max value that can be set by {@link #setMaxSqlCacheSize(int)}.
+     *
+     * Each prepared-statement is between 1K - 6K, depending on the complexity of the
+     * SQL statement & schema.  A large SQL cache may use a significant amount of memory.
+     */
+    public static final int MAX_SQL_CACHE_SIZE = 100;
+
+    private SQLiteDatabase(final String path, final int openFlags,
+            CursorFactory cursorFactory, DatabaseErrorHandler errorHandler,
+            int lookasideSlotSize, int lookasideSlotCount, long idleConnectionTimeoutMs,
+            String journalMode, String syncMode) {
+        mCursorFactory = cursorFactory;
+        mErrorHandler = errorHandler != null ? errorHandler : new DefaultDatabaseErrorHandler();
+        mConfigurationLocked = new SQLiteDatabaseConfiguration(path, openFlags);
+        mConfigurationLocked.lookasideSlotSize = lookasideSlotSize;
+        mConfigurationLocked.lookasideSlotCount = lookasideSlotCount;
+        // Disable lookaside allocator on low-RAM devices
+        if (ActivityManager.isLowRamDeviceStatic()) {
+            mConfigurationLocked.lookasideSlotCount = 0;
+            mConfigurationLocked.lookasideSlotSize = 0;
+        }
+        long effectiveTimeoutMs = Long.MAX_VALUE;
+        // Never close idle connections for in-memory databases
+        if (!mConfigurationLocked.isInMemoryDb()) {
+            // First, check app-specific value. Otherwise use defaults
+            // -1 in idleConnectionTimeoutMs indicates unset value
+            if (idleConnectionTimeoutMs >= 0) {
+                effectiveTimeoutMs = idleConnectionTimeoutMs;
+            } else if (DEBUG_CLOSE_IDLE_CONNECTIONS) {
+                effectiveTimeoutMs = SQLiteGlobal.getIdleConnectionTimeout();
+            }
+        }
+        mConfigurationLocked.idleConnectionTimeoutMs = effectiveTimeoutMs;
+        mConfigurationLocked.journalMode = journalMode;
+        mConfigurationLocked.syncMode = syncMode;
+        if (SQLiteCompatibilityWalFlags.isLegacyCompatibilityWalEnabled()) {
+            mConfigurationLocked.openFlags |= ENABLE_LEGACY_COMPATIBILITY_WAL;
+        }
+    }
+
+    @Override
+    protected void finalize() throws Throwable {
+        try {
+            dispose(true);
+        } finally {
+            super.finalize();
+        }
+    }
+
+    @Override
+    protected void onAllReferencesReleased() {
+        dispose(false);
+    }
+
+    private void dispose(boolean finalized) {
+        final SQLiteConnectionPool pool;
+        synchronized (mLock) {
+            if (mCloseGuardLocked != null) {
+                if (finalized) {
+                    mCloseGuardLocked.warnIfOpen();
+                }
+                mCloseGuardLocked.close();
+            }
+
+            pool = mConnectionPoolLocked;
+            mConnectionPoolLocked = null;
+        }
+
+        if (!finalized) {
+            synchronized (sActiveDatabases) {
+                sActiveDatabases.remove(this);
+            }
+
+            if (pool != null) {
+                pool.close();
+            }
+        }
+    }
+
+    /**
+     * Attempts to release memory that SQLite holds but does not require to
+     * operate properly. Typically this memory will come from the page cache.
+     *
+     * @return the number of bytes actually released
+     */
+    public static int releaseMemory() {
+        return SQLiteGlobal.releaseMemory();
+    }
+
+    /**
+     * Control whether or not the SQLiteDatabase is made thread-safe by using locks
+     * around critical sections. This is pretty expensive, so if you know that your
+     * DB will only be used by a single thread then you should set this to false.
+     * The default is true.
+     * @param lockingEnabled set to true to enable locks, false otherwise
+     *
+     * @deprecated This method now does nothing.  Do not use.
+     */
+    @Deprecated
+    public void setLockingEnabled(boolean lockingEnabled) {
+    }
+
+    /**
+     * Gets a label to use when describing the database in log messages.
+     * @return The label.
+     */
+    String getLabel() {
+        synchronized (mLock) {
+            return mConfigurationLocked.label;
+        }
+    }
+
+    /**
+     * Sends a corruption message to the database error handler.
+     */
+    void onCorruption() {
+        EventLog.writeEvent(EVENT_DB_CORRUPT, getLabel());
+        mErrorHandler.onCorruption(this);
+    }
+
+    /**
+     * Gets the {@link SQLiteSession} that belongs to this thread for this database.
+     * Once a thread has obtained a session, it will continue to obtain the same
+     * session even after the database has been closed (although the session will not
+     * be usable).  However, a thread that does not already have a session cannot
+     * obtain one after the database has been closed.
+     *
+     * The idea is that threads that have active connections to the database may still
+     * have work to complete even after the call to {@link #close}.  Active database
+     * connections are not actually disposed until they are released by the threads
+     * that own them.
+     *
+     * @return The session, never null.
+     *
+     * @throws IllegalStateException if the thread does not yet have a session and
+     * the database is not open.
+     */
+    @UnsupportedAppUsage
+    SQLiteSession getThreadSession() {
+        return mThreadSession.get(); // initialValue() throws if database closed
+    }
+
+    SQLiteSession createSession() {
+        final SQLiteConnectionPool pool;
+        synchronized (mLock) {
+            throwIfNotOpenLocked();
+            pool = mConnectionPoolLocked;
+        }
+        return new SQLiteSession(pool);
+    }
+
+    /**
+     * Gets default connection flags that are appropriate for this thread, taking into
+     * account whether the thread is acting on behalf of the UI.
+     *
+     * @param readOnly True if the connection should be read-only.
+     * @return The connection flags.
+     */
+    int getThreadDefaultConnectionFlags(boolean readOnly) {
+        int flags = readOnly ? SQLiteConnectionPool.CONNECTION_FLAG_READ_ONLY :
+                SQLiteConnectionPool.CONNECTION_FLAG_PRIMARY_CONNECTION_AFFINITY;
+        if (isMainThread()) {
+            flags |= SQLiteConnectionPool.CONNECTION_FLAG_INTERACTIVE;
+        }
+        return flags;
+    }
+
+    private static boolean isMainThread() {
+        // FIXME: There should be a better way to do this.
+        // Would also be nice to have something that would work across Binder calls.
+        Looper looper = Looper.myLooper();
+        return looper != null && looper == Looper.getMainLooper();
+    }
+
+    /**
+     * Begins a transaction in EXCLUSIVE mode.
+     * <p>
+     * Transactions can be nested.
+     * When the outer transaction is ended all of
+     * the work done in that transaction and all of the nested transactions will be committed or
+     * rolled back. The changes will be rolled back if any transaction is ended without being
+     * marked as clean (by calling setTransactionSuccessful). Otherwise they will be committed.
+     * </p>
+     * <p>Here is the standard idiom for transactions:
+     *
+     * <pre>
+     *   db.beginTransaction();
+     *   try {
+     *     ...
+     *     db.setTransactionSuccessful();
+     *   } finally {
+     *     db.endTransaction();
+     *   }
+     * </pre>
+     */
+    public void beginTransaction() {
+        beginTransaction(null /* transactionStatusCallback */, true);
+    }
+
+    /**
+     * Begins a transaction in IMMEDIATE mode. Transactions can be nested. When
+     * the outer transaction is ended all of the work done in that transaction
+     * and all of the nested transactions will be committed or rolled back. The
+     * changes will be rolled back if any transaction is ended without being
+     * marked as clean (by calling setTransactionSuccessful). Otherwise they
+     * will be committed.
+     * <p>
+     * Here is the standard idiom for transactions:
+     *
+     * <pre>
+     *   db.beginTransactionNonExclusive();
+     *   try {
+     *     ...
+     *     db.setTransactionSuccessful();
+     *   } finally {
+     *     db.endTransaction();
+     *   }
+     * </pre>
+     */
+    public void beginTransactionNonExclusive() {
+        beginTransaction(null /* transactionStatusCallback */, false);
+    }
+
+    /**
+     * Begins a transaction in EXCLUSIVE mode.
+     * <p>
+     * Transactions can be nested.
+     * When the outer transaction is ended all of
+     * the work done in that transaction and all of the nested transactions will be committed or
+     * rolled back. The changes will be rolled back if any transaction is ended without being
+     * marked as clean (by calling setTransactionSuccessful). Otherwise they will be committed.
+     * </p>
+     * <p>Here is the standard idiom for transactions:
+     *
+     * <pre>
+     *   db.beginTransactionWithListener(listener);
+     *   try {
+     *     ...
+     *     db.setTransactionSuccessful();
+     *   } finally {
+     *     db.endTransaction();
+     *   }
+     * </pre>
+     *
+     * @param transactionListener listener that should be notified when the transaction begins,
+     * commits, or is rolled back, either explicitly or by a call to
+     * {@link #yieldIfContendedSafely}.
+     */
+    public void beginTransactionWithListener(SQLiteTransactionListener transactionListener) {
+        beginTransaction(transactionListener, true);
+    }
+
+    /**
+     * Begins a transaction in IMMEDIATE mode. Transactions can be nested. When
+     * the outer transaction is ended all of the work done in that transaction
+     * and all of the nested transactions will be committed or rolled back. The
+     * changes will be rolled back if any transaction is ended without being
+     * marked as clean (by calling setTransactionSuccessful). Otherwise they
+     * will be committed.
+     * <p>
+     * Here is the standard idiom for transactions:
+     *
+     * <pre>
+     *   db.beginTransactionWithListenerNonExclusive(listener);
+     *   try {
+     *     ...
+     *     db.setTransactionSuccessful();
+     *   } finally {
+     *     db.endTransaction();
+     *   }
+     * </pre>
+     *
+     * @param transactionListener listener that should be notified when the
+     *            transaction begins, commits, or is rolled back, either
+     *            explicitly or by a call to {@link #yieldIfContendedSafely}.
+     */
+    public void beginTransactionWithListenerNonExclusive(
+            SQLiteTransactionListener transactionListener) {
+        beginTransaction(transactionListener, false);
+    }
+
+    @UnsupportedAppUsage
+    private void beginTransaction(SQLiteTransactionListener transactionListener,
+            boolean exclusive) {
+        acquireReference();
+        try {
+            getThreadSession().beginTransaction(
+                    exclusive ? SQLiteSession.TRANSACTION_MODE_EXCLUSIVE :
+                            SQLiteSession.TRANSACTION_MODE_IMMEDIATE,
+                    transactionListener,
+                    getThreadDefaultConnectionFlags(false /*readOnly*/), null);
+        } finally {
+            releaseReference();
+        }
+    }
+
+    /**
+     * End a transaction. See beginTransaction for notes about how to use this and when transactions
+     * are committed and rolled back.
+     */
+    public void endTransaction() {
+        acquireReference();
+        try {
+            getThreadSession().endTransaction(null);
+        } finally {
+            releaseReference();
+        }
+    }
+
+    /**
+     * Marks the current transaction as successful. Do not do any more database work between
+     * calling this and calling endTransaction. Do as little non-database work as possible in that
+     * situation too. If any errors are encountered between this and endTransaction the transaction
+     * will still be committed.
+     *
+     * @throws IllegalStateException if the current thread is not in a transaction or the
+     * transaction is already marked as successful.
+     */
+    public void setTransactionSuccessful() {
+        acquireReference();
+        try {
+            getThreadSession().setTransactionSuccessful();
+        } finally {
+            releaseReference();
+        }
+    }
+
+    /**
+     * Returns true if the current thread has a transaction pending.
+     *
+     * @return True if the current thread is in a transaction.
+     */
+    public boolean inTransaction() {
+        acquireReference();
+        try {
+            return getThreadSession().hasTransaction();
+        } finally {
+            releaseReference();
+        }
+    }
+
+    /**
+     * Returns true if the current thread is holding an active connection to the database.
+     * <p>
+     * The name of this method comes from a time when having an active connection
+     * to the database meant that the thread was holding an actual lock on the
+     * database.  Nowadays, there is no longer a true "database lock" although threads
+     * may block if they cannot acquire a database connection to perform a
+     * particular operation.
+     * </p>
+     *
+     * @return True if the current thread is holding an active connection to the database.
+     */
+    public boolean isDbLockedByCurrentThread() {
+        acquireReference();
+        try {
+            return getThreadSession().hasConnection();
+        } finally {
+            releaseReference();
+        }
+    }
+
+    /**
+     * Always returns false.
+     * <p>
+     * There is no longer the concept of a database lock, so this method always returns false.
+     * </p>
+     *
+     * @return False.
+     * @deprecated Always returns false.  Do not use this method.
+     */
+    @Deprecated
+    public boolean isDbLockedByOtherThreads() {
+        return false;
+    }
+
+    /**
+     * Temporarily end the transaction to let other threads run. The transaction is assumed to be
+     * successful so far. Do not call setTransactionSuccessful before calling this. When this
+     * returns a new transaction will have been created but not marked as successful.
+     * @return true if the transaction was yielded
+     * @deprecated if the db is locked more than once (because of nested transactions) then the lock
+     *   will not be yielded. Use yieldIfContendedSafely instead.
+     */
+    @Deprecated
+    public boolean yieldIfContended() {
+        return yieldIfContendedHelper(false /* do not check yielding */,
+                -1 /* sleepAfterYieldDelay */);
+    }
+
+    /**
+     * Temporarily end the transaction to let other threads run. The transaction is assumed to be
+     * successful so far. Do not call setTransactionSuccessful before calling this. When this
+     * returns a new transaction will have been created but not marked as successful. This assumes
+     * that there are no nested transactions (beginTransaction has only been called once) and will
+     * throw an exception if that is not the case.
+     * @return true if the transaction was yielded
+     */
+    public boolean yieldIfContendedSafely() {
+        return yieldIfContendedHelper(true /* check yielding */, -1 /* sleepAfterYieldDelay*/);
+    }
+
+    /**
+     * Temporarily end the transaction to let other threads run. The transaction is assumed to be
+     * successful so far. Do not call setTransactionSuccessful before calling this. When this
+     * returns a new transaction will have been created but not marked as successful. This assumes
+     * that there are no nested transactions (beginTransaction has only been called once) and will
+     * throw an exception if that is not the case.
+     * @param sleepAfterYieldDelay if > 0, sleep this long before starting a new transaction if
+     *   the lock was actually yielded. This will allow other background threads to make some
+     *   more progress than they would if we started the transaction immediately.
+     * @return true if the transaction was yielded
+     */
+    public boolean yieldIfContendedSafely(long sleepAfterYieldDelay) {
+        return yieldIfContendedHelper(true /* check yielding */, sleepAfterYieldDelay);
+    }
+
+    private boolean yieldIfContendedHelper(boolean throwIfUnsafe, long sleepAfterYieldDelay) {
+        acquireReference();
+        try {
+            return getThreadSession().yieldTransaction(sleepAfterYieldDelay, throwIfUnsafe, null);
+        } finally {
+            releaseReference();
+        }
+    }
+
+    /**
+     * Deprecated.
+     * @deprecated This method no longer serves any useful purpose and has been deprecated.
+     */
+    @Deprecated
+    public Map<String, String> getSyncedTables() {
+        return new HashMap<String, String>(0);
+    }
+
+    /**
+     * Open the database according to the flags {@link #OPEN_READWRITE}
+     * {@link #OPEN_READONLY} {@link #CREATE_IF_NECESSARY} and/or {@link #NO_LOCALIZED_COLLATORS}.
+     *
+     * <p>Sets the locale of the database to the  the system's current locale.
+     * Call {@link #setLocale} if you would like something else.</p>
+     *
+     * @param path to database file to open and/or create
+     * @param factory an optional factory class that is called to instantiate a
+     *            cursor when query is called, or null for default
+     * @param flags to control database access mode
+     * @return the newly opened database
+     * @throws SQLiteException if the database cannot be opened
+     */
+    public static SQLiteDatabase openDatabase(@NonNull String path, @Nullable CursorFactory factory,
+            @DatabaseOpenFlags int flags) {
+        return openDatabase(path, factory, flags, null);
+    }
+
+    /**
+     * Open the database according to the specified {@link OpenParams parameters}
+     *
+     * @param path path to database file to open and/or create.
+     * <p><strong>Important:</strong> The file should be constructed either from an absolute path or
+     * by using {@link android.content.Context#getDatabasePath(String)}.
+     * @param openParams configuration parameters that are used for opening {@link SQLiteDatabase}
+     * @return the newly opened database
+     * @throws SQLiteException if the database cannot be opened
+     */
+    public static SQLiteDatabase openDatabase(@NonNull File path,
+            @NonNull OpenParams openParams) {
+        return openDatabase(path.getPath(), openParams);
+    }
+
+    @UnsupportedAppUsage
+    private static SQLiteDatabase openDatabase(@NonNull String path,
+            @NonNull OpenParams openParams) {
+        Preconditions.checkArgument(openParams != null, "OpenParams cannot be null");
+        SQLiteDatabase db = new SQLiteDatabase(path, openParams.mOpenFlags,
+                openParams.mCursorFactory, openParams.mErrorHandler,
+                openParams.mLookasideSlotSize, openParams.mLookasideSlotCount,
+                openParams.mIdleConnectionTimeout, openParams.mJournalMode, openParams.mSyncMode);
+        db.open();
+        return db;
+    }
+
+    /**
+     * Open the database according to the flags {@link #OPEN_READWRITE}
+     * {@link #OPEN_READONLY} {@link #CREATE_IF_NECESSARY} and/or {@link #NO_LOCALIZED_COLLATORS}.
+     *
+     * <p>Sets the locale of the database to the  the system's current locale.
+     * Call {@link #setLocale} if you would like something else.</p>
+     *
+     * <p>Accepts input param: a concrete instance of {@link DatabaseErrorHandler} to be
+     * used to handle corruption when sqlite reports database corruption.</p>
+     *
+     * @param path to database file to open and/or create
+     * @param factory an optional factory class that is called to instantiate a
+     *            cursor when query is called, or null for default
+     * @param flags to control database access mode
+     * @param errorHandler the {@link DatabaseErrorHandler} obj to be used to handle corruption
+     * when sqlite reports database corruption
+     * @return the newly opened database
+     * @throws SQLiteException if the database cannot be opened
+     */
+    public static SQLiteDatabase openDatabase(@NonNull String path, @Nullable CursorFactory factory,
+            @DatabaseOpenFlags int flags, @Nullable DatabaseErrorHandler errorHandler) {
+        SQLiteDatabase db = new SQLiteDatabase(path, flags, factory, errorHandler, -1, -1, -1, null,
+                null);
+        db.open();
+        return db;
+    }
+
+    /**
+     * Equivalent to openDatabase(file.getPath(), factory, CREATE_IF_NECESSARY).
+     */
+    public static SQLiteDatabase openOrCreateDatabase(@NonNull File file,
+            @Nullable CursorFactory factory) {
+        return openOrCreateDatabase(file.getPath(), factory);
+    }
+
+    /**
+     * Equivalent to openDatabase(path, factory, CREATE_IF_NECESSARY).
+     */
+    public static SQLiteDatabase openOrCreateDatabase(@NonNull String path,
+            @Nullable CursorFactory factory) {
+        return openDatabase(path, factory, CREATE_IF_NECESSARY, null);
+    }
+
+    /**
+     * Equivalent to openDatabase(path, factory, CREATE_IF_NECESSARY, errorHandler).
+     */
+    public static SQLiteDatabase openOrCreateDatabase(@NonNull String path,
+            @Nullable CursorFactory factory, @Nullable DatabaseErrorHandler errorHandler) {
+        return openDatabase(path, factory, CREATE_IF_NECESSARY, errorHandler);
+    }
+
+    /**
+     * Deletes a database including its journal file and other auxiliary files
+     * that may have been created by the database engine.
+     *
+     * @param file The database file path.
+     * @return True if the database was successfully deleted.
+     */
+    public static boolean deleteDatabase(@NonNull File file) {
+        return deleteDatabase(file, /*removeCheckFile=*/ true);
+    }
+
+
+    /** @hide */
+    public static boolean deleteDatabase(@NonNull File file, boolean removeCheckFile) {
+        if (file == null) {
+            throw new IllegalArgumentException("file must not be null");
+        }
+
+        boolean deleted = false;
+        deleted |= file.delete();
+        deleted |= new File(file.getPath() + "-journal").delete();
+        deleted |= new File(file.getPath() + "-shm").delete();
+        deleted |= new File(file.getPath() + "-wal").delete();
+
+        // This file is not a standard SQLite file, so don't update the deleted flag.
+        new File(file.getPath() + SQLiteGlobal.WIPE_CHECK_FILE_SUFFIX).delete();
+
+        File dir = file.getParentFile();
+        if (dir != null) {
+            final String prefix = file.getName() + "-mj";
+            File[] files = dir.listFiles(new FileFilter() {
+                @Override
+                public boolean accept(File candidate) {
+                    return candidate.getName().startsWith(prefix);
+                }
+            });
+            if (files != null) {
+                for (File masterJournal : files) {
+                    deleted |= masterJournal.delete();
+                }
+            }
+        }
+        return deleted;
+    }
+
+    /**
+     * Reopens the database in read-write mode.
+     * If the database is already read-write, does nothing.
+     *
+     * @throws SQLiteException if the database could not be reopened as requested, in which
+     * case it remains open in read only mode.
+     * @throws IllegalStateException if the database is not open.
+     *
+     * @see #isReadOnly()
+     * @hide
+     */
+    @UnsupportedAppUsage
+    public void reopenReadWrite() {
+        synchronized (mLock) {
+            throwIfNotOpenLocked();
+
+            if (!isReadOnlyLocked()) {
+                return; // nothing to do
+            }
+
+            // Reopen the database in read-write mode.
+            final int oldOpenFlags = mConfigurationLocked.openFlags;
+            mConfigurationLocked.openFlags = (mConfigurationLocked.openFlags & ~OPEN_READ_MASK)
+                    | OPEN_READWRITE;
+            try {
+                mConnectionPoolLocked.reconfigure(mConfigurationLocked);
+            } catch (RuntimeException ex) {
+                mConfigurationLocked.openFlags = oldOpenFlags;
+                throw ex;
+            }
+        }
+    }
+
+    private void open() {
+        try {
+            try {
+                openInner();
+            } catch (RuntimeException ex) {
+                if (SQLiteDatabaseCorruptException.isCorruptException(ex)) {
+                    Log.e(TAG, "Database corruption detected in open()", ex);
+                    onCorruption();
+                    openInner();
+                } else {
+                    throw ex;
+                }
+            }
+        } catch (SQLiteException ex) {
+            Log.e(TAG, "Failed to open database '" + getLabel() + "'.", ex);
+            close();
+            throw ex;
+        }
+    }
+
+    private void openInner() {
+        synchronized (mLock) {
+            assert mConnectionPoolLocked == null;
+            mConnectionPoolLocked = SQLiteConnectionPool.open(mConfigurationLocked);
+            mCloseGuardLocked.open("close");
+        }
+
+        synchronized (sActiveDatabases) {
+            sActiveDatabases.put(this, null);
+        }
+    }
+
+    /**
+     * Create a memory backed SQLite database.  Its contents will be destroyed
+     * when the database is closed.
+     *
+     * <p>Sets the locale of the database to the  the system's current locale.
+     * Call {@link #setLocale} if you would like something else.</p>
+     *
+     * @param factory an optional factory class that is called to instantiate a
+     *            cursor when query is called
+     * @return a SQLiteDatabase instance
+     * @throws SQLiteException if the database cannot be created
+     */
+    @NonNull
+    public static SQLiteDatabase create(@Nullable CursorFactory factory) {
+        // This is a magic string with special meaning for SQLite.
+        return openDatabase(SQLiteDatabaseConfiguration.MEMORY_DB_PATH,
+                factory, CREATE_IF_NECESSARY);
+    }
+
+    /**
+     * Create a memory backed SQLite database.  Its contents will be destroyed
+     * when the database is closed.
+     *
+     * <p>Sets the locale of the database to the  the system's current locale.
+     * Call {@link #setLocale} if you would like something else.</p>
+     * @param openParams configuration parameters that are used for opening SQLiteDatabase
+     * @return a SQLiteDatabase instance
+     * @throws SQLException if the database cannot be created
+     */
+    @NonNull
+    public static SQLiteDatabase createInMemory(@NonNull OpenParams openParams) {
+        return openDatabase(SQLiteDatabaseConfiguration.MEMORY_DB_PATH,
+                openParams.toBuilder().addOpenFlags(CREATE_IF_NECESSARY).build());
+    }
+
+    /**
+     * Register a custom scalar function that can be called from SQL
+     * expressions.
+     * <p>
+     * For example, registering a custom scalar function named {@code REVERSE}
+     * could be used in a query like
+     * {@code SELECT REVERSE(name) FROM employees}.
+     * <p>
+     * When attempting to register multiple functions with the same function
+     * name, SQLite will replace any previously defined functions with the
+     * latest definition, regardless of what function type they are. SQLite does
+     * not support unregistering functions.
+     *
+     * @param functionName Case-insensitive name to register this function
+     *            under, limited to 255 UTF-8 bytes in length.
+     * @param scalarFunction Functional interface that will be invoked when the
+     *            function name is used by a SQL statement. The argument values
+     *            from the SQL statement are passed to the functional interface,
+     *            and the return values from the functional interface are
+     *            returned back into the SQL statement.
+     * @throws SQLiteException if the custom function could not be registered.
+     * @see #setCustomAggregateFunction(String, BinaryOperator)
+     */
+    public void setCustomScalarFunction(@NonNull String functionName,
+            @NonNull UnaryOperator<String> scalarFunction) throws SQLiteException {
+        Objects.requireNonNull(functionName);
+        Objects.requireNonNull(scalarFunction);
+
+        synchronized (mLock) {
+            throwIfNotOpenLocked();
+
+            mConfigurationLocked.customScalarFunctions.put(functionName, scalarFunction);
+            try {
+                mConnectionPoolLocked.reconfigure(mConfigurationLocked);
+            } catch (RuntimeException ex) {
+                mConfigurationLocked.customScalarFunctions.remove(functionName);
+                throw ex;
+            }
+        }
+    }
+
+    /**
+     * Register a custom aggregate function that can be called from SQL
+     * expressions.
+     * <p>
+     * For example, registering a custom aggregation function named
+     * {@code LONGEST} could be used in a query like
+     * {@code SELECT LONGEST(name) FROM employees}.
+     * <p>
+     * The implementation of this method follows the reduction flow outlined in
+     * {@link java.util.stream.Stream#reduce(BinaryOperator)}, and the custom
+     * aggregation function is expected to be an associative accumulation
+     * function, as defined by that class.
+     * <p>
+     * When attempting to register multiple functions with the same function
+     * name, SQLite will replace any previously defined functions with the
+     * latest definition, regardless of what function type they are. SQLite does
+     * not support unregistering functions.
+     *
+     * @param functionName Case-insensitive name to register this function
+     *            under, limited to 255 UTF-8 bytes in length.
+     * @param aggregateFunction Functional interface that will be invoked when
+     *            the function name is used by a SQL statement. The argument
+     *            values from the SQL statement are passed to the functional
+     *            interface, and the return values from the functional interface
+     *            are returned back into the SQL statement.
+     * @throws SQLiteException if the custom function could not be registered.
+     * @see #setCustomScalarFunction(String, UnaryOperator)
+     */
+    public void setCustomAggregateFunction(@NonNull String functionName,
+            @NonNull BinaryOperator<String> aggregateFunction) throws SQLiteException {
+        Objects.requireNonNull(functionName);
+        Objects.requireNonNull(aggregateFunction);
+
+        synchronized (mLock) {
+            throwIfNotOpenLocked();
+
+            mConfigurationLocked.customAggregateFunctions.put(functionName, aggregateFunction);
+            try {
+                mConnectionPoolLocked.reconfigure(mConfigurationLocked);
+            } catch (RuntimeException ex) {
+                mConfigurationLocked.customAggregateFunctions.remove(functionName);
+                throw ex;
+            }
+        }
+    }
+
+    /**
+     * Execute the given SQL statement on all connections to this database.
+     * <p>
+     * This statement will be immediately executed on all existing connections,
+     * and will be automatically executed on all future connections.
+     * <p>
+     * Some example usages are changes like {@code PRAGMA trusted_schema=OFF} or
+     * functions like {@code SELECT icu_load_collation()}. If you execute these
+     * statements using {@link #execSQL} then they will only apply to a single
+     * database connection; using this method will ensure that they are
+     * uniformly applied to all current and future connections.
+     *
+     * @param sql The SQL statement to be executed. Multiple statements
+     *            separated by semicolons are not supported.
+     * @param bindArgs The arguments that should be bound to the SQL statement.
+     */
+    public void execPerConnectionSQL(@NonNull String sql, @Nullable Object[] bindArgs)
+            throws SQLException {
+        Objects.requireNonNull(sql);
+
+        // Copy arguments to ensure that the caller doesn't accidentally change
+        // the values used by future connections
+        bindArgs = DatabaseUtils.deepCopyOf(bindArgs);
+
+        synchronized (mLock) {
+            throwIfNotOpenLocked();
+
+            final int index = mConfigurationLocked.perConnectionSql.size();
+            mConfigurationLocked.perConnectionSql.add(Pair.create(sql, bindArgs));
+            try {
+                mConnectionPoolLocked.reconfigure(mConfigurationLocked);
+            } catch (RuntimeException ex) {
+                mConfigurationLocked.perConnectionSql.remove(index);
+                throw ex;
+            }
+        }
+    }
+
+    /**
+     * Gets the database version.
+     *
+     * @return the database version
+     */
+    public int getVersion() {
+        return ((Long) DatabaseUtils.longForQuery(this, "PRAGMA user_version;", null)).intValue();
+    }
+
+    /**
+     * Sets the database version.
+     *
+     * @param version the new database version
+     */
+    public void setVersion(int version) {
+        execSQL("PRAGMA user_version = " + version);
+    }
+
+    /**
+     * Returns the maximum size the database may grow to.
+     *
+     * @return the new maximum database size
+     */
+    public long getMaximumSize() {
+        long pageCount = DatabaseUtils.longForQuery(this, "PRAGMA max_page_count;", null);
+        return pageCount * getPageSize();
+    }
+
+    /**
+     * Sets the maximum size the database will grow to. The maximum size cannot
+     * be set below the current size.
+     *
+     * @param numBytes the maximum database size, in bytes
+     * @return the new maximum database size
+     */
+    public long setMaximumSize(long numBytes) {
+        long pageSize = getPageSize();
+        long numPages = numBytes / pageSize;
+        // If numBytes isn't a multiple of pageSize, bump up a page
+        if ((numBytes % pageSize) != 0) {
+            numPages++;
+        }
+        long newPageCount = DatabaseUtils.longForQuery(this, "PRAGMA max_page_count = " + numPages,
+                null);
+        return newPageCount * pageSize;
+    }
+
+    /**
+     * Returns the current database page size, in bytes.
+     *
+     * @return the database page size, in bytes
+     */
+    public long getPageSize() {
+        return DatabaseUtils.longForQuery(this, "PRAGMA page_size;", null);
+    }
+
+    /**
+     * Sets the database page size. The page size must be a power of two. This
+     * method does not work if any data has been written to the database file,
+     * and must be called right after the database has been created.
+     *
+     * @param numBytes the database page size, in bytes
+     */
+    public void setPageSize(long numBytes) {
+        execSQL("PRAGMA page_size = " + numBytes);
+    }
+
+    /**
+     * Mark this table as syncable. When an update occurs in this table the
+     * _sync_dirty field will be set to ensure proper syncing operation.
+     *
+     * @param table the table to mark as syncable
+     * @param deletedTable The deleted table that corresponds to the
+     *          syncable table
+     * @deprecated This method no longer serves any useful purpose and has been deprecated.
+     */
+    @Deprecated
+    public void markTableSyncable(String table, String deletedTable) {
+    }
+
+    /**
+     * Mark this table as syncable, with the _sync_dirty residing in another
+     * table. When an update occurs in this table the _sync_dirty field of the
+     * row in updateTable with the _id in foreignKey will be set to
+     * ensure proper syncing operation.
+     *
+     * @param table an update on this table will trigger a sync time removal
+     * @param foreignKey this is the column in table whose value is an _id in
+     *          updateTable
+     * @param updateTable this is the table that will have its _sync_dirty
+     * @deprecated This method no longer serves any useful purpose and has been deprecated.
+     */
+    @Deprecated
+    public void markTableSyncable(String table, String foreignKey, String updateTable) {
+    }
+
+    /**
+     * Finds the name of the first table, which is editable.
+     *
+     * @param tables a list of tables
+     * @return the first table listed
+     */
+    public static String findEditTable(String tables) {
+        if (!TextUtils.isEmpty(tables)) {
+            // find the first word terminated by either a space or a comma
+            int spacepos = tables.indexOf(' ');
+            int commapos = tables.indexOf(',');
+
+            if (spacepos > 0 && (spacepos < commapos || commapos < 0)) {
+                return tables.substring(0, spacepos);
+            } else if (commapos > 0 && (commapos < spacepos || spacepos < 0) ) {
+                return tables.substring(0, commapos);
+            }
+            return tables;
+        } else {
+            throw new IllegalStateException("Invalid tables");
+        }
+    }
+
+    /**
+     * Compiles an SQL statement into a reusable pre-compiled statement object.
+     * The parameters are identical to {@link #execSQL(String)}. You may put ?s in the
+     * statement and fill in those values with {@link SQLiteProgram#bindString}
+     * and {@link SQLiteProgram#bindLong} each time you want to run the
+     * statement. Statements may not return result sets larger than 1x1.
+     *<p>
+     * No two threads should be using the same {@link SQLiteStatement} at the same time.
+     *
+     * @param sql The raw SQL statement, may contain ? for unknown values to be
+     *            bound later.
+     * @return A pre-compiled {@link SQLiteStatement} object. Note that
+     * {@link SQLiteStatement}s are not synchronized, see the documentation for more details.
+     */
+    public SQLiteStatement compileStatement(String sql) throws SQLException {
+        acquireReference();
+        try {
+            return new SQLiteStatement(this, sql, null);
+        } finally {
+            releaseReference();
+        }
+    }
+
+    /**
+     * Query the given URL, returning a {@link Cursor} over the result set.
+     *
+     * @param distinct true if you want each row to be unique, false otherwise.
+     * @param table The table name to compile the query against.
+     * @param columns A list of which columns to return. Passing null will
+     *            return all columns, which is discouraged to prevent reading
+     *            data from storage that isn't going to be used.
+     * @param selection A filter declaring which rows to return, formatted as an
+     *            SQL WHERE clause (excluding the WHERE itself). Passing null
+     *            will return all rows for the given table.
+     * @param selectionArgs You may include ?s in selection, which will be
+     *         replaced by the values from selectionArgs, in order that they
+     *         appear in the selection. The values will be bound as Strings.
+     * @param groupBy A filter declaring how to group rows, formatted as an SQL
+     *            GROUP BY clause (excluding the GROUP BY itself). Passing null
+     *            will cause the rows to not be grouped.
+     * @param having A filter declare which row groups to include in the cursor,
+     *            if row grouping is being used, formatted as an SQL HAVING
+     *            clause (excluding the HAVING itself). Passing null will cause
+     *            all row groups to be included, and is required when row
+     *            grouping is not being used.
+     * @param orderBy How to order the rows, formatted as an SQL ORDER BY clause
+     *            (excluding the ORDER BY itself). Passing null will use the
+     *            default sort order, which may be unordered.
+     * @param limit Limits the number of rows returned by the query,
+     *            formatted as LIMIT clause. Passing null denotes no LIMIT clause.
+     * @return A {@link Cursor} object, which is positioned before the first entry. Note that
+     * {@link Cursor}s are not synchronized, see the documentation for more details.
+     * @see Cursor
+     */
+    public Cursor query(boolean distinct, String table, String[] columns,
+            String selection, String[] selectionArgs, String groupBy,
+            String having, String orderBy, String limit) {
+        return queryWithFactory(null, distinct, table, columns, selection, selectionArgs,
+                groupBy, having, orderBy, limit, null);
+    }
+
+    /**
+     * Query the given URL, returning a {@link Cursor} over the result set.
+     *
+     * @param distinct true if you want each row to be unique, false otherwise.
+     * @param table The table name to compile the query against.
+     * @param columns A list of which columns to return. Passing null will
+     *            return all columns, which is discouraged to prevent reading
+     *            data from storage that isn't going to be used.
+     * @param selection A filter declaring which rows to return, formatted as an
+     *            SQL WHERE clause (excluding the WHERE itself). Passing null
+     *            will return all rows for the given table.
+     * @param selectionArgs You may include ?s in selection, which will be
+     *         replaced by the values from selectionArgs, in order that they
+     *         appear in the selection. The values will be bound as Strings.
+     * @param groupBy A filter declaring how to group rows, formatted as an SQL
+     *            GROUP BY clause (excluding the GROUP BY itself). Passing null
+     *            will cause the rows to not be grouped.
+     * @param having A filter declare which row groups to include in the cursor,
+     *            if row grouping is being used, formatted as an SQL HAVING
+     *            clause (excluding the HAVING itself). Passing null will cause
+     *            all row groups to be included, and is required when row
+     *            grouping is not being used.
+     * @param orderBy How to order the rows, formatted as an SQL ORDER BY clause
+     *            (excluding the ORDER BY itself). Passing null will use the
+     *            default sort order, which may be unordered.
+     * @param limit Limits the number of rows returned by the query,
+     *            formatted as LIMIT clause. Passing null denotes no LIMIT clause.
+     * @param cancellationSignal A signal to cancel the operation in progress, or null if none.
+     * If the operation is canceled, then {@link OperationCanceledException} will be thrown
+     * when the query is executed.
+     * @return A {@link Cursor} object, which is positioned before the first entry. Note that
+     * {@link Cursor}s are not synchronized, see the documentation for more details.
+     * @see Cursor
+     */
+    public Cursor query(boolean distinct, String table, String[] columns,
+            String selection, String[] selectionArgs, String groupBy,
+            String having, String orderBy, String limit, CancellationSignal cancellationSignal) {
+        return queryWithFactory(null, distinct, table, columns, selection, selectionArgs,
+                groupBy, having, orderBy, limit, cancellationSignal);
+    }
+
+    /**
+     * Query the given URL, returning a {@link Cursor} over the result set.
+     *
+     * @param cursorFactory the cursor factory to use, or null for the default factory
+     * @param distinct true if you want each row to be unique, false otherwise.
+     * @param table The table name to compile the query against.
+     * @param columns A list of which columns to return. Passing null will
+     *            return all columns, which is discouraged to prevent reading
+     *            data from storage that isn't going to be used.
+     * @param selection A filter declaring which rows to return, formatted as an
+     *            SQL WHERE clause (excluding the WHERE itself). Passing null
+     *            will return all rows for the given table.
+     * @param selectionArgs You may include ?s in selection, which will be
+     *         replaced by the values from selectionArgs, in order that they
+     *         appear in the selection. The values will be bound as Strings.
+     * @param groupBy A filter declaring how to group rows, formatted as an SQL
+     *            GROUP BY clause (excluding the GROUP BY itself). Passing null
+     *            will cause the rows to not be grouped.
+     * @param having A filter declare which row groups to include in the cursor,
+     *            if row grouping is being used, formatted as an SQL HAVING
+     *            clause (excluding the HAVING itself). Passing null will cause
+     *            all row groups to be included, and is required when row
+     *            grouping is not being used.
+     * @param orderBy How to order the rows, formatted as an SQL ORDER BY clause
+     *            (excluding the ORDER BY itself). Passing null will use the
+     *            default sort order, which may be unordered.
+     * @param limit Limits the number of rows returned by the query,
+     *            formatted as LIMIT clause. Passing null denotes no LIMIT clause.
+     * @return A {@link Cursor} object, which is positioned before the first entry. Note that
+     * {@link Cursor}s are not synchronized, see the documentation for more details.
+     * @see Cursor
+     */
+    public Cursor queryWithFactory(CursorFactory cursorFactory,
+            boolean distinct, String table, String[] columns,
+            String selection, String[] selectionArgs, String groupBy,
+            String having, String orderBy, String limit) {
+        return queryWithFactory(cursorFactory, distinct, table, columns, selection,
+                selectionArgs, groupBy, having, orderBy, limit, null);
+    }
+
+    /**
+     * Query the given URL, returning a {@link Cursor} over the result set.
+     *
+     * @param cursorFactory the cursor factory to use, or null for the default factory
+     * @param distinct true if you want each row to be unique, false otherwise.
+     * @param table The table name to compile the query against.
+     * @param columns A list of which columns to return. Passing null will
+     *            return all columns, which is discouraged to prevent reading
+     *            data from storage that isn't going to be used.
+     * @param selection A filter declaring which rows to return, formatted as an
+     *            SQL WHERE clause (excluding the WHERE itself). Passing null
+     *            will return all rows for the given table.
+     * @param selectionArgs You may include ?s in selection, which will be
+     *         replaced by the values from selectionArgs, in order that they
+     *         appear in the selection. The values will be bound as Strings.
+     * @param groupBy A filter declaring how to group rows, formatted as an SQL
+     *            GROUP BY clause (excluding the GROUP BY itself). Passing null
+     *            will cause the rows to not be grouped.
+     * @param having A filter declare which row groups to include in the cursor,
+     *            if row grouping is being used, formatted as an SQL HAVING
+     *            clause (excluding the HAVING itself). Passing null will cause
+     *            all row groups to be included, and is required when row
+     *            grouping is not being used.
+     * @param orderBy How to order the rows, formatted as an SQL ORDER BY clause
+     *            (excluding the ORDER BY itself). Passing null will use the
+     *            default sort order, which may be unordered.
+     * @param limit Limits the number of rows returned by the query,
+     *            formatted as LIMIT clause. Passing null denotes no LIMIT clause.
+     * @param cancellationSignal A signal to cancel the operation in progress, or null if none.
+     * If the operation is canceled, then {@link OperationCanceledException} will be thrown
+     * when the query is executed.
+     * @return A {@link Cursor} object, which is positioned before the first entry. Note that
+     * {@link Cursor}s are not synchronized, see the documentation for more details.
+     * @see Cursor
+     */
+    public Cursor queryWithFactory(CursorFactory cursorFactory,
+            boolean distinct, String table, String[] columns,
+            String selection, String[] selectionArgs, String groupBy,
+            String having, String orderBy, String limit, CancellationSignal cancellationSignal) {
+        acquireReference();
+        try {
+            String sql = SQLiteQueryBuilder.buildQueryString(
+                    distinct, table, columns, selection, groupBy, having, orderBy, limit);
+
+            return rawQueryWithFactory(cursorFactory, sql, selectionArgs,
+                    findEditTable(table), cancellationSignal);
+        } finally {
+            releaseReference();
+        }
+    }
+
+    /**
+     * Query the given table, returning a {@link Cursor} over the result set.
+     *
+     * @param table The table name to compile the query against.
+     * @param columns A list of which columns to return. Passing null will
+     *            return all columns, which is discouraged to prevent reading
+     *            data from storage that isn't going to be used.
+     * @param selection A filter declaring which rows to return, formatted as an
+     *            SQL WHERE clause (excluding the WHERE itself). Passing null
+     *            will return all rows for the given table.
+     * @param selectionArgs You may include ?s in selection, which will be
+     *         replaced by the values from selectionArgs, in order that they
+     *         appear in the selection. The values will be bound as Strings.
+     * @param groupBy A filter declaring how to group rows, formatted as an SQL
+     *            GROUP BY clause (excluding the GROUP BY itself). Passing null
+     *            will cause the rows to not be grouped.
+     * @param having A filter declare which row groups to include in the cursor,
+     *            if row grouping is being used, formatted as an SQL HAVING
+     *            clause (excluding the HAVING itself). Passing null will cause
+     *            all row groups to be included, and is required when row
+     *            grouping is not being used.
+     * @param orderBy How to order the rows, formatted as an SQL ORDER BY clause
+     *            (excluding the ORDER BY itself). Passing null will use the
+     *            default sort order, which may be unordered.
+     * @return A {@link Cursor} object, which is positioned before the first entry. Note that
+     * {@link Cursor}s are not synchronized, see the documentation for more details.
+     * @see Cursor
+     */
+    public Cursor query(String table, String[] columns, String selection,
+            String[] selectionArgs, String groupBy, String having,
+            String orderBy) {
+
+        return query(false, table, columns, selection, selectionArgs, groupBy,
+                having, orderBy, null /* limit */);
+    }
+
+    /**
+     * Query the given table, returning a {@link Cursor} over the result set.
+     *
+     * @param table The table name to compile the query against.
+     * @param columns A list of which columns to return. Passing null will
+     *            return all columns, which is discouraged to prevent reading
+     *            data from storage that isn't going to be used.
+     * @param selection A filter declaring which rows to return, formatted as an
+     *            SQL WHERE clause (excluding the WHERE itself). Passing null
+     *            will return all rows for the given table.
+     * @param selectionArgs You may include ?s in selection, which will be
+     *         replaced by the values from selectionArgs, in order that they
+     *         appear in the selection. The values will be bound as Strings.
+     * @param groupBy A filter declaring how to group rows, formatted as an SQL
+     *            GROUP BY clause (excluding the GROUP BY itself). Passing null
+     *            will cause the rows to not be grouped.
+     * @param having A filter declare which row groups to include in the cursor,
+     *            if row grouping is being used, formatted as an SQL HAVING
+     *            clause (excluding the HAVING itself). Passing null will cause
+     *            all row groups to be included, and is required when row
+     *            grouping is not being used.
+     * @param orderBy How to order the rows, formatted as an SQL ORDER BY clause
+     *            (excluding the ORDER BY itself). Passing null will use the
+     *            default sort order, which may be unordered.
+     * @param limit Limits the number of rows returned by the query,
+     *            formatted as LIMIT clause. Passing null denotes no LIMIT clause.
+     * @return A {@link Cursor} object, which is positioned before the first entry. Note that
+     * {@link Cursor}s are not synchronized, see the documentation for more details.
+     * @see Cursor
+     */
+    public Cursor query(String table, String[] columns, String selection,
+            String[] selectionArgs, String groupBy, String having,
+            String orderBy, String limit) {
+
+        return query(false, table, columns, selection, selectionArgs, groupBy,
+                having, orderBy, limit);
+    }
+
+    /**
+     * Runs the provided SQL and returns a {@link Cursor} over the result set.
+     *
+     * @param sql the SQL query. The SQL string must not be ; terminated
+     * @param selectionArgs You may include ?s in where clause in the query,
+     *     which will be replaced by the values from selectionArgs. The
+     *     values will be bound as Strings.
+     * @return A {@link Cursor} object, which is positioned before the first entry. Note that
+     * {@link Cursor}s are not synchronized, see the documentation for more details.
+     */
+    public Cursor rawQuery(String sql, String[] selectionArgs) {
+        return rawQueryWithFactory(null, sql, selectionArgs, null, null);
+    }
+
+    /**
+     * Runs the provided SQL and returns a {@link Cursor} over the result set.
+     *
+     * @param sql the SQL query. The SQL string must not be ; terminated
+     * @param selectionArgs You may include ?s in where clause in the query,
+     *     which will be replaced by the values from selectionArgs. The
+     *     values will be bound as Strings.
+     * @param cancellationSignal A signal to cancel the operation in progress, or null if none.
+     * If the operation is canceled, then {@link OperationCanceledException} will be thrown
+     * when the query is executed.
+     * @return A {@link Cursor} object, which is positioned before the first entry. Note that
+     * {@link Cursor}s are not synchronized, see the documentation for more details.
+     */
+    public Cursor rawQuery(String sql, String[] selectionArgs,
+            CancellationSignal cancellationSignal) {
+        return rawQueryWithFactory(null, sql, selectionArgs, null, cancellationSignal);
+    }
+
+    /**
+     * Runs the provided SQL and returns a cursor over the result set.
+     *
+     * @param cursorFactory the cursor factory to use, or null for the default factory
+     * @param sql the SQL query. The SQL string must not be ; terminated
+     * @param selectionArgs You may include ?s in where clause in the query,
+     *     which will be replaced by the values from selectionArgs. The
+     *     values will be bound as Strings.
+     * @param editTable the name of the first table, which is editable
+     * @return A {@link Cursor} object, which is positioned before the first entry. Note that
+     * {@link Cursor}s are not synchronized, see the documentation for more details.
+     */
+    public Cursor rawQueryWithFactory(
+            CursorFactory cursorFactory, String sql, String[] selectionArgs,
+            String editTable) {
+        return rawQueryWithFactory(cursorFactory, sql, selectionArgs, editTable, null);
+    }
+
+    /**
+     * Runs the provided SQL and returns a cursor over the result set.
+     *
+     * @param cursorFactory the cursor factory to use, or null for the default factory
+     * @param sql the SQL query. The SQL string must not be ; terminated
+     * @param selectionArgs You may include ?s in where clause in the query,
+     *     which will be replaced by the values from selectionArgs. The
+     *     values will be bound as Strings.
+     * @param editTable the name of the first table, which is editable
+     * @param cancellationSignal A signal to cancel the operation in progress, or null if none.
+     * If the operation is canceled, then {@link OperationCanceledException} will be thrown
+     * when the query is executed.
+     * @return A {@link Cursor} object, which is positioned before the first entry. Note that
+     * {@link Cursor}s are not synchronized, see the documentation for more details.
+     */
+    public Cursor rawQueryWithFactory(
+            CursorFactory cursorFactory, String sql, String[] selectionArgs,
+            String editTable, CancellationSignal cancellationSignal) {
+        acquireReference();
+        try {
+            SQLiteCursorDriver driver = new SQLiteDirectCursorDriver(this, sql, editTable,
+                    cancellationSignal);
+            return driver.query(cursorFactory != null ? cursorFactory : mCursorFactory,
+                    selectionArgs);
+        } finally {
+            releaseReference();
+        }
+    }
+
+    /**
+     * Convenience method for inserting a row into the database.
+     *
+     * @param table the table to insert the row into
+     * @param nullColumnHack optional; may be <code>null</code>.
+     *            SQL doesn't allow inserting a completely empty row without
+     *            naming at least one column name.  If your provided <code>values</code> is
+     *            empty, no column names are known and an empty row can't be inserted.
+     *            If not set to null, the <code>nullColumnHack</code> parameter
+     *            provides the name of nullable column name to explicitly insert a NULL into
+     *            in the case where your <code>values</code> is empty.
+     * @param values this map contains the initial column values for the
+     *            row. The keys should be the column names and the values the
+     *            column values
+     * @return the row ID of the newly inserted row, or -1 if an error occurred
+     */
+    public long insert(String table, String nullColumnHack, ContentValues values) {
+        try {
+            return insertWithOnConflict(table, nullColumnHack, values, CONFLICT_NONE);
+        } catch (SQLException e) {
+            Log.e(TAG, "Error inserting " + values, e);
+            return -1;
+        }
+    }
+
+    /**
+     * Convenience method for inserting a row into the database.
+     *
+     * @param table the table to insert the row into
+     * @param nullColumnHack optional; may be <code>null</code>.
+     *            SQL doesn't allow inserting a completely empty row without
+     *            naming at least one column name.  If your provided <code>values</code> is
+     *            empty, no column names are known and an empty row can't be inserted.
+     *            If not set to null, the <code>nullColumnHack</code> parameter
+     *            provides the name of nullable column name to explicitly insert a NULL into
+     *            in the case where your <code>values</code> is empty.
+     * @param values this map contains the initial column values for the
+     *            row. The keys should be the column names and the values the
+     *            column values
+     * @throws SQLException
+     * @return the row ID of the newly inserted row, or -1 if an error occurred
+     */
+    public long insertOrThrow(String table, String nullColumnHack, ContentValues values)
+            throws SQLException {
+        return insertWithOnConflict(table, nullColumnHack, values, CONFLICT_NONE);
+    }
+
+    /**
+     * Convenience method for replacing a row in the database.
+     * Inserts a new row if a row does not already exist.
+     *
+     * @param table the table in which to replace the row
+     * @param nullColumnHack optional; may be <code>null</code>.
+     *            SQL doesn't allow inserting a completely empty row without
+     *            naming at least one column name.  If your provided <code>initialValues</code> is
+     *            empty, no column names are known and an empty row can't be inserted.
+     *            If not set to null, the <code>nullColumnHack</code> parameter
+     *            provides the name of nullable column name to explicitly insert a NULL into
+     *            in the case where your <code>initialValues</code> is empty.
+     * @param initialValues this map contains the initial column values for
+     *   the row. The keys should be the column names and the values the column values.
+     * @return the row ID of the newly inserted row, or -1 if an error occurred
+     */
+    public long replace(String table, String nullColumnHack, ContentValues initialValues) {
+        try {
+            return insertWithOnConflict(table, nullColumnHack, initialValues,
+                    CONFLICT_REPLACE);
+        } catch (SQLException e) {
+            Log.e(TAG, "Error inserting " + initialValues, e);
+            return -1;
+        }
+    }
+
+    /**
+     * Convenience method for replacing a row in the database.
+     * Inserts a new row if a row does not already exist.
+     *
+     * @param table the table in which to replace the row
+     * @param nullColumnHack optional; may be <code>null</code>.
+     *            SQL doesn't allow inserting a completely empty row without
+     *            naming at least one column name.  If your provided <code>initialValues</code> is
+     *            empty, no column names are known and an empty row can't be inserted.
+     *            If not set to null, the <code>nullColumnHack</code> parameter
+     *            provides the name of nullable column name to explicitly insert a NULL into
+     *            in the case where your <code>initialValues</code> is empty.
+     * @param initialValues this map contains the initial column values for
+     *   the row. The keys should be the column names and the values the column values.
+     * @throws SQLException
+     * @return the row ID of the newly inserted row, or -1 if an error occurred
+     */
+    public long replaceOrThrow(String table, String nullColumnHack,
+            ContentValues initialValues) throws SQLException {
+        return insertWithOnConflict(table, nullColumnHack, initialValues,
+                CONFLICT_REPLACE);
+    }
+
+    /**
+     * General method for inserting a row into the database.
+     *
+     * @param table the table to insert the row into
+     * @param nullColumnHack optional; may be <code>null</code>.
+     *            SQL doesn't allow inserting a completely empty row without
+     *            naming at least one column name.  If your provided <code>initialValues</code> is
+     *            empty, no column names are known and an empty row can't be inserted.
+     *            If not set to null, the <code>nullColumnHack</code> parameter
+     *            provides the name of nullable column name to explicitly insert a NULL into
+     *            in the case where your <code>initialValues</code> is empty.
+     * @param initialValues this map contains the initial column values for the
+     *            row. The keys should be the column names and the values the
+     *            column values
+     * @param conflictAlgorithm for insert conflict resolver
+     * @return the row ID of the newly inserted row OR <code>-1</code> if either the
+     *            input parameter <code>conflictAlgorithm</code> = {@link #CONFLICT_IGNORE}
+     *            or an error occurred.
+     */
+    public long insertWithOnConflict(String table, String nullColumnHack,
+            ContentValues initialValues, int conflictAlgorithm) {
+        acquireReference();
+        try {
+            StringBuilder sql = new StringBuilder();
+            sql.append("INSERT");
+            sql.append(CONFLICT_VALUES[conflictAlgorithm]);
+            sql.append(" INTO ");
+            sql.append(table);
+            sql.append('(');
+
+            Object[] bindArgs = null;
+            int size = (initialValues != null && !initialValues.isEmpty())
+                    ? initialValues.size() : 0;
+            if (size > 0) {
+                bindArgs = new Object[size];
+                int i = 0;
+                for (String colName : initialValues.keySet()) {
+                    sql.append((i > 0) ? "," : "");
+                    sql.append(colName);
+                    bindArgs[i++] = initialValues.get(colName);
+                }
+                sql.append(')');
+                sql.append(" VALUES (");
+                for (i = 0; i < size; i++) {
+                    sql.append((i > 0) ? ",?" : "?");
+                }
+            } else {
+                sql.append(nullColumnHack + ") VALUES (NULL");
+            }
+            sql.append(')');
+
+            SQLiteStatement statement = new SQLiteStatement(this, sql.toString(), bindArgs);
+            try {
+                return statement.executeInsert();
+            } finally {
+                statement.close();
+            }
+        } finally {
+            releaseReference();
+        }
+    }
+
+    /**
+     * Convenience method for deleting rows in the database.
+     *
+     * @param table the table to delete from
+     * @param whereClause the optional WHERE clause to apply when deleting.
+     *            Passing null will delete all rows.
+     * @param whereArgs You may include ?s in the where clause, which
+     *            will be replaced by the values from whereArgs. The values
+     *            will be bound as Strings.
+     * @return the number of rows affected if a whereClause is passed in, 0
+     *         otherwise. To remove all rows and get a count pass "1" as the
+     *         whereClause.
+     */
+    public int delete(String table, String whereClause, String[] whereArgs) {
+        acquireReference();
+        try {
+            SQLiteStatement statement =  new SQLiteStatement(this, "DELETE FROM " + table +
+                    (!TextUtils.isEmpty(whereClause) ? " WHERE " + whereClause : ""), whereArgs);
+            try {
+                return statement.executeUpdateDelete();
+            } finally {
+                statement.close();
+            }
+        } finally {
+            releaseReference();
+        }
+    }
+
+    /**
+     * Convenience method for updating rows in the database.
+     *
+     * @param table the table to update in
+     * @param values a map from column names to new column values. null is a
+     *            valid value that will be translated to NULL.
+     * @param whereClause the optional WHERE clause to apply when updating.
+     *            Passing null will update all rows.
+     * @param whereArgs You may include ?s in the where clause, which
+     *            will be replaced by the values from whereArgs. The values
+     *            will be bound as Strings.
+     * @return the number of rows affected
+     */
+    public int update(String table, ContentValues values, String whereClause, String[] whereArgs) {
+        return updateWithOnConflict(table, values, whereClause, whereArgs, CONFLICT_NONE);
+    }
+
+    /**
+     * Convenience method for updating rows in the database.
+     *
+     * @param table the table to update in
+     * @param values a map from column names to new column values. null is a
+     *            valid value that will be translated to NULL.
+     * @param whereClause the optional WHERE clause to apply when updating.
+     *            Passing null will update all rows.
+     * @param whereArgs You may include ?s in the where clause, which
+     *            will be replaced by the values from whereArgs. The values
+     *            will be bound as Strings.
+     * @param conflictAlgorithm for update conflict resolver
+     * @return the number of rows affected
+     */
+    public int updateWithOnConflict(String table, ContentValues values,
+            String whereClause, String[] whereArgs, int conflictAlgorithm) {
+        if (values == null || values.isEmpty()) {
+            throw new IllegalArgumentException("Empty values");
+        }
+
+        acquireReference();
+        try {
+            StringBuilder sql = new StringBuilder(120);
+            sql.append("UPDATE ");
+            sql.append(CONFLICT_VALUES[conflictAlgorithm]);
+            sql.append(table);
+            sql.append(" SET ");
+
+            // move all bind args to one array
+            int setValuesSize = values.size();
+            int bindArgsSize = (whereArgs == null) ? setValuesSize : (setValuesSize + whereArgs.length);
+            Object[] bindArgs = new Object[bindArgsSize];
+            int i = 0;
+            for (String colName : values.keySet()) {
+                sql.append((i > 0) ? "," : "");
+                sql.append(colName);
+                bindArgs[i++] = values.get(colName);
+                sql.append("=?");
+            }
+            if (whereArgs != null) {
+                for (i = setValuesSize; i < bindArgsSize; i++) {
+                    bindArgs[i] = whereArgs[i - setValuesSize];
+                }
+            }
+            if (!TextUtils.isEmpty(whereClause)) {
+                sql.append(" WHERE ");
+                sql.append(whereClause);
+            }
+
+            SQLiteStatement statement = new SQLiteStatement(this, sql.toString(), bindArgs);
+            try {
+                return statement.executeUpdateDelete();
+            } finally {
+                statement.close();
+            }
+        } finally {
+            releaseReference();
+        }
+    }
+
+    /**
+     * Execute a single SQL statement that is NOT a SELECT
+     * or any other SQL statement that returns data.
+     * <p>
+     * It has no means to return any data (such as the number of affected rows).
+     * Instead, you're encouraged to use {@link #insert(String, String, ContentValues)},
+     * {@link #update(String, ContentValues, String, String[])}, et al, when possible.
+     * </p>
+     * <p>
+     * When using {@link #enableWriteAheadLogging()}, journal_mode is
+     * automatically managed by this class. So, do not set journal_mode
+     * using "PRAGMA journal_mode'<value>" statement if your app is using
+     * {@link #enableWriteAheadLogging()}
+     * </p>
+     * <p>
+     * Note that {@code PRAGMA} values which apply on a per-connection basis
+     * should <em>not</em> be configured using this method; you should instead
+     * use {@link #execPerConnectionSQL} to ensure that they are uniformly
+     * applied to all current and future connections.
+     * </p>
+     *
+     * @param sql the SQL statement to be executed. Multiple statements separated by semicolons are
+     * not supported.
+     * @throws SQLException if the SQL string is invalid
+     */
+    public void execSQL(String sql) throws SQLException {
+        executeSql(sql, null);
+    }
+
+    /**
+     * Execute a single SQL statement that is NOT a SELECT/INSERT/UPDATE/DELETE.
+     * <p>
+     * For INSERT statements, use any of the following instead.
+     * <ul>
+     *   <li>{@link #insert(String, String, ContentValues)}</li>
+     *   <li>{@link #insertOrThrow(String, String, ContentValues)}</li>
+     *   <li>{@link #insertWithOnConflict(String, String, ContentValues, int)}</li>
+     * </ul>
+     * <p>
+     * For UPDATE statements, use any of the following instead.
+     * <ul>
+     *   <li>{@link #update(String, ContentValues, String, String[])}</li>
+     *   <li>{@link #updateWithOnConflict(String, ContentValues, String, String[], int)}</li>
+     * </ul>
+     * <p>
+     * For DELETE statements, use any of the following instead.
+     * <ul>
+     *   <li>{@link #delete(String, String, String[])}</li>
+     * </ul>
+     * <p>
+     * For example, the following are good candidates for using this method:
+     * <ul>
+     *   <li>ALTER TABLE</li>
+     *   <li>CREATE or DROP table / trigger / view / index / virtual table</li>
+     *   <li>REINDEX</li>
+     *   <li>RELEASE</li>
+     *   <li>SAVEPOINT</li>
+     *   <li>PRAGMA that returns no data</li>
+     * </ul>
+     * </p>
+     * <p>
+     * When using {@link #enableWriteAheadLogging()}, journal_mode is
+     * automatically managed by this class. So, do not set journal_mode
+     * using "PRAGMA journal_mode'<value>" statement if your app is using
+     * {@link #enableWriteAheadLogging()}
+     * </p>
+     * <p>
+     * Note that {@code PRAGMA} values which apply on a per-connection basis
+     * should <em>not</em> be configured using this method; you should instead
+     * use {@link #execPerConnectionSQL} to ensure that they are uniformly
+     * applied to all current and future connections.
+     * </p>
+     *
+     * @param sql the SQL statement to be executed. Multiple statements separated by semicolons are
+     * not supported.
+     * @param bindArgs only byte[], String, Long and Double are supported in bindArgs.
+     * @throws SQLException if the SQL string is invalid
+     */
+    public void execSQL(String sql, Object[] bindArgs) throws SQLException {
+        if (bindArgs == null) {
+            throw new IllegalArgumentException("Empty bindArgs");
+        }
+        executeSql(sql, bindArgs);
+    }
+
+    /** {@hide} */
+    public int executeSql(String sql, Object[] bindArgs) throws SQLException {
+        acquireReference();
+        try {
+            final int statementType = DatabaseUtils.getSqlStatementType(sql);
+            if (statementType == DatabaseUtils.STATEMENT_ATTACH) {
+                boolean disableWal = false;
+                synchronized (mLock) {
+                    if (!mHasAttachedDbsLocked) {
+                        mHasAttachedDbsLocked = true;
+                        disableWal = true;
+                        mConnectionPoolLocked.disableIdleConnectionHandler();
+                    }
+                }
+                if (disableWal) {
+                    disableWriteAheadLogging();
+                }
+            }
+
+            try (SQLiteStatement statement = new SQLiteStatement(this, sql, bindArgs)) {
+                return statement.executeUpdateDelete();
+            } finally {
+                // If schema was updated, close non-primary connections, otherwise they might
+                // have outdated schema information
+                if (statementType == DatabaseUtils.STATEMENT_DDL) {
+                    mConnectionPoolLocked.closeAvailableNonPrimaryConnectionsAndLogExceptions();
+                }
+            }
+        } finally {
+            releaseReference();
+        }
+    }
+
+    /**
+     * Verifies that a SQL SELECT statement is valid by compiling it.
+     * If the SQL statement is not valid, this method will throw a {@link SQLiteException}.
+     *
+     * @param sql SQL to be validated
+     * @param cancellationSignal A signal to cancel the operation in progress, or null if none.
+     * If the operation is canceled, then {@link OperationCanceledException} will be thrown
+     * when the query is executed.
+     * @throws SQLiteException if {@code sql} is invalid
+     */
+    public void validateSql(@NonNull String sql, @Nullable CancellationSignal cancellationSignal) {
+        getThreadSession().prepare(sql,
+                getThreadDefaultConnectionFlags(/* readOnly =*/ true), cancellationSignal, null);
+    }
+
+    /**
+     * Returns true if the database is opened as read only.
+     *
+     * @return True if database is opened as read only.
+     */
+    public boolean isReadOnly() {
+        synchronized (mLock) {
+            return isReadOnlyLocked();
+        }
+    }
+
+    private boolean isReadOnlyLocked() {
+        return (mConfigurationLocked.openFlags & OPEN_READ_MASK) == OPEN_READONLY;
+    }
+
+    /**
+     * Returns true if the database is in-memory db.
+     *
+     * @return True if the database is in-memory.
+     * @hide
+     */
+    public boolean isInMemoryDatabase() {
+        synchronized (mLock) {
+            return mConfigurationLocked.isInMemoryDb();
+        }
+    }
+
+    /**
+     * Returns true if the database is currently open.
+     *
+     * @return True if the database is currently open (has not been closed).
+     */
+    public boolean isOpen() {
+        synchronized (mLock) {
+            return mConnectionPoolLocked != null;
+        }
+    }
+
+    /**
+     * Returns true if the new version code is greater than the current database version.
+     *
+     * @param newVersion The new version code.
+     * @return True if the new version code is greater than the current database version.
+     */
+    public boolean needUpgrade(int newVersion) {
+        return newVersion > getVersion();
+    }
+
+    /**
+     * Gets the path to the database file.
+     *
+     * @return The path to the database file.
+     */
+    public final String getPath() {
+        synchronized (mLock) {
+            return mConfigurationLocked.path;
+        }
+    }
+
+    /**
+     * Sets the locale for this database.  Does nothing if this database has
+     * the {@link #NO_LOCALIZED_COLLATORS} flag set or was opened read only.
+     *
+     * @param locale The new locale.
+     *
+     * @throws SQLException if the locale could not be set.  The most common reason
+     * for this is that there is no collator available for the locale you requested.
+     * In this case the database remains unchanged.
+     */
+    public void setLocale(Locale locale) {
+        if (locale == null) {
+            throw new IllegalArgumentException("locale must not be null.");
+        }
+
+        synchronized (mLock) {
+            throwIfNotOpenLocked();
+
+            final Locale oldLocale = mConfigurationLocked.locale;
+            mConfigurationLocked.locale = locale;
+            try {
+                mConnectionPoolLocked.reconfigure(mConfigurationLocked);
+            } catch (RuntimeException ex) {
+                mConfigurationLocked.locale = oldLocale;
+                throw ex;
+            }
+        }
+    }
+
+    /**
+     * Sets the maximum size of the prepared-statement cache for this database.
+     * (size of the cache = number of compiled-sql-statements stored in the cache).
+     *<p>
+     * Maximum cache size can ONLY be increased from its current size (default = 10).
+     * If this method is called with smaller size than the current maximum value,
+     * then IllegalStateException is thrown.
+     *<p>
+     * This method is thread-safe.
+     *
+     * @param cacheSize the size of the cache. can be (0 to {@link #MAX_SQL_CACHE_SIZE})
+     * @throws IllegalStateException if input cacheSize > {@link #MAX_SQL_CACHE_SIZE}.
+     */
+    public void setMaxSqlCacheSize(int cacheSize) {
+        if (cacheSize > MAX_SQL_CACHE_SIZE || cacheSize < 0) {
+            throw new IllegalStateException(
+                    "expected value between 0 and " + MAX_SQL_CACHE_SIZE);
+        }
+
+        synchronized (mLock) {
+            throwIfNotOpenLocked();
+
+            final int oldMaxSqlCacheSize = mConfigurationLocked.maxSqlCacheSize;
+            mConfigurationLocked.maxSqlCacheSize = cacheSize;
+            try {
+                mConnectionPoolLocked.reconfigure(mConfigurationLocked);
+            } catch (RuntimeException ex) {
+                mConfigurationLocked.maxSqlCacheSize = oldMaxSqlCacheSize;
+                throw ex;
+            }
+        }
+    }
+
+    /**
+     * Sets whether foreign key constraints are enabled for the database.
+     * <p>
+     * By default, foreign key constraints are not enforced by the database.
+     * This method allows an application to enable foreign key constraints.
+     * It must be called each time the database is opened to ensure that foreign
+     * key constraints are enabled for the session.
+     * </p><p>
+     * A good time to call this method is right after calling {@link #openOrCreateDatabase}
+     * or in the {@link SQLiteOpenHelper#onConfigure} callback.
+     * </p><p>
+     * When foreign key constraints are disabled, the database does not check whether
+     * changes to the database will violate foreign key constraints.  Likewise, when
+     * foreign key constraints are disabled, the database will not execute cascade
+     * delete or update triggers.  As a result, it is possible for the database
+     * state to become inconsistent.  To perform a database integrity check,
+     * call {@link #isDatabaseIntegrityOk}.
+     * </p><p>
+     * This method must not be called while a transaction is in progress.
+     * </p><p>
+     * See also <a href="http://sqlite.org/foreignkeys.html">SQLite Foreign Key Constraints</a>
+     * for more details about foreign key constraint support.
+     * </p>
+     *
+     * @param enable True to enable foreign key constraints, false to disable them.
+     *
+     * @throws IllegalStateException if the are transactions is in progress
+     * when this method is called.
+     */
+    public void setForeignKeyConstraintsEnabled(boolean enable) {
+        synchronized (mLock) {
+            throwIfNotOpenLocked();
+
+            if (mConfigurationLocked.foreignKeyConstraintsEnabled == enable) {
+                return;
+            }
+
+            mConfigurationLocked.foreignKeyConstraintsEnabled = enable;
+            try {
+                mConnectionPoolLocked.reconfigure(mConfigurationLocked);
+            } catch (RuntimeException ex) {
+                mConfigurationLocked.foreignKeyConstraintsEnabled = !enable;
+                throw ex;
+            }
+        }
+    }
+
+    /**
+     * This method enables parallel execution of queries from multiple threads on the
+     * same database.  It does this by opening multiple connections to the database
+     * and using a different database connection for each query.  The database
+     * journal mode is also changed to enable writes to proceed concurrently with reads.
+     * <p>
+     * When write-ahead logging is not enabled (the default), it is not possible for
+     * reads and writes to occur on the database at the same time.  Before modifying the
+     * database, the writer implicitly acquires an exclusive lock on the database which
+     * prevents readers from accessing the database until the write is completed.
+     * </p><p>
+     * In contrast, when write-ahead logging is enabled (by calling this method), write
+     * operations occur in a separate log file which allows reads to proceed concurrently.
+     * While a write is in progress, readers on other threads will perceive the state
+     * of the database as it was before the write began.  When the write completes, readers
+     * on other threads will then perceive the new state of the database.
+     * </p><p>
+     * It is a good idea to enable write-ahead logging whenever a database will be
+     * concurrently accessed and modified by multiple threads at the same time.
+     * However, write-ahead logging uses significantly more memory than ordinary
+     * journaling because there are multiple connections to the same database.
+     * So if a database will only be used by a single thread, or if optimizing
+     * concurrency is not very important, then write-ahead logging should be disabled.
+     * </p><p>
+     * After calling this method, execution of queries in parallel is enabled as long as
+     * the database remains open.  To disable execution of queries in parallel, either
+     * call {@link #disableWriteAheadLogging} or close the database and reopen it.
+     * </p><p>
+     * The maximum number of connections used to execute queries in parallel is
+     * dependent upon the device memory and possibly other properties.
+     * </p><p>
+     * If a query is part of a transaction, then it is executed on the same database handle the
+     * transaction was begun.
+     * </p><p>
+     * Writers should use {@link #beginTransactionNonExclusive()} or
+     * {@link #beginTransactionWithListenerNonExclusive(SQLiteTransactionListener)}
+     * to start a transaction.  Non-exclusive mode allows database file to be in readable
+     * by other threads executing queries.
+     * </p><p>
+     * If the database has any attached databases, then execution of queries in parallel is NOT
+     * possible.  Likewise, write-ahead logging is not supported for read-only databases
+     * or memory databases.  In such cases, {@link #enableWriteAheadLogging} returns false.
+     * </p><p>
+     * The best way to enable write-ahead logging is to pass the
+     * {@link #ENABLE_WRITE_AHEAD_LOGGING} flag to {@link #openDatabase}.  This is
+     * more efficient than calling {@link #enableWriteAheadLogging}.
+     * <code><pre>
+     *     SQLiteDatabase db = SQLiteDatabase.openDatabase("db_filename", cursorFactory,
+     *             SQLiteDatabase.CREATE_IF_NECESSARY | SQLiteDatabase.ENABLE_WRITE_AHEAD_LOGGING,
+     *             myDatabaseErrorHandler);
+     * </pre></code>
+     * </p><p>
+     * Another way to enable write-ahead logging is to call {@link #enableWriteAheadLogging}
+     * after opening the database.
+     * <code><pre>
+     *     SQLiteDatabase db = SQLiteDatabase.openDatabase("db_filename", cursorFactory,
+     *             SQLiteDatabase.CREATE_IF_NECESSARY, myDatabaseErrorHandler);
+     *     db.enableWriteAheadLogging();
+     * </pre></code>
+     * </p><p>
+     * See also <a href="http://sqlite.org/wal.html">SQLite Write-Ahead Logging</a> for
+     * more details about how write-ahead logging works.
+     * </p>
+     *
+     * @return True if write-ahead logging is enabled.
+     *
+     * @throws IllegalStateException if there are transactions in progress at the
+     * time this method is called.  WAL mode can only be changed when there are no
+     * transactions in progress.
+     *
+     * @see #ENABLE_WRITE_AHEAD_LOGGING
+     * @see #disableWriteAheadLogging
+     */
+    public boolean enableWriteAheadLogging() {
+        synchronized (mLock) {
+            throwIfNotOpenLocked();
+
+            if ((mConfigurationLocked.openFlags & ENABLE_WRITE_AHEAD_LOGGING) != 0) {
+                return true;
+            }
+
+            if (isReadOnlyLocked()) {
+                // WAL doesn't make sense for readonly-databases.
+                // TODO: True, but connection pooling does still make sense...
+                return false;
+            }
+
+            if (mConfigurationLocked.isInMemoryDb()) {
+                Log.i(TAG, "can't enable WAL for memory databases.");
+                return false;
+            }
+
+            // make sure this database has NO attached databases because sqlite's write-ahead-logging
+            // doesn't work for databases with attached databases
+            if (mHasAttachedDbsLocked) {
+                if (Log.isLoggable(TAG, Log.DEBUG)) {
+                    Log.d(TAG, "this database: " + mConfigurationLocked.label
+                            + " has attached databases. can't  enable WAL.");
+                }
+                return false;
+            }
+
+            mConfigurationLocked.openFlags |= ENABLE_WRITE_AHEAD_LOGGING;
+            try {
+                mConnectionPoolLocked.reconfigure(mConfigurationLocked);
+            } catch (RuntimeException ex) {
+                mConfigurationLocked.openFlags &= ~ENABLE_WRITE_AHEAD_LOGGING;
+                throw ex;
+            }
+        }
+        return true;
+    }
+
+    /**
+     * This method disables the features enabled by {@link #enableWriteAheadLogging()}.
+     *
+     * @throws IllegalStateException if there are transactions in progress at the
+     * time this method is called.  WAL mode can only be changed when there are no
+     * transactions in progress.
+     *
+     * @see #enableWriteAheadLogging
+     */
+    public void disableWriteAheadLogging() {
+        synchronized (mLock) {
+            throwIfNotOpenLocked();
+
+            final int oldFlags = mConfigurationLocked.openFlags;
+            final boolean walEnabled = (oldFlags & ENABLE_WRITE_AHEAD_LOGGING) != 0;
+            final boolean compatibilityWalEnabled =
+                    (oldFlags & ENABLE_LEGACY_COMPATIBILITY_WAL) != 0;
+            // WAL was never enabled for this database, so there's nothing left to do.
+            if (!walEnabled && !compatibilityWalEnabled) {
+                return;
+            }
+
+            // If an app explicitly disables WAL, it takes priority over any directive
+            // to use the legacy "compatibility WAL" mode.
+            mConfigurationLocked.openFlags &= ~ENABLE_WRITE_AHEAD_LOGGING;
+            mConfigurationLocked.openFlags &= ~ENABLE_LEGACY_COMPATIBILITY_WAL;
+
+            try {
+                mConnectionPoolLocked.reconfigure(mConfigurationLocked);
+            } catch (RuntimeException ex) {
+                mConfigurationLocked.openFlags = oldFlags;
+                throw ex;
+            }
+        }
+    }
+
+    /**
+     * Returns true if write-ahead logging has been enabled for this database.
+     *
+     * @return True if write-ahead logging has been enabled for this database.
+     *
+     * @see #enableWriteAheadLogging
+     * @see #ENABLE_WRITE_AHEAD_LOGGING
+     */
+    public boolean isWriteAheadLoggingEnabled() {
+        synchronized (mLock) {
+            throwIfNotOpenLocked();
+
+            return (mConfigurationLocked.openFlags & ENABLE_WRITE_AHEAD_LOGGING) != 0;
+        }
+    }
+
+    /**
+     * Collect statistics about all open databases in the current process.
+     * Used by bug report.
+     */
+    static ArrayList<DbStats> getDbStats() {
+        ArrayList<DbStats> dbStatsList = new ArrayList<DbStats>();
+        for (SQLiteDatabase db : getActiveDatabases()) {
+            db.collectDbStats(dbStatsList);
+        }
+        return dbStatsList;
+    }
+
+    @UnsupportedAppUsage
+    private void collectDbStats(ArrayList<DbStats> dbStatsList) {
+        synchronized (mLock) {
+            if (mConnectionPoolLocked != null) {
+                mConnectionPoolLocked.collectDbStats(dbStatsList);
+            }
+        }
+    }
+
+    @UnsupportedAppUsage
+    private static ArrayList<SQLiteDatabase> getActiveDatabases() {
+        ArrayList<SQLiteDatabase> databases = new ArrayList<SQLiteDatabase>();
+        synchronized (sActiveDatabases) {
+            databases.addAll(sActiveDatabases.keySet());
+        }
+        return databases;
+    }
+
+    /**
+     * Dump detailed information about all open databases in the current process.
+     * Used by bug report.
+     */
+    static void dumpAll(Printer printer, boolean verbose, boolean isSystem) {
+        // Use this ArraySet to collect file paths.
+        final ArraySet<String> directories = new ArraySet<>();
+
+        for (SQLiteDatabase db : getActiveDatabases()) {
+            db.dump(printer, verbose, isSystem, directories);
+        }
+
+        // Dump DB files in the directories.
+        if (directories.size() > 0) {
+            final String[] dirs = directories.toArray(new String[directories.size()]);
+            Arrays.sort(dirs);
+            for (String dir : dirs) {
+                dumpDatabaseDirectory(printer, new File(dir), isSystem);
+            }
+        }
+    }
+
+    private void dump(Printer printer, boolean verbose, boolean isSystem, ArraySet directories) {
+        synchronized (mLock) {
+            if (mConnectionPoolLocked != null) {
+                printer.println("");
+                mConnectionPoolLocked.dump(printer, verbose, directories);
+            }
+        }
+    }
+
+    private static void dumpDatabaseDirectory(Printer pw, File dir, boolean isSystem) {
+        pw.println("");
+        pw.println("Database files in " + dir.getAbsolutePath() + ":");
+        final File[] files = dir.listFiles();
+        if (files == null || files.length == 0) {
+            pw.println("  [none]");
+            return;
+        }
+        Arrays.sort(files, (a, b) -> a.getName().compareTo(b.getName()));
+
+        for (File f : files) {
+            if (isSystem) {
+                // If called within the system server, the directory contains other files too, so
+                // filter by file extensions.
+                // (If it's an app, just print all files because they may not use *.db
+                // extension.)
+                final String name = f.getName();
+                if (!(name.endsWith(".db") || name.endsWith(".db-wal")
+                        || name.endsWith(".db-journal")
+                        || name.endsWith(SQLiteGlobal.WIPE_CHECK_FILE_SUFFIX))) {
+                    continue;
+                }
+            }
+            pw.println(String.format("  %-40s %7db %s", f.getName(), f.length(),
+                    SQLiteDatabase.getFileTimestamps(f.getAbsolutePath())));
+        }
+    }
+
+    /**
+     * Returns list of full pathnames of all attached databases including the main database
+     * by executing 'pragma database_list' on the database.
+     *
+     * @return ArrayList of pairs of (database name, database file path) or null if the database
+     * is not open.
+     */
+    public List<Pair<String, String>> getAttachedDbs() {
+        ArrayList<Pair<String, String>> attachedDbs = new ArrayList<Pair<String, String>>();
+        synchronized (mLock) {
+            if (mConnectionPoolLocked == null) {
+                return null; // not open
+            }
+
+            if (!mHasAttachedDbsLocked) {
+                // No attached databases.
+                // There is a small window where attached databases exist but this flag is not
+                // set yet.  This can occur when this thread is in a race condition with another
+                // thread that is executing the SQL statement: "attach database <blah> as <foo>"
+                // If this thread is NOT ok with such a race condition (and thus possibly not
+                // receivethe entire list of attached databases), then the caller should ensure
+                // that no thread is executing any SQL statements while a thread is calling this
+                // method.  Typically, this method is called when 'adb bugreport' is done or the
+                // caller wants to collect stats on the database and all its attached databases.
+                attachedDbs.add(new Pair<String, String>("main", mConfigurationLocked.path));
+                return attachedDbs;
+            }
+
+            acquireReference();
+        }
+
+        try {
+            // has attached databases. query sqlite to get the list of attached databases.
+            Cursor c = null;
+            try {
+                c = rawQuery("pragma database_list;", null);
+                while (c.moveToNext()) {
+                    // sqlite returns a row for each database in the returned list of databases.
+                    //   in each row,
+                    //       1st column is the database name such as main, or the database
+                    //                              name specified on the "ATTACH" command
+                    //       2nd column is the database file path.
+                    attachedDbs.add(new Pair<String, String>(c.getString(1), c.getString(2)));
+                }
+            } finally {
+                if (c != null) {
+                    c.close();
+                }
+            }
+            return attachedDbs;
+        } finally {
+            releaseReference();
+        }
+    }
+
+    /**
+     * Runs 'pragma integrity_check' on the given database (and all the attached databases)
+     * and returns true if the given database (and all its attached databases) pass integrity_check,
+     * false otherwise.
+     *<p>
+     * If the result is false, then this method logs the errors reported by the integrity_check
+     * command execution.
+     *<p>
+     * Note that 'pragma integrity_check' on a database can take a long time.
+     *
+     * @return true if the given database (and all its attached databases) pass integrity_check,
+     * false otherwise.
+     */
+    public boolean isDatabaseIntegrityOk() {
+        acquireReference();
+        try {
+            List<Pair<String, String>> attachedDbs = null;
+            try {
+                attachedDbs = getAttachedDbs();
+                if (attachedDbs == null) {
+                    throw new IllegalStateException("databaselist for: " + getPath() + " couldn't " +
+                            "be retrieved. probably because the database is closed");
+                }
+            } catch (SQLiteException e) {
+                // can't get attachedDb list. do integrity check on the main database
+                attachedDbs = new ArrayList<Pair<String, String>>();
+                attachedDbs.add(new Pair<String, String>("main", getPath()));
+            }
+
+            for (int i = 0; i < attachedDbs.size(); i++) {
+                Pair<String, String> p = attachedDbs.get(i);
+                SQLiteStatement prog = null;
+                try {
+                    prog = compileStatement("PRAGMA " + p.first + ".integrity_check(1);");
+                    String rslt = prog.simpleQueryForString();
+                    if (!rslt.equalsIgnoreCase("ok")) {
+                        // integrity_checker failed on main or attached databases
+                        Log.e(TAG, "PRAGMA integrity_check on " + p.second + " returned: " + rslt);
+                        return false;
+                    }
+                } finally {
+                    if (prog != null) prog.close();
+                }
+            }
+        } finally {
+            releaseReference();
+        }
+        return true;
+    }
+
+    @Override
+    public String toString() {
+        return "SQLiteDatabase: " + getPath();
+    }
+
+    private void throwIfNotOpenLocked() {
+        if (mConnectionPoolLocked == null) {
+            throw new IllegalStateException("The database '" + mConfigurationLocked.label
+                    + "' is not open.");
+        }
+    }
+
+    /**
+     * Used to allow returning sub-classes of {@link Cursor} when calling query.
+     */
+    public interface CursorFactory {
+        /**
+         * See {@link SQLiteCursor#SQLiteCursor(SQLiteCursorDriver, String, SQLiteQuery)}.
+         */
+        public Cursor newCursor(SQLiteDatabase db,
+                SQLiteCursorDriver masterQuery, String editTable,
+                SQLiteQuery query);
+    }
+
+    /**
+     * A callback interface for a custom sqlite3 function.
+     * This can be used to create a function that can be called from
+     * sqlite3 database triggers.
+     * @hide
+     */
+    public interface CustomFunction {
+        public void callback(String[] args);
+    }
+
+    /**
+     * Wrapper for configuration parameters that are used for opening {@link SQLiteDatabase}
+     */
+    public static final class OpenParams {
+        private final int mOpenFlags;
+        private final CursorFactory mCursorFactory;
+        private final DatabaseErrorHandler mErrorHandler;
+        private final int mLookasideSlotSize;
+        private final int mLookasideSlotCount;
+        private final long mIdleConnectionTimeout;
+        private final String mJournalMode;
+        private final String mSyncMode;
+
+        private OpenParams(int openFlags, CursorFactory cursorFactory,
+                DatabaseErrorHandler errorHandler, int lookasideSlotSize, int lookasideSlotCount,
+                long idleConnectionTimeout, String journalMode, String syncMode) {
+            mOpenFlags = openFlags;
+            mCursorFactory = cursorFactory;
+            mErrorHandler = errorHandler;
+            mLookasideSlotSize = lookasideSlotSize;
+            mLookasideSlotCount = lookasideSlotCount;
+            mIdleConnectionTimeout = idleConnectionTimeout;
+            mJournalMode = journalMode;
+            mSyncMode = syncMode;
+        }
+
+        /**
+         * Returns size in bytes of each lookaside slot or -1 if not set.
+         *
+         * @see Builder#setLookasideConfig(int, int)
+         */
+        @IntRange(from = -1)
+        public int getLookasideSlotSize() {
+            return mLookasideSlotSize;
+        }
+
+        /**
+         * Returns total number of lookaside memory slots per database connection or -1 if not
+         * set.
+         *
+         * @see Builder#setLookasideConfig(int, int)
+         */
+        @IntRange(from = -1)
+        public int getLookasideSlotCount() {
+            return mLookasideSlotCount;
+        }
+
+        /**
+         * Returns flags to control database access mode. Default value is 0.
+         *
+         * @see Builder#setOpenFlags(int)
+         */
+        @DatabaseOpenFlags
+        public int getOpenFlags() {
+            return mOpenFlags;
+        }
+
+        /**
+         * Returns an optional factory class that is called to instantiate a cursor when query
+         * is called
+         *
+         * @see Builder#setCursorFactory(CursorFactory)
+         */
+        @Nullable
+        public CursorFactory getCursorFactory() {
+            return mCursorFactory;
+        }
+
+        /**
+         * Returns handler for database corruption errors
+         *
+         * @see Builder#setErrorHandler(DatabaseErrorHandler)
+         */
+        @Nullable
+        public DatabaseErrorHandler getErrorHandler() {
+            return mErrorHandler;
+        }
+
+        /**
+         * Returns maximum number of milliseconds that SQLite connection is allowed to be idle
+         * before it is closed and removed from the pool.
+         * <p>If the value isn't set, the timeout defaults to the system wide timeout
+         *
+         * @return timeout in milliseconds or -1 if the value wasn't set.
+         */
+        public long getIdleConnectionTimeout() {
+            return mIdleConnectionTimeout;
+        }
+
+        /**
+         * Returns <a href="https://sqlite.org/pragma.html#pragma_journal_mode">journal mode</a>.
+         * This journal mode will only be used if {@link SQLiteDatabase#ENABLE_WRITE_AHEAD_LOGGING}
+         * flag is not set, otherwise a platform will use "WAL" journal mode.
+         * @see Builder#setJournalMode(String)
+         */
+        @Nullable
+        public String getJournalMode() {
+            return mJournalMode;
+        }
+
+        /**
+         * Returns <a href="https://sqlite.org/pragma.html#pragma_synchronous">synchronous mode</a>.
+         * If not set, a system wide default will be used.
+         * @see Builder#setSynchronousMode(String)
+         */
+        @Nullable
+        public String getSynchronousMode() {
+            return mSyncMode;
+        }
+
+        /**
+         * Creates a new instance of builder {@link Builder#Builder(OpenParams) initialized} with
+         * {@code this} parameters.
+         * @hide
+         */
+        @NonNull
+        public Builder toBuilder() {
+            return new Builder(this);
+        }
+
+        /**
+         * Builder for {@link OpenParams}.
+         */
+        public static final class Builder {
+            private int mLookasideSlotSize = -1;
+            private int mLookasideSlotCount = -1;
+            private long mIdleConnectionTimeout = -1;
+            private int mOpenFlags;
+            private CursorFactory mCursorFactory;
+            private DatabaseErrorHandler mErrorHandler;
+            private String mJournalMode;
+            private String mSyncMode;
+
+            public Builder() {
+            }
+
+            public Builder(OpenParams params) {
+                mLookasideSlotSize = params.mLookasideSlotSize;
+                mLookasideSlotCount = params.mLookasideSlotCount;
+                mOpenFlags = params.mOpenFlags;
+                mCursorFactory = params.mCursorFactory;
+                mErrorHandler = params.mErrorHandler;
+                mJournalMode = params.mJournalMode;
+                mSyncMode = params.mSyncMode;
+            }
+
+            /**
+             * Configures
+             * <a href="https://sqlite.org/malloc.html#lookaside">lookaside memory allocator</a>
+             *
+             * <p>SQLite default settings will be used, if this method isn't called.
+             * Use {@code setLookasideConfig(0,0)} to disable lookaside
+             *
+             * <p><strong>Note:</strong> Provided slotSize/slotCount configuration is just a
+             * recommendation. The system may choose different values depending on a device, e.g.
+             * lookaside allocations can be disabled on low-RAM devices
+             *
+             * @param slotSize The size in bytes of each lookaside slot.
+             * @param slotCount The total number of lookaside memory slots per database connection.
+             */
+            public Builder setLookasideConfig(@IntRange(from = 0) final int slotSize,
+                    @IntRange(from = 0) final int slotCount) {
+                Preconditions.checkArgument(slotSize >= 0,
+                        "lookasideSlotCount cannot be negative");
+                Preconditions.checkArgument(slotCount >= 0,
+                        "lookasideSlotSize cannot be negative");
+                Preconditions.checkArgument(
+                        (slotSize > 0 && slotCount > 0) || (slotCount == 0 && slotSize == 0),
+                        "Invalid configuration: " + slotSize + ", " + slotCount);
+
+                mLookasideSlotSize = slotSize;
+                mLookasideSlotCount = slotCount;
+                return this;
+            }
+
+            /**
+             * Returns true if {@link #ENABLE_WRITE_AHEAD_LOGGING} flag is set
+             * @hide
+             */
+            public boolean isWriteAheadLoggingEnabled() {
+                return (mOpenFlags & ENABLE_WRITE_AHEAD_LOGGING) != 0;
+            }
+
+            /**
+             * Sets flags to control database access mode
+             * @param openFlags The new flags to set
+             * @see #OPEN_READWRITE
+             * @see #OPEN_READONLY
+             * @see #CREATE_IF_NECESSARY
+             * @see #NO_LOCALIZED_COLLATORS
+             * @see #ENABLE_WRITE_AHEAD_LOGGING
+             * @return same builder instance for chaining multiple calls into a single statement
+             */
+            @NonNull
+            public Builder setOpenFlags(@DatabaseOpenFlags int openFlags) {
+                mOpenFlags = openFlags;
+                return this;
+            }
+
+            /**
+             * Adds flags to control database access mode
+             *
+             * @param openFlags The new flags to add
+             * @return same builder instance for chaining multiple calls into a single statement
+             */
+            @NonNull
+            public Builder addOpenFlags(@DatabaseOpenFlags int openFlags) {
+                mOpenFlags |= openFlags;
+                return this;
+            }
+
+            /**
+             * Removes database access mode flags
+             *
+             * @param openFlags Flags to remove
+             * @return same builder instance for chaining multiple calls into a single statement
+             */
+            @NonNull
+            public Builder removeOpenFlags(@DatabaseOpenFlags int openFlags) {
+                mOpenFlags &= ~openFlags;
+                return this;
+            }
+
+            /**
+             * Sets {@link #ENABLE_WRITE_AHEAD_LOGGING} flag if {@code enabled} is {@code true},
+             * unsets otherwise
+             * @hide
+             */
+            public void setWriteAheadLoggingEnabled(boolean enabled) {
+                if (enabled) {
+                    addOpenFlags(ENABLE_WRITE_AHEAD_LOGGING);
+                } else {
+                    removeOpenFlags(ENABLE_WRITE_AHEAD_LOGGING);
+                }
+            }
+
+            /**
+             * Set an optional factory class that is called to instantiate a cursor when query
+             * is called.
+             *
+             * @param cursorFactory instance
+             * @return same builder instance for chaining multiple calls into a single statement
+             */
+            @NonNull
+            public Builder setCursorFactory(@Nullable CursorFactory cursorFactory) {
+                mCursorFactory = cursorFactory;
+                return this;
+            }
+
+
+            /**
+             * Sets {@link DatabaseErrorHandler} object to handle db corruption errors
+             */
+            @NonNull
+            public Builder setErrorHandler(@Nullable DatabaseErrorHandler errorHandler) {
+                mErrorHandler = errorHandler;
+                return this;
+            }
+
+            /**
+             * Sets the maximum number of milliseconds that SQLite connection is allowed to be idle
+             * before it is closed and removed from the pool.
+             *
+             * <p><b>DO NOT USE</b> this method.
+             * This feature has negative side effects that are very hard to foresee.
+             * <p>A connection timeout allows the system to internally close a connection to
+             * a SQLite database after a given timeout, which is good for reducing app's memory
+             * consumption.
+             * <b>However</b> the side effect is it <b>will reset all of SQLite's per-connection
+             * states</b>, which are typically modified with a {@code PRAGMA} statement, and
+             * these states <b>will not be restored</b> when a connection is re-established
+             * internally, and the system does not provide a callback for an app to reconfigure a
+             * connection.
+             * This feature may only be used if an app relies on none of such per-connection states.
+             *
+             * @param idleConnectionTimeoutMs timeout in milliseconds. Use {@link Long#MAX_VALUE}
+             * to allow unlimited idle connections.
+             *
+             * @see SQLiteOpenHelper#setIdleConnectionTimeout(long)
+             *
+             * @deprecated DO NOT USE this method. See the javadoc for the details.
+             */
+            @NonNull
+            @Deprecated
+            public Builder setIdleConnectionTimeout(
+                    @IntRange(from = 0) long idleConnectionTimeoutMs) {
+                Preconditions.checkArgument(idleConnectionTimeoutMs >= 0,
+                        "idle connection timeout cannot be negative");
+                mIdleConnectionTimeout = idleConnectionTimeoutMs;
+                return this;
+            }
+
+
+            /**
+             * Sets <a href="https://sqlite.org/pragma.html#pragma_journal_mode">journal mode</a>
+             * to use when {@link SQLiteDatabase#ENABLE_WRITE_AHEAD_LOGGING} flag is not set.
+             */
+            @NonNull
+            public Builder setJournalMode(@NonNull  String journalMode) {
+                Objects.requireNonNull(journalMode);
+                mJournalMode = journalMode;
+                return this;
+            }
+
+            /**w
+             * Sets <a href="https://sqlite.org/pragma.html#pragma_synchronous">synchronous mode</a>
+             * .
+             * @return
+             */
+            @NonNull
+            public Builder setSynchronousMode(@NonNull String syncMode) {
+                Objects.requireNonNull(syncMode);
+                mSyncMode = syncMode;
+                return this;
+            }
+
+            /**
+             * Creates an instance of {@link OpenParams} with the options that were previously set
+             * on this builder
+             */
+            @NonNull
+            public OpenParams build() {
+                return new OpenParams(mOpenFlags, mCursorFactory, mErrorHandler, mLookasideSlotSize,
+                        mLookasideSlotCount, mIdleConnectionTimeout, mJournalMode, mSyncMode);
+            }
+        }
+    }
+
+    /** @hide */
+    @IntDef(flag = true, prefix = {"OPEN_", "CREATE_", "NO_", "ENABLE_"}, value = {
+            OPEN_READWRITE,
+            OPEN_READONLY,
+            CREATE_IF_NECESSARY,
+            NO_LOCALIZED_COLLATORS,
+            ENABLE_WRITE_AHEAD_LOGGING
+    })
+    @Retention(RetentionPolicy.SOURCE)
+    public @interface DatabaseOpenFlags {}
+
+    /** @hide */
+    public static void wipeDetected(String filename, String reason) {
+        wtfAsSystemServer(TAG, "DB wipe detected:"
+                + " package=" + ActivityThread.currentPackageName()
+                + " reason=" + reason
+                + " file=" + filename
+                + " " + getFileTimestamps(filename)
+                + " checkfile " + getFileTimestamps(filename + SQLiteGlobal.WIPE_CHECK_FILE_SUFFIX),
+                new Throwable("STACKTRACE"));
+    }
+
+    /** @hide */
+    public static String getFileTimestamps(String path) {
+        try {
+            BasicFileAttributes attr = Files.readAttributes(
+                    FileSystems.getDefault().getPath(path), BasicFileAttributes.class);
+            return "ctime=" + attr.creationTime()
+                    + " mtime=" + attr.lastModifiedTime()
+                    + " atime=" + attr.lastAccessTime();
+        } catch (IOException e) {
+            return "[unable to obtain timestamp]";
+        }
+    }
+
+    /** @hide */
+    static void wtfAsSystemServer(String tag, String message, Throwable stacktrace) {
+        Log.e(tag, message, stacktrace);
+        ContentResolver.onDbCorruption(tag, message, stacktrace);
+    }
+}
+
diff --git a/android/database/sqlite/SQLiteDatabaseConfiguration.java b/android/database/sqlite/SQLiteDatabaseConfiguration.java
new file mode 100644
index 0000000..21c21c9
--- /dev/null
+++ b/android/database/sqlite/SQLiteDatabaseConfiguration.java
@@ -0,0 +1,235 @@
+/*
+ * Copyright (C) 2011 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.database.sqlite;
+
+import android.compat.annotation.UnsupportedAppUsage;
+import android.util.ArrayMap;
+import android.util.Pair;
+
+import java.util.ArrayList;
+import java.util.Locale;
+import java.util.function.BinaryOperator;
+import java.util.function.UnaryOperator;
+import java.util.regex.Pattern;
+
+/**
+ * Describes how to configure a database.
+ * <p>
+ * The purpose of this object is to keep track of all of the little
+ * configuration settings that are applied to a database after it
+ * is opened so that they can be applied to all connections in the
+ * connection pool uniformly.
+ * </p><p>
+ * Each connection maintains its own copy of this object so it can
+ * keep track of which settings have already been applied.
+ * </p>
+ *
+ * @hide
+ */
+public final class SQLiteDatabaseConfiguration {
+    // The pattern we use to strip email addresses from database paths
+    // when constructing a label to use in log messages.
+    private static final Pattern EMAIL_IN_DB_PATTERN =
+            Pattern.compile("[\\w\\.\\-]+@[\\w\\.\\-]+");
+
+    /**
+     * Special path used by in-memory databases.
+     */
+    public static final String MEMORY_DB_PATH = ":memory:";
+
+    /**
+     * The database path.
+     */
+    public final String path;
+
+    /**
+     * The label to use to describe the database when it appears in logs.
+     * This is derived from the path but is stripped to remove PII.
+     */
+    public final String label;
+
+    /**
+     * The flags used to open the database.
+     */
+    public int openFlags;
+
+    /**
+     * The maximum size of the prepared statement cache for each database connection.
+     * Must be non-negative.
+     *
+     * Default is 25.
+     */
+    @UnsupportedAppUsage
+    public int maxSqlCacheSize;
+
+    /**
+     * The database locale.
+     *
+     * Default is the value returned by {@link Locale#getDefault()}.
+     */
+    public Locale locale;
+
+    /**
+     * True if foreign key constraints are enabled.
+     *
+     * Default is false.
+     */
+    public boolean foreignKeyConstraintsEnabled;
+
+    /**
+     * The custom scalar functions to register.
+     */
+    public final ArrayMap<String, UnaryOperator<String>> customScalarFunctions
+            = new ArrayMap<>();
+
+    /**
+     * The custom aggregate functions to register.
+     */
+    public final ArrayMap<String, BinaryOperator<String>> customAggregateFunctions
+            = new ArrayMap<>();
+
+    /**
+     * The statements to execute to initialize each connection.
+     */
+    public final ArrayList<Pair<String, Object[]>> perConnectionSql = new ArrayList<>();
+
+    /**
+     * The size in bytes of each lookaside slot
+     *
+     * <p>If negative, the default lookaside configuration will be used
+     */
+    public int lookasideSlotSize = -1;
+
+    /**
+     * The total number of lookaside memory slots per database connection
+     *
+     * <p>If negative, the default lookaside configuration will be used
+     */
+    public int lookasideSlotCount = -1;
+
+    /**
+     * The number of milliseconds that SQLite connection is allowed to be idle before it
+     * is closed and removed from the pool.
+     * <p>By default, idle connections are not closed
+     */
+    public long idleConnectionTimeoutMs = Long.MAX_VALUE;
+
+    /**
+     * Journal mode to use when {@link SQLiteDatabase#ENABLE_WRITE_AHEAD_LOGGING} is not set.
+     * <p>Default is returned by {@link SQLiteGlobal#getDefaultJournalMode()}
+     */
+    public String journalMode;
+
+    /**
+     * Synchronous mode to use.
+     * <p>Default is returned by {@link SQLiteGlobal#getDefaultSyncMode()}
+     * or {@link SQLiteGlobal#getWALSyncMode()} depending on journal mode
+     */
+    public String syncMode;
+
+    /**
+     * Creates a database configuration with the required parameters for opening a
+     * database and default values for all other parameters.
+     *
+     * @param path The database path.
+     * @param openFlags Open flags for the database, such as {@link SQLiteDatabase#OPEN_READWRITE}.
+     */
+    public SQLiteDatabaseConfiguration(String path, int openFlags) {
+        if (path == null) {
+            throw new IllegalArgumentException("path must not be null.");
+        }
+
+        this.path = path;
+        label = stripPathForLogs(path);
+        this.openFlags = openFlags;
+
+        // Set default values for optional parameters.
+        maxSqlCacheSize = 25;
+        locale = Locale.getDefault();
+    }
+
+    /**
+     * Creates a database configuration as a copy of another configuration.
+     *
+     * @param other The other configuration.
+     */
+    public SQLiteDatabaseConfiguration(SQLiteDatabaseConfiguration other) {
+        if (other == null) {
+            throw new IllegalArgumentException("other must not be null.");
+        }
+
+        this.path = other.path;
+        this.label = other.label;
+        updateParametersFrom(other);
+    }
+
+    /**
+     * Updates the non-immutable parameters of this configuration object
+     * from the other configuration object.
+     *
+     * @param other The object from which to copy the parameters.
+     */
+    public void updateParametersFrom(SQLiteDatabaseConfiguration other) {
+        if (other == null) {
+            throw new IllegalArgumentException("other must not be null.");
+        }
+        if (!path.equals(other.path)) {
+            throw new IllegalArgumentException("other configuration must refer to "
+                    + "the same database.");
+        }
+
+        openFlags = other.openFlags;
+        maxSqlCacheSize = other.maxSqlCacheSize;
+        locale = other.locale;
+        foreignKeyConstraintsEnabled = other.foreignKeyConstraintsEnabled;
+        customScalarFunctions.clear();
+        customScalarFunctions.putAll(other.customScalarFunctions);
+        customAggregateFunctions.clear();
+        customAggregateFunctions.putAll(other.customAggregateFunctions);
+        perConnectionSql.clear();
+        perConnectionSql.addAll(other.perConnectionSql);
+        lookasideSlotSize = other.lookasideSlotSize;
+        lookasideSlotCount = other.lookasideSlotCount;
+        idleConnectionTimeoutMs = other.idleConnectionTimeoutMs;
+        journalMode = other.journalMode;
+        syncMode = other.syncMode;
+    }
+
+    /**
+     * Returns true if the database is in-memory.
+     * @return True if the database is in-memory.
+     */
+    public boolean isInMemoryDb() {
+        return path.equalsIgnoreCase(MEMORY_DB_PATH);
+    }
+
+    boolean isLegacyCompatibilityWalEnabled() {
+        return journalMode == null && syncMode == null
+                && (openFlags & SQLiteDatabase.ENABLE_LEGACY_COMPATIBILITY_WAL) != 0;
+    }
+
+    private static String stripPathForLogs(String path) {
+        if (path.indexOf('@') == -1) {
+            return path;
+        }
+        return EMAIL_IN_DB_PATTERN.matcher(path).replaceAll("XX@YY");
+    }
+
+    boolean isLookasideConfigSet() {
+        return lookasideSlotCount >= 0 && lookasideSlotSize >= 0;
+    }
+}
diff --git a/android/database/sqlite/SQLiteDatabaseCorruptException.java b/android/database/sqlite/SQLiteDatabaseCorruptException.java
new file mode 100644
index 0000000..488ef46
--- /dev/null
+++ b/android/database/sqlite/SQLiteDatabaseCorruptException.java
@@ -0,0 +1,44 @@
+/*
+ * Copyright (C) 2006 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.database.sqlite;
+
+/**
+ * An exception that indicates that the SQLite database file is corrupt.
+ */
+public class SQLiteDatabaseCorruptException extends SQLiteException {
+    public SQLiteDatabaseCorruptException() {}
+
+    public SQLiteDatabaseCorruptException(String error) {
+        super(error);
+    }
+
+    /**
+     * @return true if a given {@link Throwable} or any of its inner causes is of
+     * {@link SQLiteDatabaseCorruptException}.
+     *
+     * @hide
+     */
+    public static boolean isCorruptException(Throwable th) {
+        while (th != null) {
+            if (th instanceof SQLiteDatabaseCorruptException) {
+                return true;
+            }
+            th = th.getCause();
+        }
+        return false;
+    }
+}
diff --git a/android/database/sqlite/SQLiteDatabaseLockedException.java b/android/database/sqlite/SQLiteDatabaseLockedException.java
new file mode 100644
index 0000000..f0e2d81
--- /dev/null
+++ b/android/database/sqlite/SQLiteDatabaseLockedException.java
@@ -0,0 +1,33 @@
+/*
+ * 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.database.sqlite;
+
+/**
+ * Thrown if  the database engine was unable to acquire the
+ * database locks it needs to do its job.  If the statement is a [COMMIT]
+ * or occurs outside of an explicit transaction, then you can retry the
+ * statement.  If the statement is not a [COMMIT] and occurs within a
+ * explicit transaction then you should rollback the transaction before
+ * continuing.
+ */
+public class SQLiteDatabaseLockedException extends SQLiteException {
+    public SQLiteDatabaseLockedException() {}
+
+    public SQLiteDatabaseLockedException(String error) {
+        super(error);
+    }
+}
diff --git a/android/database/sqlite/SQLiteDatatypeMismatchException.java b/android/database/sqlite/SQLiteDatatypeMismatchException.java
new file mode 100644
index 0000000..7f82535
--- /dev/null
+++ b/android/database/sqlite/SQLiteDatatypeMismatchException.java
@@ -0,0 +1,25 @@
+/*
+ * Copyright (C) 2008 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.database.sqlite;
+
+public class SQLiteDatatypeMismatchException extends SQLiteException {
+    public SQLiteDatatypeMismatchException() {}
+
+    public SQLiteDatatypeMismatchException(String error) {
+        super(error);
+    }
+}
diff --git a/android/database/sqlite/SQLiteDebug.java b/android/database/sqlite/SQLiteDebug.java
new file mode 100644
index 0000000..165f863
--- /dev/null
+++ b/android/database/sqlite/SQLiteDebug.java
@@ -0,0 +1,220 @@
+/*
+ * 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.database.sqlite;
+
+import android.annotation.TestApi;
+import android.compat.annotation.UnsupportedAppUsage;
+import android.os.Build;
+import android.os.Process;
+import android.os.SystemProperties;
+import android.util.Log;
+import android.util.Printer;
+
+import java.util.ArrayList;
+
+/**
+ * Provides debugging info about all SQLite databases running in the current process.
+ *
+ * {@hide}
+ */
+@TestApi
+public final class SQLiteDebug {
+    private static native void nativeGetPagerStats(PagerStats stats);
+
+    /**
+     * Inner class to avoid getting the value frozen in zygote.
+     *
+     * {@hide}
+     */
+    public static final class NoPreloadHolder {
+        /**
+         * Controls the printing of informational SQL log messages.
+         *
+         * Enable using "adb shell setprop log.tag.SQLiteLog VERBOSE".
+         */
+        public static final boolean DEBUG_SQL_LOG =
+                Log.isLoggable("SQLiteLog", Log.VERBOSE);
+
+        /**
+         * Controls the printing of SQL statements as they are executed.
+         *
+         * Enable using "adb shell setprop log.tag.SQLiteStatements VERBOSE".
+         */
+        public static final boolean DEBUG_SQL_STATEMENTS =
+                Log.isLoggable("SQLiteStatements", Log.VERBOSE);
+
+        /**
+         * Controls the printing of wall-clock time taken to execute SQL statements
+         * as they are executed.
+         *
+         * Enable using "adb shell setprop log.tag.SQLiteTime VERBOSE".
+         */
+        public static final boolean DEBUG_SQL_TIME =
+                Log.isLoggable("SQLiteTime", Log.VERBOSE);
+
+
+        /**
+         * True to enable database performance testing instrumentation.
+         */
+        public static final boolean DEBUG_LOG_SLOW_QUERIES = Build.IS_DEBUGGABLE;
+
+        private static final String SLOW_QUERY_THRESHOLD_PROP = "db.log.slow_query_threshold";
+
+        private static final String SLOW_QUERY_THRESHOLD_UID_PROP =
+                SLOW_QUERY_THRESHOLD_PROP + "." + Process.myUid();
+
+        /**
+         * Whether to add detailed information to slow query log.
+         */
+        public static final boolean DEBUG_LOG_DETAILED = Build.IS_DEBUGGABLE
+                && SystemProperties.getBoolean("db.log.detailed", false);
+    }
+
+    private SQLiteDebug() {
+    }
+
+    /**
+     * Determines whether a query should be logged.
+     *
+     * Reads the "db.log.slow_query_threshold" system property, which can be changed
+     * by the user at any time.  If the value is zero, then all queries will
+     * be considered slow.  If the value does not exist or is negative, then no queries will
+     * be considered slow.
+     *
+     * To enable it for a specific UID, "db.log.slow_query_threshold.UID" could also be used.
+     *
+     * This value can be changed dynamically while the system is running.
+     * For example, "adb shell setprop db.log.slow_query_threshold 200" will
+     * log all queries that take 200ms or longer to run.
+     * @hide
+     */
+    public static boolean shouldLogSlowQuery(long elapsedTimeMillis) {
+        final int slowQueryMillis = Math.min(
+                SystemProperties.getInt(NoPreloadHolder.SLOW_QUERY_THRESHOLD_PROP,
+                        Integer.MAX_VALUE),
+                SystemProperties.getInt(NoPreloadHolder.SLOW_QUERY_THRESHOLD_UID_PROP,
+                        Integer.MAX_VALUE));
+        return elapsedTimeMillis >= slowQueryMillis;
+    }
+
+    /**
+     * Contains statistics about the active pagers in the current process.
+     *
+     * @see #nativeGetPagerStats(PagerStats)
+     */
+    public static class PagerStats {
+
+        @UnsupportedAppUsage
+        public PagerStats() {
+        }
+
+        /** the current amount of memory checked out by sqlite using sqlite3_malloc().
+         * documented at http://www.sqlite.org/c3ref/c_status_malloc_size.html
+         */
+        @UnsupportedAppUsage
+        public int memoryUsed;
+
+        /** the number of bytes of page cache allocation which could not be sattisfied by the
+         * SQLITE_CONFIG_PAGECACHE buffer and where forced to overflow to sqlite3_malloc().
+         * The returned value includes allocations that overflowed because they where too large
+         * (they were larger than the "sz" parameter to SQLITE_CONFIG_PAGECACHE) and allocations
+         * that overflowed because no space was left in the page cache.
+         * documented at http://www.sqlite.org/c3ref/c_status_malloc_size.html
+         */
+        @UnsupportedAppUsage
+        public int pageCacheOverflow;
+
+        /** records the largest memory allocation request handed to sqlite3.
+         * documented at http://www.sqlite.org/c3ref/c_status_malloc_size.html
+         */
+        @UnsupportedAppUsage
+        public int largestMemAlloc;
+
+        /** a list of {@link DbStats} - one for each main database opened by the applications
+         * running on the android device
+         */
+        @UnsupportedAppUsage
+        public ArrayList<DbStats> dbStats;
+    }
+
+    /**
+     * contains statistics about a database
+     */
+    public static class DbStats {
+        /** name of the database */
+        @UnsupportedAppUsage
+        public String dbName;
+
+        /** the page size for the database */
+        @UnsupportedAppUsage
+        public long pageSize;
+
+        /** the database size */
+        @UnsupportedAppUsage
+        public long dbSize;
+
+        /**
+         * Number of lookaside slots: http://www.sqlite.org/c3ref/c_dbstatus_lookaside_used.html */
+        @UnsupportedAppUsage
+        public int lookaside;
+
+        /** statement cache stats: hits/misses/cachesize */
+        public String cache;
+
+        public DbStats(String dbName, long pageCount, long pageSize, int lookaside,
+            int hits, int misses, int cachesize) {
+            this.dbName = dbName;
+            this.pageSize = pageSize / 1024;
+            dbSize = (pageCount * pageSize) / 1024;
+            this.lookaside = lookaside;
+            this.cache = hits + "/" + misses + "/" + cachesize;
+        }
+    }
+
+    /**
+     * return all pager and database stats for the current process.
+     * @return {@link PagerStats}
+     */
+    @UnsupportedAppUsage
+    public static PagerStats getDatabaseInfo() {
+        PagerStats stats = new PagerStats();
+        nativeGetPagerStats(stats);
+        stats.dbStats = SQLiteDatabase.getDbStats();
+        return stats;
+    }
+
+    /**
+     * Dumps detailed information about all databases used by the process.
+     * @param printer The printer for dumping database state.
+     * @param args Command-line arguments supplied to dumpsys dbinfo
+     */
+    public static void dump(Printer printer, String[] args) {
+        dump(printer, args, false);
+    }
+
+    /** @hide */
+    public static void dump(Printer printer, String[] args, boolean isSystem) {
+        boolean verbose = false;
+        for (String arg : args) {
+            if (arg.equals("-v")) {
+                verbose = true;
+            }
+        }
+
+        SQLiteDatabase.dumpAll(printer, verbose, isSystem);
+    }
+}
diff --git a/android/database/sqlite/SQLiteDirectCursorDriver.java b/android/database/sqlite/SQLiteDirectCursorDriver.java
new file mode 100644
index 0000000..1721e0c
--- /dev/null
+++ b/android/database/sqlite/SQLiteDirectCursorDriver.java
@@ -0,0 +1,85 @@
+/*
+ * 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.database.sqlite;
+
+import android.annotation.TestApi;
+import android.database.Cursor;
+import android.database.sqlite.SQLiteDatabase.CursorFactory;
+import android.os.CancellationSignal;
+
+/**
+ * A cursor driver that uses the given query directly.
+ * 
+ * @hide
+ */
+@TestApi
+public final class SQLiteDirectCursorDriver implements SQLiteCursorDriver {
+    private final SQLiteDatabase mDatabase;
+    private final String mEditTable; 
+    private final String mSql;
+    private final CancellationSignal mCancellationSignal;
+    private SQLiteQuery mQuery;
+
+    public SQLiteDirectCursorDriver(SQLiteDatabase db, String sql, String editTable,
+            CancellationSignal cancellationSignal) {
+        mDatabase = db;
+        mEditTable = editTable;
+        mSql = sql;
+        mCancellationSignal = cancellationSignal;
+    }
+
+    public Cursor query(CursorFactory factory, String[] selectionArgs) {
+        final SQLiteQuery query = new SQLiteQuery(mDatabase, mSql, mCancellationSignal);
+        final Cursor cursor;
+        try {
+            query.bindAllArgsAsStrings(selectionArgs);
+
+            if (factory == null) {
+                cursor = new SQLiteCursor(this, mEditTable, query);
+            } else {
+                cursor = factory.newCursor(mDatabase, this, mEditTable, query);
+            }
+        } catch (RuntimeException ex) {
+            query.close();
+            throw ex;
+        }
+
+        mQuery = query;
+        return cursor;
+    }
+
+    public void cursorClosed() {
+        // Do nothing
+    }
+
+    public void setBindArguments(String[] bindArgs) {
+        mQuery.bindAllArgsAsStrings(bindArgs);
+    }
+
+    public void cursorDeactivated() {
+        // Do nothing
+    }
+
+    public void cursorRequeried(Cursor cursor) {
+        // Do nothing
+    }
+
+    @Override
+    public String toString() {
+        return "SQLiteDirectCursorDriver: " + mSql;
+    }
+}
diff --git a/android/database/sqlite/SQLiteDiskIOException.java b/android/database/sqlite/SQLiteDiskIOException.java
new file mode 100644
index 0000000..01b2069
--- /dev/null
+++ b/android/database/sqlite/SQLiteDiskIOException.java
@@ -0,0 +1,29 @@
+/*
+ * Copyright (C) 2006 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.database.sqlite;
+
+/**
+ * An exception that indicates that an IO error occured while accessing the 
+ * SQLite database file.
+ */
+public class SQLiteDiskIOException extends SQLiteException {
+    public SQLiteDiskIOException() {}
+
+    public SQLiteDiskIOException(String error) {
+        super(error);
+    }
+}
diff --git a/android/database/sqlite/SQLiteDoneException.java b/android/database/sqlite/SQLiteDoneException.java
new file mode 100644
index 0000000..d6d3f66
--- /dev/null
+++ b/android/database/sqlite/SQLiteDoneException.java
@@ -0,0 +1,31 @@
+/*
+ * Copyright (C) 2008 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.database.sqlite;
+
+/**
+ * An exception that indicates that the SQLite program is done.
+ * Thrown when an operation that expects a row (such as {@link
+ * SQLiteStatement#simpleQueryForString} or {@link
+ * SQLiteStatement#simpleQueryForLong}) does not get one.
+ */
+public class SQLiteDoneException extends SQLiteException {
+    public SQLiteDoneException() {}
+
+    public SQLiteDoneException(String error) {
+        super(error);
+    }
+}
diff --git a/android/database/sqlite/SQLiteException.java b/android/database/sqlite/SQLiteException.java
new file mode 100644
index 0000000..a1d9c9f
--- /dev/null
+++ b/android/database/sqlite/SQLiteException.java
@@ -0,0 +1,35 @@
+/*
+ * Copyright (C) 2006 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.database.sqlite;
+
+import android.database.SQLException;
+
+/**
+ * A SQLite exception that indicates there was an error with SQL parsing or execution.
+ */
+public class SQLiteException extends SQLException {
+    public SQLiteException() {
+    }
+
+    public SQLiteException(String error) {
+        super(error);
+    }
+
+    public SQLiteException(String error, Throwable cause) {
+        super(error, cause);
+    }
+}
diff --git a/android/database/sqlite/SQLiteFullException.java b/android/database/sqlite/SQLiteFullException.java
new file mode 100644
index 0000000..582d930
--- /dev/null
+++ b/android/database/sqlite/SQLiteFullException.java
@@ -0,0 +1,28 @@
+/*
+ * Copyright (C) 2008 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.database.sqlite;
+
+/**
+ * An exception that indicates that the SQLite database is full.
+ */
+public class SQLiteFullException extends SQLiteException {
+    public SQLiteFullException() {}
+
+    public SQLiteFullException(String error) {
+        super(error);
+    }
+}
diff --git a/android/database/sqlite/SQLiteGlobal.java b/android/database/sqlite/SQLiteGlobal.java
new file mode 100644
index 0000000..5e2875d
--- /dev/null
+++ b/android/database/sqlite/SQLiteGlobal.java
@@ -0,0 +1,181 @@
+/*
+ * Copyright (C) 2011 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.database.sqlite;
+
+import android.annotation.TestApi;
+import android.content.res.Resources;
+import android.os.StatFs;
+import android.os.SystemProperties;
+
+/**
+ * Provides access to SQLite functions that affect all database connection,
+ * such as memory management.
+ *
+ * The native code associated with SQLiteGlobal is also sets global configuration options
+ * using sqlite3_config() then calls sqlite3_initialize() to ensure that the SQLite
+ * library is properly initialized exactly once before any other framework or application
+ * code has a chance to run.
+ *
+ * Verbose SQLite logging is enabled if the "log.tag.SQLiteLog" property is set to "V".
+ * (per {@link SQLiteDebug#DEBUG_SQL_LOG}).
+ *
+ * @hide
+ */
+@TestApi
+public final class SQLiteGlobal {
+    private static final String TAG = "SQLiteGlobal";
+
+    /** @hide */
+    public static final String SYNC_MODE_FULL = "FULL";
+
+    /** @hide */
+    static final String WIPE_CHECK_FILE_SUFFIX = "-wipecheck";
+
+    private static final Object sLock = new Object();
+
+    private static int sDefaultPageSize;
+
+    private static native int nativeReleaseMemory();
+
+    /** @hide */
+    public static volatile String sDefaultSyncMode;
+
+    private SQLiteGlobal() {
+    }
+
+    /**
+     * Attempts to release memory by pruning the SQLite page cache and other
+     * internal data structures.
+     *
+     * @return The number of bytes that were freed.
+     */
+    public static int releaseMemory() {
+        return nativeReleaseMemory();
+    }
+
+    /**
+     * Gets the default page size to use when creating a database.
+     */
+    public static int getDefaultPageSize() {
+        synchronized (sLock) {
+            if (sDefaultPageSize == 0) {
+                // If there is an issue accessing /data, something is so seriously
+                // wrong that we just let the IllegalArgumentException propagate.
+                sDefaultPageSize = new StatFs("/data").getBlockSize();
+            }
+            return SystemProperties.getInt("debug.sqlite.pagesize", sDefaultPageSize);
+        }
+    }
+
+    /**
+     * Gets the default journal mode when WAL is not in use.
+     */
+    public static String getDefaultJournalMode() {
+        return SystemProperties.get("debug.sqlite.journalmode",
+                Resources.getSystem().getString(
+                com.android.internal.R.string.db_default_journal_mode));
+    }
+
+    /**
+     * Gets the journal size limit in bytes.
+     */
+    public static int getJournalSizeLimit() {
+        return SystemProperties.getInt("debug.sqlite.journalsizelimit",
+                Resources.getSystem().getInteger(
+                com.android.internal.R.integer.db_journal_size_limit));
+    }
+
+    /**
+     * Gets the default database synchronization mode when WAL is not in use.
+     */
+    public static String getDefaultSyncMode() {
+        // Use the FULL synchronous mode for system processes by default.
+        String defaultMode = sDefaultSyncMode;
+        if (defaultMode != null) {
+            return defaultMode;
+        }
+        return SystemProperties.get("debug.sqlite.syncmode",
+                Resources.getSystem().getString(
+                com.android.internal.R.string.db_default_sync_mode));
+    }
+
+    /**
+     * Gets the database synchronization mode when in WAL mode.
+     */
+    public static String getWALSyncMode() {
+        // Use the FULL synchronous mode for system processes by default.
+        String defaultMode = sDefaultSyncMode;
+        if (defaultMode != null) {
+            return defaultMode;
+        }
+        return SystemProperties.get("debug.sqlite.wal.syncmode",
+                Resources.getSystem().getString(
+                com.android.internal.R.string.db_wal_sync_mode));
+    }
+
+    /**
+     * Gets the WAL auto-checkpoint integer in database pages.
+     */
+    public static int getWALAutoCheckpoint() {
+        int value = SystemProperties.getInt("debug.sqlite.wal.autocheckpoint",
+                Resources.getSystem().getInteger(
+                com.android.internal.R.integer.db_wal_autocheckpoint));
+        return Math.max(1, value);
+    }
+
+    /**
+     * Gets the connection pool size when in WAL mode.
+     */
+    public static int getWALConnectionPoolSize() {
+        int value = SystemProperties.getInt("debug.sqlite.wal.poolsize",
+                Resources.getSystem().getInteger(
+                com.android.internal.R.integer.db_connection_pool_size));
+        return Math.max(2, value);
+    }
+
+    /**
+     * The default number of milliseconds that SQLite connection is allowed to be idle before it
+     * is closed and removed from the pool.
+     */
+    public static int getIdleConnectionTimeout() {
+        return SystemProperties.getInt("debug.sqlite.idle_connection_timeout",
+                Resources.getSystem().getInteger(
+                        com.android.internal.R.integer.db_default_idle_connection_timeout));
+    }
+
+    /**
+     * When opening a database, if the WAL file is larger than this size, we'll truncate it.
+     *
+     * (If it's 0, we do not truncate.)
+     *
+     * @hide
+     */
+    public static long getWALTruncateSize() {
+        final long setting = SQLiteCompatibilityWalFlags.getTruncateSize();
+        if (setting >= 0) {
+            return setting;
+        }
+        return SystemProperties.getInt("debug.sqlite.wal.truncatesize",
+                Resources.getSystem().getInteger(
+                        com.android.internal.R.integer.db_wal_truncate_size));
+    }
+
+    /** @hide */
+    public static boolean checkDbWipe() {
+        return false;
+    }
+}
diff --git a/android/database/sqlite/SQLiteMisuseException.java b/android/database/sqlite/SQLiteMisuseException.java
new file mode 100644
index 0000000..546ec08
--- /dev/null
+++ b/android/database/sqlite/SQLiteMisuseException.java
@@ -0,0 +1,37 @@
+/*
+ * Copyright (C) 2008 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.database.sqlite;
+
+/**
+ * This error can occur if the application creates a SQLiteStatement object and allows multiple
+ * threads in the application use it at the same time.
+ * Sqlite returns this error if bind and execute methods on this object occur at the same time
+ * from multiple threads, like so:
+ *     thread # 1: in execute() method of the SQLiteStatement object
+ *     while thread # 2: is in bind..() on the same object.
+ *</p>
+ * FIX this by NEVER sharing the same SQLiteStatement object between threads.
+ * Create a local instance of the SQLiteStatement whenever it is needed, use it and close it ASAP.
+ * NEVER make it globally available.
+ */
+public class SQLiteMisuseException extends SQLiteException {
+    public SQLiteMisuseException() {}
+
+    public SQLiteMisuseException(String error) {
+        super(error);
+    }
+}
diff --git a/android/database/sqlite/SQLiteOpenHelper.java b/android/database/sqlite/SQLiteOpenHelper.java
new file mode 100644
index 0000000..3341800
--- /dev/null
+++ b/android/database/sqlite/SQLiteOpenHelper.java
@@ -0,0 +1,558 @@
+/*
+ * 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.database.sqlite;
+
+import android.annotation.IntRange;
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+import android.compat.annotation.UnsupportedAppUsage;
+import android.content.Context;
+import android.database.DatabaseErrorHandler;
+import android.database.SQLException;
+import android.database.sqlite.SQLiteDatabase.CursorFactory;
+import android.os.FileUtils;
+import android.util.Log;
+
+import java.io.File;
+import java.util.Objects;
+
+/**
+ * A helper class to manage database creation and version management.
+ *
+ * <p>You create a subclass implementing {@link #onCreate}, {@link #onUpgrade} and
+ * optionally {@link #onOpen}, and this class takes care of opening the database
+ * if it exists, creating it if it does not, and upgrading it as necessary.
+ * Transactions are used to make sure the database is always in a sensible state.
+ *
+ * <p>This class makes it easy for {@link android.content.ContentProvider}
+ * implementations to defer opening and upgrading the database until first use,
+ * to avoid blocking application startup with long-running database upgrades.
+ *
+ * <p>For an example, see the NotePadProvider class in the NotePad sample application,
+ * in the <em>samples/</em> directory of the SDK.</p>
+ *
+ * <p class="note"><strong>Note:</strong> this class assumes
+ * monotonically increasing version numbers for upgrades.</p>
+ *
+ * <p class="note"><strong>Note:</strong> the {@link AutoCloseable} interface was
+ * first added in the {@link android.os.Build.VERSION_CODES#Q} release.</p>
+ */
+public abstract class SQLiteOpenHelper implements AutoCloseable {
+    private static final String TAG = SQLiteOpenHelper.class.getSimpleName();
+
+    private final Context mContext;
+    @UnsupportedAppUsage
+    private final String mName;
+    private final int mNewVersion;
+    private final int mMinimumSupportedVersion;
+
+    private SQLiteDatabase mDatabase;
+    private boolean mIsInitializing;
+    private SQLiteDatabase.OpenParams.Builder mOpenParamsBuilder;
+
+    /**
+     * Create a helper object to create, open, and/or manage a database.
+     * This method always returns very quickly.  The database is not actually
+     * created or opened until one of {@link #getWritableDatabase} or
+     * {@link #getReadableDatabase} is called.
+     *
+     * @param context to use for locating paths to the the database
+     * @param name of the database file, or null for an in-memory database
+     * @param factory to use for creating cursor objects, or null for the default
+     * @param version number of the database (starting at 1); if the database is older,
+     *     {@link #onUpgrade} will be used to upgrade the database; if the database is
+     *     newer, {@link #onDowngrade} will be used to downgrade the database
+     */
+    public SQLiteOpenHelper(@Nullable Context context, @Nullable String name,
+            @Nullable CursorFactory factory, int version) {
+        this(context, name, factory, version, null);
+    }
+
+    /**
+     * Create a helper object to create, open, and/or manage a database.
+     * The database is not actually created or opened until one of
+     * {@link #getWritableDatabase} or {@link #getReadableDatabase} is called.
+     *
+     * <p>Accepts input param: a concrete instance of {@link DatabaseErrorHandler} to be
+     * used to handle corruption when sqlite reports database corruption.</p>
+     *
+     * @param context to use for locating paths to the the database
+     * @param name of the database file, or null for an in-memory database
+     * @param factory to use for creating cursor objects, or null for the default
+     * @param version number of the database (starting at 1); if the database is older,
+     *     {@link #onUpgrade} will be used to upgrade the database; if the database is
+     *     newer, {@link #onDowngrade} will be used to downgrade the database
+     * @param errorHandler the {@link DatabaseErrorHandler} to be used when sqlite reports database
+     * corruption, or null to use the default error handler.
+     */
+    public SQLiteOpenHelper(@Nullable Context context, @Nullable String name,
+            @Nullable CursorFactory factory, int version,
+            @Nullable DatabaseErrorHandler errorHandler) {
+        this(context, name, factory, version, 0, errorHandler);
+    }
+
+    /**
+     * Create a helper object to create, open, and/or manage a database.
+     * This method always returns very quickly.  The database is not actually
+     * created or opened until one of {@link #getWritableDatabase} or
+     * {@link #getReadableDatabase} is called.
+     *
+     * @param context to use for locating paths to the the database
+     * @param name of the database file, or null for an in-memory database
+     * @param version number of the database (starting at 1); if the database is older,
+     *     {@link #onUpgrade} will be used to upgrade the database; if the database is
+     *     newer, {@link #onDowngrade} will be used to downgrade the database
+     * @param openParams configuration parameters that are used for opening {@link SQLiteDatabase}.
+     *        Please note that {@link SQLiteDatabase#CREATE_IF_NECESSARY} flag will always be
+     *        set when the helper opens the database
+     */
+    public SQLiteOpenHelper(@Nullable Context context, @Nullable String name, int version,
+            @NonNull SQLiteDatabase.OpenParams openParams) {
+        this(context, name, version, 0, openParams.toBuilder());
+    }
+
+    /**
+     * Same as {@link #SQLiteOpenHelper(Context, String, CursorFactory, int, DatabaseErrorHandler)}
+     * but also accepts an integer minimumSupportedVersion as a convenience for upgrading very old
+     * versions of this database that are no longer supported. If a database with older version that
+     * minimumSupportedVersion is found, it is simply deleted and a new database is created with the
+     * given name and version
+     *
+     * @param context to use for locating paths to the the database
+     * @param name the name of the database file, null for a temporary in-memory database
+     * @param factory to use for creating cursor objects, null for default
+     * @param version the required version of the database
+     * @param minimumSupportedVersion the minimum version that is supported to be upgraded to
+     *            {@code version} via {@link #onUpgrade}. If the current database version is lower
+     *            than this, database is simply deleted and recreated with the version passed in
+     *            {@code version}. {@link #onBeforeDelete} is called before deleting the database
+     *            when this happens. This is 0 by default.
+     * @param errorHandler the {@link DatabaseErrorHandler} to be used when sqlite reports database
+     *            corruption, or null to use the default error handler.
+     * @see #onBeforeDelete(SQLiteDatabase)
+     * @see #SQLiteOpenHelper(Context, String, CursorFactory, int, DatabaseErrorHandler)
+     * @see #onUpgrade(SQLiteDatabase, int, int)
+     * @hide
+     */
+    public SQLiteOpenHelper(@Nullable Context context, @Nullable String name,
+            @Nullable CursorFactory factory, int version,
+            int minimumSupportedVersion, @Nullable DatabaseErrorHandler errorHandler) {
+        this(context, name, version, minimumSupportedVersion,
+                new SQLiteDatabase.OpenParams.Builder());
+        mOpenParamsBuilder.setCursorFactory(factory);
+        mOpenParamsBuilder.setErrorHandler(errorHandler);
+    }
+
+    private SQLiteOpenHelper(@Nullable Context context, @Nullable String name, int version,
+            int minimumSupportedVersion,
+            @NonNull SQLiteDatabase.OpenParams.Builder openParamsBuilder) {
+        Objects.requireNonNull(openParamsBuilder);
+        if (version < 1) throw new IllegalArgumentException("Version must be >= 1, was " + version);
+
+        mContext = context;
+        mName = name;
+        mNewVersion = version;
+        mMinimumSupportedVersion = Math.max(0, minimumSupportedVersion);
+        setOpenParamsBuilder(openParamsBuilder);
+    }
+
+    /**
+     * Return the name of the SQLite database being opened, as given to
+     * the constructor.
+     */
+    public String getDatabaseName() {
+        return mName;
+    }
+
+    /**
+     * Enables or disables the use of write-ahead logging for the database.
+     *
+     * Write-ahead logging cannot be used with read-only databases so the value of
+     * this flag is ignored if the database is opened read-only.
+     *
+     * @param enabled True if write-ahead logging should be enabled, false if it
+     * should be disabled.
+     *
+     * @see SQLiteDatabase#enableWriteAheadLogging()
+     */
+    public void setWriteAheadLoggingEnabled(boolean enabled) {
+        synchronized (this) {
+            if (mOpenParamsBuilder.isWriteAheadLoggingEnabled() != enabled) {
+                if (mDatabase != null && mDatabase.isOpen() && !mDatabase.isReadOnly()) {
+                    if (enabled) {
+                        mDatabase.enableWriteAheadLogging();
+                    } else {
+                        mDatabase.disableWriteAheadLogging();
+                    }
+                }
+                mOpenParamsBuilder.setWriteAheadLoggingEnabled(enabled);
+            }
+
+            // Compatibility WAL is disabled if an app disables or enables WAL
+            mOpenParamsBuilder.removeOpenFlags(SQLiteDatabase.ENABLE_LEGACY_COMPATIBILITY_WAL);
+        }
+    }
+
+    /**
+     * Configures <a href="https://sqlite.org/malloc.html#lookaside">lookaside memory allocator</a>
+     *
+     * <p>This method should be called from the constructor of the subclass,
+     * before opening the database, since lookaside memory configuration can only be changed
+     * when no connection is using it
+     *
+     * <p>SQLite default settings will be used, if this method isn't called.
+     * Use {@code setLookasideConfig(0,0)} to disable lookaside
+     *
+     * <p><strong>Note:</strong> Provided slotSize/slotCount configuration is just a recommendation.
+     * The system may choose different values depending on a device, e.g. lookaside allocations
+     * can be disabled on low-RAM devices
+     *
+     * @param slotSize The size in bytes of each lookaside slot.
+     * @param slotCount The total number of lookaside memory slots per database connection.
+     */
+    public void setLookasideConfig(@IntRange(from = 0) final int slotSize,
+            @IntRange(from = 0) final int slotCount) {
+        synchronized (this) {
+            if (mDatabase != null && mDatabase.isOpen()) {
+                throw new IllegalStateException(
+                        "Lookaside memory config cannot be changed after opening the database");
+            }
+            mOpenParamsBuilder.setLookasideConfig(slotSize, slotCount);
+        }
+    }
+
+    /**
+     * Sets configuration parameters that are used for opening {@link SQLiteDatabase}.
+     * <p>Please note that {@link SQLiteDatabase#CREATE_IF_NECESSARY} flag will always be set when
+     * opening the database
+     *
+     * @param openParams configuration parameters that are used for opening {@link SQLiteDatabase}.
+     * @throws IllegalStateException if the database is already open
+     */
+    public void setOpenParams(@NonNull SQLiteDatabase.OpenParams openParams) {
+        Objects.requireNonNull(openParams);
+        synchronized (this) {
+            if (mDatabase != null && mDatabase.isOpen()) {
+                throw new IllegalStateException(
+                        "OpenParams cannot be set after opening the database");
+            }
+            setOpenParamsBuilder(new SQLiteDatabase.OpenParams.Builder(openParams));
+        }
+    }
+
+    private void setOpenParamsBuilder(SQLiteDatabase.OpenParams.Builder openParamsBuilder) {
+        mOpenParamsBuilder = openParamsBuilder;
+        mOpenParamsBuilder.addOpenFlags(SQLiteDatabase.CREATE_IF_NECESSARY);
+    }
+
+    /**
+     * Sets the maximum number of milliseconds that SQLite connection is allowed to be idle
+     * before it is closed and removed from the pool.
+     *
+     * <p>This method should be called from the constructor of the subclass,
+     * before opening the database
+     *
+     * <p><b>DO NOT USE</b> this method.
+     * This feature has negative side effects that are very hard to foresee.
+     * See the javadoc of
+     * {@link SQLiteDatabase.OpenParams.Builder#setIdleConnectionTimeout(long)}
+     * for the details.
+     *
+     * @param idleConnectionTimeoutMs timeout in milliseconds. Use {@link Long#MAX_VALUE} value
+     * to allow unlimited idle connections.
+     *
+     * @see SQLiteDatabase.OpenParams.Builder#setIdleConnectionTimeout(long)
+     *
+     * @deprecated DO NOT USE this method. See the javadoc of
+     * {@link SQLiteDatabase.OpenParams.Builder#setIdleConnectionTimeout(long)}
+     * for the details.
+     */
+    @Deprecated
+    public void setIdleConnectionTimeout(@IntRange(from = 0) final long idleConnectionTimeoutMs) {
+        synchronized (this) {
+            if (mDatabase != null && mDatabase.isOpen()) {
+                throw new IllegalStateException(
+                        "Connection timeout setting cannot be changed after opening the database");
+            }
+            mOpenParamsBuilder.setIdleConnectionTimeout(idleConnectionTimeoutMs);
+        }
+    }
+
+    /**
+     * Create and/or open a database that will be used for reading and writing.
+     * The first time this is called, the database will be opened and
+     * {@link #onCreate}, {@link #onUpgrade} and/or {@link #onOpen} will be
+     * called.
+     *
+     * <p>Once opened successfully, the database is cached, so you can
+     * call this method every time you need to write to the database.
+     * (Make sure to call {@link #close} when you no longer need the database.)
+     * Errors such as bad permissions or a full disk may cause this method
+     * to fail, but future attempts may succeed if the problem is fixed.</p>
+     *
+     * <p class="caution">Database upgrade may take a long time, you
+     * should not call this method from the application main thread, including
+     * from {@link android.content.ContentProvider#onCreate ContentProvider.onCreate()}.
+     *
+     * @throws SQLiteException if the database cannot be opened for writing
+     * @return a read/write database object valid until {@link #close} is called
+     */
+    public SQLiteDatabase getWritableDatabase() {
+        synchronized (this) {
+            return getDatabaseLocked(true);
+        }
+    }
+
+    /**
+     * Create and/or open a database.  This will be the same object returned by
+     * {@link #getWritableDatabase} unless some problem, such as a full disk,
+     * requires the database to be opened read-only.  In that case, a read-only
+     * database object will be returned.  If the problem is fixed, a future call
+     * to {@link #getWritableDatabase} may succeed, in which case the read-only
+     * database object will be closed and the read/write object will be returned
+     * in the future.
+     *
+     * <p class="caution">Like {@link #getWritableDatabase}, this method may
+     * take a long time to return, so you should not call it from the
+     * application main thread, including from
+     * {@link android.content.ContentProvider#onCreate ContentProvider.onCreate()}.
+     *
+     * @throws SQLiteException if the database cannot be opened
+     * @return a database object valid until {@link #getWritableDatabase}
+     *     or {@link #close} is called.
+     */
+    public SQLiteDatabase getReadableDatabase() {
+        synchronized (this) {
+            return getDatabaseLocked(false);
+        }
+    }
+
+    private SQLiteDatabase getDatabaseLocked(boolean writable) {
+        if (mDatabase != null) {
+            if (!mDatabase.isOpen()) {
+                // Darn!  The user closed the database by calling mDatabase.close().
+                mDatabase = null;
+            } else if (!writable || !mDatabase.isReadOnly()) {
+                // The database is already open for business.
+                return mDatabase;
+            }
+        }
+
+        if (mIsInitializing) {
+            throw new IllegalStateException("getDatabase called recursively");
+        }
+
+        SQLiteDatabase db = mDatabase;
+        try {
+            mIsInitializing = true;
+
+            if (db != null) {
+                if (writable && db.isReadOnly()) {
+                    db.reopenReadWrite();
+                }
+            } else if (mName == null) {
+                db = SQLiteDatabase.createInMemory(mOpenParamsBuilder.build());
+            } else {
+                final File filePath = mContext.getDatabasePath(mName);
+                SQLiteDatabase.OpenParams params = mOpenParamsBuilder.build();
+                try {
+                    db = SQLiteDatabase.openDatabase(filePath, params);
+                    // Keep pre-O-MR1 behavior by resetting file permissions to 660
+                    setFilePermissionsForDb(filePath.getPath());
+                } catch (SQLException ex) {
+                    if (writable) {
+                        throw ex;
+                    }
+                    Log.e(TAG, "Couldn't open " + mName
+                            + " for writing (will try read-only):", ex);
+                    params = params.toBuilder().addOpenFlags(SQLiteDatabase.OPEN_READONLY).build();
+                    db = SQLiteDatabase.openDatabase(filePath, params);
+                }
+            }
+
+            onConfigure(db);
+
+            final int version = db.getVersion();
+            if (version != mNewVersion) {
+                if (db.isReadOnly()) {
+                    throw new SQLiteException("Can't upgrade read-only database from version " +
+                            db.getVersion() + " to " + mNewVersion + ": " + mName);
+                }
+
+                if (version > 0 && version < mMinimumSupportedVersion) {
+                    File databaseFile = new File(db.getPath());
+                    onBeforeDelete(db);
+                    db.close();
+                    if (SQLiteDatabase.deleteDatabase(databaseFile)) {
+                        mIsInitializing = false;
+                        return getDatabaseLocked(writable);
+                    } else {
+                        throw new IllegalStateException("Unable to delete obsolete database "
+                                + mName + " with version " + version);
+                    }
+                } else {
+                    db.beginTransaction();
+                    try {
+                        if (version == 0) {
+                            onCreate(db);
+                        } else {
+                            if (version > mNewVersion) {
+                                onDowngrade(db, version, mNewVersion);
+                            } else {
+                                onUpgrade(db, version, mNewVersion);
+                            }
+                        }
+                        db.setVersion(mNewVersion);
+                        db.setTransactionSuccessful();
+                    } finally {
+                        db.endTransaction();
+                    }
+                }
+            }
+
+            onOpen(db);
+
+            if (db.isReadOnly()) {
+                Log.w(TAG, "Opened " + mName + " in read-only mode");
+            }
+
+            mDatabase = db;
+            return db;
+        } finally {
+            mIsInitializing = false;
+            if (db != null && db != mDatabase) {
+                db.close();
+            }
+        }
+    }
+
+    private static void setFilePermissionsForDb(String dbPath) {
+        int perms = FileUtils.S_IRUSR | FileUtils.S_IWUSR | FileUtils.S_IRGRP | FileUtils.S_IWGRP;
+        FileUtils.setPermissions(dbPath, perms, -1, -1);
+    }
+
+    /**
+     * Close any open database object.
+     */
+    public synchronized void close() {
+        if (mIsInitializing) throw new IllegalStateException("Closed during initialization");
+
+        if (mDatabase != null && mDatabase.isOpen()) {
+            mDatabase.close();
+            mDatabase = null;
+        }
+    }
+
+    /**
+     * Called when the database connection is being configured, to enable features such as
+     * write-ahead logging or foreign key support.
+     * <p>
+     * This method is called before {@link #onCreate}, {@link #onUpgrade}, {@link #onDowngrade}, or
+     * {@link #onOpen} are called. It should not modify the database except to configure the
+     * database connection as required.
+     * </p>
+     * <p>
+     * This method should only call methods that configure the parameters of the database
+     * connection, such as {@link SQLiteDatabase#enableWriteAheadLogging}
+     * {@link SQLiteDatabase#setForeignKeyConstraintsEnabled}, {@link SQLiteDatabase#setLocale},
+     * {@link SQLiteDatabase#setMaximumSize}, or executing PRAGMA statements.
+     * </p>
+     *
+     * @param db The database.
+     */
+    public void onConfigure(SQLiteDatabase db) {}
+
+    /**
+     * Called before the database is deleted when the version returned by
+     * {@link SQLiteDatabase#getVersion()} is lower than the minimum supported version passed (if at
+     * all) while creating this helper. After the database is deleted, a fresh database with the
+     * given version is created. This will be followed by {@link #onConfigure(SQLiteDatabase)} and
+     * {@link #onCreate(SQLiteDatabase)} being called with a new SQLiteDatabase object
+     *
+     * @param db the database opened with this helper
+     * @see #SQLiteOpenHelper(Context, String, CursorFactory, int, int, DatabaseErrorHandler)
+     * @hide
+     */
+    public void onBeforeDelete(SQLiteDatabase db) {
+    }
+
+    /**
+     * Called when the database is created for the first time. This is where the
+     * creation of tables and the initial population of the tables should happen.
+     *
+     * @param db The database.
+     */
+    public abstract void onCreate(SQLiteDatabase db);
+
+    /**
+     * Called when the database needs to be upgraded. The implementation
+     * should use this method to drop tables, add tables, or do anything else it
+     * needs to upgrade to the new schema version.
+     *
+     * <p>
+     * The SQLite ALTER TABLE documentation can be found
+     * <a href="http://sqlite.org/lang_altertable.html">here</a>. If you add new columns
+     * you can use ALTER TABLE to insert them into a live table. If you rename or remove columns
+     * you can use ALTER TABLE to rename the old table, then create the new table and then
+     * populate the new table with the contents of the old table.
+     * </p><p>
+     * This method executes within a transaction.  If an exception is thrown, all changes
+     * will automatically be rolled back.
+     * </p>
+     *
+     * @param db The database.
+     * @param oldVersion The old database version.
+     * @param newVersion The new database version.
+     */
+    public abstract void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion);
+
+    /**
+     * Called when the database needs to be downgraded. This is strictly similar to
+     * {@link #onUpgrade} method, but is called whenever current version is newer than requested one.
+     * However, this method is not abstract, so it is not mandatory for a customer to
+     * implement it. If not overridden, default implementation will reject downgrade and
+     * throws SQLiteException
+     *
+     * <p>
+     * This method executes within a transaction.  If an exception is thrown, all changes
+     * will automatically be rolled back.
+     * </p>
+     *
+     * @param db The database.
+     * @param oldVersion The old database version.
+     * @param newVersion The new database version.
+     */
+    public void onDowngrade(SQLiteDatabase db, int oldVersion, int newVersion) {
+        throw new SQLiteException("Can't downgrade database from version " +
+                oldVersion + " to " + newVersion);
+    }
+
+    /**
+     * Called when the database has been opened.  The implementation
+     * should check {@link SQLiteDatabase#isReadOnly} before updating the
+     * database.
+     * <p>
+     * This method is called after the database connection has been configured
+     * and after the database schema has been created, upgraded or downgraded as necessary.
+     * If the database connection must be configured in some way before the schema
+     * is created, upgraded, or downgraded, do it in {@link #onConfigure} instead.
+     * </p>
+     *
+     * @param db The database.
+     */
+    public void onOpen(SQLiteDatabase db) {}
+}
diff --git a/android/database/sqlite/SQLiteOutOfMemoryException.java b/android/database/sqlite/SQLiteOutOfMemoryException.java
new file mode 100644
index 0000000..98ce8b5
--- /dev/null
+++ b/android/database/sqlite/SQLiteOutOfMemoryException.java
@@ -0,0 +1,25 @@
+/*
+ * 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.database.sqlite;
+
+public class SQLiteOutOfMemoryException extends SQLiteException {
+    public SQLiteOutOfMemoryException() {}
+
+    public SQLiteOutOfMemoryException(String error) {
+        super(error);
+    }
+}
diff --git a/android/database/sqlite/SQLiteProgram.java b/android/database/sqlite/SQLiteProgram.java
new file mode 100644
index 0000000..de1c543
--- /dev/null
+++ b/android/database/sqlite/SQLiteProgram.java
@@ -0,0 +1,221 @@
+/*
+ * Copyright (C) 2006 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.database.sqlite;
+
+import android.compat.annotation.UnsupportedAppUsage;
+import android.database.DatabaseUtils;
+import android.os.CancellationSignal;
+
+import java.util.Arrays;
+
+/**
+ * A base class for compiled SQLite programs.
+ * <p>
+ * This class is not thread-safe.
+ * </p>
+ */
+public abstract class SQLiteProgram extends SQLiteClosable {
+    private static final String[] EMPTY_STRING_ARRAY = new String[0];
+
+    private final SQLiteDatabase mDatabase;
+    @UnsupportedAppUsage
+    private final String mSql;
+    private final boolean mReadOnly;
+    private final String[] mColumnNames;
+    private final int mNumParameters;
+    @UnsupportedAppUsage
+    private final Object[] mBindArgs;
+
+    SQLiteProgram(SQLiteDatabase db, String sql, Object[] bindArgs,
+            CancellationSignal cancellationSignalForPrepare) {
+        mDatabase = db;
+        mSql = sql.trim();
+
+        int n = DatabaseUtils.getSqlStatementType(mSql);
+        switch (n) {
+            case DatabaseUtils.STATEMENT_BEGIN:
+            case DatabaseUtils.STATEMENT_COMMIT:
+            case DatabaseUtils.STATEMENT_ABORT:
+                mReadOnly = false;
+                mColumnNames = EMPTY_STRING_ARRAY;
+                mNumParameters = 0;
+                break;
+
+            default:
+                boolean assumeReadOnly = (n == DatabaseUtils.STATEMENT_SELECT);
+                SQLiteStatementInfo info = new SQLiteStatementInfo();
+                db.getThreadSession().prepare(mSql,
+                        db.getThreadDefaultConnectionFlags(assumeReadOnly),
+                        cancellationSignalForPrepare, info);
+                mReadOnly = info.readOnly;
+                mColumnNames = info.columnNames;
+                mNumParameters = info.numParameters;
+                break;
+        }
+
+        if (bindArgs != null && bindArgs.length > mNumParameters) {
+            throw new IllegalArgumentException("Too many bind arguments.  "
+                    + bindArgs.length + " arguments were provided but the statement needs "
+                    + mNumParameters + " arguments.");
+        }
+
+        if (mNumParameters != 0) {
+            mBindArgs = new Object[mNumParameters];
+            if (bindArgs != null) {
+                System.arraycopy(bindArgs, 0, mBindArgs, 0, bindArgs.length);
+            }
+        } else {
+            mBindArgs = null;
+        }
+    }
+
+    final SQLiteDatabase getDatabase() {
+        return mDatabase;
+    }
+
+    final String getSql() {
+        return mSql;
+    }
+
+    final Object[] getBindArgs() {
+        return mBindArgs;
+    }
+
+    final String[] getColumnNames() {
+        return mColumnNames;
+    }
+
+    /** @hide */
+    protected final SQLiteSession getSession() {
+        return mDatabase.getThreadSession();
+    }
+
+    /** @hide */
+    protected final int getConnectionFlags() {
+        return mDatabase.getThreadDefaultConnectionFlags(mReadOnly);
+    }
+
+    /** @hide */
+    protected final void onCorruption() {
+        mDatabase.onCorruption();
+    }
+
+    /**
+     * Unimplemented.
+     * @deprecated This method is deprecated and must not be used.
+     */
+    @Deprecated
+    public final int getUniqueId() {
+        return -1;
+    }
+
+    /**
+     * Bind a NULL value to this statement. The value remains bound until
+     * {@link #clearBindings} is called.
+     *
+     * @param index The 1-based index to the parameter to bind null to
+     */
+    public void bindNull(int index) {
+        bind(index, null);
+    }
+
+    /**
+     * Bind a long value to this statement. The value remains bound until
+     * {@link #clearBindings} is called.
+     *addToBindArgs
+     * @param index The 1-based index to the parameter to bind
+     * @param value The value to bind
+     */
+    public void bindLong(int index, long value) {
+        bind(index, value);
+    }
+
+    /**
+     * Bind a double value to this statement. The value remains bound until
+     * {@link #clearBindings} is called.
+     *
+     * @param index The 1-based index to the parameter to bind
+     * @param value The value to bind
+     */
+    public void bindDouble(int index, double value) {
+        bind(index, value);
+    }
+
+    /**
+     * Bind a String value to this statement. The value remains bound until
+     * {@link #clearBindings} is called.
+     *
+     * @param index The 1-based index to the parameter to bind
+     * @param value The value to bind, must not be null
+     */
+    public void bindString(int index, String value) {
+        if (value == null) {
+            throw new IllegalArgumentException("the bind value at index " + index + " is null");
+        }
+        bind(index, value);
+    }
+
+    /**
+     * Bind a byte array value to this statement. The value remains bound until
+     * {@link #clearBindings} is called.
+     *
+     * @param index The 1-based index to the parameter to bind
+     * @param value The value to bind, must not be null
+     */
+    public void bindBlob(int index, byte[] value) {
+        if (value == null) {
+            throw new IllegalArgumentException("the bind value at index " + index + " is null");
+        }
+        bind(index, value);
+    }
+
+    /**
+     * Clears all existing bindings. Unset bindings are treated as NULL.
+     */
+    public void clearBindings() {
+        if (mBindArgs != null) {
+            Arrays.fill(mBindArgs, null);
+        }
+    }
+
+    /**
+     * Given an array of String bindArgs, this method binds all of them in one single call.
+     *
+     * @param bindArgs the String array of bind args, none of which must be null.
+     */
+    public void bindAllArgsAsStrings(String[] bindArgs) {
+        if (bindArgs != null) {
+            for (int i = bindArgs.length; i != 0; i--) {
+                bindString(i, bindArgs[i - 1]);
+            }
+        }
+    }
+
+    @Override
+    protected void onAllReferencesReleased() {
+        clearBindings();
+    }
+
+    private void bind(int index, Object value) {
+        if (index < 1 || index > mNumParameters) {
+            throw new IllegalArgumentException("Cannot bind argument at index "
+                    + index + " because the index is out of range.  "
+                    + "The statement has " + mNumParameters + " parameters.");
+        }
+        mBindArgs[index - 1] = value;
+    }
+}
diff --git a/android/database/sqlite/SQLiteQuery.java b/android/database/sqlite/SQLiteQuery.java
new file mode 100644
index 0000000..62bcc20
--- /dev/null
+++ b/android/database/sqlite/SQLiteQuery.java
@@ -0,0 +1,84 @@
+/*
+ * Copyright (C) 2006 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.database.sqlite;
+
+import android.database.CursorWindow;
+import android.os.CancellationSignal;
+import android.os.OperationCanceledException;
+import android.util.Log;
+
+/**
+ * Represents a query that reads the resulting rows into a {@link SQLiteQuery}.
+ * This class is used by {@link SQLiteCursor} and isn't useful itself.
+ * <p>
+ * This class is not thread-safe.
+ * </p>
+ */
+public final class SQLiteQuery extends SQLiteProgram {
+    private static final String TAG = "SQLiteQuery";
+
+    private final CancellationSignal mCancellationSignal;
+
+    SQLiteQuery(SQLiteDatabase db, String query, CancellationSignal cancellationSignal) {
+        super(db, query, null, cancellationSignal);
+
+        mCancellationSignal = cancellationSignal;
+    }
+
+    /**
+     * Reads rows into a buffer.
+     *
+     * @param window The window to fill into
+     * @param startPos The start position for filling the window.
+     * @param requiredPos The position of a row that MUST be in the window.
+     * If it won't fit, then the query should discard part of what it filled.
+     * @param countAllRows True to count all rows that the query would
+     * return regardless of whether they fit in the window.
+     * @return Number of rows that were enumerated.  Might not be all rows
+     * unless countAllRows is true.
+     *
+     * @throws SQLiteException if an error occurs.
+     * @throws OperationCanceledException if the operation was canceled.
+     */
+    int fillWindow(CursorWindow window, int startPos, int requiredPos, boolean countAllRows) {
+        acquireReference();
+        try {
+            window.acquireReference();
+            try {
+                int numRows = getSession().executeForCursorWindow(getSql(), getBindArgs(),
+                        window, startPos, requiredPos, countAllRows, getConnectionFlags(),
+                        mCancellationSignal);
+                return numRows;
+            } catch (SQLiteDatabaseCorruptException ex) {
+                onCorruption();
+                throw ex;
+            } catch (SQLiteException ex) {
+                Log.e(TAG, "exception: " + ex.getMessage() + "; query: " + getSql());
+                throw ex;
+            } finally {
+                window.releaseReference();
+            }
+        } finally {
+            releaseReference();
+        }
+    }
+
+    @Override
+    public String toString() {
+        return "SQLiteQuery: " + getSql();
+    }
+}
diff --git a/android/database/sqlite/SQLiteQueryBuilder.java b/android/database/sqlite/SQLiteQueryBuilder.java
new file mode 100644
index 0000000..36ec67e
--- /dev/null
+++ b/android/database/sqlite/SQLiteQueryBuilder.java
@@ -0,0 +1,1203 @@
+/*
+ * Copyright (C) 2006 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.database.sqlite;
+
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+import android.compat.annotation.UnsupportedAppUsage;
+import android.content.ContentValues;
+import android.database.Cursor;
+import android.database.DatabaseUtils;
+import android.os.Build;
+import android.os.CancellationSignal;
+import android.os.OperationCanceledException;
+import android.provider.BaseColumns;
+import android.text.TextUtils;
+import android.util.ArrayMap;
+import android.util.Log;
+
+import com.android.internal.util.ArrayUtils;
+
+import libcore.util.EmptyArray;
+
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.Iterator;
+import java.util.Locale;
+import java.util.Map;
+import java.util.Map.Entry;
+import java.util.Objects;
+import java.util.Set;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+/**
+ * This is a convenience class that helps build SQL queries to be sent to
+ * {@link SQLiteDatabase} objects.
+ */
+public class SQLiteQueryBuilder {
+    private static final String TAG = "SQLiteQueryBuilder";
+
+    private static final Pattern sAggregationPattern = Pattern.compile(
+            "(?i)(AVG|COUNT|MAX|MIN|SUM|TOTAL|GROUP_CONCAT)\\((.+)\\)");
+
+    private Map<String, String> mProjectionMap = null;
+    private Collection<Pattern> mProjectionGreylist = null;
+
+    @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023)
+    private String mTables = "";
+    @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023)
+    private StringBuilder mWhereClause = null;  // lazily created
+    @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023)
+    private boolean mDistinct;
+    private SQLiteDatabase.CursorFactory mFactory;
+
+    private static final int STRICT_PARENTHESES = 1 << 0;
+    private static final int STRICT_COLUMNS = 1 << 1;
+    private static final int STRICT_GRAMMAR = 1 << 2;
+
+    private int mStrictFlags;
+
+    public SQLiteQueryBuilder() {
+        mDistinct = false;
+        mFactory = null;
+    }
+
+    /**
+     * Mark the query as {@code DISTINCT}.
+     *
+     * @param distinct if true the query is {@code DISTINCT}, otherwise it isn't
+     */
+    public void setDistinct(boolean distinct) {
+        mDistinct = distinct;
+    }
+
+    /**
+     * Get if the query is marked as {@code DISTINCT}, as last configured by
+     * {@link #setDistinct(boolean)}.
+     */
+    public boolean isDistinct() {
+        return mDistinct;
+    }
+
+    /**
+     * Returns the list of tables being queried
+     *
+     * @return the list of tables being queried
+     */
+    public @Nullable String getTables() {
+        return mTables;
+    }
+
+    /**
+     * Sets the list of tables to query. Multiple tables can be specified to perform a join.
+     * For example:
+     *   setTables("foo, bar")
+     *   setTables("foo LEFT OUTER JOIN bar ON (foo.id = bar.foo_id)")
+     *
+     * @param inTables the list of tables to query on
+     */
+    public void setTables(@Nullable String inTables) {
+        mTables = inTables;
+    }
+
+    /**
+     * Append a chunk to the {@code WHERE} clause of the query. All chunks appended are surrounded
+     * by parenthesis and {@code AND}ed with the selection passed to {@link #query}. The final
+     * {@code WHERE} clause looks like:
+     * <p>
+     * WHERE (&lt;append chunk 1>&lt;append chunk2>) AND (&lt;query() selection parameter>)
+     *
+     * @param inWhere the chunk of text to append to the {@code WHERE} clause.
+     */
+    public void appendWhere(@NonNull CharSequence inWhere) {
+        if (mWhereClause == null) {
+            mWhereClause = new StringBuilder(inWhere.length() + 16);
+        }
+        mWhereClause.append(inWhere);
+    }
+
+    /**
+     * Append a chunk to the {@code WHERE} clause of the query. All chunks appended are surrounded
+     * by parenthesis and ANDed with the selection passed to {@link #query}. The final
+     * {@code WHERE} clause looks like:
+     * <p>
+     * WHERE (&lt;append chunk 1>&lt;append chunk2>) AND (&lt;query() selection parameter>)
+     *
+     * @param inWhere the chunk of text to append to the {@code WHERE} clause. it will be escaped
+     * to avoid SQL injection attacks
+     */
+    public void appendWhereEscapeString(@NonNull String inWhere) {
+        if (mWhereClause == null) {
+            mWhereClause = new StringBuilder(inWhere.length() + 16);
+        }
+        DatabaseUtils.appendEscapedSQLString(mWhereClause, inWhere);
+    }
+
+    /**
+     * Add a standalone chunk to the {@code WHERE} clause of this query.
+     * <p>
+     * This method differs from {@link #appendWhere(CharSequence)} in that it
+     * automatically appends {@code AND} to any existing {@code WHERE} clause
+     * already under construction before appending the given standalone
+     * expression wrapped in parentheses.
+     *
+     * @param inWhere the standalone expression to append to the {@code WHERE}
+     *            clause. It will be wrapped in parentheses when it's appended.
+     */
+    public void appendWhereStandalone(@NonNull CharSequence inWhere) {
+        if (mWhereClause == null) {
+            mWhereClause = new StringBuilder(inWhere.length() + 16);
+        }
+        if (mWhereClause.length() > 0) {
+            mWhereClause.append(" AND ");
+        }
+        mWhereClause.append('(').append(inWhere).append(')');
+    }
+
+    /**
+     * Sets the projection map for the query.  The projection map maps
+     * from column names that the caller passes into query to database
+     * column names. This is useful for renaming columns as well as
+     * disambiguating column names when doing joins. For example you
+     * could map "name" to "people.name".  If a projection map is set
+     * it must contain all column names the user may request, even if
+     * the key and value are the same.
+     *
+     * @param columnMap maps from the user column names to the database column names
+     */
+    public void setProjectionMap(@Nullable Map<String, String> columnMap) {
+        mProjectionMap = columnMap;
+    }
+
+    /**
+     * Gets the projection map for the query, as last configured by
+     * {@link #setProjectionMap(Map)}.
+     */
+    public @Nullable Map<String, String> getProjectionMap() {
+        return mProjectionMap;
+    }
+
+    /**
+     * Sets a projection greylist of columns that will be allowed through, even
+     * when {@link #setStrict(boolean)} is enabled. This provides a way for
+     * abusive custom columns like {@code COUNT(*)} to continue working.
+     */
+    public void setProjectionGreylist(@Nullable Collection<Pattern> projectionGreylist) {
+        mProjectionGreylist = projectionGreylist;
+    }
+
+    /**
+     * Gets the projection greylist for the query, as last configured by
+     * {@link #setProjectionGreylist}.
+     */
+    public @Nullable Collection<Pattern> getProjectionGreylist() {
+        return mProjectionGreylist;
+    }
+
+    /** {@hide} */
+    @Deprecated
+    public void setProjectionAggregationAllowed(boolean projectionAggregationAllowed) {
+    }
+
+    /** {@hide} */
+    @Deprecated
+    public boolean isProjectionAggregationAllowed() {
+        return true;
+    }
+
+    /**
+     * Sets the cursor factory to be used for the query.  You can use
+     * one factory for all queries on a database but it is normally
+     * easier to specify the factory when doing this query.
+     *
+     * @param factory the factory to use.
+     */
+    public void setCursorFactory(@Nullable SQLiteDatabase.CursorFactory factory) {
+        mFactory = factory;
+    }
+
+    /**
+     * Gets the cursor factory to be used for the query, as last configured by
+     * {@link #setCursorFactory(android.database.sqlite.SQLiteDatabase.CursorFactory)}.
+     */
+    public @Nullable SQLiteDatabase.CursorFactory getCursorFactory() {
+        return mFactory;
+    }
+
+    /**
+     * When set, the selection is verified against malicious arguments. When
+     * using this class to create a statement using
+     * {@link #buildQueryString(boolean, String, String[], String, String, String, String, String)},
+     * non-numeric limits will raise an exception. If a projection map is
+     * specified, fields not in that map will be ignored. If this class is used
+     * to execute the statement directly using
+     * {@link #query(SQLiteDatabase, String[], String, String[], String, String, String)}
+     * or
+     * {@link #query(SQLiteDatabase, String[], String, String[], String, String, String, String)},
+     * additionally also parenthesis escaping selection are caught. To
+     * summarize: To get maximum protection against malicious third party apps
+     * (for example content provider consumers), make sure to do the following:
+     * <ul>
+     * <li>Set this value to true</li>
+     * <li>Use a projection map</li>
+     * <li>Use one of the query overloads instead of getting the statement as a
+     * sql string</li>
+     * </ul>
+     * <p>
+     * This feature is disabled by default on each newly constructed
+     * {@link SQLiteQueryBuilder} and needs to be manually enabled.
+     */
+    public void setStrict(boolean strict) {
+        if (strict) {
+            mStrictFlags |= STRICT_PARENTHESES;
+        } else {
+            mStrictFlags &= ~STRICT_PARENTHESES;
+        }
+    }
+
+    /**
+     * Get if the query is marked as strict, as last configured by
+     * {@link #setStrict(boolean)}.
+     */
+    public boolean isStrict() {
+        return (mStrictFlags & STRICT_PARENTHESES) != 0;
+    }
+
+    /**
+     * When enabled, verify that all projections and {@link ContentValues} only
+     * contain valid columns as defined by {@link #setProjectionMap(Map)}.
+     * <p>
+     * This enforcement applies to {@link #insert}, {@link #query}, and
+     * {@link #update} operations. Any enforcement failures will throw an
+     * {@link IllegalArgumentException}.
+     * <p>
+     * This feature is disabled by default on each newly constructed
+     * {@link SQLiteQueryBuilder} and needs to be manually enabled.
+     */
+    public void setStrictColumns(boolean strictColumns) {
+        if (strictColumns) {
+            mStrictFlags |= STRICT_COLUMNS;
+        } else {
+            mStrictFlags &= ~STRICT_COLUMNS;
+        }
+    }
+
+    /**
+     * Get if the query is marked as strict, as last configured by
+     * {@link #setStrictColumns(boolean)}.
+     */
+    public boolean isStrictColumns() {
+        return (mStrictFlags & STRICT_COLUMNS) != 0;
+    }
+
+    /**
+     * When enabled, verify that all untrusted SQL conforms to a restricted SQL
+     * grammar. Here are the restrictions applied:
+     * <ul>
+     * <li>In {@code WHERE} and {@code HAVING} clauses: subqueries, raising, and
+     * windowing terms are rejected.
+     * <li>In {@code GROUP BY} clauses: only valid columns are allowed.
+     * <li>In {@code ORDER BY} clauses: only valid columns, collation, and
+     * ordering terms are allowed.
+     * <li>In {@code LIMIT} clauses: only numerical values and offset terms are
+     * allowed.
+     * </ul>
+     * All column references must be valid as defined by
+     * {@link #setProjectionMap(Map)}.
+     * <p>
+     * This enforcement applies to {@link #query}, {@link #update} and
+     * {@link #delete} operations. This enforcement does not apply to trusted
+     * inputs, such as those provided by {@link #appendWhere}. Any enforcement
+     * failures will throw an {@link IllegalArgumentException}.
+     * <p>
+     * This feature is disabled by default on each newly constructed
+     * {@link SQLiteQueryBuilder} and needs to be manually enabled.
+     */
+    public void setStrictGrammar(boolean strictGrammar) {
+        if (strictGrammar) {
+            mStrictFlags |= STRICT_GRAMMAR;
+        } else {
+            mStrictFlags &= ~STRICT_GRAMMAR;
+        }
+    }
+
+    /**
+     * Get if the query is marked as strict, as last configured by
+     * {@link #setStrictGrammar(boolean)}.
+     */
+    public boolean isStrictGrammar() {
+        return (mStrictFlags & STRICT_GRAMMAR) != 0;
+    }
+
+    /**
+     * Build an SQL query string from the given clauses.
+     *
+     * @param distinct true if you want each row to be unique, false otherwise.
+     * @param tables The table names to compile the query against.
+     * @param columns A list of which columns to return. Passing null will
+     *            return all columns, which is discouraged to prevent reading
+     *            data from storage that isn't going to be used.
+     * @param where A filter declaring which rows to return, formatted as an SQL
+     *            {@code WHERE} clause (excluding the {@code WHERE} itself). Passing {@code null} will
+     *            return all rows for the given URL.
+     * @param groupBy A filter declaring how to group rows, formatted as an SQL
+     *            {@code GROUP BY} clause (excluding the {@code GROUP BY} itself). Passing {@code null}
+     *            will cause the rows to not be grouped.
+     * @param having A filter declare which row groups to include in the cursor,
+     *            if row grouping is being used, formatted as an SQL {@code HAVING}
+     *            clause (excluding the {@code HAVING} itself). Passing null will cause
+     *            all row groups to be included, and is required when row
+     *            grouping is not being used.
+     * @param orderBy How to order the rows, formatted as an SQL {@code ORDER BY} clause
+     *            (excluding the {@code ORDER BY} itself). Passing null will use the
+     *            default sort order, which may be unordered.
+     * @param limit Limits the number of rows returned by the query,
+     *            formatted as {@code LIMIT} clause. Passing null denotes no {@code LIMIT} clause.
+     * @return the SQL query string
+     */
+    public static String buildQueryString(
+            boolean distinct, String tables, String[] columns, String where,
+            String groupBy, String having, String orderBy, String limit) {
+        if (TextUtils.isEmpty(groupBy) && !TextUtils.isEmpty(having)) {
+            throw new IllegalArgumentException(
+                    "HAVING clauses are only permitted when using a groupBy clause");
+        }
+
+        StringBuilder query = new StringBuilder(120);
+
+        query.append("SELECT ");
+        if (distinct) {
+            query.append("DISTINCT ");
+        }
+        if (columns != null && columns.length != 0) {
+            appendColumns(query, columns);
+        } else {
+            query.append("* ");
+        }
+        query.append("FROM ");
+        query.append(tables);
+        appendClause(query, " WHERE ", where);
+        appendClause(query, " GROUP BY ", groupBy);
+        appendClause(query, " HAVING ", having);
+        appendClause(query, " ORDER BY ", orderBy);
+        appendClause(query, " LIMIT ", limit);
+
+        return query.toString();
+    }
+
+    private static void appendClause(StringBuilder s, String name, String clause) {
+        if (!TextUtils.isEmpty(clause)) {
+            s.append(name);
+            s.append(clause);
+        }
+    }
+
+    /**
+     * Add the names that are non-null in columns to s, separating
+     * them with commas.
+     */
+    public static void appendColumns(StringBuilder s, String[] columns) {
+        int n = columns.length;
+
+        for (int i = 0; i < n; i++) {
+            String column = columns[i];
+
+            if (column != null) {
+                if (i > 0) {
+                    s.append(", ");
+                }
+                s.append(column);
+            }
+        }
+        s.append(' ');
+    }
+
+    /**
+     * Perform a query by combining all current settings and the
+     * information passed into this method.
+     *
+     * @param db the database to query on
+     * @param projectionIn A list of which columns to return. Passing
+     *   null will return all columns, which is discouraged to prevent
+     *   reading data from storage that isn't going to be used.
+     * @param selection A filter declaring which rows to return,
+     *   formatted as an SQL {@code WHERE} clause (excluding the {@code WHERE}
+     *   itself). Passing null will return all rows for the given URL.
+     * @param selectionArgs You may include ?s in selection, which
+     *   will be replaced by the values from selectionArgs, in order
+     *   that they appear in the selection. The values will be bound
+     *   as Strings.
+     * @param groupBy A filter declaring how to group rows, formatted
+     *   as an SQL {@code GROUP BY} clause (excluding the {@code GROUP BY}
+     *   itself). Passing null will cause the rows to not be grouped.
+     * @param having A filter declare which row groups to include in
+     *   the cursor, if row grouping is being used, formatted as an
+     *   SQL {@code HAVING} clause (excluding the {@code HAVING} itself).  Passing
+     *   null will cause all row groups to be included, and is
+     *   required when row grouping is not being used.
+     * @param sortOrder How to order the rows, formatted as an SQL
+     *   {@code ORDER BY} clause (excluding the {@code ORDER BY} itself). Passing null
+     *   will use the default sort order, which may be unordered.
+     * @return a cursor over the result set
+     * @see android.content.ContentResolver#query(android.net.Uri, String[],
+     *      String, String[], String)
+     */
+    public Cursor query(SQLiteDatabase db, String[] projectionIn,
+            String selection, String[] selectionArgs, String groupBy,
+            String having, String sortOrder) {
+        return query(db, projectionIn, selection, selectionArgs, groupBy, having, sortOrder,
+                null /* limit */, null /* cancellationSignal */);
+    }
+
+    /**
+     * Perform a query by combining all current settings and the
+     * information passed into this method.
+     *
+     * @param db the database to query on
+     * @param projectionIn A list of which columns to return. Passing
+     *   null will return all columns, which is discouraged to prevent
+     *   reading data from storage that isn't going to be used.
+     * @param selection A filter declaring which rows to return,
+     *   formatted as an SQL {@code WHERE} clause (excluding the {@code WHERE}
+     *   itself). Passing null will return all rows for the given URL.
+     * @param selectionArgs You may include ?s in selection, which
+     *   will be replaced by the values from selectionArgs, in order
+     *   that they appear in the selection. The values will be bound
+     *   as Strings.
+     * @param groupBy A filter declaring how to group rows, formatted
+     *   as an SQL {@code GROUP BY} clause (excluding the {@code GROUP BY}
+     *   itself). Passing null will cause the rows to not be grouped.
+     * @param having A filter declare which row groups to include in
+     *   the cursor, if row grouping is being used, formatted as an
+     *   SQL {@code HAVING} clause (excluding the {@code HAVING} itself).  Passing
+     *   null will cause all row groups to be included, and is
+     *   required when row grouping is not being used.
+     * @param sortOrder How to order the rows, formatted as an SQL
+     *   {@code ORDER BY} clause (excluding the {@code ORDER BY} itself). Passing null
+     *   will use the default sort order, which may be unordered.
+     * @param limit Limits the number of rows returned by the query,
+     *   formatted as {@code LIMIT} clause. Passing null denotes no {@code LIMIT} clause.
+     * @return a cursor over the result set
+     * @see android.content.ContentResolver#query(android.net.Uri, String[],
+     *      String, String[], String)
+     */
+    public Cursor query(SQLiteDatabase db, String[] projectionIn,
+            String selection, String[] selectionArgs, String groupBy,
+            String having, String sortOrder, String limit) {
+        return query(db, projectionIn, selection, selectionArgs,
+                groupBy, having, sortOrder, limit, null);
+    }
+
+    /**
+     * Perform a query by combining all current settings and the
+     * information passed into this method.
+     *
+     * @param db the database to query on
+     * @param projectionIn A list of which columns to return. Passing
+     *   null will return all columns, which is discouraged to prevent
+     *   reading data from storage that isn't going to be used.
+     * @param selection A filter declaring which rows to return,
+     *   formatted as an SQL {@code WHERE} clause (excluding the {@code WHERE}
+     *   itself). Passing null will return all rows for the given URL.
+     * @param selectionArgs You may include ?s in selection, which
+     *   will be replaced by the values from selectionArgs, in order
+     *   that they appear in the selection. The values will be bound
+     *   as Strings.
+     * @param groupBy A filter declaring how to group rows, formatted
+     *   as an SQL {@code GROUP BY} clause (excluding the {@code GROUP BY}
+     *   itself). Passing null will cause the rows to not be grouped.
+     * @param having A filter declare which row groups to include in
+     *   the cursor, if row grouping is being used, formatted as an
+     *   SQL {@code HAVING} clause (excluding the {@code HAVING} itself).  Passing
+     *   null will cause all row groups to be included, and is
+     *   required when row grouping is not being used.
+     * @param sortOrder How to order the rows, formatted as an SQL
+     *   {@code ORDER BY} clause (excluding the {@code ORDER BY} itself). Passing null
+     *   will use the default sort order, which may be unordered.
+     * @param limit Limits the number of rows returned by the query,
+     *   formatted as {@code LIMIT} clause. Passing null denotes no {@code LIMIT} clause.
+     * @param cancellationSignal A signal to cancel the operation in progress, or null if none.
+     * If the operation is canceled, then {@link OperationCanceledException} will be thrown
+     * when the query is executed.
+     * @return a cursor over the result set
+     * @see android.content.ContentResolver#query(android.net.Uri, String[],
+     *      String, String[], String)
+     */
+    public Cursor query(SQLiteDatabase db, String[] projectionIn,
+            String selection, String[] selectionArgs, String groupBy,
+            String having, String sortOrder, String limit, CancellationSignal cancellationSignal) {
+        if (mTables == null) {
+            return null;
+        }
+
+        final String sql;
+        final String unwrappedSql = buildQuery(
+                projectionIn, selection, groupBy, having,
+                sortOrder, limit);
+
+        if (isStrictColumns()) {
+            enforceStrictColumns(projectionIn);
+        }
+        if (isStrictGrammar()) {
+            enforceStrictGrammar(selection, groupBy, having, sortOrder, limit);
+        }
+        if (isStrict()) {
+            // Validate the user-supplied selection to detect syntactic anomalies
+            // in the selection string that could indicate a SQL injection attempt.
+            // The idea is to ensure that the selection clause is a valid SQL expression
+            // by compiling it twice: once wrapped in parentheses and once as
+            // originally specified. An attacker cannot create an expression that
+            // would escape the SQL expression while maintaining balanced parentheses
+            // in both the wrapped and original forms.
+
+            // NOTE: The ordering of the below operations is important; we must
+            // execute the wrapped query to ensure the untrusted clause has been
+            // fully isolated.
+
+            // Validate the unwrapped query
+            db.validateSql(unwrappedSql, cancellationSignal); // will throw if query is invalid
+
+            // Execute wrapped query for extra protection
+            final String wrappedSql = buildQuery(projectionIn, wrap(selection), groupBy,
+                    wrap(having), sortOrder, limit);
+            sql = wrappedSql;
+        } else {
+            // Execute unwrapped query
+            sql = unwrappedSql;
+        }
+
+        final String[] sqlArgs = selectionArgs;
+        if (Log.isLoggable(TAG, Log.DEBUG)) {
+            if (Build.IS_DEBUGGABLE) {
+                Log.d(TAG, sql + " with args " + Arrays.toString(sqlArgs));
+            } else {
+                Log.d(TAG, sql);
+            }
+        }
+        return db.rawQueryWithFactory(
+                mFactory, sql, sqlArgs,
+                SQLiteDatabase.findEditTable(mTables),
+                cancellationSignal); // will throw if query is invalid
+    }
+
+    /**
+     * Perform an insert by combining all current settings and the
+     * information passed into this method.
+     *
+     * @param db the database to insert on
+     * @return the row ID of the newly inserted row, or -1 if an error occurred
+     */
+    public long insert(@NonNull SQLiteDatabase db, @NonNull ContentValues values) {
+        Objects.requireNonNull(mTables, "No tables defined");
+        Objects.requireNonNull(db, "No database defined");
+        Objects.requireNonNull(values, "No values defined");
+
+        if (isStrictColumns()) {
+            enforceStrictColumns(values);
+        }
+
+        final String sql = buildInsert(values);
+
+        final ArrayMap<String, Object> rawValues = values.getValues();
+        final int valuesLength = rawValues.size();
+        final Object[] sqlArgs = new Object[valuesLength];
+        for (int i = 0; i < sqlArgs.length; i++) {
+            sqlArgs[i] = rawValues.valueAt(i);
+        }
+        if (Log.isLoggable(TAG, Log.DEBUG)) {
+            if (Build.IS_DEBUGGABLE) {
+                Log.d(TAG, sql + " with args " + Arrays.toString(sqlArgs));
+            } else {
+                Log.d(TAG, sql);
+            }
+        }
+        return db.executeSql(sql, sqlArgs);
+    }
+
+    /**
+     * Perform an update by combining all current settings and the
+     * information passed into this method.
+     *
+     * @param db the database to update on
+     * @param selection A filter declaring which rows to return,
+     *   formatted as an SQL {@code WHERE} clause (excluding the {@code WHERE}
+     *   itself). Passing null will return all rows for the given URL.
+     * @param selectionArgs You may include ?s in selection, which
+     *   will be replaced by the values from selectionArgs, in order
+     *   that they appear in the selection. The values will be bound
+     *   as Strings.
+     * @return the number of rows updated
+     */
+    public int update(@NonNull SQLiteDatabase db, @NonNull ContentValues values,
+            @Nullable String selection, @Nullable String[] selectionArgs) {
+        Objects.requireNonNull(mTables, "No tables defined");
+        Objects.requireNonNull(db, "No database defined");
+        Objects.requireNonNull(values, "No values defined");
+
+        final String sql;
+        final String unwrappedSql = buildUpdate(values, selection);
+
+        if (isStrictColumns()) {
+            enforceStrictColumns(values);
+        }
+        if (isStrictGrammar()) {
+            enforceStrictGrammar(selection, null, null, null, null);
+        }
+        if (isStrict()) {
+            // Validate the user-supplied selection to detect syntactic anomalies
+            // in the selection string that could indicate a SQL injection attempt.
+            // The idea is to ensure that the selection clause is a valid SQL expression
+            // by compiling it twice: once wrapped in parentheses and once as
+            // originally specified. An attacker cannot create an expression that
+            // would escape the SQL expression while maintaining balanced parentheses
+            // in both the wrapped and original forms.
+
+            // NOTE: The ordering of the below operations is important; we must
+            // execute the wrapped query to ensure the untrusted clause has been
+            // fully isolated.
+
+            // Validate the unwrapped query
+            db.validateSql(unwrappedSql, null); // will throw if query is invalid
+
+            // Execute wrapped query for extra protection
+            final String wrappedSql = buildUpdate(values, wrap(selection));
+            sql = wrappedSql;
+        } else {
+            // Execute unwrapped query
+            sql = unwrappedSql;
+        }
+
+        if (selectionArgs == null) {
+            selectionArgs = EmptyArray.STRING;
+        }
+        final ArrayMap<String, Object> rawValues = values.getValues();
+        final int valuesLength = rawValues.size();
+        final Object[] sqlArgs = new Object[valuesLength + selectionArgs.length];
+        for (int i = 0; i < sqlArgs.length; i++) {
+            if (i < valuesLength) {
+                sqlArgs[i] = rawValues.valueAt(i);
+            } else {
+                sqlArgs[i] = selectionArgs[i - valuesLength];
+            }
+        }
+        if (Log.isLoggable(TAG, Log.DEBUG)) {
+            if (Build.IS_DEBUGGABLE) {
+                Log.d(TAG, sql + " with args " + Arrays.toString(sqlArgs));
+            } else {
+                Log.d(TAG, sql);
+            }
+        }
+        return db.executeSql(sql, sqlArgs);
+    }
+
+    /**
+     * Perform a delete by combining all current settings and the
+     * information passed into this method.
+     *
+     * @param db the database to delete on
+     * @param selection A filter declaring which rows to return,
+     *   formatted as an SQL {@code WHERE} clause (excluding the {@code WHERE}
+     *   itself). Passing null will return all rows for the given URL.
+     * @param selectionArgs You may include ?s in selection, which
+     *   will be replaced by the values from selectionArgs, in order
+     *   that they appear in the selection. The values will be bound
+     *   as Strings.
+     * @return the number of rows deleted
+     */
+    public int delete(@NonNull SQLiteDatabase db, @Nullable String selection,
+            @Nullable String[] selectionArgs) {
+        Objects.requireNonNull(mTables, "No tables defined");
+        Objects.requireNonNull(db, "No database defined");
+
+        final String sql;
+        final String unwrappedSql = buildDelete(selection);
+
+        if (isStrictGrammar()) {
+            enforceStrictGrammar(selection, null, null, null, null);
+        }
+        if (isStrict()) {
+            // Validate the user-supplied selection to detect syntactic anomalies
+            // in the selection string that could indicate a SQL injection attempt.
+            // The idea is to ensure that the selection clause is a valid SQL expression
+            // by compiling it twice: once wrapped in parentheses and once as
+            // originally specified. An attacker cannot create an expression that
+            // would escape the SQL expression while maintaining balanced parentheses
+            // in both the wrapped and original forms.
+
+            // NOTE: The ordering of the below operations is important; we must
+            // execute the wrapped query to ensure the untrusted clause has been
+            // fully isolated.
+
+            // Validate the unwrapped query
+            db.validateSql(unwrappedSql, null); // will throw if query is invalid
+
+            // Execute wrapped query for extra protection
+            final String wrappedSql = buildDelete(wrap(selection));
+            sql = wrappedSql;
+        } else {
+            // Execute unwrapped query
+            sql = unwrappedSql;
+        }
+
+        final String[] sqlArgs = selectionArgs;
+        if (Log.isLoggable(TAG, Log.DEBUG)) {
+            if (Build.IS_DEBUGGABLE) {
+                Log.d(TAG, sql + " with args " + Arrays.toString(sqlArgs));
+            } else {
+                Log.d(TAG, sql);
+            }
+        }
+        return db.executeSql(sql, sqlArgs);
+    }
+
+    private void enforceStrictColumns(@Nullable String[] projection) {
+        Objects.requireNonNull(mProjectionMap, "No projection map defined");
+
+        computeProjection(projection);
+    }
+
+    private void enforceStrictColumns(@NonNull ContentValues values) {
+        Objects.requireNonNull(mProjectionMap, "No projection map defined");
+
+        final ArrayMap<String, Object> rawValues = values.getValues();
+        for (int i = 0; i < rawValues.size(); i++) {
+            final String column = rawValues.keyAt(i);
+            if (!mProjectionMap.containsKey(column)) {
+                throw new IllegalArgumentException("Invalid column " + column);
+            }
+        }
+    }
+
+    private void enforceStrictGrammar(@Nullable String selection, @Nullable String groupBy,
+            @Nullable String having, @Nullable String sortOrder, @Nullable String limit) {
+        SQLiteTokenizer.tokenize(selection, SQLiteTokenizer.OPTION_NONE,
+                this::enforceStrictToken);
+        SQLiteTokenizer.tokenize(groupBy, SQLiteTokenizer.OPTION_NONE,
+                this::enforceStrictToken);
+        SQLiteTokenizer.tokenize(having, SQLiteTokenizer.OPTION_NONE,
+                this::enforceStrictToken);
+        SQLiteTokenizer.tokenize(sortOrder, SQLiteTokenizer.OPTION_NONE,
+                this::enforceStrictToken);
+        SQLiteTokenizer.tokenize(limit, SQLiteTokenizer.OPTION_NONE,
+                this::enforceStrictToken);
+    }
+
+    private void enforceStrictToken(@NonNull String token) {
+        if (isTableOrColumn(token)) return;
+        if (SQLiteTokenizer.isFunction(token)) return;
+        if (SQLiteTokenizer.isType(token)) return;
+
+        // Carefully block any tokens that are attempting to jump across query
+        // clauses or create subqueries, since they could leak data that should
+        // have been filtered by the trusted where clause
+        boolean isAllowedKeyword = SQLiteTokenizer.isKeyword(token);
+        switch (token.toUpperCase(Locale.US)) {
+            case "SELECT":
+            case "FROM":
+            case "WHERE":
+            case "GROUP":
+            case "HAVING":
+            case "WINDOW":
+            case "VALUES":
+            case "ORDER":
+            case "LIMIT":
+                isAllowedKeyword = false;
+                break;
+        }
+        if (!isAllowedKeyword) {
+            throw new IllegalArgumentException("Invalid token " + token);
+        }
+    }
+
+    /**
+     * Construct a {@code SELECT} statement suitable for use in a group of
+     * {@code SELECT} statements that will be joined through {@code UNION} operators
+     * in buildUnionQuery.
+     *
+     * @param projectionIn A list of which columns to return. Passing
+     *    null will return all columns, which is discouraged to
+     *    prevent reading data from storage that isn't going to be
+     *    used.
+     * @param selection A filter declaring which rows to return,
+     *   formatted as an SQL {@code WHERE} clause (excluding the {@code WHERE}
+     *   itself).  Passing null will return all rows for the given
+     *   URL.
+     * @param groupBy A filter declaring how to group rows, formatted
+     *   as an SQL {@code GROUP BY} clause (excluding the {@code GROUP BY} itself).
+     *   Passing null will cause the rows to not be grouped.
+     * @param having A filter declare which row groups to include in
+     *   the cursor, if row grouping is being used, formatted as an
+     *   SQL {@code HAVING} clause (excluding the {@code HAVING} itself).  Passing
+     *   null will cause all row groups to be included, and is
+     *   required when row grouping is not being used.
+     * @param sortOrder How to order the rows, formatted as an SQL
+     *   {@code ORDER BY} clause (excluding the {@code ORDER BY} itself). Passing null
+     *   will use the default sort order, which may be unordered.
+     * @param limit Limits the number of rows returned by the query,
+     *   formatted as {@code LIMIT} clause. Passing null denotes no {@code LIMIT} clause.
+     * @return the resulting SQL {@code SELECT} statement
+     */
+    public String buildQuery(
+            String[] projectionIn, String selection, String groupBy,
+            String having, String sortOrder, String limit) {
+        String[] projection = computeProjection(projectionIn);
+        String where = computeWhere(selection);
+
+        return buildQueryString(
+                mDistinct, mTables, projection, where,
+                groupBy, having, sortOrder, limit);
+    }
+
+    /**
+     * @deprecated This method's signature is misleading since no SQL parameter
+     * substitution is carried out.  The selection arguments parameter does not get
+     * used at all.  To avoid confusion, call
+     * {@link #buildQuery(String[], String, String, String, String, String)} instead.
+     */
+    @Deprecated
+    public String buildQuery(
+            String[] projectionIn, String selection, String[] selectionArgs,
+            String groupBy, String having, String sortOrder, String limit) {
+        return buildQuery(projectionIn, selection, groupBy, having, sortOrder, limit);
+    }
+
+    /** {@hide} */
+    public String buildInsert(ContentValues values) {
+        if (values == null || values.isEmpty()) {
+            throw new IllegalArgumentException("Empty values");
+        }
+
+        StringBuilder sql = new StringBuilder(120);
+        sql.append("INSERT INTO ");
+        sql.append(SQLiteDatabase.findEditTable(mTables));
+        sql.append(" (");
+
+        final ArrayMap<String, Object> rawValues = values.getValues();
+        for (int i = 0; i < rawValues.size(); i++) {
+            if (i > 0) {
+                sql.append(',');
+            }
+            sql.append(rawValues.keyAt(i));
+        }
+        sql.append(") VALUES (");
+        for (int i = 0; i < rawValues.size(); i++) {
+            if (i > 0) {
+                sql.append(',');
+            }
+            sql.append('?');
+        }
+        sql.append(")");
+        return sql.toString();
+    }
+
+    /** {@hide} */
+    public String buildUpdate(ContentValues values, String selection) {
+        if (values == null || values.isEmpty()) {
+            throw new IllegalArgumentException("Empty values");
+        }
+
+        StringBuilder sql = new StringBuilder(120);
+        sql.append("UPDATE ");
+        sql.append(SQLiteDatabase.findEditTable(mTables));
+        sql.append(" SET ");
+
+        final ArrayMap<String, Object> rawValues = values.getValues();
+        for (int i = 0; i < rawValues.size(); i++) {
+            if (i > 0) {
+                sql.append(',');
+            }
+            sql.append(rawValues.keyAt(i));
+            sql.append("=?");
+        }
+
+        final String where = computeWhere(selection);
+        appendClause(sql, " WHERE ", where);
+        return sql.toString();
+    }
+
+    /** {@hide} */
+    public String buildDelete(String selection) {
+        StringBuilder sql = new StringBuilder(120);
+        sql.append("DELETE FROM ");
+        sql.append(SQLiteDatabase.findEditTable(mTables));
+
+        final String where = computeWhere(selection);
+        appendClause(sql, " WHERE ", where);
+        return sql.toString();
+    }
+
+    /**
+     * Construct a {@code SELECT} statement suitable for use in a group of
+     * {@code SELECT} statements that will be joined through {@code UNION} operators
+     * in buildUnionQuery.
+     *
+     * @param typeDiscriminatorColumn the name of the result column
+     *   whose cells will contain the name of the table from which
+     *   each row was drawn.
+     * @param unionColumns the names of the columns to appear in the
+     *   result.  This may include columns that do not appear in the
+     *   table this {@code SELECT} is querying (i.e. mTables), but that do
+     *   appear in one of the other tables in the {@code UNION} query that we
+     *   are constructing.
+     * @param columnsPresentInTable a Set of the names of the columns
+     *   that appear in this table (i.e. in the table whose name is
+     *   mTables).  Since columns in unionColumns include columns that
+     *   appear only in other tables, we use this array to distinguish
+     *   which ones actually are present.  Other columns will have
+     *   NULL values for results from this subquery.
+     * @param computedColumnsOffset all columns in unionColumns before
+     *   this index are included under the assumption that they're
+     *   computed and therefore won't appear in columnsPresentInTable,
+     *   e.g. "date * 1000 as normalized_date"
+     * @param typeDiscriminatorValue the value used for the
+     *   type-discriminator column in this subquery
+     * @param selection A filter declaring which rows to return,
+     *   formatted as an SQL {@code WHERE} clause (excluding the {@code WHERE}
+     *   itself).  Passing null will return all rows for the given
+     *   URL.
+     * @param groupBy A filter declaring how to group rows, formatted
+     *   as an SQL {@code GROUP BY} clause (excluding the {@code GROUP BY} itself).
+     *   Passing null will cause the rows to not be grouped.
+     * @param having A filter declare which row groups to include in
+     *   the cursor, if row grouping is being used, formatted as an
+     *   SQL {@code HAVING} clause (excluding the {@code HAVING} itself).  Passing
+     *   null will cause all row groups to be included, and is
+     *   required when row grouping is not being used.
+     * @return the resulting SQL {@code SELECT} statement
+     */
+    public String buildUnionSubQuery(
+            String typeDiscriminatorColumn,
+            String[] unionColumns,
+            Set<String> columnsPresentInTable,
+            int computedColumnsOffset,
+            String typeDiscriminatorValue,
+            String selection,
+            String groupBy,
+            String having) {
+        int unionColumnsCount = unionColumns.length;
+        String[] projectionIn = new String[unionColumnsCount];
+
+        for (int i = 0; i < unionColumnsCount; i++) {
+            String unionColumn = unionColumns[i];
+
+            if (unionColumn.equals(typeDiscriminatorColumn)) {
+                projectionIn[i] = "'" + typeDiscriminatorValue + "' AS "
+                        + typeDiscriminatorColumn;
+            } else if (i <= computedColumnsOffset
+                       || columnsPresentInTable.contains(unionColumn)) {
+                projectionIn[i] = unionColumn;
+            } else {
+                projectionIn[i] = "NULL AS " + unionColumn;
+            }
+        }
+        return buildQuery(
+                projectionIn, selection, groupBy, having,
+                null /* sortOrder */,
+                null /* limit */);
+    }
+
+    /**
+     * @deprecated This method's signature is misleading since no SQL parameter
+     * substitution is carried out.  The selection arguments parameter does not get
+     * used at all.  To avoid confusion, call
+     * {@link #buildUnionSubQuery}
+     * instead.
+     */
+    @Deprecated
+    public String buildUnionSubQuery(
+            String typeDiscriminatorColumn,
+            String[] unionColumns,
+            Set<String> columnsPresentInTable,
+            int computedColumnsOffset,
+            String typeDiscriminatorValue,
+            String selection,
+            String[] selectionArgs,
+            String groupBy,
+            String having) {
+        return buildUnionSubQuery(
+                typeDiscriminatorColumn, unionColumns, columnsPresentInTable,
+                computedColumnsOffset, typeDiscriminatorValue, selection,
+                groupBy, having);
+    }
+
+    /**
+     * Given a set of subqueries, all of which are {@code SELECT} statements,
+     * construct a query that returns the union of what those
+     * subqueries return.
+     * @param subQueries an array of SQL {@code SELECT} statements, all of
+     *   which must have the same columns as the same positions in
+     *   their results
+     * @param sortOrder How to order the rows, formatted as an SQL
+     *   {@code ORDER BY} clause (excluding the {@code ORDER BY} itself).  Passing
+     *   null will use the default sort order, which may be unordered.
+     * @param limit The limit clause, which applies to the entire union result set
+     *
+     * @return the resulting SQL {@code SELECT} statement
+     */
+    public String buildUnionQuery(String[] subQueries, String sortOrder, String limit) {
+        StringBuilder query = new StringBuilder(128);
+        int subQueryCount = subQueries.length;
+        String unionOperator = mDistinct ? " UNION " : " UNION ALL ";
+
+        for (int i = 0; i < subQueryCount; i++) {
+            if (i > 0) {
+                query.append(unionOperator);
+            }
+            query.append(subQueries[i]);
+        }
+        appendClause(query, " ORDER BY ", sortOrder);
+        appendClause(query, " LIMIT ", limit);
+        return query.toString();
+    }
+
+    private static @NonNull String maybeWithOperator(@Nullable String operator,
+            @NonNull String column) {
+        if (operator != null) {
+            return operator + "(" + column + ")";
+        } else {
+            return column;
+        }
+    }
+
+    /** {@hide} */
+    @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023)
+    public @Nullable String[] computeProjection(@Nullable String[] projectionIn) {
+        if (!ArrayUtils.isEmpty(projectionIn)) {
+            String[] projectionOut = new String[projectionIn.length];
+            for (int i = 0; i < projectionIn.length; i++) {
+                projectionOut[i] = computeSingleProjectionOrThrow(projectionIn[i]);
+            }
+            return projectionOut;
+        } else if (mProjectionMap != null) {
+            // Return all columns in projection map.
+            Set<Entry<String, String>> entrySet = mProjectionMap.entrySet();
+            String[] projection = new String[entrySet.size()];
+            Iterator<Entry<String, String>> entryIter = entrySet.iterator();
+            int i = 0;
+
+            while (entryIter.hasNext()) {
+                Entry<String, String> entry = entryIter.next();
+
+                // Don't include the _count column when people ask for no projection.
+                if (entry.getKey().equals(BaseColumns._COUNT)) {
+                    continue;
+                }
+                projection[i++] = entry.getValue();
+            }
+            return projection;
+        }
+        return null;
+    }
+
+    private @NonNull String computeSingleProjectionOrThrow(@NonNull String userColumn) {
+        final String column = computeSingleProjection(userColumn);
+        if (column != null) {
+            return column;
+        } else {
+            throw new IllegalArgumentException("Invalid column " + userColumn);
+        }
+    }
+
+    private @Nullable String computeSingleProjection(@NonNull String userColumn) {
+        // When no mapping provided, anything goes
+        if (mProjectionMap == null) {
+            return userColumn;
+        }
+
+        String operator = null;
+        String column = mProjectionMap.get(userColumn);
+
+        // When no direct match found, look for aggregation
+        if (column == null) {
+            final Matcher matcher = sAggregationPattern.matcher(userColumn);
+            if (matcher.matches()) {
+                operator = matcher.group(1);
+                userColumn = matcher.group(2);
+                column = mProjectionMap.get(userColumn);
+            }
+        }
+
+        if (column != null) {
+            return maybeWithOperator(operator, column);
+        }
+
+        if (mStrictFlags == 0 &&
+                (userColumn.contains(" AS ") || userColumn.contains(" as "))) {
+            /* A column alias already exist */
+            return maybeWithOperator(operator, userColumn);
+        }
+
+        // If greylist is configured, we might be willing to let
+        // this custom column bypass our strict checks.
+        if (mProjectionGreylist != null) {
+            boolean match = false;
+            for (Pattern p : mProjectionGreylist) {
+                if (p.matcher(userColumn).matches()) {
+                    match = true;
+                    break;
+                }
+            }
+
+            if (match) {
+                Log.w(TAG, "Allowing abusive custom column: " + userColumn);
+                return maybeWithOperator(operator, userColumn);
+            }
+        }
+
+        return null;
+    }
+
+    private boolean isTableOrColumn(String token) {
+        if (mTables.equals(token)) return true;
+        return computeSingleProjection(token) != null;
+    }
+
+    /** {@hide} */
+    public @Nullable String computeWhere(@Nullable String selection) {
+        final boolean hasInternal = !TextUtils.isEmpty(mWhereClause);
+        final boolean hasExternal = !TextUtils.isEmpty(selection);
+
+        if (hasInternal || hasExternal) {
+            final StringBuilder where = new StringBuilder();
+            if (hasInternal) {
+                where.append('(').append(mWhereClause).append(')');
+            }
+            if (hasInternal && hasExternal) {
+                where.append(" AND ");
+            }
+            if (hasExternal) {
+                where.append('(').append(selection).append(')');
+            }
+            return where.toString();
+        } else {
+            return null;
+        }
+    }
+
+    /**
+     * Wrap given argument in parenthesis, unless it's {@code null} or
+     * {@code ()}, in which case return it verbatim.
+     */
+    private @Nullable String wrap(@Nullable String arg) {
+        if (TextUtils.isEmpty(arg)) {
+            return arg;
+        } else {
+            return "(" + arg + ")";
+        }
+    }
+}
diff --git a/android/database/sqlite/SQLiteReadOnlyDatabaseException.java b/android/database/sqlite/SQLiteReadOnlyDatabaseException.java
new file mode 100644
index 0000000..5b633c6
--- /dev/null
+++ b/android/database/sqlite/SQLiteReadOnlyDatabaseException.java
@@ -0,0 +1,25 @@
+/*
+ * 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.database.sqlite;
+
+public class SQLiteReadOnlyDatabaseException extends SQLiteException {
+    public SQLiteReadOnlyDatabaseException() {}
+
+    public SQLiteReadOnlyDatabaseException(String error) {
+        super(error);
+    }
+}
diff --git a/android/database/sqlite/SQLiteSession.java b/android/database/sqlite/SQLiteSession.java
new file mode 100644
index 0000000..24b62b8
--- /dev/null
+++ b/android/database/sqlite/SQLiteSession.java
@@ -0,0 +1,965 @@
+/*
+ * Copyright (C) 2011 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.database.sqlite;
+
+import android.compat.annotation.UnsupportedAppUsage;
+import android.database.CursorWindow;
+import android.database.DatabaseUtils;
+import android.os.CancellationSignal;
+import android.os.OperationCanceledException;
+import android.os.ParcelFileDescriptor;
+
+/**
+ * Provides a single client the ability to use a database.
+ *
+ * <h2>About database sessions</h2>
+ * <p>
+ * Database access is always performed using a session.  The session
+ * manages the lifecycle of transactions and database connections.
+ * </p><p>
+ * Sessions can be used to perform both read-only and read-write operations.
+ * There is some advantage to knowing when a session is being used for
+ * read-only purposes because the connection pool can optimize the use
+ * of the available connections to permit multiple read-only operations
+ * to execute in parallel whereas read-write operations may need to be serialized.
+ * </p><p>
+ * When <em>Write Ahead Logging (WAL)</em> is enabled, the database can
+ * execute simultaneous read-only and read-write transactions, provided that
+ * at most one read-write transaction is performed at a time.  When WAL is not
+ * enabled, read-only transactions can execute in parallel but read-write
+ * transactions are mutually exclusive.
+ * </p>
+ *
+ * <h2>Ownership and concurrency guarantees</h2>
+ * <p>
+ * Session objects are not thread-safe.  In fact, session objects are thread-bound.
+ * The {@link SQLiteDatabase} uses a thread-local variable to associate a session
+ * with each thread for the use of that thread alone.  Consequently, each thread
+ * has its own session object and therefore its own transaction state independent
+ * of other threads.
+ * </p><p>
+ * A thread has at most one session per database.  This constraint ensures that
+ * a thread can never use more than one database connection at a time for a
+ * given database.  As the number of available database connections is limited,
+ * if a single thread tried to acquire multiple connections for the same database
+ * at the same time, it might deadlock.  Therefore we allow there to be only
+ * one session (so, at most one connection) per thread per database.
+ * </p>
+ *
+ * <h2>Transactions</h2>
+ * <p>
+ * There are two kinds of transaction: implicit transactions and explicit
+ * transactions.
+ * </p><p>
+ * An implicit transaction is created whenever a database operation is requested
+ * and there is no explicit transaction currently in progress.  An implicit transaction
+ * only lasts for the duration of the database operation in question and then it
+ * is ended.  If the database operation was successful, then its changes are committed.
+ * </p><p>
+ * An explicit transaction is started by calling {@link #beginTransaction} and
+ * specifying the desired transaction mode.  Once an explicit transaction has begun,
+ * all subsequent database operations will be performed as part of that transaction.
+ * To end an explicit transaction, first call {@link #setTransactionSuccessful} if the
+ * transaction was successful, then call {@link #end}.  If the transaction was
+ * marked successful, its changes will be committed, otherwise they will be rolled back.
+ * </p><p>
+ * Explicit transactions can also be nested.  A nested explicit transaction is
+ * started with {@link #beginTransaction}, marked successful with
+ * {@link #setTransactionSuccessful}and ended with {@link #endTransaction}.
+ * If any nested transaction is not marked successful, then the entire transaction
+ * including all of its nested transactions will be rolled back
+ * when the outermost transaction is ended.
+ * </p><p>
+ * To improve concurrency, an explicit transaction can be yielded by calling
+ * {@link #yieldTransaction}.  If there is contention for use of the database,
+ * then yielding ends the current transaction, commits its changes, releases the
+ * database connection for use by another session for a little while, and starts a
+ * new transaction with the same properties as the original one.
+ * Changes committed by {@link #yieldTransaction} cannot be rolled back.
+ * </p><p>
+ * When a transaction is started, the client can provide a {@link SQLiteTransactionListener}
+ * to listen for notifications of transaction-related events.
+ * </p><p>
+ * Recommended usage:
+ * <code><pre>
+ * // First, begin the transaction.
+ * session.beginTransaction(SQLiteSession.TRANSACTION_MODE_DEFERRED, 0);
+ * try {
+ *     // Then do stuff...
+ *     session.execute("INSERT INTO ...", null, 0);
+ *
+ *     // As the very last step before ending the transaction, mark it successful.
+ *     session.setTransactionSuccessful();
+ * } finally {
+ *     // Finally, end the transaction.
+ *     // This statement will commit the transaction if it was marked successful or
+ *     // roll it back otherwise.
+ *     session.endTransaction();
+ * }
+ * </pre></code>
+ * </p>
+ *
+ * <h2>Database connections</h2>
+ * <p>
+ * A {@link SQLiteDatabase} can have multiple active sessions at the same
+ * time.  Each session acquires and releases connections to the database
+ * as needed to perform each requested database transaction.  If all connections
+ * are in use, then database transactions on some sessions will block until a
+ * connection becomes available.
+ * </p><p>
+ * The session acquires a single database connection only for the duration
+ * of a single (implicit or explicit) database transaction, then releases it.
+ * This characteristic allows a small pool of database connections to be shared
+ * efficiently by multiple sessions as long as they are not all trying to perform
+ * database transactions at the same time.
+ * </p>
+ *
+ * <h2>Responsiveness</h2>
+ * <p>
+ * Because there are a limited number of database connections and the session holds
+ * a database connection for the entire duration of a database transaction,
+ * it is important to keep transactions short.  This is especially important
+ * for read-write transactions since they may block other transactions
+ * from executing.  Consider calling {@link #yieldTransaction} periodically
+ * during long-running transactions.
+ * </p><p>
+ * Another important consideration is that transactions that take too long to
+ * run may cause the application UI to become unresponsive.  Even if the transaction
+ * is executed in a background thread, the user will get bored and
+ * frustrated if the application shows no data for several seconds while
+ * a transaction runs.
+ * </p><p>
+ * Guidelines:
+ * <ul>
+ * <li>Do not perform database transactions on the UI thread.</li>
+ * <li>Keep database transactions as short as possible.</li>
+ * <li>Simple queries often run faster than complex queries.</li>
+ * <li>Measure the performance of your database transactions.</li>
+ * <li>Consider what will happen when the size of the data set grows.
+ * A query that works well on 100 rows may struggle with 10,000.</li>
+ * </ul>
+ *
+ * <h2>Reentrance</h2>
+ * <p>
+ * This class must tolerate reentrant execution of SQLite operations because
+ * triggers may call custom SQLite functions that perform additional queries.
+ * </p>
+ *
+ * @hide
+ */
+public final class SQLiteSession {
+    private final SQLiteConnectionPool mConnectionPool;
+
+    private SQLiteConnection mConnection;
+    private int mConnectionFlags;
+    private int mConnectionUseCount;
+    private Transaction mTransactionPool;
+    private Transaction mTransactionStack;
+
+    /**
+     * Transaction mode: Deferred.
+     * <p>
+     * In a deferred transaction, no locks are acquired on the database
+     * until the first operation is performed.  If the first operation is
+     * read-only, then a <code>SHARED</code> lock is acquired, otherwise
+     * a <code>RESERVED</code> lock is acquired.
+     * </p><p>
+     * While holding a <code>SHARED</code> lock, this session is only allowed to
+     * read but other sessions are allowed to read or write.
+     * While holding a <code>RESERVED</code> lock, this session is allowed to read
+     * or write but other sessions are only allowed to read.
+     * </p><p>
+     * Because the lock is only acquired when needed in a deferred transaction,
+     * it is possible for another session to write to the database first before
+     * this session has a chance to do anything.
+     * </p><p>
+     * Corresponds to the SQLite <code>BEGIN DEFERRED</code> transaction mode.
+     * </p>
+     */
+    public static final int TRANSACTION_MODE_DEFERRED = 0;
+
+    /**
+     * Transaction mode: Immediate.
+     * <p>
+     * When an immediate transaction begins, the session acquires a
+     * <code>RESERVED</code> lock.
+     * </p><p>
+     * While holding a <code>RESERVED</code> lock, this session is allowed to read
+     * or write but other sessions are only allowed to read.
+     * </p><p>
+     * Corresponds to the SQLite <code>BEGIN IMMEDIATE</code> transaction mode.
+     * </p>
+     */
+    public static final int TRANSACTION_MODE_IMMEDIATE = 1;
+
+    /**
+     * Transaction mode: Exclusive.
+     * <p>
+     * When an exclusive transaction begins, the session acquires an
+     * <code>EXCLUSIVE</code> lock.
+     * </p><p>
+     * While holding an <code>EXCLUSIVE</code> lock, this session is allowed to read
+     * or write but no other sessions are allowed to access the database.
+     * </p><p>
+     * Corresponds to the SQLite <code>BEGIN EXCLUSIVE</code> transaction mode.
+     * </p>
+     */
+    public static final int TRANSACTION_MODE_EXCLUSIVE = 2;
+
+    /**
+     * Creates a session bound to the specified connection pool.
+     *
+     * @param connectionPool The connection pool.
+     */
+    public SQLiteSession(SQLiteConnectionPool connectionPool) {
+        if (connectionPool == null) {
+            throw new IllegalArgumentException("connectionPool must not be null");
+        }
+
+        mConnectionPool = connectionPool;
+    }
+
+    /**
+     * Returns true if the session has a transaction in progress.
+     *
+     * @return True if the session has a transaction in progress.
+     */
+    public boolean hasTransaction() {
+        return mTransactionStack != null;
+    }
+
+    /**
+     * Returns true if the session has a nested transaction in progress.
+     *
+     * @return True if the session has a nested transaction in progress.
+     */
+    public boolean hasNestedTransaction() {
+        return mTransactionStack != null && mTransactionStack.mParent != null;
+    }
+
+    /**
+     * Returns true if the session has an active database connection.
+     *
+     * @return True if the session has an active database connection.
+     */
+    public boolean hasConnection() {
+        return mConnection != null;
+    }
+
+    /**
+     * Begins a transaction.
+     * <p>
+     * Transactions may nest.  If the transaction is not in progress,
+     * then a database connection is obtained and a new transaction is started.
+     * Otherwise, a nested transaction is started.
+     * </p><p>
+     * Each call to {@link #beginTransaction} must be matched exactly by a call
+     * to {@link #endTransaction}.  To mark a transaction as successful,
+     * call {@link #setTransactionSuccessful} before calling {@link #endTransaction}.
+     * If the transaction is not successful, or if any of its nested
+     * transactions were not successful, then the entire transaction will
+     * be rolled back when the outermost transaction is ended.
+     * </p>
+     *
+     * @param transactionMode The transaction mode.  One of: {@link #TRANSACTION_MODE_DEFERRED},
+     * {@link #TRANSACTION_MODE_IMMEDIATE}, or {@link #TRANSACTION_MODE_EXCLUSIVE}.
+     * Ignored when creating a nested transaction.
+     * @param transactionListener The transaction listener, or null if none.
+     * @param connectionFlags The connection flags to use if a connection must be
+     * acquired by this operation.  Refer to {@link SQLiteConnectionPool}.
+     * @param cancellationSignal A signal to cancel the operation in progress, or null if none.
+     *
+     * @throws IllegalStateException if {@link #setTransactionSuccessful} has already been
+     * called for the current transaction.
+     * @throws SQLiteException if an error occurs.
+     * @throws OperationCanceledException if the operation was canceled.
+     *
+     * @see #setTransactionSuccessful
+     * @see #yieldTransaction
+     * @see #endTransaction
+     */
+    @UnsupportedAppUsage
+    public void beginTransaction(int transactionMode,
+            SQLiteTransactionListener transactionListener, int connectionFlags,
+            CancellationSignal cancellationSignal) {
+        throwIfTransactionMarkedSuccessful();
+        beginTransactionUnchecked(transactionMode, transactionListener, connectionFlags,
+                cancellationSignal);
+    }
+
+    private void beginTransactionUnchecked(int transactionMode,
+            SQLiteTransactionListener transactionListener, int connectionFlags,
+            CancellationSignal cancellationSignal) {
+        if (cancellationSignal != null) {
+            cancellationSignal.throwIfCanceled();
+        }
+
+        if (mTransactionStack == null) {
+            acquireConnection(null, connectionFlags, cancellationSignal); // might throw
+        }
+        try {
+            // Set up the transaction such that we can back out safely
+            // in case we fail part way.
+            if (mTransactionStack == null) {
+                // Execute SQL might throw a runtime exception.
+                switch (transactionMode) {
+                    case TRANSACTION_MODE_IMMEDIATE:
+                        mConnection.execute("BEGIN IMMEDIATE;", null,
+                                cancellationSignal); // might throw
+                        break;
+                    case TRANSACTION_MODE_EXCLUSIVE:
+                        mConnection.execute("BEGIN EXCLUSIVE;", null,
+                                cancellationSignal); // might throw
+                        break;
+                    default:
+                        mConnection.execute("BEGIN;", null, cancellationSignal); // might throw
+                        break;
+                }
+            }
+
+            // Listener might throw a runtime exception.
+            if (transactionListener != null) {
+                try {
+                    transactionListener.onBegin(); // might throw
+                } catch (RuntimeException ex) {
+                    if (mTransactionStack == null) {
+                        mConnection.execute("ROLLBACK;", null, cancellationSignal); // might throw
+                    }
+                    throw ex;
+                }
+            }
+
+            // Bookkeeping can't throw, except an OOM, which is just too bad...
+            Transaction transaction = obtainTransaction(transactionMode, transactionListener);
+            transaction.mParent = mTransactionStack;
+            mTransactionStack = transaction;
+        } finally {
+            if (mTransactionStack == null) {
+                releaseConnection(); // might throw
+            }
+        }
+    }
+
+    /**
+     * Marks the current transaction as having completed successfully.
+     * <p>
+     * This method can be called at most once between {@link #beginTransaction} and
+     * {@link #endTransaction} to indicate that the changes made by the transaction should be
+     * committed.  If this method is not called, the changes will be rolled back
+     * when the transaction is ended.
+     * </p>
+     *
+     * @throws IllegalStateException if there is no current transaction, or if
+     * {@link #setTransactionSuccessful} has already been called for the current transaction.
+     *
+     * @see #beginTransaction
+     * @see #endTransaction
+     */
+    public void setTransactionSuccessful() {
+        throwIfNoTransaction();
+        throwIfTransactionMarkedSuccessful();
+
+        mTransactionStack.mMarkedSuccessful = true;
+    }
+
+    /**
+     * Ends the current transaction and commits or rolls back changes.
+     * <p>
+     * If this is the outermost transaction (not nested within any other
+     * transaction), then the changes are committed if {@link #setTransactionSuccessful}
+     * was called or rolled back otherwise.
+     * </p><p>
+     * This method must be called exactly once for each call to {@link #beginTransaction}.
+     * </p>
+     *
+     * @param cancellationSignal A signal to cancel the operation in progress, or null if none.
+     *
+     * @throws IllegalStateException if there is no current transaction.
+     * @throws SQLiteException if an error occurs.
+     * @throws OperationCanceledException if the operation was canceled.
+     *
+     * @see #beginTransaction
+     * @see #setTransactionSuccessful
+     * @see #yieldTransaction
+     */
+    public void endTransaction(CancellationSignal cancellationSignal) {
+        throwIfNoTransaction();
+        assert mConnection != null;
+
+        endTransactionUnchecked(cancellationSignal, false);
+    }
+
+    private void endTransactionUnchecked(CancellationSignal cancellationSignal, boolean yielding) {
+        if (cancellationSignal != null) {
+            cancellationSignal.throwIfCanceled();
+        }
+
+        final Transaction top = mTransactionStack;
+        boolean successful = (top.mMarkedSuccessful || yielding) && !top.mChildFailed;
+
+        RuntimeException listenerException = null;
+        final SQLiteTransactionListener listener = top.mListener;
+        if (listener != null) {
+            try {
+                if (successful) {
+                    listener.onCommit(); // might throw
+                } else {
+                    listener.onRollback(); // might throw
+                }
+            } catch (RuntimeException ex) {
+                listenerException = ex;
+                successful = false;
+            }
+        }
+
+        mTransactionStack = top.mParent;
+        recycleTransaction(top);
+
+        if (mTransactionStack != null) {
+            if (!successful) {
+                mTransactionStack.mChildFailed = true;
+            }
+        } else {
+            try {
+                if (successful) {
+                    mConnection.execute("COMMIT;", null, cancellationSignal); // might throw
+                } else {
+                    mConnection.execute("ROLLBACK;", null, cancellationSignal); // might throw
+                }
+            } finally {
+                releaseConnection(); // might throw
+            }
+        }
+
+        if (listenerException != null) {
+            throw listenerException;
+        }
+    }
+
+    /**
+     * Temporarily ends a transaction to let other threads have use of
+     * the database.  Begins a new transaction after a specified delay.
+     * <p>
+     * If there are other threads waiting to acquire connections,
+     * then the current transaction is committed and the database
+     * connection is released.  After a short delay, a new transaction
+     * is started.
+     * </p><p>
+     * The transaction is assumed to be successful so far.  Do not call
+     * {@link #setTransactionSuccessful()} before calling this method.
+     * This method will fail if the transaction has already been marked
+     * successful.
+     * </p><p>
+     * The changes that were committed by a yield cannot be rolled back later.
+     * </p><p>
+     * Before this method was called, there must already have been
+     * a transaction in progress.  When this method returns, there will
+     * still be a transaction in progress, either the same one as before
+     * or a new one if the transaction was actually yielded.
+     * </p><p>
+     * This method should not be called when there is a nested transaction
+     * in progress because it is not possible to yield a nested transaction.
+     * If <code>throwIfNested</code> is true, then attempting to yield
+     * a nested transaction will throw {@link IllegalStateException}, otherwise
+     * the method will return <code>false</code> in that case.
+     * </p><p>
+     * If there is no nested transaction in progress but a previous nested
+     * transaction failed, then the transaction is not yielded (because it
+     * must be rolled back) and this method returns <code>false</code>.
+     * </p>
+     *
+     * @param sleepAfterYieldDelayMillis A delay time to wait after yielding
+     * the database connection to allow other threads some time to run.
+     * If the value is less than or equal to zero, there will be no additional
+     * delay beyond the time it will take to begin a new transaction.
+     * @param throwIfUnsafe If true, then instead of returning false when no
+     * transaction is in progress, a nested transaction is in progress, or when
+     * the transaction has already been marked successful, throws {@link IllegalStateException}.
+     * @param cancellationSignal A signal to cancel the operation in progress, or null if none.
+     * @return True if the transaction was actually yielded.
+     *
+     * @throws IllegalStateException if <code>throwIfNested</code> is true and
+     * there is no current transaction, there is a nested transaction in progress or
+     * if {@link #setTransactionSuccessful} has already been called for the current transaction.
+     * @throws SQLiteException if an error occurs.
+     * @throws OperationCanceledException if the operation was canceled.
+     *
+     * @see #beginTransaction
+     * @see #endTransaction
+     */
+    public boolean yieldTransaction(long sleepAfterYieldDelayMillis, boolean throwIfUnsafe,
+            CancellationSignal cancellationSignal) {
+        if (throwIfUnsafe) {
+            throwIfNoTransaction();
+            throwIfTransactionMarkedSuccessful();
+            throwIfNestedTransaction();
+        } else {
+            if (mTransactionStack == null || mTransactionStack.mMarkedSuccessful
+                    || mTransactionStack.mParent != null) {
+                return false;
+            }
+        }
+        assert mConnection != null;
+
+        if (mTransactionStack.mChildFailed) {
+            return false;
+        }
+
+        return yieldTransactionUnchecked(sleepAfterYieldDelayMillis,
+                cancellationSignal); // might throw
+    }
+
+    private boolean yieldTransactionUnchecked(long sleepAfterYieldDelayMillis,
+            CancellationSignal cancellationSignal) {
+        if (cancellationSignal != null) {
+            cancellationSignal.throwIfCanceled();
+        }
+
+        if (!mConnectionPool.shouldYieldConnection(mConnection, mConnectionFlags)) {
+            return false;
+        }
+
+        final int transactionMode = mTransactionStack.mMode;
+        final SQLiteTransactionListener listener = mTransactionStack.mListener;
+        final int connectionFlags = mConnectionFlags;
+        endTransactionUnchecked(cancellationSignal, true); // might throw
+
+        if (sleepAfterYieldDelayMillis > 0) {
+            try {
+                Thread.sleep(sleepAfterYieldDelayMillis);
+            } catch (InterruptedException ex) {
+                // we have been interrupted, that's all we need to do
+            }
+        }
+
+        beginTransactionUnchecked(transactionMode, listener, connectionFlags,
+                cancellationSignal); // might throw
+        return true;
+    }
+
+    /**
+     * Prepares a statement for execution but does not bind its parameters or execute it.
+     * <p>
+     * This method can be used to check for syntax errors during compilation
+     * prior to execution of the statement.  If the {@code outStatementInfo} argument
+     * is not null, the provided {@link SQLiteStatementInfo} object is populated
+     * with information about the statement.
+     * </p><p>
+     * A prepared statement makes no reference to the arguments that may eventually
+     * be bound to it, consequently it it possible to cache certain prepared statements
+     * such as SELECT or INSERT/UPDATE statements.  If the statement is cacheable,
+     * then it will be stored in the cache for later and reused if possible.
+     * </p>
+     *
+     * @param sql The SQL statement to prepare.
+     * @param connectionFlags The connection flags to use if a connection must be
+     * acquired by this operation.  Refer to {@link SQLiteConnectionPool}.
+     * @param cancellationSignal A signal to cancel the operation in progress, or null if none.
+     * @param outStatementInfo The {@link SQLiteStatementInfo} object to populate
+     * with information about the statement, or null if none.
+     *
+     * @throws SQLiteException if an error occurs, such as a syntax error.
+     * @throws OperationCanceledException if the operation was canceled.
+     */
+    public void prepare(String sql, int connectionFlags, CancellationSignal cancellationSignal,
+            SQLiteStatementInfo outStatementInfo) {
+        if (sql == null) {
+            throw new IllegalArgumentException("sql must not be null.");
+        }
+
+        if (cancellationSignal != null) {
+            cancellationSignal.throwIfCanceled();
+        }
+
+        acquireConnection(sql, connectionFlags, cancellationSignal); // might throw
+        try {
+            mConnection.prepare(sql, outStatementInfo); // might throw
+        } finally {
+            releaseConnection(); // might throw
+        }
+    }
+
+    /**
+     * Executes a statement that does not return a result.
+     *
+     * @param sql The SQL statement to execute.
+     * @param bindArgs The arguments to bind, or null if none.
+     * @param connectionFlags The connection flags to use if a connection must be
+     * acquired by this operation.  Refer to {@link SQLiteConnectionPool}.
+     * @param cancellationSignal A signal to cancel the operation in progress, or null if none.
+     *
+     * @throws SQLiteException if an error occurs, such as a syntax error
+     * or invalid number of bind arguments.
+     * @throws OperationCanceledException if the operation was canceled.
+     */
+    public void execute(String sql, Object[] bindArgs, int connectionFlags,
+            CancellationSignal cancellationSignal) {
+        if (sql == null) {
+            throw new IllegalArgumentException("sql must not be null.");
+        }
+
+        if (executeSpecial(sql, bindArgs, connectionFlags, cancellationSignal)) {
+            return;
+        }
+
+        acquireConnection(sql, connectionFlags, cancellationSignal); // might throw
+        try {
+            mConnection.execute(sql, bindArgs, cancellationSignal); // might throw
+        } finally {
+            releaseConnection(); // might throw
+        }
+    }
+
+    /**
+     * Executes a statement that returns a single <code>long</code> result.
+     *
+     * @param sql The SQL statement to execute.
+     * @param bindArgs The arguments to bind, or null if none.
+     * @param connectionFlags The connection flags to use if a connection must be
+     * acquired by this operation.  Refer to {@link SQLiteConnectionPool}.
+     * @param cancellationSignal A signal to cancel the operation in progress, or null if none.
+     * @return The value of the first column in the first row of the result set
+     * as a <code>long</code>, or zero if none.
+     *
+     * @throws SQLiteException if an error occurs, such as a syntax error
+     * or invalid number of bind arguments.
+     * @throws OperationCanceledException if the operation was canceled.
+     */
+    public long executeForLong(String sql, Object[] bindArgs, int connectionFlags,
+            CancellationSignal cancellationSignal) {
+        if (sql == null) {
+            throw new IllegalArgumentException("sql must not be null.");
+        }
+
+        if (executeSpecial(sql, bindArgs, connectionFlags, cancellationSignal)) {
+            return 0;
+        }
+
+        acquireConnection(sql, connectionFlags, cancellationSignal); // might throw
+        try {
+            return mConnection.executeForLong(sql, bindArgs, cancellationSignal); // might throw
+        } finally {
+            releaseConnection(); // might throw
+        }
+    }
+
+    /**
+     * Executes a statement that returns a single {@link String} result.
+     *
+     * @param sql The SQL statement to execute.
+     * @param bindArgs The arguments to bind, or null if none.
+     * @param connectionFlags The connection flags to use if a connection must be
+     * acquired by this operation.  Refer to {@link SQLiteConnectionPool}.
+     * @param cancellationSignal A signal to cancel the operation in progress, or null if none.
+     * @return The value of the first column in the first row of the result set
+     * as a <code>String</code>, or null if none.
+     *
+     * @throws SQLiteException if an error occurs, such as a syntax error
+     * or invalid number of bind arguments.
+     * @throws OperationCanceledException if the operation was canceled.
+     */
+    public String executeForString(String sql, Object[] bindArgs, int connectionFlags,
+            CancellationSignal cancellationSignal) {
+        if (sql == null) {
+            throw new IllegalArgumentException("sql must not be null.");
+        }
+
+        if (executeSpecial(sql, bindArgs, connectionFlags, cancellationSignal)) {
+            return null;
+        }
+
+        acquireConnection(sql, connectionFlags, cancellationSignal); // might throw
+        try {
+            return mConnection.executeForString(sql, bindArgs, cancellationSignal); // might throw
+        } finally {
+            releaseConnection(); // might throw
+        }
+    }
+
+    /**
+     * Executes a statement that returns a single BLOB result as a
+     * file descriptor to a shared memory region.
+     *
+     * @param sql The SQL statement to execute.
+     * @param bindArgs The arguments to bind, or null if none.
+     * @param connectionFlags The connection flags to use if a connection must be
+     * acquired by this operation.  Refer to {@link SQLiteConnectionPool}.
+     * @param cancellationSignal A signal to cancel the operation in progress, or null if none.
+     * @return The file descriptor for a shared memory region that contains
+     * the value of the first column in the first row of the result set as a BLOB,
+     * or null if none.
+     *
+     * @throws SQLiteException if an error occurs, such as a syntax error
+     * or invalid number of bind arguments.
+     * @throws OperationCanceledException if the operation was canceled.
+     */
+    public ParcelFileDescriptor executeForBlobFileDescriptor(String sql, Object[] bindArgs,
+            int connectionFlags, CancellationSignal cancellationSignal) {
+        if (sql == null) {
+            throw new IllegalArgumentException("sql must not be null.");
+        }
+
+        if (executeSpecial(sql, bindArgs, connectionFlags, cancellationSignal)) {
+            return null;
+        }
+
+        acquireConnection(sql, connectionFlags, cancellationSignal); // might throw
+        try {
+            return mConnection.executeForBlobFileDescriptor(sql, bindArgs,
+                    cancellationSignal); // might throw
+        } finally {
+            releaseConnection(); // might throw
+        }
+    }
+
+    /**
+     * Executes a statement that returns a count of the number of rows
+     * that were changed.  Use for UPDATE or DELETE SQL statements.
+     *
+     * @param sql The SQL statement to execute.
+     * @param bindArgs The arguments to bind, or null if none.
+     * @param connectionFlags The connection flags to use if a connection must be
+     * acquired by this operation.  Refer to {@link SQLiteConnectionPool}.
+     * @param cancellationSignal A signal to cancel the operation in progress, or null if none.
+     * @return The number of rows that were changed.
+     *
+     * @throws SQLiteException if an error occurs, such as a syntax error
+     * or invalid number of bind arguments.
+     * @throws OperationCanceledException if the operation was canceled.
+     */
+    public int executeForChangedRowCount(String sql, Object[] bindArgs, int connectionFlags,
+            CancellationSignal cancellationSignal) {
+        if (sql == null) {
+            throw new IllegalArgumentException("sql must not be null.");
+        }
+
+        if (executeSpecial(sql, bindArgs, connectionFlags, cancellationSignal)) {
+            return 0;
+        }
+
+        acquireConnection(sql, connectionFlags, cancellationSignal); // might throw
+        try {
+            return mConnection.executeForChangedRowCount(sql, bindArgs,
+                    cancellationSignal); // might throw
+        } finally {
+            releaseConnection(); // might throw
+        }
+    }
+
+    /**
+     * Executes a statement that returns the row id of the last row inserted
+     * by the statement.  Use for INSERT SQL statements.
+     *
+     * @param sql The SQL statement to execute.
+     * @param bindArgs The arguments to bind, or null if none.
+     * @param connectionFlags The connection flags to use if a connection must be
+     * acquired by this operation.  Refer to {@link SQLiteConnectionPool}.
+     * @param cancellationSignal A signal to cancel the operation in progress, or null if none.
+     * @return The row id of the last row that was inserted, or 0 if none.
+     *
+     * @throws SQLiteException if an error occurs, such as a syntax error
+     * or invalid number of bind arguments.
+     * @throws OperationCanceledException if the operation was canceled.
+     */
+    public long executeForLastInsertedRowId(String sql, Object[] bindArgs, int connectionFlags,
+            CancellationSignal cancellationSignal) {
+        if (sql == null) {
+            throw new IllegalArgumentException("sql must not be null.");
+        }
+
+        if (executeSpecial(sql, bindArgs, connectionFlags, cancellationSignal)) {
+            return 0;
+        }
+
+        acquireConnection(sql, connectionFlags, cancellationSignal); // might throw
+        try {
+            return mConnection.executeForLastInsertedRowId(sql, bindArgs,
+                    cancellationSignal); // might throw
+        } finally {
+            releaseConnection(); // might throw
+        }
+    }
+
+    /**
+     * Executes a statement and populates the specified {@link CursorWindow}
+     * with a range of results.  Returns the number of rows that were counted
+     * during query execution.
+     *
+     * @param sql The SQL statement to execute.
+     * @param bindArgs The arguments to bind, or null if none.
+     * @param window The cursor window to clear and fill.
+     * @param startPos The start position for filling the window.
+     * @param requiredPos The position of a row that MUST be in the window.
+     * If it won't fit, then the query should discard part of what it filled
+     * so that it does.  Must be greater than or equal to <code>startPos</code>.
+     * @param countAllRows True to count all rows that the query would return
+     * regagless of whether they fit in the window.
+     * @param connectionFlags The connection flags to use if a connection must be
+     * acquired by this operation.  Refer to {@link SQLiteConnectionPool}.
+     * @param cancellationSignal A signal to cancel the operation in progress, or null if none.
+     * @return The number of rows that were counted during query execution.  Might
+     * not be all rows in the result set unless <code>countAllRows</code> is true.
+     *
+     * @throws SQLiteException if an error occurs, such as a syntax error
+     * or invalid number of bind arguments.
+     * @throws OperationCanceledException if the operation was canceled.
+     */
+    public int executeForCursorWindow(String sql, Object[] bindArgs,
+            CursorWindow window, int startPos, int requiredPos, boolean countAllRows,
+            int connectionFlags, CancellationSignal cancellationSignal) {
+        if (sql == null) {
+            throw new IllegalArgumentException("sql must not be null.");
+        }
+        if (window == null) {
+            throw new IllegalArgumentException("window must not be null.");
+        }
+
+        if (executeSpecial(sql, bindArgs, connectionFlags, cancellationSignal)) {
+            window.clear();
+            return 0;
+        }
+
+        acquireConnection(sql, connectionFlags, cancellationSignal); // might throw
+        try {
+            return mConnection.executeForCursorWindow(sql, bindArgs,
+                    window, startPos, requiredPos, countAllRows,
+                    cancellationSignal); // might throw
+        } finally {
+            releaseConnection(); // might throw
+        }
+    }
+
+    /**
+     * Performs special reinterpretation of certain SQL statements such as "BEGIN",
+     * "COMMIT" and "ROLLBACK" to ensure that transaction state invariants are
+     * maintained.
+     *
+     * This function is mainly used to support legacy apps that perform their
+     * own transactions by executing raw SQL rather than calling {@link #beginTransaction}
+     * and the like.
+     *
+     * @param sql The SQL statement to execute.
+     * @param bindArgs The arguments to bind, or null if none.
+     * @param connectionFlags The connection flags to use if a connection must be
+     * acquired by this operation.  Refer to {@link SQLiteConnectionPool}.
+     * @param cancellationSignal A signal to cancel the operation in progress, or null if none.
+     * @return True if the statement was of a special form that was handled here,
+     * false otherwise.
+     *
+     * @throws SQLiteException if an error occurs, such as a syntax error
+     * or invalid number of bind arguments.
+     * @throws OperationCanceledException if the operation was canceled.
+     */
+    private boolean executeSpecial(String sql, Object[] bindArgs, int connectionFlags,
+            CancellationSignal cancellationSignal) {
+        if (cancellationSignal != null) {
+            cancellationSignal.throwIfCanceled();
+        }
+
+        final int type = DatabaseUtils.getSqlStatementType(sql);
+        switch (type) {
+            case DatabaseUtils.STATEMENT_BEGIN:
+                beginTransaction(TRANSACTION_MODE_EXCLUSIVE, null, connectionFlags,
+                        cancellationSignal);
+                return true;
+
+            case DatabaseUtils.STATEMENT_COMMIT:
+                setTransactionSuccessful();
+                endTransaction(cancellationSignal);
+                return true;
+
+            case DatabaseUtils.STATEMENT_ABORT:
+                endTransaction(cancellationSignal);
+                return true;
+        }
+        return false;
+    }
+
+    private void acquireConnection(String sql, int connectionFlags,
+            CancellationSignal cancellationSignal) {
+        if (mConnection == null) {
+            assert mConnectionUseCount == 0;
+            mConnection = mConnectionPool.acquireConnection(sql, connectionFlags,
+                    cancellationSignal); // might throw
+            mConnectionFlags = connectionFlags;
+        }
+        mConnectionUseCount += 1;
+    }
+
+    private void releaseConnection() {
+        assert mConnection != null;
+        assert mConnectionUseCount > 0;
+        if (--mConnectionUseCount == 0) {
+            try {
+                mConnectionPool.releaseConnection(mConnection); // might throw
+            } finally {
+                mConnection = null;
+            }
+        }
+    }
+
+    private void throwIfNoTransaction() {
+        if (mTransactionStack == null) {
+            throw new IllegalStateException("Cannot perform this operation because "
+                    + "there is no current transaction.");
+        }
+    }
+
+    private void throwIfTransactionMarkedSuccessful() {
+        if (mTransactionStack != null && mTransactionStack.mMarkedSuccessful) {
+            throw new IllegalStateException("Cannot perform this operation because "
+                    + "the transaction has already been marked successful.  The only "
+                    + "thing you can do now is call endTransaction().");
+        }
+    }
+
+    private void throwIfNestedTransaction() {
+        if (hasNestedTransaction()) {
+            throw new IllegalStateException("Cannot perform this operation because "
+                    + "a nested transaction is in progress.");
+        }
+    }
+
+    private Transaction obtainTransaction(int mode, SQLiteTransactionListener listener) {
+        Transaction transaction = mTransactionPool;
+        if (transaction != null) {
+            mTransactionPool = transaction.mParent;
+            transaction.mParent = null;
+            transaction.mMarkedSuccessful = false;
+            transaction.mChildFailed = false;
+        } else {
+            transaction = new Transaction();
+        }
+        transaction.mMode = mode;
+        transaction.mListener = listener;
+        return transaction;
+    }
+
+    private void recycleTransaction(Transaction transaction) {
+        transaction.mParent = mTransactionPool;
+        transaction.mListener = null;
+        mTransactionPool = transaction;
+    }
+
+    private static final class Transaction {
+        public Transaction mParent;
+        public int mMode;
+        public SQLiteTransactionListener mListener;
+        public boolean mMarkedSuccessful;
+        public boolean mChildFailed;
+    }
+}
diff --git a/android/database/sqlite/SQLiteStatement.java b/android/database/sqlite/SQLiteStatement.java
new file mode 100644
index 0000000..9fda8b0
--- /dev/null
+++ b/android/database/sqlite/SQLiteStatement.java
@@ -0,0 +1,165 @@
+/*
+ * Copyright (C) 2006 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.database.sqlite;
+
+import android.compat.annotation.UnsupportedAppUsage;
+import android.os.ParcelFileDescriptor;
+
+/**
+ * Represents a statement that can be executed against a database.  The statement
+ * cannot return multiple rows or columns, but single value (1 x 1) result sets
+ * are supported.
+ * <p>
+ * This class is not thread-safe.
+ * </p>
+ */
+public final class SQLiteStatement extends SQLiteProgram {
+    @UnsupportedAppUsage
+    SQLiteStatement(SQLiteDatabase db, String sql, Object[] bindArgs) {
+        super(db, sql, bindArgs, null);
+    }
+
+    /**
+     * Execute this SQL statement, if it is not a SELECT / INSERT / DELETE / UPDATE, for example
+     * CREATE / DROP table, view, trigger, index etc.
+     *
+     * @throws android.database.SQLException If the SQL string is invalid for
+     *         some reason
+     */
+    public void execute() {
+        acquireReference();
+        try {
+            getSession().execute(getSql(), getBindArgs(), getConnectionFlags(), null);
+        } catch (SQLiteDatabaseCorruptException ex) {
+            onCorruption();
+            throw ex;
+        } finally {
+            releaseReference();
+        }
+    }
+
+    /**
+     * Execute this SQL statement, if the number of rows affected by execution of this SQL
+     * statement is of any importance to the caller - for example, UPDATE / DELETE SQL statements.
+     *
+     * @return the number of rows affected by this SQL statement execution.
+     * @throws android.database.SQLException If the SQL string is invalid for
+     *         some reason
+     */
+    public int executeUpdateDelete() {
+        acquireReference();
+        try {
+            return getSession().executeForChangedRowCount(
+                    getSql(), getBindArgs(), getConnectionFlags(), null);
+        } catch (SQLiteDatabaseCorruptException ex) {
+            onCorruption();
+            throw ex;
+        } finally {
+            releaseReference();
+        }
+    }
+
+    /**
+     * Execute this SQL statement and return the ID of the row inserted due to this call.
+     * The SQL statement should be an INSERT for this to be a useful call.
+     *
+     * @return the row ID of the last row inserted, if this insert is successful. -1 otherwise.
+     *
+     * @throws android.database.SQLException If the SQL string is invalid for
+     *         some reason
+     */
+    public long executeInsert() {
+        acquireReference();
+        try {
+            return getSession().executeForLastInsertedRowId(
+                    getSql(), getBindArgs(), getConnectionFlags(), null);
+        } catch (SQLiteDatabaseCorruptException ex) {
+            onCorruption();
+            throw ex;
+        } finally {
+            releaseReference();
+        }
+    }
+
+    /**
+     * Execute a statement that returns a 1 by 1 table with a numeric value.
+     * For example, SELECT COUNT(*) FROM table;
+     *
+     * @return The result of the query.
+     *
+     * @throws android.database.sqlite.SQLiteDoneException if the query returns zero rows
+     */
+    public long simpleQueryForLong() {
+        acquireReference();
+        try {
+            return getSession().executeForLong(
+                    getSql(), getBindArgs(), getConnectionFlags(), null);
+        } catch (SQLiteDatabaseCorruptException ex) {
+            onCorruption();
+            throw ex;
+        } finally {
+            releaseReference();
+        }
+    }
+
+    /**
+     * Execute a statement that returns a 1 by 1 table with a text value.
+     * For example, SELECT COUNT(*) FROM table;
+     *
+     * @return The result of the query.
+     *
+     * @throws android.database.sqlite.SQLiteDoneException if the query returns zero rows
+     */
+    public String simpleQueryForString() {
+        acquireReference();
+        try {
+            return getSession().executeForString(
+                    getSql(), getBindArgs(), getConnectionFlags(), null);
+        } catch (SQLiteDatabaseCorruptException ex) {
+            onCorruption();
+            throw ex;
+        } finally {
+            releaseReference();
+        }
+    }
+
+    /**
+     * Executes a statement that returns a 1 by 1 table with a blob value.
+     *
+     * @return A read-only file descriptor for a copy of the blob value, or {@code null}
+     *         if the value is null or could not be read for some reason.
+     *
+     * @throws android.database.sqlite.SQLiteDoneException if the query returns zero rows
+     */
+    public ParcelFileDescriptor simpleQueryForBlobFileDescriptor() {
+        acquireReference();
+        try {
+            return getSession().executeForBlobFileDescriptor(
+                    getSql(), getBindArgs(), getConnectionFlags(), null);
+        } catch (SQLiteDatabaseCorruptException ex) {
+            onCorruption();
+            throw ex;
+        } finally {
+            releaseReference();
+        }
+    }
+
+    @Override
+    public String toString() {
+        return "SQLiteProgram: " + getSql();
+    }
+}
diff --git a/android/database/sqlite/SQLiteStatementInfo.java b/android/database/sqlite/SQLiteStatementInfo.java
new file mode 100644
index 0000000..3edfdb0
--- /dev/null
+++ b/android/database/sqlite/SQLiteStatementInfo.java
@@ -0,0 +1,39 @@
+/*
+ * Copyright (C) 2011 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.database.sqlite;
+
+/**
+ * Describes a SQLite statement.
+ *
+ * @hide
+ */
+public final class SQLiteStatementInfo {
+    /**
+     * The number of parameters that the statement has.
+     */
+    public int numParameters;
+
+    /**
+     * The names of all columns in the result set of the statement.
+     */
+    public String[] columnNames;
+
+    /**
+     * True if the statement is read-only.
+     */
+    public boolean readOnly;
+}
diff --git a/android/database/sqlite/SQLiteTableLockedException.java b/android/database/sqlite/SQLiteTableLockedException.java
new file mode 100644
index 0000000..8278df0
--- /dev/null
+++ b/android/database/sqlite/SQLiteTableLockedException.java
@@ -0,0 +1,25 @@
+/*
+ * 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.database.sqlite;
+
+public class SQLiteTableLockedException extends SQLiteException {
+    public SQLiteTableLockedException() {}
+
+    public SQLiteTableLockedException(String error) {
+        super(error);
+    }
+}
diff --git a/android/database/sqlite/SQLiteTokenizer.java b/android/database/sqlite/SQLiteTokenizer.java
new file mode 100644
index 0000000..7e7c3fb
--- /dev/null
+++ b/android/database/sqlite/SQLiteTokenizer.java
@@ -0,0 +1,297 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.database.sqlite;
+
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Locale;
+import java.util.function.Consumer;
+
+/**
+ * SQL Tokenizer specialized to extract tokens from SQL (snippets).
+ * <p>
+ * Based on sqlite3GetToken() in tokenzie.c in SQLite.
+ * <p>
+ * Source for v3.8.6 (which android uses): http://www.sqlite.org/src/artifact/ae45399d6252b4d7
+ * (Latest source as of now: http://www.sqlite.org/src/artifact/78c8085bc7af1922)
+ * <p>
+ * Also draft spec: http://www.sqlite.org/draft/tokenreq.html
+ *
+ * @hide
+ */
+public class SQLiteTokenizer {
+    private static boolean isAlpha(char ch) {
+        return ('a' <= ch && ch <= 'z') || ('A' <= ch && ch <= 'Z') || (ch == '_');
+    }
+
+    private static boolean isNum(char ch) {
+        return ('0' <= ch && ch <= '9');
+    }
+
+    private static boolean isAlNum(char ch) {
+        return isAlpha(ch) || isNum(ch);
+    }
+
+    private static boolean isAnyOf(char ch, String set) {
+        return set.indexOf(ch) >= 0;
+    }
+
+    private static IllegalArgumentException genException(String message, String sql) {
+        throw new IllegalArgumentException(message + " in '" + sql + "'");
+    }
+
+    private static char peek(String s, int index) {
+        return index < s.length() ? s.charAt(index) : '\0';
+    }
+
+    public static final int OPTION_NONE = 0;
+
+    /**
+     * Require that SQL contains only tokens; any comments or values will result
+     * in an exception.
+     */
+    public static final int OPTION_TOKEN_ONLY = 1 << 0;
+
+    /**
+     * Tokenize the given SQL, returning the list of each encountered token.
+     *
+     * @throws IllegalArgumentException if invalid SQL is encountered.
+     */
+    public static List<String> tokenize(@Nullable String sql, int options) {
+        final ArrayList<String> res = new ArrayList<>();
+        tokenize(sql, options, res::add);
+        return res;
+    }
+
+    /**
+     * Tokenize the given SQL, sending each encountered token to the given
+     * {@link Consumer}.
+     *
+     * @throws IllegalArgumentException if invalid SQL is encountered.
+     */
+    public static void tokenize(@Nullable String sql, int options, Consumer<String> checker) {
+        if (sql == null) {
+            return;
+        }
+        int pos = 0;
+        final int len = sql.length();
+        while (pos < len) {
+            final char ch = peek(sql, pos);
+
+            // Regular token.
+            if (isAlpha(ch)) {
+                final int start = pos;
+                pos++;
+                while (isAlNum(peek(sql, pos))) {
+                    pos++;
+                }
+                final int end = pos;
+
+                final String token = sql.substring(start, end);
+                checker.accept(token);
+
+                continue;
+            }
+
+            // Handle quoted tokens
+            if (isAnyOf(ch, "'\"`")) {
+                final int quoteStart = pos;
+                pos++;
+
+                for (;;) {
+                    pos = sql.indexOf(ch, pos);
+                    if (pos < 0) {
+                        throw genException("Unterminated quote", sql);
+                    }
+                    if (peek(sql, pos + 1) != ch) {
+                        break;
+                    }
+                    // Quoted quote char -- e.g. "abc""def" is a single string.
+                    pos += 2;
+                }
+                final int quoteEnd = pos;
+                pos++;
+
+                if (ch != '\'') {
+                    // Extract the token
+                    final String tokenUnquoted = sql.substring(quoteStart + 1, quoteEnd);
+
+                    final String token;
+
+                    // Unquote if needed. i.e. "aa""bb" -> aa"bb
+                    if (tokenUnquoted.indexOf(ch) >= 0) {
+                        token = tokenUnquoted.replaceAll(
+                                String.valueOf(ch) + ch, String.valueOf(ch));
+                    } else {
+                        token = tokenUnquoted;
+                    }
+                    checker.accept(token);
+                } else {
+                    if ((options &= OPTION_TOKEN_ONLY) != 0) {
+                        throw genException("Non-token detected", sql);
+                    }
+                }
+                continue;
+            }
+            // Handle tokens enclosed in [...]
+            if (ch == '[') {
+                final int quoteStart = pos;
+                pos++;
+
+                pos = sql.indexOf(']', pos);
+                if (pos < 0) {
+                    throw genException("Unterminated quote", sql);
+                }
+                final int quoteEnd = pos;
+                pos++;
+
+                final String token = sql.substring(quoteStart + 1, quoteEnd);
+
+                checker.accept(token);
+                continue;
+            }
+            if ((options &= OPTION_TOKEN_ONLY) != 0) {
+                throw genException("Non-token detected", sql);
+            }
+
+            // Detect comments.
+            if (ch == '-' && peek(sql, pos + 1) == '-') {
+                pos += 2;
+                pos = sql.indexOf('\n', pos);
+                if (pos < 0) {
+                    // We disallow strings ending in an inline comment.
+                    throw genException("Unterminated comment", sql);
+                }
+                pos++;
+
+                continue;
+            }
+            if (ch == '/' && peek(sql, pos + 1) == '*') {
+                pos += 2;
+                pos = sql.indexOf("*/", pos);
+                if (pos < 0) {
+                    throw genException("Unterminated comment", sql);
+                }
+                pos += 2;
+
+                continue;
+            }
+
+            // Semicolon is never allowed.
+            if (ch == ';') {
+                throw genException("Semicolon is not allowed", sql);
+            }
+
+            // For this purpose, we can simply ignore other characters.
+            // (Note it doesn't handle the X'' literal properly and reports this X as a token,
+            // but that should be fine...)
+            pos++;
+        }
+    }
+
+    /**
+     * Test if given token is a
+     * <a href="https://www.sqlite.org/lang_keywords.html">SQLite reserved
+     * keyword</a>.
+     */
+    public static boolean isKeyword(@NonNull String token) {
+        switch (token.toUpperCase(Locale.US)) {
+            case "ABORT": case "ACTION": case "ADD": case "AFTER":
+            case "ALL": case "ALTER": case "ANALYZE": case "AND":
+            case "AS": case "ASC": case "ATTACH": case "AUTOINCREMENT":
+            case "BEFORE": case "BEGIN": case "BETWEEN": case "BINARY":
+            case "BY": case "CASCADE": case "CASE": case "CAST":
+            case "CHECK": case "COLLATE": case "COLUMN": case "COMMIT":
+            case "CONFLICT": case "CONSTRAINT": case "CREATE": case "CROSS":
+            case "CURRENT": case "CURRENT_DATE": case "CURRENT_TIME": case "CURRENT_TIMESTAMP":
+            case "DATABASE": case "DEFAULT": case "DEFERRABLE": case "DEFERRED":
+            case "DELETE": case "DESC": case "DETACH": case "DISTINCT":
+            case "DO": case "DROP": case "EACH": case "ELSE":
+            case "END": case "ESCAPE": case "EXCEPT": case "EXCLUDE":
+            case "EXCLUSIVE": case "EXISTS": case "EXPLAIN": case "FAIL":
+            case "FILTER": case "FOLLOWING": case "FOR": case "FOREIGN":
+            case "FROM": case "FULL": case "GLOB": case "GROUP":
+            case "GROUPS": case "HAVING": case "IF": case "IGNORE":
+            case "IMMEDIATE": case "IN": case "INDEX": case "INDEXED":
+            case "INITIALLY": case "INNER": case "INSERT": case "INSTEAD":
+            case "INTERSECT": case "INTO": case "IS": case "ISNULL":
+            case "JOIN": case "KEY": case "LEFT": case "LIKE":
+            case "LIMIT": case "MATCH": case "NATURAL": case "NO":
+            case "NOCASE": case "NOT": case "NOTHING": case "NOTNULL":
+            case "NULL": case "OF": case "OFFSET": case "ON":
+            case "OR": case "ORDER": case "OTHERS": case "OUTER":
+            case "OVER": case "PARTITION": case "PLAN": case "PRAGMA":
+            case "PRECEDING": case "PRIMARY": case "QUERY": case "RAISE":
+            case "RANGE": case "RECURSIVE": case "REFERENCES": case "REGEXP":
+            case "REINDEX": case "RELEASE": case "RENAME": case "REPLACE":
+            case "RESTRICT": case "RIGHT": case "ROLLBACK": case "ROW":
+            case "ROWS": case "RTRIM": case "SAVEPOINT": case "SELECT":
+            case "SET": case "TABLE": case "TEMP": case "TEMPORARY":
+            case "THEN": case "TIES": case "TO": case "TRANSACTION":
+            case "TRIGGER": case "UNBOUNDED": case "UNION": case "UNIQUE":
+            case "UPDATE": case "USING": case "VACUUM": case "VALUES":
+            case "VIEW": case "VIRTUAL": case "WHEN": case "WHERE":
+            case "WINDOW": case "WITH": case "WITHOUT":
+                return true;
+            default:
+                return false;
+        }
+    }
+
+    /**
+     * Test if given token is a
+     * <a href="https://www.sqlite.org/lang_corefunc.html">SQLite reserved
+     * function</a>.
+     */
+    public static boolean isFunction(@NonNull String token) {
+        switch (token.toLowerCase(Locale.US)) {
+            case "abs": case "avg": case "char": case "coalesce":
+            case "count": case "glob": case "group_concat": case "hex":
+            case "ifnull": case "instr": case "length": case "like":
+            case "likelihood": case "likely": case "lower": case "ltrim":
+            case "max": case "min": case "nullif": case "random":
+            case "randomblob": case "replace": case "round": case "rtrim":
+            case "substr": case "sum": case "total": case "trim":
+            case "typeof": case "unicode": case "unlikely": case "upper":
+            case "zeroblob":
+                return true;
+            default:
+                return false;
+        }
+    }
+
+    /**
+     * Test if given token is a
+     * <a href="https://www.sqlite.org/datatype3.html">SQLite reserved type</a>.
+     */
+    public static boolean isType(@NonNull String token) {
+        switch (token.toUpperCase(Locale.US)) {
+            case "INT": case "INTEGER": case "TINYINT": case "SMALLINT":
+            case "MEDIUMINT": case "BIGINT": case "INT2": case "INT8":
+            case "CHARACTER": case "VARCHAR": case "NCHAR": case "NVARCHAR":
+            case "TEXT": case "CLOB": case "BLOB": case "REAL":
+            case "DOUBLE": case "FLOAT": case "NUMERIC": case "DECIMAL":
+            case "BOOLEAN": case "DATE": case "DATETIME":
+                return true;
+            default:
+                return false;
+        }
+    }
+}
diff --git a/android/database/sqlite/SQLiteTransactionListener.java b/android/database/sqlite/SQLiteTransactionListener.java
new file mode 100644
index 0000000..f03b580
--- /dev/null
+++ b/android/database/sqlite/SQLiteTransactionListener.java
@@ -0,0 +1,37 @@
+/*
+ * Copyright (C) 2009 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.database.sqlite;
+
+/**
+ * A listener for transaction events.
+ */
+public interface SQLiteTransactionListener {
+    /**
+     * Called immediately after the transaction begins.
+     */
+    void onBegin();
+
+    /**
+     * Called immediately before commiting the transaction.
+     */
+    void onCommit();
+
+    /**
+     * Called if the transaction is about to be rolled back.
+     */
+    void onRollback();
+}
diff --git a/android/database/sqlite/SqliteWrapper.java b/android/database/sqlite/SqliteWrapper.java
new file mode 100644
index 0000000..f335fbd
--- /dev/null
+++ b/android/database/sqlite/SqliteWrapper.java
@@ -0,0 +1,113 @@
+/*
+ * Copyright (C) 2008 Esmertec AG.
+ * Copyright (C) 2008 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.database.sqlite;
+
+import android.compat.annotation.UnsupportedAppUsage;
+import android.content.ContentResolver;
+import android.content.ContentValues;
+import android.content.Context;
+import android.database.Cursor;
+import android.net.Uri;
+import android.util.Log;
+import android.widget.Toast;
+
+/**
+ * @hide
+ */
+
+public final class SqliteWrapper {
+    private static final String TAG = "SqliteWrapper";
+    private static final String SQLITE_EXCEPTION_DETAIL_MESSAGE
+                = "unable to open database file";
+
+    private SqliteWrapper() {
+        // Forbidden being instantiated.
+    }
+
+    // FIXME: need to optimize this method.
+    private static boolean isLowMemory(SQLiteException e) {
+        return e.getMessage().equals(SQLITE_EXCEPTION_DETAIL_MESSAGE);
+    }
+
+    @UnsupportedAppUsage
+    public static void checkSQLiteException(Context context, SQLiteException e) {
+        if (isLowMemory(e)) {
+            Toast.makeText(context, com.android.internal.R.string.low_memory,
+                    Toast.LENGTH_SHORT).show();
+        } else {
+            throw e;
+        }
+    }
+
+    @UnsupportedAppUsage
+    public static Cursor query(Context context, ContentResolver resolver, Uri uri,
+            String[] projection, String selection, String[] selectionArgs, String sortOrder) {
+        try {
+            return resolver.query(uri, projection, selection, selectionArgs, sortOrder);
+        } catch (SQLiteException e) {
+            Log.e(TAG, "Catch a SQLiteException when query: ", e);
+            checkSQLiteException(context, e);
+            return null;
+        }
+    }
+
+    public static boolean requery(Context context, Cursor cursor) {
+        try {
+            return cursor.requery();
+        } catch (SQLiteException e) {
+            Log.e(TAG, "Catch a SQLiteException when requery: ", e);
+            checkSQLiteException(context, e);
+            return false;
+        }
+    }
+    @UnsupportedAppUsage
+    public static int update(Context context, ContentResolver resolver, Uri uri,
+            ContentValues values, String where, String[] selectionArgs) {
+        try {
+            return resolver.update(uri, values, where, selectionArgs);
+        } catch (SQLiteException e) {
+            Log.e(TAG, "Catch a SQLiteException when update: ", e);
+            checkSQLiteException(context, e);
+            return -1;
+        }
+    }
+
+    @UnsupportedAppUsage
+    public static int delete(Context context, ContentResolver resolver, Uri uri,
+            String where, String[] selectionArgs) {
+        try {
+            return resolver.delete(uri, where, selectionArgs);
+        } catch (SQLiteException e) {
+            Log.e(TAG, "Catch a SQLiteException when delete: ", e);
+            checkSQLiteException(context, e);
+            return -1;
+        }
+    }
+
+    @UnsupportedAppUsage
+    public static Uri insert(Context context, ContentResolver resolver,
+            Uri uri, ContentValues values) {
+        try {
+            return resolver.insert(uri, values);
+        } catch (SQLiteException e) {
+            Log.e(TAG, "Catch a SQLiteException when insert: ", e);
+            checkSQLiteException(context, e);
+            return null;
+        }
+    }
+}
