Settings的apk的目录是在packages\apps\Settings下,因为咱们添加的从不休眠是在显示项里面,因此咱们就直接看DisplaySettings.Java的代码了。html
[java] view plain copyjava
- @Override
- public void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- final Activity activity = getActivity();
- final ContentResolver resolver = activity.getContentResolver();
- 入display_settings的Preferences
- addPreferencesFromResource(R.xml.display_settings);
-
- mScreenSaverPreference = findPreference(KEY_SCREEN_SAVER);
- if (mScreenSaverPreference != null
- && getResources().getBoolean(
- com.android.internal.R.bool.config_dreamsSupported) == false) {
- getPreferenceScreen().removePreference(mScreenSaverPreference);
- }
- 到屏幕休眠时间的ListPreference
- mScreenTimeoutPreference = (ListPreference) findPreference(KEY_SCREEN_TIMEOUT);
- final long currentTimeout = Settings.System.getLong(resolver, SCREEN_OFF_TIMEOUT,//从settings数据库中获取屏幕休眠时间
- FALLBACK_SCREEN_TIMEOUT_VALUE);
- //mScreenTimeoutPreference.setValue(String.valueOf(currentTimeout));
- //
- long timeoutValue = (currentTimeout == Integer.MAX_VALUE) ? -1 : currentTimeout;//若是从数据库获得最大值,改为-1
- mScreenTimeoutPreference.setValue(String.valueOf(timeoutValue));
- //
- mScreenTimeoutPreference.setOnPreferenceChangeListener(this);//监听变化
- disableUnusableTimeouts(mScreenTimeoutPreference);
- //updateTimeoutPreferenceDescription(currentTimeout);
- updateTimeoutPreferenceDescription(timeoutValue);//更新屏幕上的信息
咱们先看下display_settings.xml文件中screen_timeout这个ListPreference;mysql
[html] view plain copyandroid
- <ListPreference
- android:key="screen_timeout"
- android:title="@string/screen_timeout"
- android:summary="@string/screen_timeout_summary"
- android:persistent="false"
- android:entries="@array/screen_timeout_entries"
- android:entryValues="@array/screen_timeout_values" />
接下来咱们看下updateTimeoutPreferenceDescription这个函数,这个函数最后调用preference.setSummary主要更新屏幕上的信息sql
[java] view plain copy数据库
- private void updateTimeoutPreferenceDescription(long currentTimeout) {
- ListPreference preference = mScreenTimeoutPreference;
- String summary;
- if (currentTimeout == -1) {//若是为-1,string为永不
- // Unsupported value
- summary = preference.getContext().getString(R.string.screen_never_timeout_summary);
- } else if (currentTimeout < -1) {
- // Unsupported value
- summary = "";
- } else {
- final CharSequence[] entries = preference.getEntries();
- final CharSequence[] values = preference.getEntryValues();
- if (entries == null || entries.length == 0) {
- summary = "";
- } else {
- int best = 0;
- for (int i = 0; i < values.length; i++) {
- long timeout = Long.parseLong(values[i].toString());
- /*if (currentTimeout >= timeout) {
- best = i;
- }*/
- if (currentTimeout >= timeout && timeout > 0) {//timeout为了过滤-1
- best = i;
- }
- }
- summary = preference.getContext().getString(R.string.screen_timeout_summary,
- entries[best]);
- }
- }
- preference.setSummary(summary);
- }
先看下R.string.screen_timeout_summary这个stringapp
[html] view plain copyide
- <string name="screen_timeout_summary" msgid="327761329263064327">"无操做<xliff:g id="TIMEOUT_DESCRIPTION">%1$s</xliff:g>后"</string>
能够看下dream_timeout_entries的xml文件函数
[html] view plain copythis
- <string-array name="dream_timeout_entries">
- <item msgid="3149294732238283185">"永不"</item>
- <item msgid="2194151041885903260">"15 秒"</item>
- <item msgid="5892295237131074341">"30 秒"</item>
- <item msgid="3538441365970038213">"1 分钟"</item>
- <item msgid="412343871668955639">"2 分钟"</item>
- <item msgid="5076853889688991690">"5 分钟"</item>
- <item msgid="1903860996174927898">"10 分钟"</item>
- <item msgid="6415509612413178727">"30 分钟"</item>
- </string-array>
所以二者组合起来会有"无操做5分钟后",这样的效果。
另外onPreferenceChange这个函数,是当你选择选项变化时调用。
[java] view plain copy
- public boolean onPreferenceChange(Preference preference, Object objValue) {
- final String key = preference.getKey();
- if (KEY_SCREEN_TIMEOUT.equals(key)) {//当时屏幕休眠时间那一项改变
- /*try {
- int value = Integer.parseInt((String) objValue);
- Settings.System.putInt(getContentResolver(), SCREEN_OFF_TIMEOUT, value);
- Log.e(TAG, "DisplaySettings:currentTimeout:" + value);
- updateTimeoutPreferenceDescription(value);
- } catch (NumberFormatException e) {
- Log.e(TAG, "could not persist screen timeout setting", e);
- }*/
- int value = Integer.parseInt((String) objValue);// 先获取值
- int oldvalue = Integer.parseInt(((ListPreference)preference).getValue());
- if (value != oldvalue) {
- int timeoutValue = ( -1 == value) ? Integer.MAX_VALUE : value;//若是值为-1,变为最大值
- try {
- Log.e(TAG, "timeoutValue is: " + timeoutValue);
- Settings.System.putInt(getContentResolver(), SCREEN_OFF_TIMEOUT, timeoutValue);//保存到settings这个数据库中
- updateTimeoutPreferenceDescription(value);//更新显示部分
- } catch (NumberFormatException e) {
- Log.e(TAG, "could not persist screen timeout setting", e);
- }
- }
- }
- if (KEY_FONT_SIZE.equals(key)) {
- writeFontSizePreference(objValue);
- }
- if (preference == mAutoBrightnessPreference) {
- boolean auto = (Boolean) objValue;
- Settings.System.putInt(getContentResolver(), SCREEN_BRIGHTNESS_MODE,
- auto ? SCREEN_BRIGHTNESS_MODE_AUTOMATIC : SCREEN_BRIGHTNESS_MODE_MANUAL);
- }
- if (preference == mLiftToWakePreference) {
- boolean value = (Boolean) objValue;
- Settings.Secure.putInt(getContentResolver(), WAKE_GESTURE_ENABLED, value ? 1 : 0);
- }
- if (preference == mDozePreference) {
- boolean value = (Boolean) objValue;
- Settings.Secure.putInt(getContentResolver(), DOZE_ENABLED, value ? 1 : 0);
- }
- return true;
- }
咱们能够看下screen_timeout_values的xml文件,在最后面添加了一个-1,也就是当选择"永不“的时候会传入一个-1,这时候会变成一个Integer.MAX_VALUE 存数据库。
[html] view plain copy
- <string-array name="screen_timeout_values" translatable="false">
- <!-- Do not translate. -->
- <item>15000</item>
- <!-- Do not translate. -->
- <item>30000</item>
- <!-- Do not translate. -->
- <item>60000</item>
- <!-- Do not translate. -->
- <item>120000</item>
- <!-- Do not translate. -->
- <item>300000</item>
- <!-- Do not translate. -->
- <item>600000</item>
- <!-- Do not translate. -->
- <item>1800000</item>
- <item>-1</item>
- </string-array>
这样就完成了在settings中添加永不休眠这个功能。
下面咱们再来看下PowerManagerService中如何将settings添加的这个功能生效。
在PowerManagerService中的systemReady函数中注册了对settings数据库SCREEN_OFF_TIMEOUT的监听
[java] view plain copy
- resolver.registerContentObserver(Settings.System.getUriFor(
- Settings.System.SCREEN_OFF_TIMEOUT),
- false, mSettingsObserver, UserHandle.USER_ALL);
而mSettingsObserver的类以下:
[java] view plain copy
- private final class SettingsObserver extends ContentObserver {
- public SettingsObserver(Handler handler) {
- super(handler);
- }
-
- @Override
- public void onChange(boolean selfChange, Uri uri) {
- synchronized (mLock) {
- handleSettingsChangedLocked();
- }
- }
- }
再看handleSettingsChangedLocked函数:
[java] view plain copy
- private void handleSettingsChangedLocked() {
- updateSettingsLocked();
- updatePowerStateLocked();
- }
[java] view plain copy
- private void updateSettingsLocked() {
- final ContentResolver resolver = mContext.getContentResolver();
-
- mDreamsEnabledSetting = (Settings.Secure.getIntForUser(resolver,
- Settings.Secure.SCREENSAVER_ENABLED,
- mDreamsEnabledByDefaultConfig ? 1 : 0,
- UserHandle.USER_CURRENT) != 0);
- mDreamsActivateOnSleepSetting = (Settings.Secure.getIntForUser(resolver,
- Settings.Secure.SCREENSAVER_ACTIVATE_ON_SLEEP,
- mDreamsActivatedOnSleepByDefaultConfig ? 1 : 0,
- UserHandle.USER_CURRENT) != 0);
- mDreamsActivateOnDockSetting = (Settings.Secure.getIntForUser(resolver,
- Settings.Secure.SCREENSAVER_ACTIVATE_ON_DOCK,
- mDreamsActivatedOnDockByDefaultConfig ? 1 : 0,
- UserHandle.USER_CURRENT) != 0);
- mScreenOffTimeoutSetting = Settings.System.getIntForUser(resolver,
- Settings.System.SCREEN_OFF_TIMEOUT, DEFAULT_SCREEN_OFF_TIMEOUT,
- UserHandle.USER_CURRENT);//获取settings数据库中SCREEN_OFF_TIMEOUT的值
更新了mScreenOffTimeoutSetting以后,会去调用updatePowerStateLocked函数,更新整个PowerManagerService的状态:
经过在updateUserActivitySummaryLocked函数中调用getScreenOffTimeoutLocked函数:
[java] view plain copy
- private void updateUserActivitySummaryLocked(long now, int dirty) {
- // Update the status of the user activity timeout timer.
- if ((dirty & (DIRTY_WAKE_LOCKS | DIRTY_USER_ACTIVITY
- | DIRTY_WAKEFULNESS | DIRTY_SETTINGS)) != 0) {
- mHandler.removeMessages(MSG_USER_ACTIVITY_TIMEOUT);
-
- long nextTimeout = 0;
- if (mWakefulness == WAKEFULNESS_AWAKE
- || mWakefulness == WAKEFULNESS_DREAMING
- || mWakefulness == WAKEFULNESS_DOZING) {
- final int sleepTimeout = getSleepTimeoutLocked();
- final int screenOffTimeout = getScreenOffTimeoutLocked(sleepTimeout);//调用getScreenOffTimeoutLocked函数
- final int screenDimDuration = getScreenDimDurationLocked(screenOffTimeout);
在getScreenOffTimeoutLocked函数中用mScreenOffTimeoutSetting这个成员变量:
[java] view plain copy
- private int getScreenOffTimeoutLocked(int sleepTimeout) {
- int timeout = mScreenOffTimeoutSetting;
- if (isMaximumScreenOffTimeoutFromDeviceAdminEnforcedLocked()) {
- timeout = Math.min(timeout, mMaximumScreenOffTimeoutFromDeviceAdmin);
- }
- if (mUserActivityTimeoutOverrideFromWindowManager >= 0) {
- timeout = (int)Math.min(timeout, mUserActivityTimeoutOverrideFromWindowManager);
- }
- if (sleepTimeout >= 0) {
- timeout = Math.min(timeout, sleepTimeout);
- }
- return Math.max(timeout, mMinimumScreenOffTimeoutConfig);
- }