关于Android`系统默认屏保`
1.Android 11 -- 强制清理app后台,关于权限引发的问题2.Android 11 (MTK)状态栏图标反色-->跟随当前应用变化代码流程3.Android 11 --关于Toast的异常4.Android 11 -- 关于dialog和悬浮窗导致SystemUI状态栏下拉频繁闪烁(窗口焦点问题)5.Android 11 下拉菜单长按WiFi图标SystemUI ANR6.Android 11 sim卡来电不弹出悬浮通知,默认来电默认全屏7.Android Bluetooth 蓝牙开发/蓝牙协议 小结8.Android11 —— 自定义添加一个System Services9.Android系统——AOSP相关-->随记10.Android11 , Launcher3 切换阿拉伯语,最近应用(后台)不能滑动11.Android 底层问题日志记录12.Android 11 -- app 服务保活13.Android11 - 添加自定义服务注意事项14.Android 11 导航栏添加一个虚拟按钮--问题合集15.Android 11--设置第三方Launcher并默认 与 如何预置apk16.Android11 系统修改 AOSP输入法的默认输入键盘布局17.Settings里面切换不同Launcher的代码流程
18.关于Android`系统默认屏保`
19.关于Android 11 Settings添加新的选项界面的细节20.Android 11 自由窗口模式 || 全屏模式启动app21.强制app横屏显示或者竖屏显示(动态)22.Android 11 禁止从SD卡上安装第三方应用23.实体物理音量键替换为home键24.AMS- kill Launcher进程的代码流程25.Android 11 recovery恢复出厂设置保留某些文件26.Android 11 禁用 adb root (userdebug版本)27.Android11 应用默认获取通知使用权限(可以获取系统所有通知信息)28.Android 11 UsbDebug 关于adb RSA 认证29.Android 11 NavigationBar && Status Bar 如果改变背景颜色30.Anroid 11 关于NotificationManager && NotificationManagerService -- 衍生到权限管理31.Android13 控制设置界面 双栏显示或单栏显示32.Android 13 大屏显示时关于SystemUI和Launcher3问题33.Android 系统适配无源码app34.Android 11 关于app的权限重置35.Android 11.0 关于app进程保活36.Android 11 关于按键拦截/按键事件处理分享37.Android R Settings关于屏保/PowerManagerService欺骗系统不让其进入休眠状态38.Android13 关于SystemUI更新/Nav Bar add volume button&&other button39.Android 13 移植EthernetSettings/Ethernet更新40.Anrdoir 13 关于设置静态IP后,突然断电,在上电开机卡动画41.Android T(13) The app is granted permissions by default42.Android T 关于屏幕旋转 (一)43.Android T about screen rotation(二)44.Android 13 about launcher3 (1)45.Android T don't abort background activity starts46.Android T adout replace bootanimation47.Launcher start App WINDOWING_MODE_FREEFORM48.Android 11 About SleepToken / (Settings)Screen timeout49.Settings.System数据监听/prop&SystemProperties数据监听屏保配置
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 --控制屏保在什么情况打开,显示(充电时,基座充电时或两者皆可)
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
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】凌霞软件回馈社区,博客园 & 1Panel & Halo 联合会员上线
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】博客园社区专享云产品让利特惠,阿里云新客6.5折上折
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 一个费力不讨好的项目,让我损失了近一半的绩效!
· 实操Deepseek接入个人知识库
· CSnakes vs Python.NET:高效嵌入与灵活互通的跨语言方案对比
· 【.NET】调用本地 Deepseek 模型
· Plotly.NET 一个为 .NET 打造的强大开源交互式图表库