Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 82f289a4 authored by Fyodor Kupolov's avatar Fyodor Kupolov Committed by Android (Google) Code Review
Browse files

Merge "Added setIdleConnectionTimeout method" into oc-mr1-dev

parents 102e9a7e cf97b6b7
Loading
Loading
Loading
Loading
+3 −0
Original line number Diff line number Diff line
@@ -11956,6 +11956,7 @@ package android.database.sqlite {
  public static final class SQLiteDatabase.OpenParams {
    method public android.database.sqlite.SQLiteDatabase.CursorFactory getCursorFactory();
    method public android.database.DatabaseErrorHandler getErrorHandler();
    method public long getIdleConnectionTimeout();
    method public int getLookasideSlotCount();
    method public int getLookasideSlotSize();
    method public int getOpenFlags();
@@ -11969,6 +11970,7 @@ package android.database.sqlite {
    method public android.database.sqlite.SQLiteDatabase.OpenParams.Builder removeOpenFlags(int);
    method public android.database.sqlite.SQLiteDatabase.OpenParams.Builder setCursorFactory(android.database.sqlite.SQLiteDatabase.CursorFactory);
    method public android.database.sqlite.SQLiteDatabase.OpenParams.Builder setErrorHandler(android.database.DatabaseErrorHandler);
    method public android.database.sqlite.SQLiteDatabase.OpenParams.Builder setIdleConnectionTimeout(long);
    method public android.database.sqlite.SQLiteDatabase.OpenParams.Builder setLookasideConfig(int, int);
    method public android.database.sqlite.SQLiteDatabase.OpenParams.Builder setOpenFlags(int);
  }
@@ -12026,6 +12028,7 @@ package android.database.sqlite {
    method public void onDowngrade(android.database.sqlite.SQLiteDatabase, int, int);
    method public void onOpen(android.database.sqlite.SQLiteDatabase);
    method public abstract void onUpgrade(android.database.sqlite.SQLiteDatabase, int, int);
    method public void setIdleConnectionTimeout(long);
    method public void setLookasideConfig(int, int);
    method public void setWriteAheadLoggingEnabled(boolean);
  }
+3 −0
Original line number Diff line number Diff line
@@ -12752,6 +12752,7 @@ package android.database.sqlite {
  public static final class SQLiteDatabase.OpenParams {
    method public android.database.sqlite.SQLiteDatabase.CursorFactory getCursorFactory();
    method public android.database.DatabaseErrorHandler getErrorHandler();
    method public long getIdleConnectionTimeout();
    method public int getLookasideSlotCount();
    method public int getLookasideSlotSize();
    method public int getOpenFlags();
@@ -12765,6 +12766,7 @@ package android.database.sqlite {
    method public android.database.sqlite.SQLiteDatabase.OpenParams.Builder removeOpenFlags(int);
    method public android.database.sqlite.SQLiteDatabase.OpenParams.Builder setCursorFactory(android.database.sqlite.SQLiteDatabase.CursorFactory);
    method public android.database.sqlite.SQLiteDatabase.OpenParams.Builder setErrorHandler(android.database.DatabaseErrorHandler);
    method public android.database.sqlite.SQLiteDatabase.OpenParams.Builder setIdleConnectionTimeout(long);
    method public android.database.sqlite.SQLiteDatabase.OpenParams.Builder setLookasideConfig(int, int);
    method public android.database.sqlite.SQLiteDatabase.OpenParams.Builder setOpenFlags(int);
  }
@@ -12822,6 +12824,7 @@ package android.database.sqlite {
    method public void onDowngrade(android.database.sqlite.SQLiteDatabase, int, int);
    method public void onOpen(android.database.sqlite.SQLiteDatabase);
    method public abstract void onUpgrade(android.database.sqlite.SQLiteDatabase, int, int);
    method public void setIdleConnectionTimeout(long);
    method public void setLookasideConfig(int, int);
    method public void setWriteAheadLoggingEnabled(boolean);
  }
+3 −0
Original line number Diff line number Diff line
@@ -12000,6 +12000,7 @@ package android.database.sqlite {
  public static final class SQLiteDatabase.OpenParams {
    method public android.database.sqlite.SQLiteDatabase.CursorFactory getCursorFactory();
    method public android.database.DatabaseErrorHandler getErrorHandler();
    method public long getIdleConnectionTimeout();
    method public int getLookasideSlotCount();
    method public int getLookasideSlotSize();
    method public int getOpenFlags();
@@ -12013,6 +12014,7 @@ package android.database.sqlite {
    method public android.database.sqlite.SQLiteDatabase.OpenParams.Builder removeOpenFlags(int);
    method public android.database.sqlite.SQLiteDatabase.OpenParams.Builder setCursorFactory(android.database.sqlite.SQLiteDatabase.CursorFactory);
    method public android.database.sqlite.SQLiteDatabase.OpenParams.Builder setErrorHandler(android.database.DatabaseErrorHandler);
    method public android.database.sqlite.SQLiteDatabase.OpenParams.Builder setIdleConnectionTimeout(long);
    method public android.database.sqlite.SQLiteDatabase.OpenParams.Builder setLookasideConfig(int, int);
    method public android.database.sqlite.SQLiteDatabase.OpenParams.Builder setOpenFlags(int);
  }
@@ -12095,6 +12097,7 @@ package android.database.sqlite {
    method public void onDowngrade(android.database.sqlite.SQLiteDatabase, int, int);
    method public void onOpen(android.database.sqlite.SQLiteDatabase);
    method public abstract void onUpgrade(android.database.sqlite.SQLiteDatabase, int, int);
    method public void setIdleConnectionTimeout(long);
    method public void setLookasideConfig(int, int);
    method public void setWriteAheadLoggingEnabled(boolean);
  }
+23 −28
Original line number Diff line number Diff line
@@ -16,7 +16,6 @@

package android.database.sqlite;

import android.app.ActivityManager;
import android.database.sqlite.SQLiteDebug.DbStats;
import android.os.CancellationSignal;
import android.os.Handler;
@@ -24,7 +23,6 @@ import android.os.Looper;
import android.os.Message;
import android.os.OperationCanceledException;
import android.os.SystemClock;
import android.os.SystemProperties;
import android.util.Log;
import android.util.PrefixPrinter;
import android.util.Printer;
@@ -84,15 +82,6 @@ public final class SQLiteConnectionPool implements Closeable {
    // and logging a message about the connection pool being busy.
    private static final long CONNECTION_POOL_BUSY_MILLIS = 30 * 1000; // 30 seconds

    // TODO b/63398887 Move to SQLiteGlobal
    private static final long IDLE_CONNECTION_CLOSE_DELAY_MILLIS = SystemProperties
            .getInt("persist.debug.sqlite.idle_connection_close_delay", 30000);

    // TODO b/63398887 STOPSHIP.
    // Temporarily enabled for testing across a broader set of dogfood devices.
    private static final boolean CLOSE_IDLE_CONNECTIONS = SystemProperties
            .getBoolean("persist.debug.sqlite.close_idle_connections", true);

    private final CloseGuard mCloseGuard = CloseGuard.get();

    private final Object mLock = new Object();
@@ -167,16 +156,12 @@ public final class SQLiteConnectionPool implements Closeable {

    private SQLiteConnectionPool(SQLiteDatabaseConfiguration configuration) {
        mConfiguration = new SQLiteDatabaseConfiguration(configuration);
        // Disable lookaside allocator on low-RAM devices
        if (ActivityManager.isLowRamDeviceStatic()) {
            mConfiguration.lookasideSlotCount = 0;
            mConfiguration.lookasideSlotSize = 0;
        }
        setMaxConnectionPoolSizeLocked();

        // Do not close idle connections for in-memory databases
        if (CLOSE_IDLE_CONNECTIONS && !configuration.isInMemoryDb()) {
            setupIdleConnectionHandler(Looper.getMainLooper(), IDLE_CONNECTION_CLOSE_DELAY_MILLIS);
        // 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);
        }
    }

@@ -214,6 +199,12 @@ public final class SQLiteConnectionPool implements Closeable {
        // 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;
@@ -1023,12 +1014,12 @@ public final class SQLiteConnectionPool implements Closeable {
    }

    /**
     * Set up the handler based on the provided looper and delay.
     * Set up the handler based on the provided looper and timeout.
     */
    @VisibleForTesting
    public void setupIdleConnectionHandler(Looper looper, long delayMs) {
    public void setupIdleConnectionHandler(Looper looper, long timeoutMs) {
        synchronized (mLock) {
            mIdleConnectionHandler = new IdleConnectionHandler(looper, delayMs);
            mIdleConnectionHandler = new IdleConnectionHandler(looper, timeoutMs);
        }
    }

@@ -1089,6 +1080,10 @@ public final class SQLiteConnectionPool implements Closeable {
                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);
@@ -1155,11 +1150,11 @@ public final class SQLiteConnectionPool implements Closeable {
    }

    private class IdleConnectionHandler extends Handler {
        private final long mDelay;
        private final long mTimeout;

        IdleConnectionHandler(Looper looper, long delay) {
        IdleConnectionHandler(Looper looper, long timeout) {
            super(looper);
            mDelay = delay;
            mTimeout = timeout;
        }

        @Override
@@ -1172,14 +1167,14 @@ public final class SQLiteConnectionPool implements Closeable {
                if (closeAvailableConnectionLocked(msg.what)) {
                    if (Log.isLoggable(TAG, Log.DEBUG)) {
                        Log.d(TAG, "Closed idle connection " + mConfiguration.label + " " + msg.what
                                + " after " + mDelay);
                                + " after " + mTimeout);
                    }
                }
            }
        }

        void connectionReleased(SQLiteConnection con) {
            sendEmptyMessageDelayed(con.getConnectionId(), mDelay);
            sendEmptyMessageDelayed(con.getConnectionId(), mTimeout);
        }

        void connectionAcquired(SQLiteConnection con) {
+64 −13
Original line number Diff line number Diff line
@@ -20,6 +20,7 @@ import android.annotation.IntDef;
import android.annotation.IntRange;
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.app.ActivityManager;
import android.content.ContentValues;
import android.database.Cursor;
import android.database.DatabaseErrorHandler;
@@ -30,6 +31,7 @@ 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.EventLog;
import android.util.Log;
@@ -77,21 +79,21 @@ public final class SQLiteDatabase extends SQLiteClosable {

    private static final int EVENT_DB_CORRUPT = 75004;

    // TODO b/63398887 STOPSHIP.
    // Temporarily enabled for testing across a broader set of dogfood devices.
    private static final boolean DEBUG_CLOSE_IDLE_CONNECTIONS = SystemProperties
            .getBoolean("persist.debug.sqlite.close_idle_connections", true);

    // 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<SQLiteDatabase, Object>();
    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.
    private final ThreadLocal<SQLiteSession> mThreadSession = new ThreadLocal<SQLiteSession>() {
        @Override
        protected SQLiteSession initialValue() {
            return createSession();
        }
    };
    private final ThreadLocal<SQLiteSession> mThreadSession = ThreadLocal
            .withInitial(this::createSession);

    // The optional factory to use when creating new Cursors.  May be null.
    // INVARIANT: Immutable.
@@ -261,12 +263,29 @@ public final class SQLiteDatabase extends SQLiteClosable {

    private SQLiteDatabase(final String path, final int openFlags,
            CursorFactory cursorFactory, DatabaseErrorHandler errorHandler,
            int lookasideSlotSize, int lookasideSlotCount) {
            int lookasideSlotSize, int lookasideSlotCount, long idleConnectionTimeoutMs) {
        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;
    }

    @Override
@@ -694,7 +713,8 @@ public final class SQLiteDatabase extends SQLiteClosable {
        Preconditions.checkArgument(openParams != null, "OpenParams cannot be null");
        SQLiteDatabase db = new SQLiteDatabase(path, openParams.mOpenFlags,
                openParams.mCursorFactory, openParams.mErrorHandler,
                openParams.mLookasideSlotSize, openParams.mLookasideSlotCount);
                openParams.mLookasideSlotSize, openParams.mLookasideSlotCount,
                openParams.mIdleConnectionTimeout);
        db.open();
        return db;
    }
@@ -720,7 +740,7 @@ public final class SQLiteDatabase extends SQLiteClosable {
     */
    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);
        SQLiteDatabase db = new SQLiteDatabase(path, flags, factory, errorHandler, -1, -1, -1);
        db.open();
        return db;
    }
@@ -2267,14 +2287,17 @@ public final class SQLiteDatabase extends SQLiteClosable {
        private final DatabaseErrorHandler mErrorHandler;
        private final int mLookasideSlotSize;
        private final int mLookasideSlotCount;
        private long mIdleConnectionTimeout;

        private OpenParams(int openFlags, CursorFactory cursorFactory,
                DatabaseErrorHandler errorHandler, int lookasideSlotSize, int lookasideSlotCount) {
                DatabaseErrorHandler errorHandler, int lookasideSlotSize, int lookasideSlotCount,
                long idleConnectionTimeout) {
            mOpenFlags = openFlags;
            mCursorFactory = cursorFactory;
            mErrorHandler = errorHandler;
            mLookasideSlotSize = lookasideSlotSize;
            mLookasideSlotCount = lookasideSlotCount;
            mIdleConnectionTimeout = idleConnectionTimeout;
        }

        /**
@@ -2329,6 +2352,17 @@ public final class SQLiteDatabase extends SQLiteClosable {
            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;
        }

        /**
         * Creates a new instance of builder {@link Builder#Builder(OpenParams) initialized} with
         * {@code this} parameters.
@@ -2345,6 +2379,7 @@ public final class SQLiteDatabase extends SQLiteClosable {
        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;
@@ -2473,6 +2508,22 @@ public final class SQLiteDatabase extends SQLiteClosable {
                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.
             *
             * @param idleConnectionTimeoutMs timeout in milliseconds. Use {@link Long#MAX_VALUE}
             * to allow unlimited idle connections.
             */
            @NonNull
            public Builder setIdleConnectionTimeout(
                    @IntRange(from = 0) long idleConnectionTimeoutMs) {
                Preconditions.checkArgument(idleConnectionTimeoutMs >= 0,
                        "idle connection timeout cannot be negative");
                mIdleConnectionTimeout = idleConnectionTimeoutMs;
                return this;
            }

            /**
             * Creates an instance of {@link OpenParams} with the options that were previously set
             * on this builder
@@ -2480,7 +2531,7 @@ public final class SQLiteDatabase extends SQLiteClosable {
            @NonNull
            public OpenParams build() {
                return new OpenParams(mOpenFlags, mCursorFactory, mErrorHandler, mLookasideSlotSize,
                        mLookasideSlotCount);
                        mLookasideSlotCount, mIdleConnectionTimeout);
            }
        }
    }
Loading