1a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)// Copyright 2012 The Chromium Authors. All rights reserved.
25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file.
45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)package org.chromium.android_webview;
65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)import android.content.ContentValues;
85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)import android.content.Context;
95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)import android.database.Cursor;
105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)import android.database.sqlite.SQLiteDatabase;
115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)import android.database.sqlite.SQLiteException;
125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)import android.util.Log;
135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/**
155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * This database is used to support WebView's setHttpAuthUsernamePassword and
165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * getHttpAuthUsernamePassword methods, and WebViewDatabase's clearHttpAuthUsernamePassword and
175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * hasHttpAuthUsernamePassword methods.
185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *
195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * While this class is intended to be used as a singleton, this property is not enforced in this
205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * layer, primarily for ease of testing. To line up with the classic implementation and behavior,
215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * there is no specific handling and reporting when SQL errors occur.
225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *
235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Note on thread-safety: As per the classic implementation, most API functions have thread safety
245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * provided by the underlying SQLiteDatabase instance. The exception is database opening: this
255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * is handled in the dedicated background thread, which also provides a performance gain
265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * if triggered early on (e.g. as a side effect of CookieSyncManager.createInstance() call),
275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * sufficiently in advance of the first blocking usage of the API.
285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */
295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)public class HttpAuthDatabase {
305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
319ab5563a3196760eb381d102cbb2bc0f7abc6a50Ben Murdoch    private static final String LOGTAG = "HttpAuthDatabase";
325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    private static final int DATABASE_VERSION = 1;
345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    private SQLiteDatabase mDatabase = null;
365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    private static final String ID_COL = "_id";
385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    private static final String[] ID_PROJECTION = new String[] {
405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        ID_COL
415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    };
425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // column id strings for "httpauth" table
445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    private static final String HTTPAUTH_TABLE_NAME = "httpauth";
455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    private static final String HTTPAUTH_HOST_COL = "host";
465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    private static final String HTTPAUTH_REALM_COL = "realm";
475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    private static final String HTTPAUTH_USERNAME_COL = "username";
485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    private static final String HTTPAUTH_PASSWORD_COL = "password";
495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    /**
515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)     * Initially false until the background thread completes.
525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)     */
535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    private boolean mInitialized = false;
545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
555d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    private final Object mInitializedLock = new Object();
565d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    /**
581320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci     * Creates and returns an instance of HttpAuthDatabase for the named file, and kicks-off
591320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci     * background initialization of that database.
605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)     *
615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)     * @param context the Context to use for opening the database
625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)     * @param databaseFile Name of the file to be initialized.
635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)     */
641320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    public static HttpAuthDatabase newInstance(final Context context, final String databaseFile) {
651320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci        final HttpAuthDatabase httpAuthDatabase = new HttpAuthDatabase();
665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        new Thread() {
675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            @Override
685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            public void run() {
691320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                httpAuthDatabase.initOnBackgroundThread(context, databaseFile);
705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            }
715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        }.start();
721320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci        return httpAuthDatabase;
735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
751320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    // Prevent instantiation. Callers should use newInstance().
761320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    private HttpAuthDatabase() {}
771320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    /**
795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)     * Initializes the databases and notifies any callers waiting on waitForInit.
805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)     *
815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)     * @param context the Context to use for opening the database
825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)     * @param databaseFile Name of the file to be initialized.
835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)     */
845d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    private void initOnBackgroundThread(Context context, String databaseFile) {
855d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        synchronized (mInitializedLock) {
865d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)            if (mInitialized) {
875d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                return;
885d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)            }
895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
905d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)            initDatabase(context, databaseFile);
915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
925d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)            // Thread done, notify.
935d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)            mInitialized = true;
945d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)            mInitializedLock.notifyAll();
955d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        }
965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    /**
995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)     * Opens the database, and upgrades it if necessary.
1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)     *
1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)     * @param context the Context to use for opening the database
1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)     * @param databaseFile Name of the file to be initialized.
1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)     */
1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    private void initDatabase(Context context, String databaseFile) {
1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        try {
1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            mDatabase = context.openOrCreateDatabase(databaseFile, 0, null);
1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        } catch (SQLiteException e) {
1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            // try again by deleting the old db and create a new one
1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            if (context.deleteDatabase(databaseFile)) {
1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                mDatabase = context.openOrCreateDatabase(databaseFile, 0, null);
1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            }
1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        }
1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        if (mDatabase == null) {
1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            // Not much we can do to recover at this point
1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            Log.e(LOGTAG, "Unable to open or create " + databaseFile);
1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            return;
1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        }
1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        if (mDatabase.getVersion() != DATABASE_VERSION) {
1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            mDatabase.beginTransactionNonExclusive();
1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            try {
1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                createTable();
1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                mDatabase.setTransactionSuccessful();
1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            } finally {
1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                mDatabase.endTransaction();
1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            }
1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        }
1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    private void createTable() {
1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        mDatabase.execSQL("CREATE TABLE " + HTTPAUTH_TABLE_NAME
1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                + " (" + ID_COL + " INTEGER PRIMARY KEY, "
1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                + HTTPAUTH_HOST_COL + " TEXT, " + HTTPAUTH_REALM_COL
1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                + " TEXT, " + HTTPAUTH_USERNAME_COL + " TEXT, "
1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                + HTTPAUTH_PASSWORD_COL + " TEXT," + " UNIQUE ("
1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                + HTTPAUTH_HOST_COL + ", " + HTTPAUTH_REALM_COL
1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                + ") ON CONFLICT REPLACE);");
1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        mDatabase.setVersion(DATABASE_VERSION);
1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    /**
1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)     * Waits for the background initialization thread to complete and check the database creation
1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)     * status.
1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)     *
1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)     * @return true if the database was initialized, false otherwise
1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)     */
1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    private boolean waitForInit() {
1505d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        synchronized (mInitializedLock) {
1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            while (!mInitialized) {
1525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                try {
1535d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                    mInitializedLock.wait();
1545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                } catch (InterruptedException e) {
1555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                    Log.e(LOGTAG, "Caught exception while checking initialization", e);
1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                }
1575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            }
1585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        }
1595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        return mDatabase != null;
1605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
1615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    /**
1635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)     * Sets the HTTP authentication password. Tuple (HTTPAUTH_HOST_COL, HTTPAUTH_REALM_COL,
1645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)     * HTTPAUTH_USERNAME_COL) is unique.
1655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)     *
1665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)     * @param host the host for the password
1675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)     * @param realm the realm for the password
1685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)     * @param username the username for the password.
1695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)     * @param password the password
1705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)     */
1715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    public void setHttpAuthUsernamePassword(String host, String realm, String username,
1725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            String password) {
1735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        if (host == null || realm == null || !waitForInit()) {
1745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            return;
1755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        }
1765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        final ContentValues c = new ContentValues();
1785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        c.put(HTTPAUTH_HOST_COL, host);
1795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        c.put(HTTPAUTH_REALM_COL, realm);
1805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        c.put(HTTPAUTH_USERNAME_COL, username);
1815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        c.put(HTTPAUTH_PASSWORD_COL, password);
1825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        mDatabase.insert(HTTPAUTH_TABLE_NAME, HTTPAUTH_HOST_COL, c);
1835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
1845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    /**
1865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)     * Retrieves the HTTP authentication username and password for a given host and realm pair. If
1875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)     * there are multiple username/password combinations for a host/realm, only the first one will
1885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)     * be returned.
1895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)     *
1905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)     * @param host the host the password applies to
1915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)     * @param realm the realm the password applies to
1925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)     * @return a String[] if found where String[0] is username (which can be null) and
1935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)     *         String[1] is password.  Null is returned if it can't find anything.
1945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)     */
1955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    public String[] getHttpAuthUsernamePassword(String host, String realm) {
196a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)        if (host == null || realm == null || !waitForInit()) {
1975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            return null;
1985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        }
1995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        final String[] columns = new String[] {
2015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            HTTPAUTH_USERNAME_COL, HTTPAUTH_PASSWORD_COL
2025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        };
2035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        final String selection = "(" + HTTPAUTH_HOST_COL + " == ?) AND " +
2045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                "(" + HTTPAUTH_REALM_COL + " == ?)";
2055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        String[] ret = null;
2075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        Cursor cursor = null;
2085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        try {
2095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            cursor = mDatabase.query(HTTPAUTH_TABLE_NAME, columns, selection,
2105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                    new String[] { host, realm }, null, null, null);
2115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            if (cursor.moveToFirst()) {
2125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                ret = new String[] {
2135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                        cursor.getString(cursor.getColumnIndex(HTTPAUTH_USERNAME_COL)),
2145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                        cursor.getString(cursor.getColumnIndex(HTTPAUTH_PASSWORD_COL)),
2155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                };
2165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            }
2175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        } catch (IllegalStateException e) {
2185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            Log.e(LOGTAG, "getHttpAuthUsernamePassword", e);
2195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        } finally {
2205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            if (cursor != null) cursor.close();
2215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        }
2225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        return ret;
2235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
2245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    /**
2265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)     * Determines if there are any HTTP authentication passwords saved.
2275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)     *
2285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)     * @return true if there are passwords saved
2295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)     */
2305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    public boolean hasHttpAuthUsernamePassword() {
2315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        if (!waitForInit()) {
2325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            return false;
2335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        }
2345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        Cursor cursor = null;
2365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        boolean ret = false;
2375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        try {
2385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            cursor = mDatabase.query(HTTPAUTH_TABLE_NAME, ID_PROJECTION, null, null, null, null,
2395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                    null);
2405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            ret = cursor.moveToFirst();
2415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        } catch (IllegalStateException e) {
2425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            Log.e(LOGTAG, "hasEntries", e);
2435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        } finally {
2445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            if (cursor != null) cursor.close();
2455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        }
2465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        return ret;
2475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
2485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    /**
2505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)     * Clears the HTTP authentication password database.
2515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)     */
2525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    public void clearHttpAuthUsernamePassword() {
2535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        if (!waitForInit()) {
2545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            return;
2555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        }
2565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        mDatabase.delete(HTTPAUTH_TABLE_NAME, null, null);
2575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
2585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
259