1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 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;
}
}
|