Android源码修改或添加SettingsProvider的默认值

Android ROM定制开发的时候,通常会需要添加或者修改系统设置中的默认值,比如设置屏幕熄灭时间、调整锁屏状态以及默认禁止屏幕自动旋转等功能。实现方法就是在SettingsProvider中default.xml文件中修改或者添加默认值。

1 SettingsProvider

SettingsProvider顾名思义是一个提供设置数据共享的Provider。其中包含全局性、系统级别的用户编好设置。在手机中有一个Settings应用,用户可以在Settings里面做很多设备的设置,这些用户偏好的设置很多就保存在SettingsProvider中。SettingsProvider和Android系统其它Provider有很多不一样的地方:比如SettingsProvider只接受int、float、string等基本类型的数据、SettingsProvider由Android系统framework进行了封装,使用更加快捷方便、SettingsProvider的数据由键值对组成。在Android 6.0版本时,SettingsProvider被重构,Android从性能、安全等方面考虑,把SettingsProvider中原本保存在settings.db中的数据,全部保存到了XML文件中。通常位于/data/system/users/userid/下面。

SettingsProvider对数据进行了分类,分别是Global、System、Secure三种类型,它们的区别如下:

1.1 Global

所有的偏好设置对系统的所有用户公开,第三方APP有读没有写的权限。

1.2 System

包含各种各样的用户偏好系统设置。

1.3 Secure

安全性的用户偏好系统设置,第三方APP有读没有写的权限。

1.4 调试

可以通过adb shell settings get global key获取单个数据的值,也可以通过adb shell settings list system、global或者secure来获取整个类别中的所有属性值。

2 SettingsProvider中的数据定义

系统设置中的参数定义在frameworks/base/core/java/android/provider/Settings.java文件中。代码中分别用三个class对应三种类型。比如在System class中可以看到屏幕灭屏时间以及亮度的设置对应的key值:

  /**
 * The amount of time in milliseconds before the device goes to sleep or begins
 * to dream after a period of inactivity.  This value is also known as the
 * user activity timeout period since the screen isn't necessarily turned off
 * when it expires.
 */
public static final String SCREEN_OFF_TIMEOUT = "screen_off_timeout";

private static final Validator SCREEN_OFF_TIMEOUT_VALIDATOR = sNonNegativeIntegerValidator;

/**
 * The screen backlight brightness between 0 and 255.
 */
public static final String SCREEN_BRIGHTNESS = "screen_brightness";

在framework/base/packages/SettingsProvider/src/com/android/providers/settings/DatabaseHelper.java中可以看到SettingsProvider中的数据初始化。

private void loadSettings(SQLiteDatabase db) {
        loadSystemSettings(db);
        loadSecureSettings(db);
        // The global table only exists for the 'owner/system' user
        if (mUserHandle == UserHandle.USER_SYSTEM) {
            loadGlobalSettings(db);
        }
    }

    private void loadSystemSettings(SQLiteDatabase db) {
        SQLiteStatement stmt = null;
        try {
            stmt = db.compileStatement("INSERT OR IGNORE INTO system(name,value)"
                    + " VALUES(?,?);");

            loadBooleanSetting(stmt, Settings.System.DIM_SCREEN,
                    R.bool.def_dim_screen);
            loadIntegerSetting(stmt, Settings.System.SCREEN_OFF_TIMEOUT,
                    R.integer.def_screen_off_timeout);

            // Set default cdma DTMF type
            loadSetting(stmt, Settings.System.DTMF_TONE_TYPE_WHEN_DIALING, 0);

            // Set default hearing aid
            loadSetting(stmt, Settings.System.HEARING_AID, 0);

            // Set default tty mode
            loadSetting(stmt, Settings.System.TTY_MODE, 0);

            loadIntegerSetting(stmt, Settings.System.SCREEN_BRIGHTNESS,
                    R.integer.def_screen_brightness);

            loadBooleanSetting(stmt, Settings.System.SCREEN_BRIGHTNESS_MODE,
                    R.bool.def_screen_brightness_automatic_mode);

            loadDefaultAnimationSettings(stmt);

            loadBooleanSetting(stmt, Settings.System.ACCELEROMETER_ROTATION,
                    R.bool.def_accelerometer_rotation);

            loadDefaultHapticSettings(stmt);

            loadBooleanSetting(stmt, Settings.System.NOTIFICATION_LIGHT_PULSE,
                    R.bool.def_notification_pulse);

            final boolean isShowPassword =
                    mContext.getResources().getBoolean(R.bool.config_show_password_on);
            if (isShowPassword) {
                loadBooleanSetting(stmt, Settings.System.TEXT_SHOW_PASSWORD,
                        R.bool.def_show_password_on);
            }


            loadUISoundEffectsSettings(stmt);

            loadIntegerSetting(stmt, Settings.System.POINTER_SPEED,
                    R.integer.def_pointer_speed);

            /*
             * IMPORTANT: Do not add any more upgrade steps here as the global,
             * secure, and system settings are no longer stored in a database
             * but are kept in memory and persisted to XML.
             *
             * See: SettingsProvider.UpgradeController#onUpgradeLocked
             */
        } finally {
            if (stmt != null) stmt.close();
        }
    }

3 修改实例

android系统中通过 global 中的 verifier_verify_adb_installs 开关来控制是否需要对adb安装的客户端文件进行检查,在android 8.1中 verifier_verify_adb_installs 默认为打开。如果我们想要关闭它,实际更改过程中,只需要两步即可完成修改。

  1. 添加默认值

    frameworks/base/packages/SettingsProvider/res/values/defaults.xml 中添加默认值:

    <integer name="def_verifier_verify_adb_installs">0</integer>
    
  2. 数据库初始化

    frameworks/base/packages/SettingsProvider/src/com/android/providers/settings/DatabaseHelper.java 中完成数据库初始化:

    loadIntegerSetting(stmt, Settings.Global.PACKAGE_VERIFIER_INCLUDE_ADB,
                       def_verifier_verify_adb_installs);