关于Android`系统默认屏保`
屏保配置
frameworks\base\core\res\res\values\config.xml
//默认打开
<bool name="config_dreamsEnabledByDefault">true</bool>
//允许任何时候都可进入屏保,
<bool name="config_dreamsEnabledOnBattery">true</bool>
//充电时是否默认打开屏保
<bool name="config_dreamsActivatedOnDockByDefault">false</bool>
//屏保应用
<!-- ComponentName of the default dream (Settings.Secure.DEFAULT_SCREENSAVER_COMPONENT) -->
<string name="config_dreamsDefaultComponent"translatable="false">com.google.android.deskclock/com.android.deskclock.Screensaver</string>
adb shell settings put system screen_off_timeout 2147483647 息屏休眠
adb shell settings get secure screensaver_components
com.android.deskclock/com.android.deskclock.Screensaver(时钟)
adb shell settings get secure screensaver_components
com.android.dreams.basic/com.android.dreams.basic.Colors (万花筒)
1,用户设置Settings.Secure.SCREENSAVER_COMPONENTS 的值
public static final String SCREENSAVER_COMPONENTS = "screensaver_components"
2,如果用户没有设置,则使用默认屏保,默认屏保的在default.xml中配置,配置config_dreamsDefaultComponent 值即可。
Settings 进入 Dream 流程
./packages/apps/Settings/src/com/android/settings/dream/StartNowPreferenceController.java
public class StartNowPreferenceController extends AbstractPreferenceController implements
PreferenceControllerMixin {
private final DreamBackend mBackend;
public StartNowPreferenceController(Context context) {
super(context);
mBackend = DreamBackend.getInstance(context);
mMetricsFeatureProvider = FeatureFactory.getFactory(context).getMetricsFeatureProvider();
}
@Override
public void displayPreference(PreferenceScreen screen) {
super.displayPreference(screen);
LayoutPreference pref = screen.findPreference(getPreferenceKey());
Button startButton = pref.findViewById(R.id.dream_start_now_button);
//入口
startButton.setOnClickListener(v -> {
mMetricsFeatureProvider.logClickedPreference(pref,
pref.getExtras().getInt(DashboardFragment.CATEGORY));
mBackend.startDreaming();
});
}
}
./frameworks/base/packages/SettingsLib/src/com/android/settingslib/dream/DreamBackend.java
public class DreamBackend {
public DreamBackend(Context context) {
mContext = context.getApplicationContext();
mDreamManager = IDreamManager.Stub.asInterface(
ServiceManager.getService(DreamService.DREAM_SERVICE));
...
}
public void startDreaming() {
logd("startDreaming()");
if (mDreamManager == null)
return;
try {
mDreamManager.dream();
} catch (RemoteException e) {
Log.w(TAG, "Failed to dream", e);
}
}
}
屏保启动过程:
屏保从何时启动,在系统 SystemServer startOtherServices 服务启动阶段, PowerManagerService 系统服务准备就绪时,
调用 systemReady() ,注册了更新屏保的系统广播,通过接收 Intent.ACTION_DREAMING_STARTED、Intent.ACTION_DREAMING_STOPPED 广播来对外提供控制屏保的启动与停止.
一种方式就是调用接口来控制,上述两种方式最后调用的接口最后都会调用到 DeamManagerService 服务的接口 ,
mDreamManager.stopDream(false /*immediate*/);immediate这个参数,表示是否立即退出dream ,还是给点时间执行一个退出过渡过程. mDreamManager.startDream(wakefulness == WAKEFULNESS_DOZING);
但是DreamManagerService并不在SystemServiceRegistry中,不能直接通过 Context.getSystemService 来拿到 DreamManagerService来停止屏保动作.可惜.
还有一种 方式,input 点击唤醒,退出dream
./frameworks/base/core/java/android/service/dreams/DreamService.java
@Override
public boolean dispatchKeyShortcutEvent(KeyEvent event) {
if (!mInteractive) {
if (mDebug) Slog.v(TAG, "Waking up on keyShortcutEvent");
wakeUp();
return true;
}
return mWindow.superDispatchKeyShortcutEvent(event);
}
private void wakeUp(boolean fromSystem) {
if (mDebug) Slog.v(TAG, "wakeUp(): fromSystem=" + fromSystem
+ ", mWaking=" + mWaking + ", mFinished=" + mFinished);
if (!mWaking && !mFinished) {
mWaking = true;
// As a minor optimization, invoke the callback first in case it simply
// calls finish() immediately so there wouldn't be much point in telling
// the system that we are finishing the dream gently.
onWakeUp();
// Now tell the system we are waking gently, unless we already told
// it we were finishing immediately.
if (!fromSystem && !mFinished) {
if (mActivity == null) {
Slog.w(TAG, "WakeUp was called before the dream was attached.");
} else {
try {
mDreamManager.finishSelf(mDreamToken, false /*immediate*/);
} catch (RemoteException ex) {
// system server died
}
}
}
}
}
/frameworks/base/services/core/java/com/android/server/power/PowerManagerService.java
public final class PowerManagerService extends SystemService {
// Message: 当发生用户活动超时(界面无操作)以更新电源状态时发送.
private static final int MSG_USER_ACTIVITY_TIMEOUT = 1;
// Message: 当设备进入或退出dreaming或dozing状态时发送
private static final int MSG_SANDMAN = 2;
public void systemReady(IAppOpsService appOps) {
mSystemReady = true;
mAppOps = appOps;
mDreamManager = getLocalService(DreamManagerInternal.class);
mDisplayManagerInternal = getLocalService(DisplayManagerInternal.class);
mPolicy = getLocalService(WindowManagerPolicy.class);
...
ilter = new IntentFilter();
filter.addAction(Intent.ACTION_DREAMING_STARTED);
filter.addAction(Intent.ACTION_DREAMING_STOPPED);
mContext.registerReceiver(new DreamReceiver(), filter, null, mHandler);
}
private final class DreamReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
synchronized (mLock) {
scheduleSandmanLocked();
}
}
}
// 广播调用、updateDreamLocked() 调用
private void scheduleSandmanLocked() {
if (!mSandmanScheduled) {
mSandmanScheduled = true;
// 发送消息 MSG_SANDMAN
Message msg = mHandler.obtainMessage(MSG_SANDMAN);
msg.setAsynchronous(true);
mHandler.sendMessage(msg);
}
}
}
private final class PowerManagerHandler extends Handler {
public PowerManagerHandler(Looper looper) {
super(looper, null, true /*async*/);
}
@Override
public void handleMessage(Message msg) {
switch (msg.what) {
case MSG_USER_ACTIVITY_TIMEOUT:
handleUserActivityTimeout();
break;
case MSG_SANDMAN:
// 进入屏保的入口
handleSandman();
break;
case MSG_SCREEN_BRIGHTNESS_BOOST_TIMEOUT:
handleScreenBrightnessBoostTimeout();
break;
case MSG_CHECK_FOR_LONG_WAKELOCKS:
checkForLongWakeLocks();
break;
}
}
}
\frameworks\base\services\core\java\com\android\server\dreams\DreamManagerService.java
private final class LocalService extends DreamManagerInternal {
@Override
public void startDream(boolean doze) {
startDreamInternal(doze);
}
private void startDreamInternal(boolean doze) {
final int userId = ActivityManager.getCurrentUser();
final ComponentName dream = chooseDreamForUser(doze, userId);//1.选择屏保页
if (dream != null) {
synchronized (mLock) {
startDreamLocked(dream, false /*isTest*/, doze, userId);//2.启动屏保
}
}
private ComponentName chooseDreamForUser(boolean doze, int userId) {
if (doze) {
ComponentName dozeComponent = getDozeComponent(userId);
return validateDream(dozeComponent) ? dozeComponent : null;
}
ComponentName[] dreams = getDreamComponentsForUser(userId);
return dreams != null && dreams.length != 0 ? dreams[0] : null;
private ComponentName[] getDreamComponentsForUser(int userId) {
//1.获取Settings.Secure.SCREENSAVER_COMPONENTS提供的屏保,如果这个值为null,
//2.走系统默认的getDefaultDreamComponentForUser
String names = Settings.Secure.getStringForUser(mContext.getContentResolver(),
Settings.Secure.SCREENSAVER_COMPONENTS,
userId);
ComponentName[] components = componentsFromString(names);
// first, ensure components point to valid services
List<ComponentName> validComponents = new ArrayList<ComponentName>();
if (components != null) {
for (ComponentName component : components) {
if (validateDream(component)) {
validComponents.add(component);
}
// fallback to the default dream component if necessary
if (validComponents.isEmpty()) {
//上面为null,这里获取默认的屏保
ComponentName defaultDream = getDefaultDreamComponentForUser(userId);
if (defaultDream != null) {
Slog.w(TAG, "Falling back to default dream " + defaultDream);
validComponents.add(defaultDream);
}
}
return validComponents.toArray(new ComponentName[validComponents.size()]);
}
//选择完了屏保,然后就是启动的流程,mController->DreamController
private void startDreamLocked(final ComponentName name,
final boolean isTest, final boolean canDoze, final int userId) {
.......
mHandler.post(wakeLock.wrap(
() -> mController.startDream(newToken, name, isTest, canDoze, userId, wakeLock)));
}
frameworks\base\services\core\java\com\android\server\dreams\DreamController.java
public void startDream(Binder token, ComponentName name,
boolean isTest, boolean canDoze, int userId, PowerManager.WakeLock wakeLock) {
stopDream(true /*immediate*/);
......
//DreamService.SERVICE_INTERFACE 为 android.service.dreams.DreamService
// 通过这个action来找到我们再用中自定义的屏保服务
Intent intent = new Intent(DreamService.SERVICE_INTERFACE);
intent.setComponent(name);
intent.addFlags(Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
//最后通过bindServiceAsUser 启动之前找到的DreamService服务(屏保)
if (!mContext.bindServiceAsUser(intent, mCurrentDream,
Context.BIND_AUTO_CREATE | Context.BIND_FOREGROUND_SERVICE,
new UserHandle(userId))) {
......
/ frameworks/base/core/java/android/service/dreams/DreamService.java
//该服务实现了 Window.Callback 接口,说明他能响应正常Window的用户操作
public class DreamService extends Service implements Window.Callback {
public DreamService() {
mSandman = IDreamManager.Stub.asInterface(ServiceManager.getService(DREAM_SERVICE));
}
@Override
public final IBinder onBind(Intent intent) {
if (mDebug) Slog.v(TAG, "onBind() intent = " + intent);
// 通过 DreamServiceWrapper 包装 IDreamService.Stub 来为DreamController提供代理对象。
return new DreamServiceWrapper();
}
private final class DreamServiceWrapper extends IDreamService.Stub {
@Override
public void attach(final IBinder windowToken, final boolean canDoze,
IRemoteCallback started) {
mHandler.post(new Runnable() {
@Override
public void run() {
DreamService.this.attach(windowToken, canDoze, started);//启用一个屏保窗口
}
});
}
@Override
public void detach() {
mHandler.post(new Runnable() {
@Override
public void run() {
DreamService.this.detach();
}
});
}
@Override
public void wakeUp() {
mHandler.post(new Runnable() {
@Override
public void run() {
DreamService.this.wakeUp(true /*fromSystem*/);
}
});
}
}
}
ending --控制屏保在什么情况打开,显示(充电时,基座充电时或两者皆可)
adb 看屏保要素
console:/ # settings list secure | grep screensaver
screensaver_activate_on_dock=0
screensaver_activate_on_sleep=1
screensaver_components=com.android.dreams.basic/com.android.dreams.basic.Colors
screensaver_default_component=com.android.deskclock/com.android.deskclock.Screensaver
screensaver_enabled=1
frameworks\base\services\core\java\com\android\server\power\PowerManagerService.java
//是否打开屏保
mDreamsEnabledSetting = (Settings.Secure.getIntForUser(resolver,
Settings.Secure.SCREENSAVER_ENABLED,
mDreamsEnabledByDefaultConfig ? 1 : 0,
UserHandle.USER_CURRENT) != 0);
//仅充电时设置此值为1 public static final String SCREENSAVER_ACTIVATE_ON_DOCK = "screensaver_activate_on_dock";
mDreamsActivateOnSleepSetting = (Settings.Secure.getIntForUser(resolver,
Settings.Secure.SCREENSAVER_ACTIVATE_ON_SLEEP,
mDreamsActivatedOnSleepByDefaultConfig ? 1 : 0,
UserHandle.USER_CURRENT) != 0);
//基座充电时,此值为1 public static final String SCREENSAVER_ACTIVATE_ON_SLEEP = "screensaver_activate_on_sleep";
public static final String SCREENSAVER_ACTIVATE_ON_DOCK = "screensaver_activate_on_dock";
mDreamsActivateOnDockSetting = (Settings.Secure.getIntForUser(resolver,
Settings.Secure.SCREENSAVER_ACTIVATE_ON_DOCK,
mDreamsActivatedOnDockByDefaultConfig ? 1 : 0,
UserHandle.USER_CURRENT) != 0);
都为1,两者皆可,一个为1,为1的正确
都为true,两者皆可!!!
/frameworks/base/core/res/res/values/config.xml
<!-- If supported, are dreams enabled? (by default) -->
<bool name="config_dreamsEnabledByDefault">true</bool>
<!-- If supported and enabled, are dreams activated when docked? (by default) -->
<bool name="config_dreamsActivatedOnDockByDefault">true</bool>
<!-- If supported and enabled, are dreams activated when asleep and charging? (by default) -->
<bool name="config_dreamsActivatedOnSleepByDefault">true</bool>
Android P 屏保和休眠相关知识_android 屏保-CSDN博客
去掉屏保的多余项
Android14去掉屏保的多余项_android14 去掉锁屏界面-CSDN博客
+++ b/src/com/android/settings/dream/DreamPickerController.java
public DreamPickerController(Context context, DreamBackend backend) {
super(context, PREF_KEY);
mBackend = backend;
mDreamInfos = mBackend.getDreamInfos();
mActiveDream = getActiveDreamInfo(mDreamInfos);
//add text start
for (int i = 0; i < mDreamInfos.size() ; i++) {
android.util.Log.i("tag", "item: "+mDreamInfos.get(i).componentName);
android.util.Log.i("tag", "item delete: "+mDreamInfos.get(i).componentName);
if(mDreamInfos.get(i).componentName.flattenToString().contains("com.android.dreams.phototable")){
//
mDreamInfos.remove(i);
i--;
}
}
android.util.Log.i("tag", "DreamPickerController: mActiveDream.componentName:"+mActiveDream.componentName);
//add text end
mMetricsFeatureProvider = FeatureFactory.getFactory(context).getMetricsFeatureProvider();
}
启用时机选择“充电时”,灭屏后没有启动屏保
screensaver_components=com.android.dreams.basic/com.android.dreams.basic.Colors //选中屏保:万花筒
screensaver_default_component=com.android.deskclock/com.android.deskclock.Screensaver // 默认屏保:时钟
2025-07-31 15:30:57.593 1167-1336 ActivityManager system_process D freezing 2431 com.android.deskclock
2025-07-31 15:30:57.593 1167-1336 ActivityManager system_process D freezing 2431 com.android.dreams.basic
Android 14 修改日志 -关于Android T 屏幕保护选项/屏幕程序选择
/**
* Freeze a process.
* @param proc process to be frozen
*/
@GuardedBy({"mAm"})
private void freezeProcess(final ProcessRecord proc) {
int pid = proc.getPid(); // Unlocked intentionally
final String name = proc.processName;
final long unfrozenDuration;
final boolean frozen;
final ProcessCachedOptimizerRecord opt = proc.mOptRecord;
synchronized (mProcLock) {
// someone has canceled this freeze
if (!opt.isPendingFreeze()) {
return;
}
opt.setPendingFreeze(false);
pid = proc.getPid();
if (mFreezerOverride) {
opt.setFreezerOverride(true);
Slog.d(TAG_AM, "Skipping freeze for process " + pid
+ " " + name + " curAdj = " + proc.mState.getCurAdj()
+ "(override)");
return;
}
if (opt.shouldNotFreeze()) {
if (DEBUG_FREEZER) {
Slog.d(TAG_AM, "Skipping freeze because process is marked "
+ "should not be frozen");
}
return;
}
if (pid == 0 || opt.isFrozen()) {
// Already frozen or not a real process, either one being
// launched or one being killed
if (DEBUG_FREEZER) {
Slog.d(TAG_AM, "Skipping freeze for process " + pid
+ " " + name + ". Already frozen or not a real process");
}
return;
}
//add text start
if("com.android.dreams.basic".equals(name) ||
"com.android.deskclock"..equals(name)){
Slog.d(TAG_AM, "Skipping freeze for process " + pid
+ " " + name +"to screen saver");
return;
}
//add text end
Slog.d(TAG_AM, "freezing " + pid + " " + name);
// Freeze binder interface before the process, to flush any
// transactions that might be pending.
try {
if (freezeBinder(pid, true, FREEZE_BINDER_TIMEOUT_MS) != 0) {
handleBinderFreezerFailure(proc, "outstanding txns");
return;
}
} catch (RuntimeException e) {
Slog.e(TAG_AM, "Unable to freeze binder for " + pid + " " + name);
mFreezeHandler.post(() -> {
synchronized (mAm) {
proc.killLocked("Unable to freeze binder interface",
ApplicationExitInfo.REASON_FREEZER,
ApplicationExitInfo.SUBREASON_FREEZER_BINDER_IOCTL, true);
}
});
}

浙公网安备 33010602011771号