jQuery鼠标指针特效

Android R Settings关于屏保/PowerManagerService欺骗系统不让其进入休眠状态

old

//屏保设置界面
./packages/apps/Settings/src/com/android/settings/dream/DreamSettings.java

//和PowerManagerService 建立联系
./frameworks/base/packages/SettingsLib/src/com/android/settingslib/dream/DreamBackend.java

//系统时钟屏保 继承了DreamService
./packages/apps/DeskClock/src/com/android/deskclock/Screensaver.java

./packages/apps/DeskClock/src/com/android/deskclock/ScreensaverActivity.java

public static final String SCREENSAVER_ENABLED = "screensaver_enabled";

adb shell settings get secure screensaver_enabled 
0 false(never)

如何替换activityt退出(finish)的动画

    private void textFinish() {
        new Handler().postDelayed(new Runnable() {
            @Override
            public void run() {
                //finish();
                finishAndRemoveTask();//使用这个
            }
        }, 0);
    }
    
    //复写finishAndRemoveTask
    @Override
    public void finishAndRemoveTask() {
        super.finishAndRemoveTask();
        overridePendingTransition(0, R.anim.dream_activity_close_exit);
    }

//R.anim.dream_activity_close_exit
<alpha xmlns:android="http://schemas.android.com/apk/res/android"
    android:fromAlpha="1.0"
    android:toAlpha="0.0"
    android:duration="100" />

android 屏保 (PowerManager & DreamService)

android 系统休眠过程四个状态,分别是SCREEN_BRIGHT,SCREEN_DIM,SCREEN_DREAM,SLEEP

思路1:不让系统进入后面两个状态,保持在SCREEN_DREAM,然后发送广播,操作屏幕背光--->我把它叫做假休眠(fake_sleep_mode)
(或者保持在SCREEN_DREAM后,拉起一个服务,在界面上添加一个的window,window上面布局随意,点击之后移除)

+++ b/frameworks/base/services/core/java/com/android/server/power/PowerManagerService.java
@@ -140,6 +140,8 @@ public final class PowerManagerService extends SystemService
     private static final int MSG_CHECK_FOR_LONG_WAKELOCKS = 4;
     // Message: Sent when an attentive timeout occurs to update the power state.
     private static final int MSG_ATTENTIVE_TIMEOUT = 5;
+    // Message: enter fake sleep mode
+    private static final int MSG_FAKE_SLEEP_MODE = 6;//add text

     // Dirty bit: mWakeLocks changed
     private static final int DIRTY_WAKE_LOCKS = 1 << 0;
@@ -1722,6 +1724,9 @@ public final class PowerManagerService extends SystemService
         }
     }

+    //fake sleep mode flag
+    private int fake_sleep_init = 0;//add text
+


private void updateUserActivitySummaryLocked(long now, int dirty) {
    ...
    if (Integer.MAX_VALUE == screenOffTimeout) {
                    mUserActivitySummary = USER_ACTIVITY_SCREEN_BRIGHT;
                    //Slog.d(TAG, "set mUserActivitySummary USER_ACTIVITY_SCREEN_BRIGHT never sleep " + nextTimeout);
                }

                if (mUserActivitySummary != 0 && nextTimeout >= 0) {
                    scheduleUserInactivityTimeout(nextTimeout);
                }
            } else {
                mUserActivitySummary = 0;
            }

            //add text
            if(mUserActivitySummary == 1 && fake_sleep_init > 0){
                fake_sleep_init = 0;
                Slog.d(TAG, "fake_sleep_init: reset");
            }
            //add text
    ...
}

    @SuppressWarnings("deprecation")
    private boolean goToSleepNoUpdateLocked(long eventTime, int reason, int flags, int uid) {
        if (DEBUG_SPEW) {
            Slog.d(TAG, "goToSleepNoUpdateLocked: eventTime=" + eventTime
                    + ", reason=" + reason + ", flags=" + flags + ", uid=" + uid);
        }

        //add text
        int fake_sleep_mode = SystemProperties.getInt("xxx.sys.fake_sleep_xxx", 0);
        if (fake_sleep_mode == 0) {
            if (fake_sleep_init == 0) {
                Message fake_msg = mHandler.obtainMessage(MSG_FAKE_SLEEP_MODE);
                fake_msg.setAsynchronous(true);
                mHandler.sendMessage(fake_msg);
                fake_sleep_init++;
            }
            return false;
        }
        //add text

        if (eventTime < mLastWakeTime
                || getWakefulnessLocked() == WAKEFULNESS_ASLEEP
                || getWakefulnessLocked() == WAKEFULNESS_DOZING
                || !mSystemReady
                || !mBootCompleted) {
            return false;
        }

        Trace.traceBegin(Trace.TRACE_TAG_POWER, "goToSleep");
        try {
            reason = Math.min(PowerManager.GO_TO_SLEEP_REASON_MAX,
                    Math.max(reason, PowerManager.GO_TO_SLEEP_REASON_MIN));
            Slog.i(TAG, "Going to sleep due to " + PowerManager.sleepReasonToString(reason)
                    + " (uid " + uid + ")...");

            mLastSleepTime = eventTime;
            mLastSleepReason = reason;
            mSandmanSummoned = true;
            mDozeStartInProgress = true;
            setWakefulnessLocked(WAKEFULNESS_DOZING, reason, eventTime);
            ...
}          

    private final class PowerManagerHandlerCallback implements Handler.Callback {
        @Override
        public boolean handleMessage(Message msg) {
            switch (msg.what) {
                case MSG_USER_ACTIVITY_TIMEOUT:
                    handleUserActivityTimeout();
                break;
            ...             
                //add text
                case MSG_FAKE_SLEEP_MODE:
                    //发送广播去关闭背光
                    Slog.d(TAG, "Fake sleep mode , entering clock screen...");
                    Intent intent  = new Intent("sys.android.fake.sleep.action");
                    intent.setPackage("com.android.settings");
                    mContext.sendBroadcastAsUser(intent,UserHandle.ALL);
                    break;
                //add text
  

修改Android 休眠逻辑使系统关屏而不进入休眠

Android 系统全局监听touch事件,在背光关闭的情况下.

./frameworks/base/core/java/android/view/WindowManagerPolicyConstants.java

    // TODO: move this to a more appropriate place.
    interface PointerEventListener {
        /**
         * 1. onPointerEvent will be called on the service.UiThread.
         * 2. motionEvent will be recycled after onPointerEvent returns so if it is needed later a
         * copy() must be made and the copy must be recycled.
         **/
        void onPointerEvent(MotionEvent motionEvent);
    }
    
+++ b/frameworks/base/services/core/java/com/android/server/wm/WindowManagerService.java
@@ -1149,7 +1149,7 @@ public class WindowManagerService extends IWindowManager.Stub
             String[] args, ShellCallback callback, ResultReceiver result) {
         new WindowManagerShellCommand(this).exec(this, in, out, err, args, callback, result);
     }
-
+    private static Context t_context;
     private WindowManagerService(Context context, InputManagerService inputManager,
             boolean showBootMsgs, boolean onlyCore, WindowManagerPolicy policy,
             ActivityTaskManagerService atm, Supplier<SurfaceControl.Transaction> transactionFactory,
@@ -1159,6 +1159,7 @@ public class WindowManagerService extends IWindowManager.Stub
         mGlobalLock = atm.getGlobalLock();
         mAtmService = atm;
         mContext = context;
+        t_context = context;
         mIsPc = mContext.getPackageManager().hasSystemFeature(FEATURE_PC);
         mAllowBootMessages = showBootMsgs;
         mOnlyCore = onlyCore;
@@ -6805,6 +6806,8 @@ public class WindowManagerService extends IWindowManager.Stub

     MousePositionTracker mMousePositionTracker = new MousePositionTracker();

+    private static int x_init = 0;//模拟当前背光状态

     private static class MousePositionTracker implements PointerEventListener {
         private boolean mLatestEventWasMouse;
         private float mLatestMouseX;
          ...
             } else {
                 synchronized (this) {
                     mLatestEventWasMouse = false;
+                    //add text
+                    if (motionEvent.getAction() == MotionEvent.ACTION_DOWN && x_init == 0){
+                        android.util.Log.d("tag","motionEvent---ACTION_DOWN.");
+                        mContext.sendBroadcast(new Intent("sys.android.fake.sleep.awake.action"));//发送广播点亮背光
+                        x_init++;
+                    }
+                    //add text
                 }
             }
         }


./frameworks/base/services/core/java/com/android/server/wm/SystemGesturesPointerEventListener.java:39:
class SystemGesturesPointerEventListener implements PointerEventListener {

./frameworks/base/services/core/java/com/android/server/wm/WindowManagerService.java:6808:   
 private static class MousePositionTracker implements PointerEventListener {
 
./frameworks/base/services/core/java/com/android/server/wm/TaskTapPointerEventListener.java:37:
public class TaskTapPointerEventListener implements PointerEventListener {    

Android 系统全局监听

add Dialog/add Window

    //add text
    private static TimeLayoutDialog mDialog;

    private void createTextDialog() {
        TimeLayoutDialog dialog = new TimeLayoutDialog(mContext);
        mDialog = dialog;
        mDialog.show();
    }

    static final class TimeLayoutDialog extends Dialog {
        private final Context TContext;

        TimeLayoutDialog(Context context) {
            super(context, com.android.systemui.R.style.Theme_SystemUI_Dialog_GlobalActions);
            TContext = context;

            Window window = getWindow();
            window.requestFeature(Window.FEATURE_NO_TITLE);
            window.getDecorView();
            window.getAttributes().systemUiVisibility |= View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
                    | View.SYSTEM_UI_FLAG_LAYOUT_STABLE
                    | View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION;
            window.setLayout(MATCH_PARENT, MATCH_PARENT);
            window.clearFlags(WindowManager.LayoutParams.FLAG_DIM_BEHIND);
            window.addFlags(
                    WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN
                            | WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL
                            | WindowManager.LayoutParams.FLAG_LAYOUT_INSET_DECOR
                            | WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED
                            | WindowManager.LayoutParams.FLAG_WATCH_OUTSIDE_TOUCH
                            | WindowManager.LayoutParams.FLAG_HARDWARE_ACCELERATED);
            window.setType(WindowManager.LayoutParams.TYPE_VOLUME_OVERLAY);
            window.getAttributes().setFitInsetsTypes(0 /* types */);
            
            int uiOptions = View.SYSTEM_UI_FLAG_LAYOUT_STABLE |
                    View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION |
                    View.SYSTEM_UI_FLAG_FULLSCREEN |
                    View.SYSTEM_UI_FLAG_HIDE_NAVIGATION |
                    View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN |
                    View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY;
            window.getDecorView().setSystemUiVisibility(uiOptions);

            initializeLayout();
        }

        private void initializeLayout() {
            setContentView(com.android.systemui.R.layout.global_actions_time);
            ViewGroup black_view = findViewById(com.android.systemui.R.id.time_action_root);
            black_view.setClickable(true);
            black_view.setOnClickListener(v -> {
                if (mDialog != null) mDialog.dismiss();
            });
            TextClock timeClock = findViewById(com.android.systemui.R.id.tc_timeText);
            setTimeFormat(timeClock, false);
        }

        private CharSequence get24ModeFormat(boolean includeSeconds) {
            return DateFormat.getBestDateTimePattern(Locale.getDefault(), includeSeconds ? "Hms" : "Hm");
        }

        private CharSequence get12ModeFormat(float amPmRatio, boolean includeSeconds) {
            String pattern = android.text.format.DateFormat.getBestDateTimePattern(Locale.getDefault(),
                    includeSeconds ? "hmsa" : "hma");
            if (amPmRatio <= 0) {
                pattern = pattern.replaceAll("a", "").trim();
            }

            // Replace spaces with "Hair Space"
            pattern = pattern.replaceAll(" ", "\u200A");
            // Build a spannable so that the am/pm will be formatted
            int amPmPos = pattern.indexOf('a');
            if (amPmPos == -1) {
                return pattern;
            }

            final Spannable sp = new SpannableString(pattern);
            sp.setSpan(new RelativeSizeSpan(amPmRatio), amPmPos, amPmPos + 1,
                    Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
            sp.setSpan(new StyleSpan(Typeface.NORMAL), amPmPos, amPmPos + 1,
                    Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
            sp.setSpan(new TypefaceSpan("sans-serif"), amPmPos, amPmPos + 1,
                    Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);

            return sp;
        }

        private void setTimeFormat(TextClock clock, boolean includeSeconds) {
            if (clock != null) {
                // Get the best format for 12 hours mode according to the locale
                clock.setFormat12Hour(get12ModeFormat(0.4f /* amPmRatio */, includeSeconds));
                // Get the best format for 24 hours mode according to the locale
                clock.setFormat24Hour(get24ModeFormat(includeSeconds));
            }
        }
    }
    //add text


//adout R.layout.global_actions_time's widget
    <TextClock
        android:id="@+id/tc_timeText"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_marginTop="18dp"
        android:format12Hour="hh:mm"
        android:format24Hour="HH:mm"
        android:gravity="center"
        android:textColor="#ffffff"
        android:textSize="85sp"
        android:textStyle="italic" />

    <TextClock
        android:id="@+id/tc_dateText"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:format12Hour="E,MMM dd"
        android:format24Hour="E,MMM dd"
        android:gravity="center"
        android:textColor="#ffffff"
        android:textSize="25sp"
        android:textStyle="italic" />

repair bug

上面的方案导致的bug:
persist.xxx.fake_sleep_enable 为true时 , 影响到了正常power键短按灭亮屏的流程.

分析:
当时为了不让系统进入sleep,在PMS::goToSleepNoUpdateLocked返回了false(做了拦截),但是power的灭屏流程也会经过这里,
导致bug的出现.

解决:
还是在原有方案的基础上改进,多添加一个SystemProperties.set("hello.xxx.power_xxx_sleep", "true")的变量进行判断,
系统按压power时,将它置为true,不拦截,走正常的灭屏流程,当设备亮屏时,置为false,继续拦截.

private void powerPress(long eventTime, boolean interactive, int count) {
    ...
    Slog.d(TAG, "powerPress: eventTime=" + eventTime + " interactive=" + interactive
                + " count=" + count + " beganFromNonInteractive=" + mBeganFromNonInteractive +
                " mShortPressOnPowerBehavior=" + mShortPressOnPowerBehavior);
}

powerPress: eventTime=3705285 interactive=true count=1 beganFromNonInteractive=false mShortPressOnPowerBehavior=1

private boolean goToSleepFromPowerButton(long eventTime, int flags) {...}

实际修改之后操作发现:
正常的息屏休眠,走updatePowerStateLocked,
但是如果先按power键灭屏,在亮屏,之后就发现发现息屏休眠流程不走goToSleepNoUpdateLocked,原因是插了usb连接了adb,用了AS的虚拟投屏(具体原因不知道),反正断了adb,就正常了.也是个乌龙...
具体也没去细查了,换了一个地方让其在界面上添加一个的window/dialog.

下面就是goToSleepNoUpdateLocked的堆栈:




                                                                                                                                                                                                     
2024-09-05 17:04:32.636   507-547   WindowManager           system_server   D  java.lang.Throwable
                                                                            at com.android.server.power.PowerManagerService.goToSleepNoUpdateLocked(PowerManagerService.java:1743)
                                                                            at com.android.server.power.PowerManagerService.updateWakefulnessLocked(PowerManagerService.java:2598)
                                                                            at com.android.server.power.PowerManagerService.updatePowerStateLocked(PowerManagerService.java:1956)
                                                                            at com.android.server.power.PowerManagerService.handleUserActivityTimeout(PowerManagerService.java:2515)
                                                                            at com.android.server.power.PowerManagerService.access$3600(PowerManagerService.java:127)
                                                                            at com.android.server.power.PowerManagerService$PowerManagerHandlerCallback.handleMessage(PowerManagerService.java:4459)
                                                                            at android.os.Handler.dispatchMessage(Handler.java:102)
                                                                            at android.os.Looper.loop(Looper.java:223)
                                                                            at android.os.HandlerThread.run(HandlerThread.java:67)
                                                                            at com.android.server.ServiceThread.run(ServiceThread.java:44)                                                                                                        
                                                                                                        
                                                                                                        
                                                                                                        
2024-09-05 17:04:00.009   507-507   WindowManager           system_server   D  java.lang.Throwable
                                                                            at com.android.server.power.PowerManagerService.goToSleepNoUpdateLocked(PowerManagerService.java:1743)
                                                                            at com.android.server.power.PowerManagerService.updateWakefulnessLocked(PowerManagerService.java:2598)
                                                                            at com.android.server.power.PowerManagerService.updatePowerStateLocked(PowerManagerService.java:1956)
                                                                            at com.android.server.power.PowerManagerService.removeWakeLockLocked(PowerManagerService.java:1441)
                                                                            at com.android.server.power.PowerManagerService.releaseWakeLockInternal(PowerManagerService.java:1409)
                                                                            at com.android.server.power.PowerManagerService.access$4700(PowerManagerService.java:127)
                                                                            at com.android.server.power.PowerManagerService$BinderService.releaseWakeLock(PowerManagerService.java:4840)
                                                                            at android.os.PowerManager$WakeLock.release(PowerManager.java:2548)
                                                                            at android.os.PowerManager$WakeLock.release(PowerManager.java:2518)
                                                                            at com.android.server.AlarmManagerService$DeliveryTracker.updateTrackingLocked(AlarmManagerService.java:4628)
                                                                            at com.android.server.AlarmManagerService$DeliveryTracker.alarmComplete(AlarmManagerService.java:4671)
                                                                            at com.android.server.AlarmManagerService$3.lambda$doAlarm$0$AlarmManagerService$3(AlarmManagerService.java:1545)
                                                                            at com.android.server.-$$Lambda$AlarmManagerService$3$jIkPWjqS66vG6aFVQoHxR2w4HPE.run(Unknown Source:4)
                                                                            at android.os.Handler.handleCallback(Handler.java:938)
                                                                            at android.os.Handler.dispatchMessage(Handler.java:99)
                                                                            at android.os.Looper.loop(Looper.java:223)
                                                                            at com.android.server.SystemServer.run(SystemServer.java:629)
                                                                            at com.android.server.SystemServer.main(SystemServer.java:415)
                                                                            at java.lang.reflect.Method.invoke(Native Method)
                                                                            at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:592)
                                                                            at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:925)
                                                                            

diff:

frameworks/base/services/core/java/com/android/server/power/PowerManagerService.java

private void updateUserActivitySummaryLocked(long now, int dirty) {
   ...
   if (Integer.MAX_VALUE == screenOffTimeout) {
                   mUserActivitySummary = USER_ACTIVITY_SCREEN_BRIGHT;
                   //Slog.d(TAG, "set mUserActivitySummary USER_ACTIVITY_SCREEN_BRIGHT never sleep " + nextTimeout);
               }

               if (mUserActivitySummary != 0 && nextTimeout >= 0) {
                   scheduleUserInactivityTimeout(nextTimeout);
               }
           } else {
               mUserActivitySummary = 0;
           }

           //add text
           if(mUserActivitySummary == 1 && fake_sleep_init > 0){
               fake_sleep_init = 0;
               Slog.d(TAG, "fake_sleep_init: reset");
           }
           boolean fake_sleep_mode = SystemProperties.getBoolean("persist.xxx.fake_sleep_xxxx", false);
           if(fake_sleep_mode ){
             if (mUserActivitySummary == 4 && fake_sleep_init == 0) {
               Message fake_msg = mHandler.obtainMessage(MSG_FAKE_SLEEP_MODE);
               fake_msg.setAsynchronous(true);
               mHandler.sendMessage(fake_msg);
               fake_sleep_init++;
             }
           }
           //add text
   ...
}

   private boolean goToSleepNoUpdateLocked(long eventTime, int reason, int flags, int uid) {
       if (DEBUG_SPEW) {
           Slog.d(TAG, "goToSleepNoUpdateLocked: eventTime=" + eventTime
                   + ", reason=" + reason + ", flags=" + flags + ", uid=" + uid);
       }

       //add text
       boolean power_sleep_mode = SystemProperties.getBoolean("hello.xxx.power_xxx_sleep", false);
       boolean fake_sleep_mode = SystemProperties.getBoolean("persist.xxx.fake_sleep_xxx", false);
       if (fake_sleep_mode && !power_sleep_mode) {
           return false;
       }
       //add text
       
       
frameworks/base/services/core/java/com/android/server/policy/PhoneWindowManager.java

private boolean goToSleepFromPowerButton(long eventTime, int flags) {
   ...
   
   //add text
       boolean fake_sleep_mode = SystemProperties.getBoolean("persist.xxx.fake_sleep_xxx", false);
       if (fake_sleep_mode){
           SystemProperties.set("hello.xxx.power_xxx_sleep", "true");
           Intent fake_wakeup_intent = new Intent("xxx.xx.xx.wakeup.action");
           fake_wakeup_intent.setPackage("com.xx.xx");
           mContext.sendBroadcast(fake_wakeup_intent);
       }
       //add text
   ...
   goToSleep(eventTime, PowerManager.GO_TO_SLEEP_REASON_POWER_BUTTON, flags);
   return true;  
}


private boolean wakeUp(long wakeTime, boolean wakeInTheaterMode, @WakeReason int reason,
           String details) {
           
       ...
       //add text
       boolean fake_sleep_mode = SystemProperties.getBoolean("persist.sys.fake_sleep_enable", false);
       if (fake_sleep_mode){
           SystemProperties.set("hello.xxx.power_xxx_sleep", "false");
       }
       //add text

       mPowerManager.wakeUp(wakeTime, reason, details);
       ...
       return true;
   }        

亮屏流程:

PowerManagerService::wakeUp(...)-->wakeUpInternal()-->wakeUpNoUpdateLocked()[更新验证和灭屏状态更新]...

system_server主线程执行PhoneWindowManager#startedWakingUp()方法,通知WMS开始亮屏

-->system_server主线程发送亮屏广播-->DMS(DisplayManagerService)请求Display状态和亮度

-->DMS返回请求状态后,system_server主线程执行PhoneWindowManager::finishedWakingUp()通知WMS模块完成亮屏

灭屏流程(power key press):

PowerManagerService::goToSleep(...)-->goToSleepInternal()-->goToSleepNoUpdateLocked()-->updatePowerStateLocked()

-->reallyGoToSleepNoUpdateLocked()

-->Notifier::handleEarlyInteractiveChange(){
    synchronized (mLock) {
            if (mInteractive) {
                ......
            } else {
                // Going to sleep...
                // 通知WMS开始灭屏
                final int why = translateOffReason(mInteractiveChangeReason);
                mHandler.post(new Runnable() {
                    @Override
                    public void run() {
                        mPolicy.startedGoingToSleep(why);
                    }
                });
            }
        }
}

Android R PowerManagerService 亮屏流程
Android R PowerManagerService模块(4) 灭屏流程
Android 11.0 Power 键亮屏灭屏流程分析

posted @   僵小七  阅读(78)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 本地部署 DeepSeek:小白也能轻松搞定!
· 如何给本地部署的DeepSeek投喂数据,让他更懂你
· 从 Windows Forms 到微服务的经验教训
· 李飞飞的50美金比肩DeepSeek把CEO忽悠瘸了,倒霉的却是程序员
· 超详细,DeepSeek 接入PyCharm实现AI编程!(支持本地部署DeepSeek及官方Dee
点击右上角即可分享
微信分享提示