Settings的apk的目录是在packages\apps\Settings下,由于我们添加的从不休眠是在显示项里面,所以我们就直接看DisplaySettings.Java的代码了。
- @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,
- FALLBACK_SCREEN_TIMEOUT_VALUE);
-
-
- long timeoutValue = (currentTimeout == Integer.MAX_VALUE) ? -1 : currentTimeout;
- mScreenTimeoutPreference.setValue(String.valueOf(timeoutValue));
-
- mScreenTimeoutPreference.setOnPreferenceChangeListener(this);
- disableUnusableTimeouts(mScreenTimeoutPreference);
-
- updateTimeoutPreferenceDescription(timeoutValue);
我们先看下display_settings.xml文件中screen_timeout这个ListPreference;
- <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主要更新屏幕上的信息
- private void updateTimeoutPreferenceDescription(long currentTimeout) {
- ListPreference preference = mScreenTimeoutPreference;
- String summary;
- if (currentTimeout == -1) {
-
- summary = preference.getContext().getString(R.string.screen_never_timeout_summary);
- } else if (currentTimeout < -1) {
-
- 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 && timeout > 0) {
- best = i;
- }
- }
- summary = preference.getContext().getString(R.string.screen_timeout_summary,
- entries[best]);
- }
- }
- preference.setSummary(summary);
- }
先看下R.string.screen_timeout_summary这个string
- <string name="screen_timeout_summary" msgid="327761329263064327">"无操作<xliff:g id="TIMEOUT_DESCRIPTION">%1$s</xliff:g>后"</string>
可以看下dream_timeout_entries的xml文件
- <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这个函数,是当你选择选项变化时调用。
- public boolean onPreferenceChange(Preference preference, Object objValue) {
- final String key = preference.getKey();
- if (KEY_SCREEN_TIMEOUT.equals(key)) {
-
-
-
-
-
-
-
-
- int value = Integer.parseInt((String) objValue);
- int oldvalue = Integer.parseInt(((ListPreference)preference).getValue());
- if (value != oldvalue) {
- int timeoutValue = ( -1 == value) ? Integer.MAX_VALUE : value;
- try {
- Log.e(TAG, "timeoutValue is: " + timeoutValue);
- Settings.System.putInt(getContentResolver(), SCREEN_OFF_TIMEOUT, timeoutValue);
- 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 存数据库。
- <string-array name="screen_timeout_values" translatable="false">
-
- <item>15000</item>
-
- <item>30000</item>
-
- <item>60000</item>
-
- <item>120000</item>
-
- <item>300000</item>
-
- <item>600000</item>
-
- <item>1800000</item>
- <item>-1</item>
- </string-array>
这样就完成了在settings中添加永不休眠这个功能。
下面我们再来看下PowerManagerService中如何将settings添加的这个功能生效。
在PowerManagerService中的systemReady函数中注册了对settings数据库SCREEN_OFF_TIMEOUT的监听
- resolver.registerContentObserver(Settings.System.getUriFor(
- Settings.System.SCREEN_OFF_TIMEOUT),
- false, mSettingsObserver, UserHandle.USER_ALL);
而mSettingsObserver的类如下:
- private final class SettingsObserver extends ContentObserver {
- public SettingsObserver(Handler handler) {
- super(handler);
- }
-
- @Override
- public void onChange(boolean selfChange, Uri uri) {
- synchronized (mLock) {
- handleSettingsChangedLocked();
- }
- }
- }
再看handleSettingsChangedLocked函数:
- private void handleSettingsChangedLocked() {
- updateSettingsLocked();
- updatePowerStateLocked();
- }
- 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);
更新了mScreenOffTimeoutSetting之后,会去调用updatePowerStateLocked函数,更新整个PowerManagerService的状态:
通过在updateUserActivitySummaryLocked函数中调用getScreenOffTimeoutLocked函数:
- private void updateUserActivitySummaryLocked(long now, int dirty) {
-
- 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);
- final int screenDimDuration = getScreenDimDurationLocked(screenOffTimeout);
在getScreenOffTimeoutLocked函数中用mScreenOffTimeoutSetting这个成员变量:
2,若是android5.0的code,请在前面的修改基础上再修改下面的代码:
frameworks/base/services/core/java/com/android/server/power/PowerManagerService.java
private int getScreenOffTimeoutLocked(int sleepTimeout) {
if (sleepTimeout >= 0) {
timeout = Math.min(timeout, sleepTimeout);
Slog.d("TAG", "..33333333..sendMessageAtTime");
}
//add_begin
if(timeout < 0 ){
timeout = Integer.MAX_VALUE ;
}
//add_end
if (mUserActivityTimeoutMin) {
timeout = (int)Math.min(timeout, mUserActivityTimeoutOverrideFromCMD);
}
return Math.max(timeout, mMinimumScreenOffTimeoutConfig);
}
- 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);
- }