赞
踩
Android P添加屏保功能,如果休眠时间设定大于屏保时间,则先进入屏保,达到休眠时间后再进入休眠
需求:
修改后的屏保:


分析与实现:
由于Android原生系统默认进入屏保的条件是充电或插入基座时,但到达休眠时才进入屏保。所以需要把进入屏保的条件修改为任何时候都能进入。
- frameworks\base\core\res\res\values\config.xml
- 把"config_dreamsEnabledOnBattery"修改为true即实现任何时候都能进入屏保
-
- <!-- Are we allowed to dream while not plugged in? -->
- <bool name="config_dreamsEnabledOnBattery">true</bool>
2.1添加系统自定义全局变量,用来保存“屏幕互保”选项开关的状态值
- frameworks/base/core/java/android/provider/Settings.java
-
- + /** @hide */
- + public static final String SCREENSAVER_SWITCH= "seewo.screensavers.switch";
- public static final class Secure extends NameValueTable {
- /** @hide */
- 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
- <PreferenceScreen
- xmlns:android="http://schemas.android.com/apk/res/android"
- + xmlns:settings="http://schemas.android.com/apk/res-auto"
- android:key="dream_overview_screen"
- <SwitchPreference
- android:key="screensaver_switch"
- android:title="@string/screensaver_switch_title"/>
2.4添加vendor/mediatek/proprietary/packages/apps/MtkSettings/src/com/android/settings/dream/ScreenSaverSwitchPreferenceController.java文件
- /*
- * Copyright (C) 2017 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file
- * except in compliance with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software distributed under the
- * License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the specific language governing
- * permissions and limitations under the License.
- */
- package com.android.settings.dream;
-
- import static android.provider.Settings.Secure.SCREENSAVER_SWITCH;
-
- import android.content.Context;
- import android.provider.Settings;
- import android.support.v14.preference.SwitchPreference;
- import android.support.v7.preference.Preference;
-
- import com.android.settings.R;
- import com.android.settings.core.PreferenceControllerMixin;
- import com.android.settingslib.core.AbstractPreferenceController;
-
- public class ScreenSaverSwitchPreferenceController extends AbstractPreferenceController
- implements PreferenceControllerMixin, Preference.OnPreferenceChangeListener {
-
- private static final String KEY_SCREENSAVER_SWITCH_NAME = "screensaver_switch";
-
- public ScreenSaverSwitchPreferenceController(Context context) {
- super(context);
- }
-
- @Override
- public boolean isAvailable() {
- return true;
- }
-
- @Override
- public String getPreferenceKey() {
- return KEY_SCREENSAVER_SWITCH_NAME;
- }
-
- @Override
- public boolean onPreferenceChange(Preference preference, Object newValue) {
- boolean value = (Boolean) newValue;
- Settings.Secure.putInt(mContext.getContentResolver(),
- KEY_SCREENSAVER_SWITCH_NAME, value ? 1 : 0);
- if (value) {
- Settings.Secure.putInt(mContext.getContentResolver(), Settings.Secure.SCREENSAVER_SWITCH,
- 1);
- } else {
- Settings.Secure.putInt(mContext.getContentResolver(), Settings.Secure.SCREENSAVER_SWITCH,
- 0);
- }
- return true;
- }
-
- @Override
- public void updateState(Preference preference) {
- int value = Settings.Secure.getInt(mContext.getContentResolver(),
- KEY_SCREENSAVER_SWITCH_NAME, 0);
- ((SwitchPreference) preference).setChecked(value == 1);
- }
- }
-

2.5 vendor/mediatek/proprietary/packages/apps/MtkSettings/src/com/android/settings/dream/DreamSettings.java
- @@ -132,6 +132,7 @@ public class DreamSettings extends DashboardFragment {
- controllers.add(new StartNowPreferenceController(context));
- + controllers.add(new ScreenSaverSwitchPreferenceController(context));
- return controllers;
-
- --- a/vendor/mediatek/proprietary/packages/apps/MtkSettings/src/com/android/settings/dream/StartNowPreferenceController.java
- +++ b/vendor/mediatek/proprietary/packages/apps/MtkSettings/src/com/android/settings/dream/StartNowPreferenceController.java
- @@ -40,7 +40,7 @@ public class StartNowPreferenceController extends AbstractPreferenceController i
-
- @Override
- public boolean isAvailable() {
- - return true;
- + return false;
- }
-
4.1添加系统自定义全局变量,用来保存无操作多少分钟后进入屏保的时间。
frameworks/base/core/java/android/provider/Settings.java
- public static final class Secure extends NameValueTable {
- /** @hide */
- public static final String SCREENSAVER_TIMEOUT= "seewo.screensavers.timeout";
4.2设置–>显示–>屏保中添加ListPreference
vendor/mediatek/proprietary/packages/apps/MtkSettings/res/xml/dream_fragment_overview.xml
- + <ListPreference
- + android:key="screensaver_timeout"
- + android:title="@string/screensaver_timeout"
- + android:entries="@array/screensaver_timeout_entries"
- + android:entryValues="@array/screensaver_timeout_values"
- + settings:controller="com.android.settings.dream.ScreenSaverTimeoutPreferenceController" />
vendor/mediatek/proprietary/packages/apps/MtkSettings/res/values/arrays.xml
- + <!-- Titles for screensaver preference. -->
- + <string-array name="screensaver_timeout_entries" >
- + <item>@string/screensaver_timeout_1min</item>
- + <item>@string/screensaver_timeout_5mins</item>
- + <item>@string/screensaver_timeout_10mins</item>
- + <item>@string/screensaver_timeout_15mins</item>
- + <item>@string/screensaver_timeout_30mins</item>
- + </string-array>
- +
- + <!-- Values for screensaver preference. -->
- + <string-array name="screensaver_timeout_values" translatable="false" >
- + <item>60000</item>
- + <item>300000</item>
- + <item>600000</item>
- + <item>900000</item>
- + <item>1800000</item>
- + </string-array>

vendor/mediatek/proprietary/packages/apps/MtkSettings/res/values-zh-rCN/strings.xml
- + <string name="screensaver_timeout">屏保</string>
- + <string name="screensaver_timeout_1min">1 分钟</string>
- + <string name="screensaver_timeout_5mins">5 分钟</string>
- + <string name="screensaver_timeout_10mins">10 分钟</string>
- + <string name="screensaver_timeout_15mins">15 分钟</string>
- + <string name="screensaver_timeout_30mins">30 分钟</string>
- + <string name="screensaver_timeout_summary">"无操作<xliff:g id="TIMEOUT_DESCRIPTION">%1$s</xliff:g>后"</string>
- + <string name="screensaver_switch_title">屏幕互保</string>
4.3添加vendor\mediatek\proprietary\packages\apps\MtkSettings\src\com\android\settings\dream\ScreenSaverTimeoutPreferenceController.java
- /*
- * Copyright (C) 2018 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License
- */
-
- package com.android.settings.dream;
-
- import static android.provider.Settings.Secure.SCREENSAVER_TIMEOUT;
-
- import android.content.Context;
- import android.provider.Settings;
- import android.support.v7.preference.ListPreference;
- import android.support.v7.preference.Preference;
- import android.support.v7.preference.PreferenceScreen;
- import android.util.FeatureFlagUtils;
- import com.android.settings.R;
- import com.android.settings.core.BasePreferenceController;
- import com.android.settings.core.PreferenceControllerMixin;
- import com.android.settingslib.core.AbstractPreferenceController;
- /**
- * Setting where user can pick if SystemUI will be light, dark or try to match
- * the wallpaper colors.
- */
- public class ScreenSaverTimeoutPreferenceController extends BasePreferenceController
- implements Preference.OnPreferenceChangeListener {
-
- private ListPreference mScreenSaverTimeoutPref;
-
- public ScreenSaverTimeoutPreferenceController(Context context, String preferenceKey) {
- super(context, preferenceKey);
- }
-
- @Override
- public int getAvailabilityStatus() {
- return AVAILABLE;
- }
-
- @Override
- public void displayPreference(PreferenceScreen screen) {
- super.displayPreference(screen);
- mScreenSaverTimeoutPref = (ListPreference) screen.findPreference(getPreferenceKey());
- int value = Settings.Secure.getInt(mContext.getContentResolver(), SCREENSAVER_TIMEOUT, 60000);
- mScreenSaverTimeoutPref.setValue(Integer.toString(value));
- }
-
- @Override
- public boolean onPreferenceChange(Preference preference, Object newValue) {
- int value = Integer.parseInt((String) newValue);
- Settings.Secure.putInt(mContext.getContentResolver(), SCREENSAVER_TIMEOUT, value);
- refreshSummary(preference);
- return true;
- }
-
- @Override
- public CharSequence getSummary() {
- int value = Settings.Secure.getInt(mContext.getContentResolver(), SCREENSAVER_TIMEOUT, 60000);
- int index = mScreenSaverTimeoutPref.findIndexOfValue(Integer.toString(value));
-
- return mContext.getString(R.string.screensaver_timeout_summary, mScreenSaverTimeoutPref.getEntries()[index]);
- }
- }
-

5.1 原生屏保默认是使用Google GMS中的时钟,因此修改为默认使用原生的时钟。
frameworks/base/core/res/res/values/config.xml
- - <string name="config_dreamsDefaultComponent" translatable="false">com.google.android.deskclock/com.android.deskclock.Screensaver</string>
- + <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
- public List<DreamInfo> getDreamInfos() {
- logd("getDreamInfos()");
- + String componentName;//del basic.Colors
- ComponentName activeDream = getActiveDream();
- PackageManager pm = mContext.getPackageManager();
- Intent dreamIntent = new Intent(DreamService.SERVICE_INTERFACE);
- @@ -124,6 +125,12 @@ public class DreamBackend {
- dreamInfo.caption = resolveInfo.loadLabel(pm);
- dreamInfo.icon = resolveInfo.loadIcon(pm);
- dreamInfo.componentName = getDreamComponentName(resolveInfo);
- + componentName = dreamInfo.componentName.toString();
- + if(componentName.contains("com.android.dreams.basic.Colors")){
- + continue;
- + }
- dreamInfo.isActive = dreamInfo.componentName.equals(activeDream);
如果休眠时间设定小于屏保时间,则优先进入休眠,如果休眠时间设定大于屏保时间,则先进入屏保,达到休眠时间后再进入休眠的实现
frameworks/base/services/core/java/com/android/server/power/PowerManagerService.java
6.1修改进入屏保的条件由Setting中的“屏幕互保”选项的开或关来决定
- private boolean updateWakefulnessLocked(int dirty) {
- boolean changed = false;
- if ((dirty & (DIRTY_WAKE_LOCKS | DIRTY_USER_ACTIVITY | DIRTY_BOOT_COMPLETED
- | DIRTY_WAKEFULNESS | DIRTY_STAY_ON | DIRTY_PROXIMITY_POSITIVE
- | DIRTY_DOCK_STATE)) != 0) {
- if (mWakefulness == WAKEFULNESS_AWAKE && isItBedTimeYetLocked()) {
- if (DEBUG_SPEW) {
- Slog.d(TAG, "updateWakefulnessLocked: Bed time...");
- }
- final long time = SystemClock.uptimeMillis();
- if (shouldNapAtBedTimeLocked()) {//此处为进入屏保的条件
- changed = napNoUpdateLocked(time, Process.SYSTEM_UID);
- } else {
- changed = goToSleepNoUpdateLocked(time,
- PowerManager.GO_TO_SLEEP_REASON_TIMEOUT, 0, Process.SYSTEM_UID);
- }
- }
- }
- return changed;
- }

shouldNapAtBedTimeLocked()为进入屏保的条件,所以需要修改shouldNapAtBedTimeLocked()的返回值。
- private boolean shouldNapAtBedTimeLocked() {
- - return mDreamsActivateOnSleepSetting
- - || (mDreamsActivateOnDockSetting
- - && mDockState != Intent.EXTRA_DOCK_STATE_UNDOCKED);
- + return Settings.Secure.getInt(mContext.getContentResolver(),Settings.Secure.SCREENSAVER_SWITCH,0) == 1;
- + //return mDreamsActivateOnSleepSetting
- + // || (mDreamsActivateOnDockSetting
- + // && mDockState != Intent.EXTRA_DOCK_STATE_UNDOCKED);
-
- }
Settings.Secure.getInt(mContext.getContentResolver(),Settings.Secure.SCREENSAVER_SWITCH,0)是获取“屏幕互保”的状态值,1表示打开,0表示关闭。
6.2修改取决于什么时候进入屏保的逻辑。
- 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;
- long screenSaverNextTimeout = 0;//添加计算下次进入屏保的时间
- boolean isScreenSaverEnabled = Settings.Secure.getInt(mContext.getContentResolver(),Settings.Secure.SCREENSAVER_SWITCH,0) == 1;//获取“屏幕互保”是否打开
- if (mWakefulness == WAKEFULNESS_AWAKE
- || mWakefulness == WAKEFULNESS_DREAMING
- || mWakefulness == WAKEFULNESS_DOZING) {
- final long sleepTimeout = getSleepTimeoutLocked();
- final long screenOffTimeout = getScreenOffTimeoutLocked(sleepTimeout);//无操作多少分钟后进入休眠的时间
- final long screenDimDuration = getScreenDimDurationLocked(screenOffTimeout);
- final boolean userInactiveOverride = mUserInactiveOverrideFromWindowManager;
- final long nextProfileTimeout = getNextProfileTimeoutLocked(now);
- final long screenSaverTimeout = Settings.Secure.getInt(mContext.getContentResolver(),Settings.Secure.SCREENSAVER_TIMEOUT,60000);//无操作多少分钟后进入屏保的时间
- mUserActivitySummary = 0;
- if (mLastUserActivityTime >= mLastWakeTime) {
- nextTimeout = mLastUserActivityTime
- + screenOffTimeout - screenDimDuration;
- screenSaverNextTimeout = mLastUserActivityTime + screenSaverTimeout;//无操作后下次进入屏保的时间
- if (now < nextTimeout) {
- //当“屏幕互保”是打开的,并且无操作后进入休眠的时间 大于 无操作后进入屏保的时间,
- //而且当前的时间 大于 无操作后下次进入屏保的时间则进入屏保
- if(isScreenSaverEnabled && screenOffTimeout > screenSaverTimeout && now > screenSaverNextTimeout ){
- mUserActivitySummary = USER_ACTIVITY_SCREEN_DREAM;
- }else{//否则保持屏保亮屏
- mUserActivitySummary = USER_ACTIVITY_SCREEN_BRIGHT;
- }
- //Neostra dangziming end screensaver
- } else {
- nextTimeout = mLastUserActivityTime + screenOffTimeout;
- if (now < nextTimeout) {
- mUserActivitySummary = USER_ACTIVITY_SCREEN_DIM;
- }
- }
- }
- if (mUserActivitySummary == 0
- && mLastUserActivityTimeNoChangeLights >= mLastWakeTime) {
- nextTimeout = mLastUserActivityTimeNoChangeLights + screenOffTimeout;
- if (now < nextTimeout) {
- if (mDisplayPowerRequest.policy == DisplayPowerRequest.POLICY_BRIGHT
- || mDisplayPowerRequest.policy == DisplayPowerRequest.POLICY_VR) {
- mUserActivitySummary = USER_ACTIVITY_SCREEN_BRIGHT;
- } else if (mDisplayPowerRequest.policy == DisplayPowerRequest.POLICY_DIM) {
- mUserActivitySummary = USER_ACTIVITY_SCREEN_DIM;
- }
- }
- }
-
- if (mUserActivitySummary == 0) {
- if (sleepTimeout >= 0) {
- final long anyUserActivity = Math.max(mLastUserActivityTime,
- mLastUserActivityTimeNoChangeLights);
- if (anyUserActivity >= mLastWakeTime) {
- nextTimeout = anyUserActivity + sleepTimeout;
- if (now < nextTimeout) {
- mUserActivitySummary = USER_ACTIVITY_SCREEN_DREAM;
- }
- }
- } else {
- //mUserActivitySummary = USER_ACTIVITY_SCREEN_DREAM;//删除系统进入休眠后才进入屏保的逻辑
- nextTimeout = -1;
- }
- }
-
- if (mUserActivitySummary != USER_ACTIVITY_SCREEN_DREAM && userInactiveOverride) {
- if ((mUserActivitySummary &
- (USER_ACTIVITY_SCREEN_BRIGHT | USER_ACTIVITY_SCREEN_DIM)) != 0) {
- // Device is being kept awake by recent user activity
- if (nextTimeout >= now && mOverriddenTimeout == -1) {
- // Save when the next timeout would have occurred
- mOverriddenTimeout = nextTimeout;
- }
- }
- mUserActivitySummary = USER_ACTIVITY_SCREEN_DREAM;
- nextTimeout = -1;
- }
-
- if (nextProfileTimeout > 0) {
- nextTimeout = Math.min(nextTimeout, nextProfileTimeout);
- }
-
- if (mUserActivitySummary != 0 && nextTimeout >= 0) {
- //当“屏幕互保”是打开的,并且无操作后进入休眠的时间 大于 无操作后进入屏保的时间,
- //而且当前的时间 大于 无操作后下次进入屏保的时间则发送信息进入屏保
- if(isScreenSaverEnabled && screenOffTimeout > screenSaverTimeout && now <= screenSaverNextTimeout ){
- scheduleUserInactivityTimeout(screenSaverNextTimeout);
- }else{//否则发送进入休眠的信息
- scheduleUserInactivityTimeout(nextTimeout);
- }
- //Neostra dangziming end screensaver
- }
- } else {
- mUserActivitySummary = 0;
- }
-
- if (DEBUG_SPEW) {
- Slog.d(TAG, "updateUserActivitySummaryLocked: mWakefulness="
- + PowerManagerInternal.wakefulnessToString(mWakefulness)
- + ", mUserActivitySummary=0x" + Integer.toHexString(mUserActivitySummary)
- + ", nextTimeout=" + TimeUtils.formatUptime(nextTimeout));
- }
- }
- }

updateUserActivitySummaryLocked()的逻辑分析可以参考Android 8.1 PowerManagerService分析(二) ——updatePowerStateLocked()方法
如果此文章解答了您的相关疑惑,节约了您的宝贵时间,可以赏小编鸡腿哟!
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。