1 /*
2  * Copyright (C) 2017 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 package com.android.systemui.keyguard;
18 
19 import android.annotation.IntDef;
20 import android.os.Handler;
21 import android.os.Looper;
22 import android.os.Message;
23 import android.os.TraceNameSupplier;
24 
25 import androidx.annotation.NonNull;
26 
27 import com.android.systemui.dagger.SysUISingleton;
28 import com.android.systemui.dagger.qualifiers.Main;
29 
30 import java.lang.annotation.Retention;
31 import java.lang.annotation.RetentionPolicy;
32 
33 import javax.inject.Inject;
34 
35 /**
36  * Dispatches the lifecycles keyguard gets from WindowManager on the main thread.
37  */
38 @SysUISingleton
39 public class KeyguardLifecyclesDispatcher {
40     static final int SCREEN_TURNING_ON = 0;
41     static final int SCREEN_TURNED_ON = 1;
42     static final int SCREEN_TURNING_OFF = 2;
43     static final int SCREEN_TURNED_OFF = 3;
44 
45     static final int STARTED_WAKING_UP = 4;
46     static final int FINISHED_WAKING_UP = 5;
47     static final int STARTED_GOING_TO_SLEEP = 6;
48     static final int FINISHED_GOING_TO_SLEEP = 7;
49 
50     @IntDef({
51             SCREEN_TURNING_ON,
52             SCREEN_TURNED_ON,
53             SCREEN_TURNING_OFF,
54             SCREEN_TURNED_OFF,
55             STARTED_WAKING_UP,
56             FINISHED_WAKING_UP,
57             STARTED_GOING_TO_SLEEP,
58             FINISHED_GOING_TO_SLEEP,
59     })
60     @Retention(RetentionPolicy.SOURCE)
61     public @interface KeyguardLifecycleMessageType {
62     }
63 
getNameOfMessage(@eyguardLifecycleMessageType int what)64     private static String getNameOfMessage(@KeyguardLifecycleMessageType int what) {
65         return switch (what) {
66             case SCREEN_TURNING_ON -> "SCREEN_TURNING_ON";
67             case SCREEN_TURNED_ON -> "SCREEN_TURNED_ON";
68             case SCREEN_TURNING_OFF -> "SCREEN_TURNING_OFF";
69             case SCREEN_TURNED_OFF -> "SCREEN_TURNED_OFF";
70             case STARTED_WAKING_UP -> "STARTED_WAKING_UP";
71             case FINISHED_WAKING_UP -> "FINISHED_WAKING_UP";
72             case STARTED_GOING_TO_SLEEP -> "STARTED_GOING_TO_SLEEP";
73             case FINISHED_GOING_TO_SLEEP -> "FINISHED_GOING_TO_SLEEP";
74             default -> "UNKNOWN";
75         };
76     }
77 
78     private final Handler mHandler;
79 
80     @Inject
KeyguardLifecyclesDispatcher( @ain Looper mainLooper, ScreenLifecycle screenLifecycle, WakefulnessLifecycle wakefulnessLifecycle)81     public KeyguardLifecyclesDispatcher(
82             @Main Looper mainLooper,
83             ScreenLifecycle screenLifecycle,
84             WakefulnessLifecycle wakefulnessLifecycle) {
85         mHandler = new KeyguardLifecycleHandler(mainLooper, screenLifecycle, wakefulnessLifecycle);
86     }
87 
dispatch(@eyguardLifecycleMessageType int what)88     void dispatch(@KeyguardLifecycleMessageType int what) {
89         mHandler.obtainMessage(what).sendToTarget();
90     }
91 
92     /**
93      * @param what Message to send.
94      * @param pmReason Reason this message was triggered - this should be a value from either
95      * {@link PowerManager.WakeReason} or {@link PowerManager.GoToSleepReason}.
96      */
dispatch(@eyguardLifecycleMessageType int what, int pmReason)97     void dispatch(@KeyguardLifecycleMessageType int what, int pmReason) {
98         final Message message = mHandler.obtainMessage(what);
99         message.arg1 = pmReason;
100         message.sendToTarget();
101     }
102 
103     /**
104      * @param what Message to send.
105      * @param object Object to send with the message
106      */
dispatch(@eyguardLifecycleMessageType int what, Object object)107     void dispatch(@KeyguardLifecycleMessageType int what, Object object) {
108         mHandler.obtainMessage(what, object).sendToTarget();
109     }
110 
111     private static class KeyguardLifecycleHandler extends Handler {
112         private static final String TAG = "KeyguardLifecycleHandler";
113         private final ScreenLifecycle mScreenLifecycle;
114         private final WakefulnessLifecycle mWakefulnessLifecycle;
115 
KeyguardLifecycleHandler(Looper looper, ScreenLifecycle screenLifecycle, WakefulnessLifecycle wakefulnessLifecycle)116         public KeyguardLifecycleHandler(Looper looper,
117                                          ScreenLifecycle screenLifecycle,
118                                          WakefulnessLifecycle wakefulnessLifecycle) {
119             super(looper);
120             mScreenLifecycle = screenLifecycle;
121             mWakefulnessLifecycle = wakefulnessLifecycle;
122         }
123 
124         @NonNull
125         @Override
getTraceName(@onNull Message msg)126         public String getTraceName(@NonNull Message msg) {
127             if (msg.getCallback() instanceof TraceNameSupplier || msg.getCallback() != null) {
128                 return super.getTraceName(msg);
129             }
130             return TAG + "#" + getNameOfMessage(msg.what);
131         }
132 
133         @Override
handleMessage(@onNull Message msg)134         public void handleMessage(@NonNull Message msg) {
135             switch (msg.what) {
136                 case SCREEN_TURNING_ON -> mScreenLifecycle.dispatchScreenTurningOn();
137                 case SCREEN_TURNED_ON -> mScreenLifecycle.dispatchScreenTurnedOn();
138                 case SCREEN_TURNING_OFF -> mScreenLifecycle.dispatchScreenTurningOff();
139                 case SCREEN_TURNED_OFF -> mScreenLifecycle.dispatchScreenTurnedOff();
140                 case STARTED_WAKING_UP ->
141                         mWakefulnessLifecycle.dispatchStartedWakingUp(msg.arg1 /* pmReason */);
142                 case FINISHED_WAKING_UP -> mWakefulnessLifecycle.dispatchFinishedWakingUp();
143                 case STARTED_GOING_TO_SLEEP ->
144                         mWakefulnessLifecycle.dispatchStartedGoingToSleep(msg.arg1 /* pmReason */);
145                 case FINISHED_GOING_TO_SLEEP ->
146                         mWakefulnessLifecycle.dispatchFinishedGoingToSleep();
147                 default -> throw new IllegalArgumentException("Unknown message: " + msg);
148             }
149         }
150     }
151 }
152