/*
 * 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 global compatibility WAL settings.

The value of Global.SQLITE_COMPATIBILITY_WAL_FLAGS is cached on first access for consistent behavior across all connections opened in the process.

@hide
/** * 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; private static volatile boolean sFlagsSet; private static volatile boolean sCompatibilityWalSupported; 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;
@hide
/** * @hide */
@VisibleForTesting public static boolean areFlagsSet() { initIfNeeded(); return sFlagsSet; }
@hide
/** * @hide */
@VisibleForTesting public static boolean isCompatibilityWalSupported() { initIfNeeded(); return sCompatibilityWalSupported; }
@hide
/** * @hide */
@VisibleForTesting public static String getWALSyncMode() { initIfNeeded(); return sWALSyncMode; }
Override db_wal_truncate_size.db_wal_truncate_size.
Returns:the value set in the global setting, or -1 if a value is not set.
@hide
/** * 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
/** * @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()); sTruncateSize = parser.getInt("truncate_size", -1); Log.i(TAG, "Read compatibility WAL flags: compatibility_wal_supported=" + sCompatibilityWalSupported + ", wal_syncmode=" + sWALSyncMode); sFlagsSet = true; sInitialized = true; }
@hide
/** * @hide */
@VisibleForTesting public static void reset() { sInitialized = false; sFlagsSet = false; sCompatibilityWalSupported = false; sWALSyncMode = null; } }