DatabaseHelper.java revision d24b8183b93e781080b2c16c487e60d51c12da31
1/*
2 * Copyright (C) 2007 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 com.android.providers.settings;
18
19import android.content.ComponentName;
20import android.content.ContentValues;
21import android.content.Context;
22import android.content.Intent;
23import android.content.pm.ActivityInfo;
24import android.content.pm.PackageManager;
25import android.content.res.Resources;
26import android.database.Cursor;
27import android.database.sqlite.SQLiteDatabase;
28import android.database.sqlite.SQLiteOpenHelper;
29import android.database.sqlite.SQLiteStatement;
30import android.location.LocationManager;
31import android.media.AudioManager;
32import android.media.AudioService;
33import android.net.ConnectivityManager;
34import android.os.Environment;
35import android.os.SystemProperties;
36import android.provider.Settings;
37import android.text.TextUtils;
38import android.util.Config;
39import android.util.Log;
40import android.util.Xml;
41import com.android.internal.util.XmlUtils;
42
43import com.android.internal.widget.LockPatternUtils;
44import com.android.internal.widget.LockPatternView;
45
46import org.xmlpull.v1.XmlPullParser;
47import org.xmlpull.v1.XmlPullParserException;
48
49import java.io.File;
50import java.io.FileNotFoundException;
51import java.io.FileReader;
52import java.io.IOException;
53import java.util.List;
54
55/**
56 * Database helper class for {@link SettingsProvider}.
57 * Mostly just has a bit {@link #onCreate} to initialize the database.
58 */
59class DatabaseHelper extends SQLiteOpenHelper {
60    /**
61     * Path to file containing default bookmarks, relative to ANDROID_ROOT.
62     */
63    private static final String DEFAULT_BOOKMARKS_PATH = "etc/bookmarks.xml";
64
65    private static final String TAG = "SettingsProvider";
66    private static final String DATABASE_NAME = "settings.db";
67    private static final int DATABASE_VERSION = 32;
68
69    private Context mContext;
70
71    public DatabaseHelper(Context context) {
72        super(context, DATABASE_NAME, null, DATABASE_VERSION);
73        mContext = context;
74    }
75
76    private void createSecureTable(SQLiteDatabase db) {
77        db.execSQL("CREATE TABLE secure (" +
78                "_id INTEGER PRIMARY KEY AUTOINCREMENT," +
79                "name TEXT UNIQUE ON CONFLICT REPLACE," +
80                "value TEXT" +
81                ");");
82        db.execSQL("CREATE INDEX secureIndex1 ON secure (name);");
83    }
84
85    @Override
86    public void onCreate(SQLiteDatabase db) {
87        db.execSQL("CREATE TABLE system (" +
88                    "_id INTEGER PRIMARY KEY AUTOINCREMENT," +
89                    "name TEXT UNIQUE ON CONFLICT REPLACE," +
90                    "value TEXT" +
91                    ");");
92        db.execSQL("CREATE INDEX systemIndex1 ON system (name);");
93
94        createSecureTable(db);
95
96        db.execSQL("CREATE TABLE gservices (" +
97                   "_id INTEGER PRIMARY KEY AUTOINCREMENT," +
98                   "name TEXT UNIQUE ON CONFLICT REPLACE," +
99                   "value TEXT" +
100                   ");");
101        db.execSQL("CREATE INDEX gservicesIndex1 ON gservices (name);");
102
103        db.execSQL("CREATE TABLE bluetooth_devices (" +
104                    "_id INTEGER PRIMARY KEY," +
105                    "name TEXT," +
106                    "addr TEXT," +
107                    "channel INTEGER," +
108                    "type INTEGER" +
109                    ");");
110
111        db.execSQL("CREATE TABLE bookmarks (" +
112                    "_id INTEGER PRIMARY KEY," +
113                    "title TEXT," +
114                    "folder TEXT," +
115                    "intent TEXT," +
116                    "shortcut INTEGER," +
117                    "ordering INTEGER" +
118                    ");");
119
120        db.execSQL("CREATE INDEX bookmarksIndex1 ON bookmarks (folder);");
121        db.execSQL("CREATE INDEX bookmarksIndex2 ON bookmarks (shortcut);");
122
123        // Populate bookmarks table with initial bookmarks
124        loadBookmarks(db);
125
126        // Load initial volume levels into DB
127        loadVolumeLevels(db);
128
129        // Load inital settings values
130        loadSettings(db);
131    }
132
133    @Override
134    public void onUpgrade(SQLiteDatabase db, int oldVersion, int currentVersion) {
135        Log.w(TAG, "Upgrading settings database from version " + oldVersion + " to "
136                + currentVersion);
137
138        int upgradeVersion = oldVersion;
139
140        // Pattern for upgrade blocks:
141        //
142        //    if (upgradeVersion == [the DATABASE_VERSION you set] - 1) {
143        //        .. your upgrade logic..
144        //        upgradeVersion = [the DATABASE_VERSION you set]
145        //    }
146
147        if (upgradeVersion == 20) {
148            /*
149             * Version 21 is part of the volume control refresh. There is no
150             * longer a UI-visible for setting notification vibrate on/off (in
151             * our design), but the functionality still exists. Force the
152             * notification vibrate to on.
153             */
154            loadVibrateSetting(db, true);
155            if (Config.LOGD) Log.d(TAG, "Reset system vibrate setting");
156
157            upgradeVersion = 21;
158        }
159
160        if (upgradeVersion < 22) {
161            upgradeVersion = 22;
162            // Upgrade the lock gesture storage location and format
163            upgradeLockPatternLocation(db);
164        }
165
166        if (upgradeVersion < 23) {
167            db.execSQL("UPDATE favorites SET iconResource=0 WHERE iconType=0");
168            upgradeVersion = 23;
169        }
170
171        if (upgradeVersion == 23) {
172            db.beginTransaction();
173            try {
174                db.execSQL("ALTER TABLE favorites ADD spanX INTEGER");
175                db.execSQL("ALTER TABLE favorites ADD spanY INTEGER");
176                // Shortcuts, applications, folders
177                db.execSQL("UPDATE favorites SET spanX=1, spanY=1 WHERE itemType<=0");
178                // Photo frames, clocks
179                db.execSQL("UPDATE favorites SET spanX=2, spanY=2 WHERE itemType=1000 or itemType=1002");
180                // Search boxes
181                db.execSQL("UPDATE favorites SET spanX=4, spanY=1 WHERE itemType=1001");
182                db.setTransactionSuccessful();
183            } finally {
184                db.endTransaction();
185            }
186            upgradeVersion = 24;
187        }
188
189        if (upgradeVersion == 24) {
190            db.beginTransaction();
191            try {
192                // The value of the constants for preferring wifi or preferring mobile have been
193                // swapped, so reload the default.
194                db.execSQL("DELETE FROM system WHERE name='network_preference'");
195                db.execSQL("INSERT INTO system ('name', 'value') values ('network_preference', '" +
196                        ConnectivityManager.DEFAULT_NETWORK_PREFERENCE + "')");
197                db.setTransactionSuccessful();
198            } finally {
199                db.endTransaction();
200            }
201            upgradeVersion = 25;
202        }
203
204        if (upgradeVersion == 25) {
205            db.beginTransaction();
206            try {
207                db.execSQL("ALTER TABLE favorites ADD uri TEXT");
208                db.execSQL("ALTER TABLE favorites ADD displayMode INTEGER");
209                db.setTransactionSuccessful();
210            } finally {
211                db.endTransaction();
212            }
213            upgradeVersion = 26;
214        }
215
216        if (upgradeVersion == 26) {
217            // This introduces the new secure settings table.
218            db.beginTransaction();
219            try {
220                createSecureTable(db);
221                db.setTransactionSuccessful();
222            } finally {
223                db.endTransaction();
224            }
225            upgradeVersion = 27;
226        }
227
228        if (upgradeVersion == 27) {
229            // Copy settings values from 'system' to 'secure' and delete them from 'system'
230            SQLiteStatement insertStmt = null;
231            SQLiteStatement deleteStmt = null;
232
233            db.beginTransaction();
234            try {
235                insertStmt =
236                    db.compileStatement("INSERT INTO secure (name,value) SELECT name,value FROM "
237                        + "system WHERE name=?");
238                deleteStmt = db.compileStatement("DELETE FROM system WHERE name=?");
239
240                String[] settingsToMove = {
241                    Settings.Secure.ADB_ENABLED,
242                    Settings.Secure.ANDROID_ID,
243                    Settings.Secure.BLUETOOTH_ON,
244                    Settings.Secure.DATA_ROAMING,
245                    Settings.Secure.DEVICE_PROVISIONED,
246                    Settings.Secure.HTTP_PROXY,
247                    Settings.Secure.INSTALL_NON_MARKET_APPS,
248                    Settings.Secure.LOCATION_PROVIDERS_ALLOWED,
249                    Settings.Secure.LOGGING_ID,
250                    Settings.Secure.NETWORK_PREFERENCE,
251                    Settings.Secure.PARENTAL_CONTROL_ENABLED,
252                    Settings.Secure.PARENTAL_CONTROL_LAST_UPDATE,
253                    Settings.Secure.PARENTAL_CONTROL_REDIRECT_URL,
254                    Settings.Secure.SETTINGS_CLASSNAME,
255                    Settings.Secure.USB_MASS_STORAGE_ENABLED,
256                    Settings.Secure.USE_GOOGLE_MAIL,
257                    Settings.Secure.WIFI_NETWORKS_AVAILABLE_NOTIFICATION_ON,
258                    Settings.Secure.WIFI_NETWORKS_AVAILABLE_REPEAT_DELAY,
259                    Settings.Secure.WIFI_NUM_OPEN_NETWORKS_KEPT,
260                    Settings.Secure.WIFI_ON,
261                    Settings.Secure.WIFI_WATCHDOG_ACCEPTABLE_PACKET_LOSS_PERCENTAGE,
262                    Settings.Secure.WIFI_WATCHDOG_AP_COUNT,
263                    Settings.Secure.WIFI_WATCHDOG_BACKGROUND_CHECK_DELAY_MS,
264                    Settings.Secure.WIFI_WATCHDOG_BACKGROUND_CHECK_ENABLED,
265                    Settings.Secure.WIFI_WATCHDOG_BACKGROUND_CHECK_TIMEOUT_MS,
266                    Settings.Secure.WIFI_WATCHDOG_INITIAL_IGNORED_PING_COUNT,
267                    Settings.Secure.WIFI_WATCHDOG_MAX_AP_CHECKS,
268                    Settings.Secure.WIFI_WATCHDOG_ON,
269                    Settings.Secure.WIFI_WATCHDOG_PING_COUNT,
270                    Settings.Secure.WIFI_WATCHDOG_PING_DELAY_MS,
271                    Settings.Secure.WIFI_WATCHDOG_PING_TIMEOUT_MS,
272                };
273
274                for (String setting : settingsToMove) {
275                    insertStmt.bindString(1, setting);
276                    insertStmt.execute();
277
278                    deleteStmt.bindString(1, setting);
279                    deleteStmt.execute();
280                }
281                db.setTransactionSuccessful();
282            } finally {
283                db.endTransaction();
284                if (insertStmt != null) {
285                    insertStmt.close();
286                }
287                if (deleteStmt != null) {
288                    deleteStmt.close();
289                }
290            }
291            upgradeVersion = 28;
292        }
293
294        if (upgradeVersion == 28 || upgradeVersion == 29) {
295            // Note: The upgrade to 28 was flawed since it didn't delete the old
296            // setting first before inserting. Combining 28 and 29 with the
297            // fixed version.
298
299            // This upgrade adds the STREAM_NOTIFICATION type to the list of
300            // types affected by ringer modes (silent, vibrate, etc.)
301            db.beginTransaction();
302            try {
303                db.execSQL("DELETE FROM system WHERE name='"
304                        + Settings.System.MODE_RINGER_STREAMS_AFFECTED + "'");
305                int newValue = (1 << AudioManager.STREAM_RING)
306                        | (1 << AudioManager.STREAM_NOTIFICATION)
307                        | (1 << AudioManager.STREAM_SYSTEM);
308                db.execSQL("INSERT INTO system ('name', 'value') values ('"
309                        + Settings.System.MODE_RINGER_STREAMS_AFFECTED + "', '"
310                        + String.valueOf(newValue) + "')");
311                db.setTransactionSuccessful();
312            } finally {
313                db.endTransaction();
314            }
315
316            upgradeVersion = 30;
317        }
318
319        if (upgradeVersion == 30) {
320            /*
321             * Upgrade 31 clears the title for all quick launch shortcuts so the
322             * activities' titles will be resolved at display time. Also, the
323             * folder is changed to '@quicklaunch'.
324             */
325            db.beginTransaction();
326            try {
327                db.execSQL("UPDATE bookmarks SET folder = '@quicklaunch'");
328                db.execSQL("UPDATE bookmarks SET title = ''");
329                db.setTransactionSuccessful();
330            } finally {
331                db.endTransaction();
332            }
333            upgradeVersion = 31;
334        }
335
336        if (upgradeVersion == 31) {
337            /*
338             * Animations are now turned off by default.
339             */
340            db.beginTransaction();
341            try {
342                db.execSQL("DELETE FROM system WHERE name='"
343                        + Settings.System.WINDOW_ANIMATION_SCALE + "'");
344                db.execSQL("DELETE FROM system WHERE name='"
345                        + Settings.System.TRANSITION_ANIMATION_SCALE + "'");
346                SQLiteStatement stmt = db.compileStatement("INSERT INTO system(name,value)"
347                        + " VALUES(?,?);");
348                loadDefaultAnimationSettings(stmt);
349                stmt.close();
350                db.setTransactionSuccessful();
351            } finally {
352                db.endTransaction();
353            }
354            upgradeVersion = 32;
355        }
356
357        if (upgradeVersion != currentVersion) {
358            Log.w(TAG, "Got stuck trying to upgrade from version " + upgradeVersion
359                    + ", must wipe the settings provider");
360            db.execSQL("DROP TABLE IF EXISTS system");
361            db.execSQL("DROP INDEX IF EXISTS systemIndex1");
362            db.execSQL("DROP TABLE IF EXISTS secure");
363            db.execSQL("DROP INDEX IF EXISTS secureIndex1");
364            db.execSQL("DROP TABLE IF EXISTS gservices");
365            db.execSQL("DROP INDEX IF EXISTS gservicesIndex1");
366            db.execSQL("DROP TABLE IF EXISTS bluetooth_devices");
367            db.execSQL("DROP TABLE IF EXISTS bookmarks");
368            db.execSQL("DROP INDEX IF EXISTS bookmarksIndex1");
369            db.execSQL("DROP INDEX IF EXISTS bookmarksIndex2");
370            db.execSQL("DROP TABLE IF EXISTS favorites");
371            onCreate(db);
372        }
373    }
374
375    private void upgradeLockPatternLocation(SQLiteDatabase db) {
376        Cursor c = db.query("system", new String[] {"_id", "value"}, "name='lock_pattern'",
377                null, null, null, null);
378        if (c.getCount() > 0) {
379            c.moveToFirst();
380            String lockPattern = c.getString(1);
381            if (!TextUtils.isEmpty(lockPattern)) {
382                // Convert lock pattern
383                try {
384                    LockPatternUtils lpu = new LockPatternUtils(mContext.getContentResolver());
385                    List<LockPatternView.Cell> cellPattern =
386                            LockPatternUtils.stringToPattern(lockPattern);
387                    lpu.saveLockPattern(cellPattern);
388                } catch (IllegalArgumentException e) {
389                    // Don't want corrupted lock pattern to hang the reboot process
390                }
391            }
392            c.close();
393            db.delete("system", "name='lock_pattern'", null);
394        } else {
395            c.close();
396        }
397    }
398
399    /**
400     * Loads the default set of bookmarked shortcuts from an xml file.
401     *
402     * @param db The database to write the values into
403     * @param startingIndex The zero-based position at which bookmarks in this file should begin
404     * @param subPath The relative path from ANDROID_ROOT to the file to read
405     * @param quiet If true, do no complain if the file is missing
406     */
407    private int loadBookmarks(SQLiteDatabase db, int startingIndex, String subPath,
408            boolean quiet) {
409        FileReader bookmarksReader;
410
411        // Environment.getRootDirectory() is a fancy way of saying ANDROID_ROOT or "/system".
412        final File favFile = new File(Environment.getRootDirectory(), subPath);
413        try {
414            bookmarksReader = new FileReader(favFile);
415        } catch (FileNotFoundException e) {
416            if (!quiet) {
417                Log.e(TAG, "Couldn't find or open bookmarks file " + favFile);
418            }
419            return 0;
420        }
421
422        Intent intent = new Intent(Intent.ACTION_MAIN, null);
423        intent.addCategory(Intent.CATEGORY_LAUNCHER);
424        ContentValues values = new ContentValues();
425
426        PackageManager packageManager = mContext.getPackageManager();
427        ActivityInfo info;
428        int i = startingIndex;
429        try {
430            XmlPullParser parser = Xml.newPullParser();
431            parser.setInput(bookmarksReader);
432
433            XmlUtils.beginDocument(parser, "bookmarks");
434
435            while (true) {
436                XmlUtils.nextElement(parser);
437
438                String name = parser.getName();
439                if (!"bookmark".equals(name)) {
440                    break;
441                }
442
443                String pkg = parser.getAttributeValue(null, "package");
444                String cls = parser.getAttributeValue(null, "class");
445                String shortcutStr = parser.getAttributeValue(null, "shortcut");
446                int shortcutValue = (int) shortcutStr.charAt(0);
447                if (TextUtils.isEmpty(shortcutStr)) {
448                    Log.w(TAG, "Unable to get shortcut for: " + pkg + "/" + cls);
449                }
450                try {
451                    ComponentName cn = new ComponentName(pkg, cls);
452                    info = packageManager.getActivityInfo(cn, 0);
453                    intent.setComponent(cn);
454                    intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
455                    values.put(Settings.Bookmarks.INTENT, intent.toURI());
456                    values.put(Settings.Bookmarks.TITLE,
457                            info.loadLabel(packageManager).toString());
458                    values.put(Settings.Bookmarks.SHORTCUT, shortcutValue);
459                    db.insert("bookmarks", null, values);
460                    i++;
461                } catch (PackageManager.NameNotFoundException e) {
462                    Log.w(TAG, "Unable to add bookmark: " + pkg + "/" + cls, e);
463                }
464            }
465        } catch (XmlPullParserException e) {
466            Log.w(TAG, "Got execption parsing bookmarks.", e);
467        } catch (IOException e) {
468            Log.w(TAG, "Got execption parsing bookmarks.", e);
469        }
470
471        return i;
472    }
473
474    /**
475     * Loads the default set of bookmark packages.
476     *
477     * @param db The database to write the values into
478     */
479    private void loadBookmarks(SQLiteDatabase db) {
480        loadBookmarks(db, 0, DEFAULT_BOOKMARKS_PATH, false);
481    }
482
483    /**
484     * Loads the default volume levels. It is actually inserting the index of
485     * the volume array for each of the volume controls.
486     *
487     * @param db the database to insert the volume levels into
488     */
489    private void loadVolumeLevels(SQLiteDatabase db) {
490        SQLiteStatement stmt = db.compileStatement("INSERT OR IGNORE INTO system(name,value)"
491                + " VALUES(?,?);");
492
493        loadSetting(stmt, Settings.System.VOLUME_MUSIC,
494                AudioManager.DEFAULT_STREAM_VOLUME[AudioManager.STREAM_MUSIC]);
495        loadSetting(stmt, Settings.System.VOLUME_RING,
496                AudioManager.DEFAULT_STREAM_VOLUME[AudioManager.STREAM_RING]);
497        loadSetting(stmt, Settings.System.VOLUME_SYSTEM,
498                AudioManager.DEFAULT_STREAM_VOLUME[AudioManager.STREAM_SYSTEM]);
499        loadSetting(
500                stmt,
501                Settings.System.VOLUME_VOICE,
502                AudioManager.DEFAULT_STREAM_VOLUME[AudioManager.STREAM_VOICE_CALL]);
503        loadSetting(stmt, Settings.System.VOLUME_ALARM,
504                AudioManager.DEFAULT_STREAM_VOLUME[AudioManager.STREAM_ALARM]);
505        loadSetting(
506                stmt,
507                Settings.System.VOLUME_NOTIFICATION,
508                AudioManager.DEFAULT_STREAM_VOLUME[AudioManager.STREAM_NOTIFICATION]);
509        loadSetting(stmt, Settings.System.MODE_RINGER,
510                AudioManager.RINGER_MODE_NORMAL);
511
512        loadVibrateSetting(db, false);
513
514        // By default, only the ring/notification and system streams are affected
515        loadSetting(stmt, Settings.System.MODE_RINGER_STREAMS_AFFECTED,
516                (1 << AudioManager.STREAM_RING) | (1 << AudioManager.STREAM_NOTIFICATION) |
517                (1 << AudioManager.STREAM_SYSTEM));
518
519        loadSetting(stmt, Settings.System.MUTE_STREAMS_AFFECTED,
520                ((1 << AudioManager.STREAM_MUSIC) |
521                 (1 << AudioManager.STREAM_RING) |
522                 (1 << AudioManager.STREAM_NOTIFICATION) |
523                 (1 << AudioManager.STREAM_SYSTEM)));
524
525        stmt.close();
526    }
527
528    private void loadVibrateSetting(SQLiteDatabase db, boolean deleteOld) {
529        if (deleteOld) {
530            db.execSQL("DELETE FROM system WHERE name='" + Settings.System.VIBRATE_ON + "'");
531        }
532
533        SQLiteStatement stmt = db.compileStatement("INSERT OR IGNORE INTO system(name,value)"
534                + " VALUES(?,?);");
535
536        // Vibrate off by default for ringer, on for notification
537        int vibrate = 0;
538        vibrate = AudioService.getValueForVibrateSetting(vibrate,
539                AudioManager.VIBRATE_TYPE_NOTIFICATION, AudioManager.VIBRATE_SETTING_ON);
540        vibrate = AudioService.getValueForVibrateSetting(vibrate,
541                AudioManager.VIBRATE_TYPE_RINGER, AudioManager.VIBRATE_SETTING_OFF);
542        loadSetting(stmt, Settings.System.VIBRATE_ON, vibrate);
543    }
544
545    private void loadSettings(SQLiteDatabase db) {
546        loadSystemSettings(db);
547        loadSecureSettings(db);
548    }
549
550    private void loadSystemSettings(SQLiteDatabase db) {
551        SQLiteStatement stmt = db.compileStatement("INSERT OR IGNORE INTO system(name,value)"
552                + " VALUES(?,?);");
553
554        Resources r = mContext.getResources();
555        loadBooleanSetting(stmt, Settings.System.DIM_SCREEN,
556                R.bool.def_dim_screen);
557        loadSetting(stmt, Settings.System.STAY_ON_WHILE_PLUGGED_IN,
558                "1".equals(SystemProperties.get("ro.kernel.qemu")) ? 1 : 0);
559        loadIntegerSetting(stmt, Settings.System.SCREEN_OFF_TIMEOUT,
560                R.integer.def_screen_off_timeout);
561
562        loadBooleanSetting(stmt, Settings.System.AIRPLANE_MODE_ON,
563                R.bool.def_airplane_mode_on);
564
565        loadStringSetting(stmt, Settings.System.AIRPLANE_MODE_RADIOS,
566                R.string.def_airplane_mode_radios);
567
568        loadBooleanSetting(stmt, Settings.System.AUTO_TIME,
569                R.bool.def_auto_time); // Sync time to NITZ
570
571        loadIntegerSetting(stmt, Settings.System.SCREEN_BRIGHTNESS,
572                R.integer.def_screen_brightness);
573
574        loadDefaultAnimationSettings(stmt);
575
576        loadBooleanSetting(stmt, Settings.System.ACCELEROMETER_ROTATION,
577                R.bool.def_accelerometer_rotation);
578
579        // Default date format based on build
580        loadSetting(stmt, Settings.System.DATE_FORMAT,
581                SystemProperties.get("ro.com.android.dateformat",
582                        "MM-dd-yyyy"));
583        stmt.close();
584    }
585
586    private void loadDefaultAnimationSettings(SQLiteStatement stmt) {
587        loadFractionSetting(stmt, Settings.System.WINDOW_ANIMATION_SCALE,
588                R.fraction.def_window_animation_scale, 1);
589        loadFractionSetting(stmt, Settings.System.TRANSITION_ANIMATION_SCALE,
590                R.fraction.def_window_transition_scale, 1);
591    }
592
593    private void loadSecureSettings(SQLiteDatabase db) {
594        SQLiteStatement stmt = db.compileStatement("INSERT OR IGNORE INTO secure(name,value)"
595                + " VALUES(?,?);");
596
597        loadBooleanSetting(stmt, Settings.Secure.BLUETOOTH_ON,
598                R.bool.def_bluetooth_on);
599
600        // Data roaming default, based on build
601        loadSetting(stmt, Settings.Secure.DATA_ROAMING,
602                "true".equalsIgnoreCase(
603                        SystemProperties.get("ro.com.android.dataroaming",
604                                "false")) ? 1 : 0);
605
606        loadBooleanSetting(stmt, Settings.Secure.INSTALL_NON_MARKET_APPS,
607                R.bool.def_install_non_market_apps);
608
609        loadStringSetting(stmt, Settings.Secure.LOCATION_PROVIDERS_ALLOWED,
610                R.string.def_location_providers_allowed);
611
612        loadIntegerSetting(stmt, Settings.Secure.NETWORK_PREFERENCE,
613                R.integer.def_network_preference);
614
615        loadBooleanSetting(stmt, Settings.Secure.USB_MASS_STORAGE_ENABLED,
616                R.bool.def_usb_mass_storage_enabled);
617
618        loadBooleanSetting(stmt, Settings.Secure.WIFI_ON,
619                R.bool.def_wifi_on);
620        loadBooleanSetting(stmt, Settings.Secure.WIFI_NETWORKS_AVAILABLE_NOTIFICATION_ON,
621                R.bool.def_networks_available_notification_on);
622
623        // Don't do this.  The SystemServer will initialize ADB_ENABLED from a
624        // persistent system property instead.
625        //loadSetting(stmt, Settings.Secure.ADB_ENABLED, 0);
626
627        stmt.close();
628    }
629
630    private void loadSetting(SQLiteStatement stmt, String key, Object value) {
631        stmt.bindString(1, key);
632        stmt.bindString(2, value.toString());
633        stmt.execute();
634    }
635
636    private void loadStringSetting(SQLiteStatement stmt, String key, int resid) {
637        loadSetting(stmt, key, mContext.getResources().getString(resid));
638    }
639
640    private void loadBooleanSetting(SQLiteStatement stmt, String key, int resid) {
641        loadSetting(stmt, key,
642                mContext.getResources().getBoolean(resid) ? "1" : "0");
643    }
644
645    private void loadIntegerSetting(SQLiteStatement stmt, String key, int resid) {
646        loadSetting(stmt, key,
647                Integer.toString(mContext.getResources().getInteger(resid)));
648    }
649
650    private void loadFractionSetting(SQLiteStatement stmt, String key, int resid, int base) {
651        loadSetting(stmt, key,
652                Float.toString(mContext.getResources().getFraction(resid, base, base)));
653    }
654}
655