• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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.app.IWallpaperManager;
21 import android.content.Context;
22 import android.content.res.Configuration;
23 import android.graphics.Point;
24 import android.os.Bundle;
25 import android.os.PowerManager;
26 import android.os.RemoteException;
27 import android.os.Trace;
28 import android.util.DisplayMetrics;
29 
30 import androidx.annotation.Nullable;
31 
32 import com.android.systemui.Dumpable;
33 import com.android.systemui.R;
34 import com.android.systemui.dagger.SysUISingleton;
35 import com.android.systemui.dump.DumpManager;
36 import com.android.systemui.util.time.SystemClock;
37 
38 import java.io.PrintWriter;
39 import java.lang.annotation.Retention;
40 import java.lang.annotation.RetentionPolicy;
41 
42 import javax.inject.Inject;
43 
44 /**
45  * Tracks the wakefulness lifecycle, including why we're waking or sleeping.
46  */
47 @SysUISingleton
48 public class WakefulnessLifecycle extends Lifecycle<WakefulnessLifecycle.Observer> implements
49         Dumpable {
50 
51     @IntDef(prefix = { "WAKEFULNESS_" }, value = {
52             WAKEFULNESS_ASLEEP,
53             WAKEFULNESS_WAKING,
54             WAKEFULNESS_AWAKE,
55             WAKEFULNESS_GOING_TO_SLEEP,
56     })
57     @Retention(RetentionPolicy.SOURCE)
58     public @interface Wakefulness {}
59 
60     public static final int WAKEFULNESS_ASLEEP = 0;
61     public static final int WAKEFULNESS_WAKING = 1;
62     public static final int WAKEFULNESS_AWAKE = 2;
63     public static final int WAKEFULNESS_GOING_TO_SLEEP = 3;
64 
65     private final Context mContext;
66     private final DisplayMetrics mDisplayMetrics;
67     private final SystemClock mSystemClock;
68 
69     @Nullable
70     private final IWallpaperManager mWallpaperManagerService;
71 
72     private int mWakefulness = WAKEFULNESS_AWAKE;
73 
74     private @PowerManager.WakeReason int mLastWakeReason = PowerManager.WAKE_REASON_UNKNOWN;
75 
76     public static final long UNKNOWN_LAST_WAKE_TIME = -1;
77     private long mLastWakeTime = UNKNOWN_LAST_WAKE_TIME;
78 
79     @Nullable
80     private Point mLastWakeOriginLocation = null;
81 
82     private @PowerManager.GoToSleepReason int mLastSleepReason =
83             PowerManager.GO_TO_SLEEP_REASON_MIN;
84 
85     @Nullable
86     private Point mLastSleepOriginLocation = null;
87 
88     @Inject
WakefulnessLifecycle( Context context, @Nullable IWallpaperManager wallpaperManagerService, SystemClock systemClock, DumpManager dumpManager)89     public WakefulnessLifecycle(
90             Context context,
91             @Nullable IWallpaperManager wallpaperManagerService,
92             SystemClock systemClock,
93             DumpManager dumpManager) {
94         mContext = context;
95         mDisplayMetrics = context.getResources().getDisplayMetrics();
96         mWallpaperManagerService = wallpaperManagerService;
97         mSystemClock = systemClock;
98 
99         dumpManager.registerDumpable(getClass().getSimpleName(), this);
100     }
101 
getWakefulness()102     public @Wakefulness int getWakefulness() {
103         return mWakefulness;
104     }
105 
106     /**
107      * Returns the most recent reason the device woke up. This is one of PowerManager.WAKE_REASON_*.
108      */
getLastWakeReason()109     public @PowerManager.WakeReason int getLastWakeReason() {
110         return mLastWakeReason;
111     }
112 
113     /**
114      * Returns the most recent time (in device uptimeMillis) the display woke up.
115      * Returns {@link UNKNOWN_LAST_WAKE_TIME} if there hasn't been a wakeup yet.
116      */
getLastWakeTime()117     public long getLastWakeTime() {
118         return mLastWakeTime;
119     }
120 
121     /**
122      * Returns the most recent reason the device went to sleep up. This is one of
123      * PowerManager.GO_TO_SLEEP_REASON_*.
124      */
getLastSleepReason()125     public @PowerManager.GoToSleepReason int getLastSleepReason() {
126         return mLastSleepReason;
127     }
128 
dispatchStartedWakingUp(@owerManager.WakeReason int pmWakeReason)129     public void dispatchStartedWakingUp(@PowerManager.WakeReason int pmWakeReason) {
130         if (getWakefulness() == WAKEFULNESS_WAKING) {
131             return;
132         }
133         setWakefulness(WAKEFULNESS_WAKING);
134         mLastWakeReason = pmWakeReason;
135         mLastWakeTime = mSystemClock.uptimeMillis();
136         updateLastWakeOriginLocation();
137 
138         if (mWallpaperManagerService != null) {
139             try {
140                 mWallpaperManagerService.notifyWakingUp(
141                         mLastWakeOriginLocation.x, mLastWakeOriginLocation.y, new Bundle());
142             } catch (RemoteException e) {
143                 e.printStackTrace();
144             }
145         }
146 
147         dispatch(Observer::onStartedWakingUp);
148     }
149 
dispatchFinishedWakingUp()150     public void dispatchFinishedWakingUp() {
151         if (getWakefulness() == WAKEFULNESS_AWAKE) {
152             return;
153         }
154         setWakefulness(WAKEFULNESS_AWAKE);
155         dispatch(Observer::onFinishedWakingUp);
156         dispatch(Observer::onPostFinishedWakingUp);
157     }
158 
dispatchStartedGoingToSleep(@owerManager.GoToSleepReason int pmSleepReason)159     public void dispatchStartedGoingToSleep(@PowerManager.GoToSleepReason int pmSleepReason) {
160         if (getWakefulness() == WAKEFULNESS_GOING_TO_SLEEP) {
161             return;
162         }
163         setWakefulness(WAKEFULNESS_GOING_TO_SLEEP);
164         mLastSleepReason = pmSleepReason;
165         updateLastSleepOriginLocation();
166 
167         if (mWallpaperManagerService != null) {
168             try {
169                 mWallpaperManagerService.notifyGoingToSleep(
170                         mLastSleepOriginLocation.x, mLastSleepOriginLocation.y, new Bundle());
171             } catch (RemoteException e) {
172                 e.printStackTrace();
173             }
174         }
175 
176         dispatch(Observer::onStartedGoingToSleep);
177     }
178 
dispatchFinishedGoingToSleep()179     public void dispatchFinishedGoingToSleep() {
180         if (getWakefulness() == WAKEFULNESS_ASLEEP) {
181             return;
182         }
183         setWakefulness(WAKEFULNESS_ASLEEP);
184         dispatch(Observer::onFinishedGoingToSleep);
185     }
186 
187     @Override
dump(PrintWriter pw, String[] args)188     public void dump(PrintWriter pw, String[] args) {
189         pw.println("WakefulnessLifecycle:");
190         pw.println("  mWakefulness=" + mWakefulness);
191     }
192 
setWakefulness(@akefulness int wakefulness)193     private void setWakefulness(@Wakefulness int wakefulness) {
194         mWakefulness = wakefulness;
195         Trace.traceCounter(Trace.TRACE_TAG_APP, "wakefulness", wakefulness);
196     }
197 
updateLastWakeOriginLocation()198     private void updateLastWakeOriginLocation() {
199         mLastWakeOriginLocation = null;
200 
201         switch (mLastWakeReason) {
202             case PowerManager.WAKE_REASON_POWER_BUTTON:
203                 mLastWakeOriginLocation = getPowerButtonOrigin();
204                 break;
205             default:
206                 mLastWakeOriginLocation = getDefaultWakeSleepOrigin();
207                 break;
208         }
209     }
210 
updateLastSleepOriginLocation()211     private void updateLastSleepOriginLocation() {
212         mLastSleepOriginLocation = null;
213 
214         switch (mLastSleepReason) {
215             case PowerManager.GO_TO_SLEEP_REASON_POWER_BUTTON:
216                 mLastSleepOriginLocation = getPowerButtonOrigin();
217                 break;
218             default:
219                 mLastSleepOriginLocation = getDefaultWakeSleepOrigin();
220                 break;
221         }
222     }
223 
224     /**
225      * Returns the point on the screen closest to the physical power button.
226      */
getPowerButtonOrigin()227     private Point getPowerButtonOrigin() {
228         final boolean isPortrait = mContext.getResources().getConfiguration().orientation
229                 == Configuration.ORIENTATION_PORTRAIT;
230 
231         if (isPortrait) {
232             return new Point(
233                     mDisplayMetrics.widthPixels,
234                     mContext.getResources().getDimensionPixelSize(
235                             R.dimen.physical_power_button_center_screen_location_y));
236         } else {
237             return new Point(
238                     mContext.getResources().getDimensionPixelSize(
239                             R.dimen.physical_power_button_center_screen_location_y),
240                     mDisplayMetrics.heightPixels);
241         }
242     }
243 
244     /**
245      * Returns the point on the screen used as the default origin for wake/sleep events. This is the
246      * middle-bottom of the screen.
247      */
getDefaultWakeSleepOrigin()248     private Point getDefaultWakeSleepOrigin() {
249         return new Point(mDisplayMetrics.widthPixels / 2, mDisplayMetrics.heightPixels);
250     }
251 
252     public interface Observer {
onStartedWakingUp()253         default void onStartedWakingUp() {}
onFinishedWakingUp()254         default void onFinishedWakingUp() {}
255 
256         /**
257          * Called after the finished waking up call, ensuring it's after all the other listeners,
258          * reacting to {@link #onFinishedWakingUp()}
259          */
onPostFinishedWakingUp()260         default void onPostFinishedWakingUp() {}
onStartedGoingToSleep()261         default void onStartedGoingToSleep() {}
onFinishedGoingToSleep()262         default void onFinishedGoingToSleep() {}
263     }
264 }
265