• 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.annotation.TestApi;
20 import android.app.ActivityThread;
21 import android.app.Application;
22 import android.provider.Settings;
23 import android.text.TextUtils;
24 import android.util.KeyValueListParser;
25 import android.util.Log;
26 
27 import com.android.internal.annotations.VisibleForTesting;
28 
29 /**
30  * Helper class for accessing
31  * {@link Settings.Global#SQLITE_COMPATIBILITY_WAL_FLAGS global compatibility WAL settings}.
32  *
33  * <p>The value of {@link Settings.Global#SQLITE_COMPATIBILITY_WAL_FLAGS} is cached on first access
34  * for consistent behavior across all connections opened in the process.
35  * @hide
36  */
37 @TestApi
38 public class SQLiteCompatibilityWalFlags {
39 
40     private static final String TAG = "SQLiteCompatibilityWalFlags";
41 
42     private static volatile boolean sInitialized;
43     private static volatile boolean sLegacyCompatibilityWalEnabled;
44     private static volatile String sWALSyncMode;
45     private static volatile long sTruncateSize = -1;
46     // This flag is used to avoid recursive initialization due to circular dependency on Settings
47     private static volatile boolean sCallingGlobalSettings;
48 
SQLiteCompatibilityWalFlags()49     private SQLiteCompatibilityWalFlags() {
50     }
51 
52     /**
53      * @hide
54      */
55     @VisibleForTesting
isLegacyCompatibilityWalEnabled()56     public static boolean isLegacyCompatibilityWalEnabled() {
57         initIfNeeded();
58         return sLegacyCompatibilityWalEnabled;
59     }
60 
61     /**
62      * @hide
63      */
64     @VisibleForTesting
getWALSyncMode()65     public static String getWALSyncMode() {
66         initIfNeeded();
67         // The configurable WAL sync mode should only ever be used if the legacy compatibility
68         // WAL is enabled. It should *not* have any effect if app developers explicitly turn on
69         // WAL for their database using setWriteAheadLoggingEnabled. Throwing an exception here
70         // adds an extra layer of checking that we never use it in the wrong place.
71         if (!sLegacyCompatibilityWalEnabled) {
72             throw new IllegalStateException("isLegacyCompatibilityWalEnabled() == false");
73         }
74 
75         return sWALSyncMode;
76     }
77 
78     /**
79      * Override {@link com.android.internal.R.integer#db_wal_truncate_size}.
80      *
81      * @return the value set in the global setting, or -1 if a value is not set.
82      *
83      * @hide
84      */
85     @VisibleForTesting
getTruncateSize()86     public static long getTruncateSize() {
87         initIfNeeded();
88         return sTruncateSize;
89     }
90 
initIfNeeded()91     private static void initIfNeeded() {
92         if (sInitialized || sCallingGlobalSettings) {
93             return;
94         }
95         ActivityThread activityThread = ActivityThread.currentActivityThread();
96         Application app = activityThread == null ? null : activityThread.getApplication();
97         String flags = null;
98         if (app == null) {
99             Log.w(TAG, "Cannot read global setting "
100                     + Settings.Global.SQLITE_COMPATIBILITY_WAL_FLAGS + " - "
101                     + "Application state not available");
102         } else {
103             try {
104                 sCallingGlobalSettings = true;
105                 flags = Settings.Global.getString(app.getContentResolver(),
106                         Settings.Global.SQLITE_COMPATIBILITY_WAL_FLAGS);
107             } catch (Exception e) {
108                 // The process is unable to read the flags.  Treat this condition the same as if
109                 // the ActivityThread application was not available.
110                 Log.w(TAG, "Cannot read global setting "
111                         + Settings.Global.SQLITE_COMPATIBILITY_WAL_FLAGS + " - " + e.toString());
112             } finally {
113                 sCallingGlobalSettings = false;
114             }
115         }
116 
117         init(flags);
118     }
119 
120     /**
121      * @hide
122      */
123     @VisibleForTesting
init(String flags)124     public static void init(String flags) {
125         if (TextUtils.isEmpty(flags)) {
126             sInitialized = true;
127             return;
128         }
129         KeyValueListParser parser = new KeyValueListParser(',');
130         try {
131             parser.setString(flags);
132         } catch (IllegalArgumentException e) {
133             Log.e(TAG, "Setting has invalid format: " + flags, e);
134             sInitialized = true;
135             return;
136         }
137         sLegacyCompatibilityWalEnabled = parser.getBoolean(
138                 "legacy_compatibility_wal_enabled", false);
139         sWALSyncMode = parser.getString("wal_syncmode", SQLiteGlobal.getWALSyncMode());
140         sTruncateSize = parser.getInt("truncate_size", -1);
141         Log.i(TAG, "Read compatibility WAL flags: legacy_compatibility_wal_enabled="
142                 + sLegacyCompatibilityWalEnabled + ", wal_syncmode=" + sWALSyncMode);
143         sInitialized = true;
144     }
145 
146     /**
147      * @hide
148      */
149     @VisibleForTesting
150     @TestApi
reset()151     public static void reset() {
152         sInitialized = false;
153         sLegacyCompatibilityWalEnabled = false;
154         sWALSyncMode = null;
155     }
156 }
157