当前位置:   article > 正文

Android P 屏保和休眠相关知识

Android P 屏保和休眠相关知识

Android P添加屏保功能,如果休眠时间设定大于屏保时间,则先进入屏保,达到休眠时间后再进入休眠

需求:

  1. 添加屏幕互保开关,默认关闭。
  2. 只保留时钟,可设定指针和数字、夜间模式。
  3. 启用时间改多长时间无操作进入屏保,可设定1、5、10、15、30分钟。
  4. 如果休眠时间设定小于屏保时间,则优先进入休眠,如果休眠时间设定大于屏保时间,则先进入屏保,达到休眠时间后再进入休眠

修改后的屏保:

 

 分析与实现:

1.修改进入屏保的条件

由于Android原生系统默认进入屏保的条件是充电或插入基座时,但到达休眠时才进入屏保。所以需要把进入屏保的条件修改为任何时候都能进入。

  1. frameworks\base\core\res\res\values\config.xml
  2. "config_dreamsEnabledOnBattery"修改为true即实现任何时候都能进入屏保
  3. <!-- Are we allowed to dream while not plugged in? -->
  4. <bool name="config_dreamsEnabledOnBattery">true</bool>

2.在设置–>显示–>屏保中添加“屏幕互保”选项开关

2.1添加系统自定义全局变量,用来保存“屏幕互保”选项开关的状态值

  1. frameworks/base/core/java/android/provider/Settings.java
  2. + /** @hide */
  3. + public static final String SCREENSAVER_SWITCH= "seewo.screensavers.switch";
  4. public static final class Secure extends NameValueTable {
  5. /** @hide */
  6. public static final String SCREENSAVER_TIMEOUT= “seewo.screensavers.timeout”;

2.2 vendor/mediatek/proprietary/packages/apps/MtkSettings/res/values-zh-rCN/strings.xml

<string name="screensaver_switch_title">屏幕互保</string>

2.3 vendor/mediatek/proprietary/packages/apps/MtkSettings/res/xml/dream_fragment_overview.xml

  1. <PreferenceScreen
  2. xmlns:android="http://schemas.android.com/apk/res/android"
  3. + xmlns:settings="http://schemas.android.com/apk/res-auto"
  4. android:key="dream_overview_screen"
  5. <SwitchPreference
  6. android:key="screensaver_switch"
  7. android:title="@string/screensaver_switch_title"/>

2.4添加vendor/mediatek/proprietary/packages/apps/MtkSettings/src/com/android/settings/dream/ScreenSaverSwitchPreferenceController.java文件

  1. /*
  2. * Copyright (C) 2017 The Android Open Source Project
  3. *
  4. * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file
  5. * except in compliance with the License. You may obtain a copy of the License at
  6. *
  7. * http://www.apache.org/licenses/LICENSE-2.0
  8. *
  9. * Unless required by applicable law or agreed to in writing, software distributed under the
  10. * License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
  11. * KIND, either express or implied. See the License for the specific language governing
  12. * permissions and limitations under the License.
  13. */
  14. package com.android.settings.dream;
  15. import static android.provider.Settings.Secure.SCREENSAVER_SWITCH;
  16. import android.content.Context;
  17. import android.provider.Settings;
  18. import android.support.v14.preference.SwitchPreference;
  19. import android.support.v7.preference.Preference;
  20. import com.android.settings.R;
  21. import com.android.settings.core.PreferenceControllerMixin;
  22. import com.android.settingslib.core.AbstractPreferenceController;
  23. public class ScreenSaverSwitchPreferenceController extends AbstractPreferenceController
  24. implements PreferenceControllerMixin, Preference.OnPreferenceChangeListener {
  25. private static final String KEY_SCREENSAVER_SWITCH_NAME = "screensaver_switch";
  26. public ScreenSaverSwitchPreferenceController(Context context) {
  27. super(context);
  28. }
  29. @Override
  30. public boolean isAvailable() {
  31. return true;
  32. }
  33. @Override
  34. public String getPreferenceKey() {
  35. return KEY_SCREENSAVER_SWITCH_NAME;
  36. }
  37. @Override
  38. public boolean onPreferenceChange(Preference preference, Object newValue) {
  39. boolean value = (Boolean) newValue;
  40. Settings.Secure.putInt(mContext.getContentResolver(),
  41. KEY_SCREENSAVER_SWITCH_NAME, value ? 1 : 0);
  42. if (value) {
  43. Settings.Secure.putInt(mContext.getContentResolver(), Settings.Secure.SCREENSAVER_SWITCH,
  44. 1);
  45. } else {
  46. Settings.Secure.putInt(mContext.getContentResolver(), Settings.Secure.SCREENSAVER_SWITCH,
  47. 0);
  48. }
  49. return true;
  50. }
  51. @Override
  52. public void updateState(Preference preference) {
  53. int value = Settings.Secure.getInt(mContext.getContentResolver(),
  54. KEY_SCREENSAVER_SWITCH_NAME, 0);
  55. ((SwitchPreference) preference).setChecked(value == 1);
  56. }
  57. }

2.5 vendor/mediatek/proprietary/packages/apps/MtkSettings/src/com/android/settings/dream/DreamSettings.java

  1. @@ -132,6 +132,7 @@ public class DreamSettings extends DashboardFragment {
  2. controllers.add(new StartNowPreferenceController(context));
  3. + controllers.add(new ScreenSaverSwitchPreferenceController(context));
  4. return controllers;

3.隐藏“启动时间”

  1. --- a/vendor/mediatek/proprietary/packages/apps/MtkSettings/src/com/android/settings/dream/StartNowPreferenceController.java
  2. +++ b/vendor/mediatek/proprietary/packages/apps/MtkSettings/src/com/android/settings/dream/StartNowPreferenceController.java
  3. @@ -40,7 +40,7 @@ public class StartNowPreferenceController extends AbstractPreferenceController i
  4. @Override
  5. public boolean isAvailable() {
  6. - return true;
  7. + return false;
  8. }

4.添加选择无操作多少分钟后进入屏保的ListPreference

4.1添加系统自定义全局变量,用来保存无操作多少分钟后进入屏保的时间。
frameworks/base/core/java/android/provider/Settings.java

  1. public static final class Secure extends NameValueTable {
  2. /** @hide */
  3. public static final String SCREENSAVER_TIMEOUT= "seewo.screensavers.timeout";

4.2设置–>显示–>屏保中添加ListPreference
vendor/mediatek/proprietary/packages/apps/MtkSettings/res/xml/dream_fragment_overview.xml

  1. + <ListPreference
  2. + android:key="screensaver_timeout"
  3. + android:title="@string/screensaver_timeout"
  4. + android:entries="@array/screensaver_timeout_entries"
  5. + android:entryValues="@array/screensaver_timeout_values"
  6. + settings:controller="com.android.settings.dream.ScreenSaverTimeoutPreferenceController" />

vendor/mediatek/proprietary/packages/apps/MtkSettings/res/values/arrays.xml

  1. + <!-- Titles for screensaver preference. -->
  2. + <string-array name="screensaver_timeout_entries" >
  3. + <item>@string/screensaver_timeout_1min</item>
  4. + <item>@string/screensaver_timeout_5mins</item>
  5. + <item>@string/screensaver_timeout_10mins</item>
  6. + <item>@string/screensaver_timeout_15mins</item>
  7. + <item>@string/screensaver_timeout_30mins</item>
  8. + </string-array>
  9. +
  10. + <!-- Values for screensaver preference. -->
  11. + <string-array name="screensaver_timeout_values" translatable="false" >
  12. + <item>60000</item>
  13. + <item>300000</item>
  14. + <item>600000</item>
  15. + <item>900000</item>
  16. + <item>1800000</item>
  17. + </string-array>

vendor/mediatek/proprietary/packages/apps/MtkSettings/res/values-zh-rCN/strings.xml

  1. + <string name="screensaver_timeout">屏保</string>
  2. + <string name="screensaver_timeout_1min">1 分钟</string>
  3. + <string name="screensaver_timeout_5mins">5 分钟</string>
  4. + <string name="screensaver_timeout_10mins">10 分钟</string>
  5. + <string name="screensaver_timeout_15mins">15 分钟</string>
  6. + <string name="screensaver_timeout_30mins">30 分钟</string>
  7. + <string name="screensaver_timeout_summary">"无操作<xliff:g id="TIMEOUT_DESCRIPTION">%1$s</xliff:g>后"</string>
  8. + <string name="screensaver_switch_title">屏幕互保</string>

4.3添加vendor\mediatek\proprietary\packages\apps\MtkSettings\src\com\android\settings\dream\ScreenSaverTimeoutPreferenceController.java

  1. /*
  2. * Copyright (C) 2018 The Android Open Source Project
  3. *
  4. * Licensed under the Apache License, Version 2.0 (the "License");
  5. * you may not use this file except in compliance with the License.
  6. * You may obtain a copy of the License at
  7. *
  8. * http://www.apache.org/licenses/LICENSE-2.0
  9. *
  10. * Unless required by applicable law or agreed to in writing, software
  11. * distributed under the License is distributed on an "AS IS" BASIS,
  12. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  13. * See the License for the specific language governing permissions and
  14. * limitations under the License
  15. */
  16. package com.android.settings.dream;
  17. import static android.provider.Settings.Secure.SCREENSAVER_TIMEOUT;
  18. import android.content.Context;
  19. import android.provider.Settings;
  20. import android.support.v7.preference.ListPreference;
  21. import android.support.v7.preference.Preference;
  22. import android.support.v7.preference.PreferenceScreen;
  23. import android.util.FeatureFlagUtils;
  24. import com.android.settings.R;
  25. import com.android.settings.core.BasePreferenceController;
  26. import com.android.settings.core.PreferenceControllerMixin;
  27. import com.android.settingslib.core.AbstractPreferenceController;
  28. /**
  29. * Setting where user can pick if SystemUI will be light, dark or try to match
  30. * the wallpaper colors.
  31. */
  32. public class ScreenSaverTimeoutPreferenceController extends BasePreferenceController
  33. implements Preference.OnPreferenceChangeListener {
  34. private ListPreference mScreenSaverTimeoutPref;
  35. public ScreenSaverTimeoutPreferenceController(Context context, String preferenceKey) {
  36. super(context, preferenceKey);
  37. }
  38. @Override
  39. public int getAvailabilityStatus() {
  40. return AVAILABLE;
  41. }
  42. @Override
  43. public void displayPreference(PreferenceScreen screen) {
  44. super.displayPreference(screen);
  45. mScreenSaverTimeoutPref = (ListPreference) screen.findPreference(getPreferenceKey());
  46. int value = Settings.Secure.getInt(mContext.getContentResolver(), SCREENSAVER_TIMEOUT, 60000);
  47. mScreenSaverTimeoutPref.setValue(Integer.toString(value));
  48. }
  49. @Override
  50. public boolean onPreferenceChange(Preference preference, Object newValue) {
  51. int value = Integer.parseInt((String) newValue);
  52. Settings.Secure.putInt(mContext.getContentResolver(), SCREENSAVER_TIMEOUT, value);
  53. refreshSummary(preference);
  54. return true;
  55. }
  56. @Override
  57. public CharSequence getSummary() {
  58. int value = Settings.Secure.getInt(mContext.getContentResolver(), SCREENSAVER_TIMEOUT, 60000);
  59. int index = mScreenSaverTimeoutPref.findIndexOfValue(Integer.toString(value));
  60. return mContext.getString(R.string.screensaver_timeout_summary, mScreenSaverTimeoutPref.getEntries()[index]);
  61. }
  62. }

5.屏保默认为原生时钟,移除“万花筒”

5.1 原生屏保默认是使用Google GMS中的时钟,因此修改为默认使用原生的时钟。
frameworks/base/core/res/res/values/config.xml

  1. - <string name="config_dreamsDefaultComponent" translatable="false">com.google.android.deskclock/com.android.deskclock.Screensaver</string>
  2. + <string name="config_dreamsDefaultComponent" translatable="false">com.android.deskclock/com.android.deskclock.Screensaver</string>

5.2移除“万花筒”
vendor/mediatek/proprietary/packages/apps/SettingsLib/src/com/android/settingslib/dream/DreamBackend.java

  1. public List<DreamInfo> getDreamInfos() {
  2. logd("getDreamInfos()");
  3. + String componentName;//del basic.Colors
  4. ComponentName activeDream = getActiveDream();
  5. PackageManager pm = mContext.getPackageManager();
  6. Intent dreamIntent = new Intent(DreamService.SERVICE_INTERFACE);
  7. @@ -124,6 +125,12 @@ public class DreamBackend {
  8. dreamInfo.caption = resolveInfo.loadLabel(pm);
  9. dreamInfo.icon = resolveInfo.loadIcon(pm);
  10. dreamInfo.componentName = getDreamComponentName(resolveInfo);
  11. + componentName = dreamInfo.componentName.toString();
  12. + if(componentName.contains("com.android.dreams.basic.Colors")){
  13. + continue;
  14. + }
  15. dreamInfo.isActive = dreamInfo.componentName.equals(activeDream);

6.定制屏保时间

如果休眠时间设定小于屏保时间,则优先进入休眠,如果休眠时间设定大于屏保时间,则先进入屏保,达到休眠时间后再进入休眠的实现
frameworks/base/services/core/java/com/android/server/power/PowerManagerService.java

6.1修改进入屏保的条件由Setting中的“屏幕互保”选项的开或关来决定

  1. private boolean updateWakefulnessLocked(int dirty) {
  2. boolean changed = false;
  3. if ((dirty & (DIRTY_WAKE_LOCKS | DIRTY_USER_ACTIVITY | DIRTY_BOOT_COMPLETED
  4. | DIRTY_WAKEFULNESS | DIRTY_STAY_ON | DIRTY_PROXIMITY_POSITIVE
  5. | DIRTY_DOCK_STATE)) != 0) {
  6. if (mWakefulness == WAKEFULNESS_AWAKE && isItBedTimeYetLocked()) {
  7. if (DEBUG_SPEW) {
  8. Slog.d(TAG, "updateWakefulnessLocked: Bed time...");
  9. }
  10. final long time = SystemClock.uptimeMillis();
  11. if (shouldNapAtBedTimeLocked()) {//此处为进入屏保的条件
  12. changed = napNoUpdateLocked(time, Process.SYSTEM_UID);
  13. } else {
  14. changed = goToSleepNoUpdateLocked(time,
  15. PowerManager.GO_TO_SLEEP_REASON_TIMEOUT, 0, Process.SYSTEM_UID);
  16. }
  17. }
  18. }
  19. return changed;
  20. }

shouldNapAtBedTimeLocked()为进入屏保的条件,所以需要修改shouldNapAtBedTimeLocked()的返回值。

  1. private boolean shouldNapAtBedTimeLocked() {
  2. - return mDreamsActivateOnSleepSetting
  3. - || (mDreamsActivateOnDockSetting
  4. - && mDockState != Intent.EXTRA_DOCK_STATE_UNDOCKED);
  5. + return Settings.Secure.getInt(mContext.getContentResolver(),Settings.Secure.SCREENSAVER_SWITCH,0) == 1;
  6. + //return mDreamsActivateOnSleepSetting
  7. + // || (mDreamsActivateOnDockSetting
  8. + // && mDockState != Intent.EXTRA_DOCK_STATE_UNDOCKED);
  9. }

Settings.Secure.getInt(mContext.getContentResolver(),Settings.Secure.SCREENSAVER_SWITCH,0)是获取“屏幕互保”的状态值,1表示打开,0表示关闭。

6.2修改取决于什么时候进入屏保的逻辑。

  1. private void updateUserActivitySummaryLocked(long now, int dirty) {
  2. // Update the status of the user activity timeout timer.
  3. if ((dirty & (DIRTY_WAKE_LOCKS | DIRTY_USER_ACTIVITY
  4. | DIRTY_WAKEFULNESS | DIRTY_SETTINGS)) != 0) {
  5. mHandler.removeMessages(MSG_USER_ACTIVITY_TIMEOUT);
  6. long nextTimeout = 0;
  7. long screenSaverNextTimeout = 0;//添加计算下次进入屏保的时间
  8. boolean isScreenSaverEnabled = Settings.Secure.getInt(mContext.getContentResolver(),Settings.Secure.SCREENSAVER_SWITCH,0) == 1;//获取“屏幕互保”是否打开
  9. if (mWakefulness == WAKEFULNESS_AWAKE
  10. || mWakefulness == WAKEFULNESS_DREAMING
  11. || mWakefulness == WAKEFULNESS_DOZING) {
  12. final long sleepTimeout = getSleepTimeoutLocked();
  13. final long screenOffTimeout = getScreenOffTimeoutLocked(sleepTimeout);//无操作多少分钟后进入休眠的时间
  14. final long screenDimDuration = getScreenDimDurationLocked(screenOffTimeout);
  15. final boolean userInactiveOverride = mUserInactiveOverrideFromWindowManager;
  16. final long nextProfileTimeout = getNextProfileTimeoutLocked(now);
  17. final long screenSaverTimeout = Settings.Secure.getInt(mContext.getContentResolver(),Settings.Secure.SCREENSAVER_TIMEOUT,60000);//无操作多少分钟后进入屏保的时间
  18. mUserActivitySummary = 0;
  19. if (mLastUserActivityTime >= mLastWakeTime) {
  20. nextTimeout = mLastUserActivityTime
  21. + screenOffTimeout - screenDimDuration;
  22. screenSaverNextTimeout = mLastUserActivityTime + screenSaverTimeout;//无操作后下次进入屏保的时间
  23. if (now < nextTimeout) {
  24. //当“屏幕互保”是打开的,并且无操作后进入休眠的时间 大于 无操作后进入屏保的时间,
  25. //而且当前的时间 大于 无操作后下次进入屏保的时间则进入屏保
  26. if(isScreenSaverEnabled && screenOffTimeout > screenSaverTimeout && now > screenSaverNextTimeout ){
  27. mUserActivitySummary = USER_ACTIVITY_SCREEN_DREAM;
  28. }else{//否则保持屏保亮屏
  29. mUserActivitySummary = USER_ACTIVITY_SCREEN_BRIGHT;
  30. }
  31. //Neostra dangziming end screensaver
  32. } else {
  33. nextTimeout = mLastUserActivityTime + screenOffTimeout;
  34. if (now < nextTimeout) {
  35. mUserActivitySummary = USER_ACTIVITY_SCREEN_DIM;
  36. }
  37. }
  38. }
  39. if (mUserActivitySummary == 0
  40. && mLastUserActivityTimeNoChangeLights >= mLastWakeTime) {
  41. nextTimeout = mLastUserActivityTimeNoChangeLights + screenOffTimeout;
  42. if (now < nextTimeout) {
  43. if (mDisplayPowerRequest.policy == DisplayPowerRequest.POLICY_BRIGHT
  44. || mDisplayPowerRequest.policy == DisplayPowerRequest.POLICY_VR) {
  45. mUserActivitySummary = USER_ACTIVITY_SCREEN_BRIGHT;
  46. } else if (mDisplayPowerRequest.policy == DisplayPowerRequest.POLICY_DIM) {
  47. mUserActivitySummary = USER_ACTIVITY_SCREEN_DIM;
  48. }
  49. }
  50. }
  51. if (mUserActivitySummary == 0) {
  52. if (sleepTimeout >= 0) {
  53. final long anyUserActivity = Math.max(mLastUserActivityTime,
  54. mLastUserActivityTimeNoChangeLights);
  55. if (anyUserActivity >= mLastWakeTime) {
  56. nextTimeout = anyUserActivity + sleepTimeout;
  57. if (now < nextTimeout) {
  58. mUserActivitySummary = USER_ACTIVITY_SCREEN_DREAM;
  59. }
  60. }
  61. } else {
  62. //mUserActivitySummary = USER_ACTIVITY_SCREEN_DREAM;//删除系统进入休眠后才进入屏保的逻辑
  63. nextTimeout = -1;
  64. }
  65. }
  66. if (mUserActivitySummary != USER_ACTIVITY_SCREEN_DREAM && userInactiveOverride) {
  67. if ((mUserActivitySummary &
  68. (USER_ACTIVITY_SCREEN_BRIGHT | USER_ACTIVITY_SCREEN_DIM)) != 0) {
  69. // Device is being kept awake by recent user activity
  70. if (nextTimeout >= now && mOverriddenTimeout == -1) {
  71. // Save when the next timeout would have occurred
  72. mOverriddenTimeout = nextTimeout;
  73. }
  74. }
  75. mUserActivitySummary = USER_ACTIVITY_SCREEN_DREAM;
  76. nextTimeout = -1;
  77. }
  78. if (nextProfileTimeout > 0) {
  79. nextTimeout = Math.min(nextTimeout, nextProfileTimeout);
  80. }
  81. if (mUserActivitySummary != 0 && nextTimeout >= 0) {
  82. //当“屏幕互保”是打开的,并且无操作后进入休眠的时间 大于 无操作后进入屏保的时间,
  83. //而且当前的时间 大于 无操作后下次进入屏保的时间则发送信息进入屏保
  84. if(isScreenSaverEnabled && screenOffTimeout > screenSaverTimeout && now <= screenSaverNextTimeout ){
  85. scheduleUserInactivityTimeout(screenSaverNextTimeout);
  86. }else{//否则发送进入休眠的信息
  87. scheduleUserInactivityTimeout(nextTimeout);
  88. }
  89. //Neostra dangziming end screensaver
  90. }
  91. } else {
  92. mUserActivitySummary = 0;
  93. }
  94. if (DEBUG_SPEW) {
  95. Slog.d(TAG, "updateUserActivitySummaryLocked: mWakefulness="
  96. + PowerManagerInternal.wakefulnessToString(mWakefulness)
  97. + ", mUserActivitySummary=0x" + Integer.toHexString(mUserActivitySummary)
  98. + ", nextTimeout=" + TimeUtils.formatUptime(nextTimeout));
  99. }
  100. }
  101. }

updateUserActivitySummaryLocked()的逻辑分析可以参考Android 8.1 PowerManagerService分析(二) ——updatePowerStateLocked()方法

如果此文章解答了您的相关疑惑,节约了您的宝贵时间,可以赏小编鸡腿哟!

 

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/article/detail/45682?site
推荐阅读
相关标签
  

闽ICP备14008679号