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 --控制屏保在什么情况打开,显示(充电时,基座充电时或两者皆可)

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博客

posted @   僵小七  阅读(420)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 一个费力不讨好的项目,让我损失了近一半的绩效!
· 实操Deepseek接入个人知识库
· CSnakes vs Python.NET:高效嵌入与灵活互通的跨语言方案对比
· 【.NET】调用本地 Deepseek 模型
· Plotly.NET 一个为 .NET 打造的强大开源交互式图表库
点击右上角即可分享
微信分享提示