1ee90c03fe787ccc52c9605212eddf80cf50a7824Fyodor Kupolov/* 2ee90c03fe787ccc52c9605212eddf80cf50a7824Fyodor Kupolov * Copyright (C) 2017 The Android Open Source Project 3ee90c03fe787ccc52c9605212eddf80cf50a7824Fyodor Kupolov * 4ee90c03fe787ccc52c9605212eddf80cf50a7824Fyodor Kupolov * Licensed under the Apache License, Version 2.0 (the "License"); 5ee90c03fe787ccc52c9605212eddf80cf50a7824Fyodor Kupolov * you may not use this file except in compliance with the License. 6ee90c03fe787ccc52c9605212eddf80cf50a7824Fyodor Kupolov * You may obtain a copy of the License at 7ee90c03fe787ccc52c9605212eddf80cf50a7824Fyodor Kupolov * 8ee90c03fe787ccc52c9605212eddf80cf50a7824Fyodor Kupolov * http://www.apache.org/licenses/LICENSE-2.0 9ee90c03fe787ccc52c9605212eddf80cf50a7824Fyodor Kupolov * 10ee90c03fe787ccc52c9605212eddf80cf50a7824Fyodor Kupolov * Unless required by applicable law or agreed to in writing, software 11ee90c03fe787ccc52c9605212eddf80cf50a7824Fyodor Kupolov * distributed under the License is distributed on an "AS IS" BASIS, 12ee90c03fe787ccc52c9605212eddf80cf50a7824Fyodor Kupolov * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13ee90c03fe787ccc52c9605212eddf80cf50a7824Fyodor Kupolov * See the License for the specific language governing permissions and 14ee90c03fe787ccc52c9605212eddf80cf50a7824Fyodor Kupolov * limitations under the License. 15ee90c03fe787ccc52c9605212eddf80cf50a7824Fyodor Kupolov */ 16ee90c03fe787ccc52c9605212eddf80cf50a7824Fyodor Kupolov 17ee90c03fe787ccc52c9605212eddf80cf50a7824Fyodor Kupolovpackage android.database.sqlite; 18ee90c03fe787ccc52c9605212eddf80cf50a7824Fyodor Kupolov 19ee90c03fe787ccc52c9605212eddf80cf50a7824Fyodor Kupolovimport android.app.ActivityThread; 20ee90c03fe787ccc52c9605212eddf80cf50a7824Fyodor Kupolovimport android.app.Application; 21ee90c03fe787ccc52c9605212eddf80cf50a7824Fyodor Kupolovimport android.provider.Settings; 22ee90c03fe787ccc52c9605212eddf80cf50a7824Fyodor Kupolovimport android.text.TextUtils; 23ee90c03fe787ccc52c9605212eddf80cf50a7824Fyodor Kupolovimport android.util.KeyValueListParser; 24ee90c03fe787ccc52c9605212eddf80cf50a7824Fyodor Kupolovimport android.util.Log; 25ee90c03fe787ccc52c9605212eddf80cf50a7824Fyodor Kupolov 26ee90c03fe787ccc52c9605212eddf80cf50a7824Fyodor Kupolovimport com.android.internal.annotations.VisibleForTesting; 27ee90c03fe787ccc52c9605212eddf80cf50a7824Fyodor Kupolov 28ee90c03fe787ccc52c9605212eddf80cf50a7824Fyodor Kupolov/** 29ee90c03fe787ccc52c9605212eddf80cf50a7824Fyodor Kupolov * Helper class for accessing 30ee90c03fe787ccc52c9605212eddf80cf50a7824Fyodor Kupolov * {@link Settings.Global#SQLITE_COMPATIBILITY_WAL_FLAGS global compatibility WAL settings}. 31ee90c03fe787ccc52c9605212eddf80cf50a7824Fyodor Kupolov * 32ee90c03fe787ccc52c9605212eddf80cf50a7824Fyodor Kupolov * <p>The value of {@link Settings.Global#SQLITE_COMPATIBILITY_WAL_FLAGS} is cached on first access 33ee90c03fe787ccc52c9605212eddf80cf50a7824Fyodor Kupolov * for consistent behavior across all connections opened in the process. 34ee90c03fe787ccc52c9605212eddf80cf50a7824Fyodor Kupolov * @hide 35ee90c03fe787ccc52c9605212eddf80cf50a7824Fyodor Kupolov */ 36ee90c03fe787ccc52c9605212eddf80cf50a7824Fyodor Kupolovpublic class SQLiteCompatibilityWalFlags { 37ee90c03fe787ccc52c9605212eddf80cf50a7824Fyodor Kupolov 38ee90c03fe787ccc52c9605212eddf80cf50a7824Fyodor Kupolov private static final String TAG = "SQLiteCompatibilityWalFlags"; 39ee90c03fe787ccc52c9605212eddf80cf50a7824Fyodor Kupolov 407fcd659705fc77114fd96e179d6b7fd8a61f71e7Fyodor Kupolov private static volatile boolean sInitialized; 41ee90c03fe787ccc52c9605212eddf80cf50a7824Fyodor Kupolov private static volatile boolean sFlagsSet; 42ee90c03fe787ccc52c9605212eddf80cf50a7824Fyodor Kupolov private static volatile boolean sCompatibilityWalSupported; 43ee90c03fe787ccc52c9605212eddf80cf50a7824Fyodor Kupolov private static volatile String sWALSyncMode; 44ee90c03fe787ccc52c9605212eddf80cf50a7824Fyodor Kupolov // This flag is used to avoid recursive initialization due to circular dependency on Settings 45ee90c03fe787ccc52c9605212eddf80cf50a7824Fyodor Kupolov private static volatile boolean sCallingGlobalSettings; 46ee90c03fe787ccc52c9605212eddf80cf50a7824Fyodor Kupolov 47ee90c03fe787ccc52c9605212eddf80cf50a7824Fyodor Kupolov /** 48ee90c03fe787ccc52c9605212eddf80cf50a7824Fyodor Kupolov * @hide 49ee90c03fe787ccc52c9605212eddf80cf50a7824Fyodor Kupolov */ 50ee90c03fe787ccc52c9605212eddf80cf50a7824Fyodor Kupolov @VisibleForTesting 51ee90c03fe787ccc52c9605212eddf80cf50a7824Fyodor Kupolov public static boolean areFlagsSet() { 52ee90c03fe787ccc52c9605212eddf80cf50a7824Fyodor Kupolov initIfNeeded(); 53ee90c03fe787ccc52c9605212eddf80cf50a7824Fyodor Kupolov return sFlagsSet; 54ee90c03fe787ccc52c9605212eddf80cf50a7824Fyodor Kupolov } 55ee90c03fe787ccc52c9605212eddf80cf50a7824Fyodor Kupolov 56ee90c03fe787ccc52c9605212eddf80cf50a7824Fyodor Kupolov /** 57ee90c03fe787ccc52c9605212eddf80cf50a7824Fyodor Kupolov * @hide 58ee90c03fe787ccc52c9605212eddf80cf50a7824Fyodor Kupolov */ 59ee90c03fe787ccc52c9605212eddf80cf50a7824Fyodor Kupolov @VisibleForTesting 60ee90c03fe787ccc52c9605212eddf80cf50a7824Fyodor Kupolov public static boolean isCompatibilityWalSupported() { 61ee90c03fe787ccc52c9605212eddf80cf50a7824Fyodor Kupolov initIfNeeded(); 62ee90c03fe787ccc52c9605212eddf80cf50a7824Fyodor Kupolov return sCompatibilityWalSupported; 63ee90c03fe787ccc52c9605212eddf80cf50a7824Fyodor Kupolov } 64ee90c03fe787ccc52c9605212eddf80cf50a7824Fyodor Kupolov 65ee90c03fe787ccc52c9605212eddf80cf50a7824Fyodor Kupolov /** 66ee90c03fe787ccc52c9605212eddf80cf50a7824Fyodor Kupolov * @hide 67ee90c03fe787ccc52c9605212eddf80cf50a7824Fyodor Kupolov */ 68ee90c03fe787ccc52c9605212eddf80cf50a7824Fyodor Kupolov @VisibleForTesting 69ee90c03fe787ccc52c9605212eddf80cf50a7824Fyodor Kupolov public static String getWALSyncMode() { 70ee90c03fe787ccc52c9605212eddf80cf50a7824Fyodor Kupolov initIfNeeded(); 71ee90c03fe787ccc52c9605212eddf80cf50a7824Fyodor Kupolov return sWALSyncMode; 72ee90c03fe787ccc52c9605212eddf80cf50a7824Fyodor Kupolov } 73ee90c03fe787ccc52c9605212eddf80cf50a7824Fyodor Kupolov 74ee90c03fe787ccc52c9605212eddf80cf50a7824Fyodor Kupolov private static void initIfNeeded() { 75ee90c03fe787ccc52c9605212eddf80cf50a7824Fyodor Kupolov if (sInitialized || sCallingGlobalSettings) { 76ee90c03fe787ccc52c9605212eddf80cf50a7824Fyodor Kupolov return; 77ee90c03fe787ccc52c9605212eddf80cf50a7824Fyodor Kupolov } 78ee90c03fe787ccc52c9605212eddf80cf50a7824Fyodor Kupolov ActivityThread activityThread = ActivityThread.currentActivityThread(); 79ee90c03fe787ccc52c9605212eddf80cf50a7824Fyodor Kupolov Application app = activityThread == null ? null : activityThread.getApplication(); 80ee90c03fe787ccc52c9605212eddf80cf50a7824Fyodor Kupolov String flags = null; 81ee90c03fe787ccc52c9605212eddf80cf50a7824Fyodor Kupolov if (app == null) { 82ee90c03fe787ccc52c9605212eddf80cf50a7824Fyodor Kupolov Log.w(TAG, "Cannot read global setting " 83ee90c03fe787ccc52c9605212eddf80cf50a7824Fyodor Kupolov + Settings.Global.SQLITE_COMPATIBILITY_WAL_FLAGS + " - " 84ee90c03fe787ccc52c9605212eddf80cf50a7824Fyodor Kupolov + "Application state not available"); 85ee90c03fe787ccc52c9605212eddf80cf50a7824Fyodor Kupolov } else { 86ee90c03fe787ccc52c9605212eddf80cf50a7824Fyodor Kupolov try { 87ee90c03fe787ccc52c9605212eddf80cf50a7824Fyodor Kupolov sCallingGlobalSettings = true; 88ee90c03fe787ccc52c9605212eddf80cf50a7824Fyodor Kupolov flags = Settings.Global.getString(app.getContentResolver(), 89ee90c03fe787ccc52c9605212eddf80cf50a7824Fyodor Kupolov Settings.Global.SQLITE_COMPATIBILITY_WAL_FLAGS); 90ee90c03fe787ccc52c9605212eddf80cf50a7824Fyodor Kupolov } finally { 91ee90c03fe787ccc52c9605212eddf80cf50a7824Fyodor Kupolov sCallingGlobalSettings = false; 92ee90c03fe787ccc52c9605212eddf80cf50a7824Fyodor Kupolov } 93ee90c03fe787ccc52c9605212eddf80cf50a7824Fyodor Kupolov } 94ee90c03fe787ccc52c9605212eddf80cf50a7824Fyodor Kupolov 95ee90c03fe787ccc52c9605212eddf80cf50a7824Fyodor Kupolov init(flags); 96ee90c03fe787ccc52c9605212eddf80cf50a7824Fyodor Kupolov } 97ee90c03fe787ccc52c9605212eddf80cf50a7824Fyodor Kupolov 98ee90c03fe787ccc52c9605212eddf80cf50a7824Fyodor Kupolov /** 99ee90c03fe787ccc52c9605212eddf80cf50a7824Fyodor Kupolov * @hide 100ee90c03fe787ccc52c9605212eddf80cf50a7824Fyodor Kupolov */ 101ee90c03fe787ccc52c9605212eddf80cf50a7824Fyodor Kupolov @VisibleForTesting 102ee90c03fe787ccc52c9605212eddf80cf50a7824Fyodor Kupolov public static void init(String flags) { 103ee90c03fe787ccc52c9605212eddf80cf50a7824Fyodor Kupolov if (TextUtils.isEmpty(flags)) { 104ee90c03fe787ccc52c9605212eddf80cf50a7824Fyodor Kupolov sInitialized = true; 105ee90c03fe787ccc52c9605212eddf80cf50a7824Fyodor Kupolov return; 106ee90c03fe787ccc52c9605212eddf80cf50a7824Fyodor Kupolov } 107ee90c03fe787ccc52c9605212eddf80cf50a7824Fyodor Kupolov KeyValueListParser parser = new KeyValueListParser(','); 108ee90c03fe787ccc52c9605212eddf80cf50a7824Fyodor Kupolov try { 109ee90c03fe787ccc52c9605212eddf80cf50a7824Fyodor Kupolov parser.setString(flags); 110ee90c03fe787ccc52c9605212eddf80cf50a7824Fyodor Kupolov } catch (IllegalArgumentException e) { 111ee90c03fe787ccc52c9605212eddf80cf50a7824Fyodor Kupolov Log.e(TAG, "Setting has invalid format: " + flags, e); 112ee90c03fe787ccc52c9605212eddf80cf50a7824Fyodor Kupolov sInitialized = true; 113ee90c03fe787ccc52c9605212eddf80cf50a7824Fyodor Kupolov return; 114ee90c03fe787ccc52c9605212eddf80cf50a7824Fyodor Kupolov } 115ee90c03fe787ccc52c9605212eddf80cf50a7824Fyodor Kupolov sCompatibilityWalSupported = parser.getBoolean("compatibility_wal_supported", 116ee90c03fe787ccc52c9605212eddf80cf50a7824Fyodor Kupolov SQLiteGlobal.isCompatibilityWalSupported()); 117ee90c03fe787ccc52c9605212eddf80cf50a7824Fyodor Kupolov sWALSyncMode = parser.getString("wal_syncmode", SQLiteGlobal.getWALSyncMode()); 118ee90c03fe787ccc52c9605212eddf80cf50a7824Fyodor Kupolov Log.i(TAG, "Read compatibility WAL flags: compatibility_wal_supported=" 119ee90c03fe787ccc52c9605212eddf80cf50a7824Fyodor Kupolov + sCompatibilityWalSupported + ", wal_syncmode=" + sWALSyncMode); 120ee90c03fe787ccc52c9605212eddf80cf50a7824Fyodor Kupolov sFlagsSet = true; 121ee90c03fe787ccc52c9605212eddf80cf50a7824Fyodor Kupolov sInitialized = true; 122ee90c03fe787ccc52c9605212eddf80cf50a7824Fyodor Kupolov } 123ee90c03fe787ccc52c9605212eddf80cf50a7824Fyodor Kupolov 124ee90c03fe787ccc52c9605212eddf80cf50a7824Fyodor Kupolov /** 125ee90c03fe787ccc52c9605212eddf80cf50a7824Fyodor Kupolov * @hide 126ee90c03fe787ccc52c9605212eddf80cf50a7824Fyodor Kupolov */ 127ee90c03fe787ccc52c9605212eddf80cf50a7824Fyodor Kupolov @VisibleForTesting 128ee90c03fe787ccc52c9605212eddf80cf50a7824Fyodor Kupolov public static void reset() { 129ee90c03fe787ccc52c9605212eddf80cf50a7824Fyodor Kupolov sInitialized = false; 130ee90c03fe787ccc52c9605212eddf80cf50a7824Fyodor Kupolov sFlagsSet = false; 131ee90c03fe787ccc52c9605212eddf80cf50a7824Fyodor Kupolov sCompatibilityWalSupported = false; 132ee90c03fe787ccc52c9605212eddf80cf50a7824Fyodor Kupolov sWALSyncMode = null; 133ee90c03fe787ccc52c9605212eddf80cf50a7824Fyodor Kupolov } 134ee90c03fe787ccc52c9605212eddf80cf50a7824Fyodor Kupolov} 135