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