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);
- }