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