jQuery鼠标指针特效

关于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 ScreenSaver分析-CSDN博客

Android 10 如何自定义屏保功能-CSDN博客

Android P 屏保和休眠相关知识_android 屏保-CSDN博客

Android13 基座充电屏保-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);
                        }
                    });
                }

设置屏保条件默认为插入座充,插入座充之后无法进入屏保_屏保 基座-CSDN博客

posted @ 2024-05-25 15:41  僵小七  阅读(812)  评论(0)    收藏  举报