1 /*
2  * Copyright (C) 2011 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.content.res.Resources;
21 import android.os.StatFs;
22 import android.os.SystemProperties;
23 
24 /**
25  * Provides access to SQLite functions that affect all database connection,
26  * such as memory management.
27  *
28  * The native code associated with SQLiteGlobal is also sets global configuration options
29  * using sqlite3_config() then calls sqlite3_initialize() to ensure that the SQLite
30  * library is properly initialized exactly once before any other framework or application
31  * code has a chance to run.
32  *
33  * Verbose SQLite logging is enabled if the "log.tag.SQLiteLog" property is set to "V".
34  * (per {@link SQLiteDebug#DEBUG_SQL_LOG}).
35  *
36  * @hide
37  */
38 @TestApi
39 public final class SQLiteGlobal {
40     private static final String TAG = "SQLiteGlobal";
41 
42     /** @hide */
43     public static final String SYNC_MODE_FULL = "FULL";
44 
45     /** @hide */
46     static final String WIPE_CHECK_FILE_SUFFIX = "-wipecheck";
47 
48     private static final Object sLock = new Object();
49 
50     private static int sDefaultPageSize;
51 
nativeReleaseMemory()52     private static native int nativeReleaseMemory();
53 
54     /** @hide */
55     public static volatile String sDefaultSyncMode;
56 
SQLiteGlobal()57     private SQLiteGlobal() {
58     }
59 
60     /**
61      * Attempts to release memory by pruning the SQLite page cache and other
62      * internal data structures.
63      *
64      * @return The number of bytes that were freed.
65      */
releaseMemory()66     public static int releaseMemory() {
67         return nativeReleaseMemory();
68     }
69 
70     /**
71      * Gets the default page size to use when creating a database.
72      */
getDefaultPageSize()73     public static int getDefaultPageSize() {
74         synchronized (sLock) {
75             if (sDefaultPageSize == 0) {
76                 // If there is an issue accessing /data, something is so seriously
77                 // wrong that we just let the IllegalArgumentException propagate.
78                 sDefaultPageSize = new StatFs("/data").getBlockSize();
79             }
80             return SystemProperties.getInt("debug.sqlite.pagesize", sDefaultPageSize);
81         }
82     }
83 
84     /**
85      * Gets the default journal mode when WAL is not in use.
86      */
getDefaultJournalMode()87     public static String getDefaultJournalMode() {
88         return SystemProperties.get("debug.sqlite.journalmode",
89                 Resources.getSystem().getString(
90                 com.android.internal.R.string.db_default_journal_mode));
91     }
92 
93     /**
94      * Gets the journal size limit in bytes.
95      */
getJournalSizeLimit()96     public static int getJournalSizeLimit() {
97         return SystemProperties.getInt("debug.sqlite.journalsizelimit",
98                 Resources.getSystem().getInteger(
99                 com.android.internal.R.integer.db_journal_size_limit));
100     }
101 
102     /**
103      * Gets the default database synchronization mode when WAL is not in use.
104      */
getDefaultSyncMode()105     public static String getDefaultSyncMode() {
106         // Use the FULL synchronous mode for system processes by default.
107         String defaultMode = sDefaultSyncMode;
108         if (defaultMode != null) {
109             return defaultMode;
110         }
111         return SystemProperties.get("debug.sqlite.syncmode",
112                 Resources.getSystem().getString(
113                 com.android.internal.R.string.db_default_sync_mode));
114     }
115 
116     /**
117      * Gets the database synchronization mode when in WAL mode.
118      */
getWALSyncMode()119     public static String getWALSyncMode() {
120         // Use the FULL synchronous mode for system processes by default.
121         String defaultMode = sDefaultSyncMode;
122         if (defaultMode != null) {
123             return defaultMode;
124         }
125         return SystemProperties.get("debug.sqlite.wal.syncmode",
126                 Resources.getSystem().getString(
127                 com.android.internal.R.string.db_wal_sync_mode));
128     }
129 
130     /**
131      * Gets the WAL auto-checkpoint integer in database pages.
132      */
getWALAutoCheckpoint()133     public static int getWALAutoCheckpoint() {
134         int value = SystemProperties.getInt("debug.sqlite.wal.autocheckpoint",
135                 Resources.getSystem().getInteger(
136                 com.android.internal.R.integer.db_wal_autocheckpoint));
137         return Math.max(1, value);
138     }
139 
140     /**
141      * Gets the connection pool size when in WAL mode.
142      */
getWALConnectionPoolSize()143     public static int getWALConnectionPoolSize() {
144         int value = SystemProperties.getInt("debug.sqlite.wal.poolsize",
145                 Resources.getSystem().getInteger(
146                 com.android.internal.R.integer.db_connection_pool_size));
147         return Math.max(2, value);
148     }
149 
150     /**
151      * The default number of milliseconds that SQLite connection is allowed to be idle before it
152      * is closed and removed from the pool.
153      */
getIdleConnectionTimeout()154     public static int getIdleConnectionTimeout() {
155         return SystemProperties.getInt("debug.sqlite.idle_connection_timeout",
156                 Resources.getSystem().getInteger(
157                         com.android.internal.R.integer.db_default_idle_connection_timeout));
158     }
159 
160     /**
161      * When opening a database, if the WAL file is larger than this size, we'll truncate it.
162      *
163      * (If it's 0, we do not truncate.)
164      *
165      * @hide
166      */
getWALTruncateSize()167     public static long getWALTruncateSize() {
168         final long setting = SQLiteCompatibilityWalFlags.getTruncateSize();
169         if (setting >= 0) {
170             return setting;
171         }
172         return SystemProperties.getInt("debug.sqlite.wal.truncatesize",
173                 Resources.getSystem().getInteger(
174                         com.android.internal.R.integer.db_wal_truncate_size));
175     }
176 
177     /** @hide */
checkDbWipe()178     public static boolean checkDbWipe() {
179         return false;
180     }
181 }
182