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