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

Commit ee90c03f authored by Fyodor Kupolov's avatar Fyodor Kupolov
Browse files

Added compatibility WAL flags for Global.Settings

Added Settings.Global.SQLITE_COMPATIBILITY_WAL_FLAGS -
configuration flags for SQLite Compatibility WAL. Encoded as a key-value
list, separated by commas. E.g.:
compatibility_wal_supported=true, wal_syncmode=OFF

SQLiteCompatibilityWalFlags caches the value of
SQLITE_COMPATIBILITY_WAL_FLAGS on first access and keeps it through
the lifetime of the process for consistent behavior across all
connections.

Test: SQLiteCompatibilityWalFlagsTest
Test: setting put global ... + verify that dumpsys dbinfo has the new flag
Bug: 70226732
Bug: 70517616
Change-Id: Ifacbf5908c83351ebe5dea676eeb716af039fb14
parent c933f188
Loading
Loading
Loading
Loading
+134 −0
Original line number Diff line number Diff line
/*
 * 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.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
 */
public class SQLiteCompatibilityWalFlags {

    private static final String TAG = "SQLiteCompatibilityWalFlags";

    private static volatile boolean sInitialized = true; // Temporarily disable flags
    private static volatile boolean sFlagsSet;
    private static volatile boolean sCompatibilityWalSupported;
    private static volatile String sWALSyncMode;
    // This flag is used to avoid recursive initialization due to circular dependency on Settings
    private static volatile boolean sCallingGlobalSettings;

    /**
     * @hide
     */
    @VisibleForTesting
    public static boolean areFlagsSet() {
        initIfNeeded();
        return sFlagsSet;
    }

    /**
     * @hide
     */
    @VisibleForTesting
    public static boolean isCompatibilityWalSupported() {
        initIfNeeded();
        return sCompatibilityWalSupported;
    }

    /**
     * @hide
     */
    @VisibleForTesting
    public static String getWALSyncMode() {
        initIfNeeded();
        return sWALSyncMode;
    }

    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;
        }
        sCompatibilityWalSupported = parser.getBoolean("compatibility_wal_supported",
                SQLiteGlobal.isCompatibilityWalSupported());
        sWALSyncMode = parser.getString("wal_syncmode", SQLiteGlobal.getWALSyncMode());
        Log.i(TAG, "Read compatibility WAL flags: compatibility_wal_supported="
                + sCompatibilityWalSupported + ", wal_syncmode=" + sWALSyncMode);
        sFlagsSet = true;
        sInitialized = true;
    }

    /**
     * @hide
     */
    @VisibleForTesting
    public static void reset() {
        sInitialized = false;
        sFlagsSet = false;
        sCompatibilityWalSupported = false;
        sWALSyncMode = null;
    }
}
+5 −1
Original line number Diff line number Diff line
@@ -296,7 +296,11 @@ public final class SQLiteConnection implements CancellationSignal.OnCancelListen
                    && mConfiguration.syncMode == null && mConfiguration.useCompatibilityWal;
            if (walEnabled || useCompatibilityWal) {
                setJournalMode("WAL");
                if (useCompatibilityWal && SQLiteCompatibilityWalFlags.areFlagsSet()) {
                    setSyncMode(SQLiteCompatibilityWalFlags.getWALSyncMode());
                } else {
                    setSyncMode(SQLiteGlobal.getWALSyncMode());
                }
            } else {
                setJournalMode(mConfiguration.journalMode == null
                        ? SQLiteGlobal.getDefaultJournalMode() : mConfiguration.journalMode);
+6 −0
Original line number Diff line number Diff line
@@ -1094,6 +1094,12 @@ public final class SQLiteConnectionPool implements Closeable {
            printer.println("  Open: " + mIsOpen);
            printer.println("  Max connections: " + mMaxConnectionPoolSize);
            printer.println("  Total execution time: " + mTotalExecutionTimeCounter);
            if (SQLiteCompatibilityWalFlags.areFlagsSet()) {
                printer.println("  Compatibility WAL settings: compatibility_wal_supported="
                        + SQLiteCompatibilityWalFlags
                        .isCompatibilityWalSupported() + ", wal_syncmode="
                        + SQLiteCompatibilityWalFlags.getWALSyncMode());
            }
            if (mConfiguration.isLookasideConfigSet()) {
                printer.println("  Lookaside config: sz=" + mConfiguration.lookasideSlotSize
                        + " cnt=" + mConfiguration.lookasideSlotCount);
+4 −0
Original line number Diff line number Diff line
@@ -289,6 +289,10 @@ public final class SQLiteDatabase extends SQLiteClosable {
        mConfigurationLocked.journalMode = journalMode;
        mConfigurationLocked.syncMode = syncMode;
        mConfigurationLocked.useCompatibilityWal = SQLiteGlobal.isCompatibilityWalSupported();
        if (!mConfigurationLocked.isInMemoryDb() && SQLiteCompatibilityWalFlags.areFlagsSet()) {
            mConfigurationLocked.useCompatibilityWal = SQLiteCompatibilityWalFlags
                    .isCompatibilityWalSupported();
        }
    }

    @Override
+13 −0
Original line number Diff line number Diff line
@@ -11144,6 +11144,19 @@ public final class Settings {
        public static final String NOTIFICATION_SNOOZE_OPTIONS =
                "notification_snooze_options";

        /**
         * Configuration flags for SQLite Compatibility WAL. Encoded as a key-value list, separated
         * by commas. E.g.: compatibility_wal_supported=true, wal_syncmode=OFF
         *
         * Supported keys:
         * compatibility_wal_supported      (boolean)
         * wal_syncmode       (String)
         *
         * @hide
         */
        public static final String SQLITE_COMPATIBILITY_WAL_FLAGS =
                "sqlite_compatibility_wal_flags";

        /**
         * Enable GNSS Raw Measurements Full Tracking?
         * 0 = no
Loading