blob: 06c069c583b51dae3ca0e5a66e40ac86ac795dbd [file] [log] [blame]
Fyodor Kupolovee90c032017-12-12 11:52:57 -08001/*
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
17package android.database.sqlite;
18
19import android.app.ActivityThread;
20import android.app.Application;
21import android.provider.Settings;
22import android.text.TextUtils;
23import android.util.KeyValueListParser;
24import android.util.Log;
25
26import 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 */
36public class SQLiteCompatibilityWalFlags {
37
38 private static final String TAG = "SQLiteCompatibilityWalFlags";
39
Fyodor Kupolov7fcd6592017-12-15 11:56:36 -080040 private static volatile boolean sInitialized;
Fyodor Kupolovee90c032017-12-12 11:52:57 -080041 private static volatile boolean sFlagsSet;
42 private static volatile boolean sCompatibilityWalSupported;
43 private static volatile String sWALSyncMode;
Makoto Onuki0939c5a2018-08-24 13:38:40 -070044 private static volatile long sTruncateSize = -1;
Fyodor Kupolovee90c032017-12-12 11:52:57 -080045 // This flag is used to avoid recursive initialization due to circular dependency on Settings
46 private static volatile boolean sCallingGlobalSettings;
47
48 /**
49 * @hide
50 */
51 @VisibleForTesting
52 public static boolean areFlagsSet() {
53 initIfNeeded();
54 return sFlagsSet;
55 }
56
57 /**
58 * @hide
59 */
60 @VisibleForTesting
61 public static boolean isCompatibilityWalSupported() {
62 initIfNeeded();
63 return sCompatibilityWalSupported;
64 }
65
66 /**
67 * @hide
68 */
69 @VisibleForTesting
70 public static String getWALSyncMode() {
71 initIfNeeded();
72 return sWALSyncMode;
73 }
74
Makoto Onuki0939c5a2018-08-24 13:38:40 -070075 /**
76 * Override {@link com.android.internal.R.integer#db_wal_truncate_size}.
77 *
78 * @return the value set in the global setting, or -1 if a value is not set.
79 *
80 * @hide
81 */
82 @VisibleForTesting
83 public static long getTruncateSize() {
84 initIfNeeded();
85 return sTruncateSize;
86 }
87
Fyodor Kupolovee90c032017-12-12 11:52:57 -080088 private static void initIfNeeded() {
89 if (sInitialized || sCallingGlobalSettings) {
90 return;
91 }
92 ActivityThread activityThread = ActivityThread.currentActivityThread();
93 Application app = activityThread == null ? null : activityThread.getApplication();
94 String flags = null;
95 if (app == null) {
96 Log.w(TAG, "Cannot read global setting "
97 + Settings.Global.SQLITE_COMPATIBILITY_WAL_FLAGS + " - "
98 + "Application state not available");
99 } else {
100 try {
101 sCallingGlobalSettings = true;
102 flags = Settings.Global.getString(app.getContentResolver(),
103 Settings.Global.SQLITE_COMPATIBILITY_WAL_FLAGS);
104 } finally {
105 sCallingGlobalSettings = false;
106 }
107 }
108
109 init(flags);
110 }
111
112 /**
113 * @hide
114 */
115 @VisibleForTesting
116 public static void init(String flags) {
117 if (TextUtils.isEmpty(flags)) {
118 sInitialized = true;
119 return;
120 }
121 KeyValueListParser parser = new KeyValueListParser(',');
122 try {
123 parser.setString(flags);
124 } catch (IllegalArgumentException e) {
125 Log.e(TAG, "Setting has invalid format: " + flags, e);
126 sInitialized = true;
127 return;
128 }
129 sCompatibilityWalSupported = parser.getBoolean("compatibility_wal_supported",
130 SQLiteGlobal.isCompatibilityWalSupported());
131 sWALSyncMode = parser.getString("wal_syncmode", SQLiteGlobal.getWALSyncMode());
Makoto Onuki0939c5a2018-08-24 13:38:40 -0700132 sTruncateSize = parser.getInt("truncate_size", -1);
Fyodor Kupolovee90c032017-12-12 11:52:57 -0800133 Log.i(TAG, "Read compatibility WAL flags: compatibility_wal_supported="
134 + sCompatibilityWalSupported + ", wal_syncmode=" + sWALSyncMode);
135 sFlagsSet = true;
136 sInitialized = true;
137 }
138
139 /**
140 * @hide
141 */
142 @VisibleForTesting
143 public static void reset() {
144 sInitialized = false;
145 sFlagsSet = false;
146 sCompatibilityWalSupported = false;
147 sWALSyncMode = null;
148 }
149}