blob: 6f878d19aa4bf1196759253257c1042f31c6b52e [file] [log] [blame]
/*
* Copyright (C) 2017 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.android.systemui.keyguard;
import android.annotation.IntDef;
import android.app.IWallpaperManager;
import android.content.Context;
import android.content.res.Configuration;
import android.graphics.Point;
import android.os.Bundle;
import android.os.PowerManager;
import android.os.RemoteException;
import android.os.Trace;
import android.util.DisplayMetrics;
import androidx.annotation.Nullable;
import com.android.systemui.Dumpable;
import com.android.systemui.R;
import com.android.systemui.dagger.SysUISingleton;
import java.io.FileDescriptor;
import java.io.PrintWriter;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import javax.inject.Inject;
/**
* Tracks the wakefulness lifecycle, including why we're waking or sleeping.
*/
@SysUISingleton
public class WakefulnessLifecycle extends Lifecycle<WakefulnessLifecycle.Observer> implements
Dumpable {
@IntDef(prefix = { "WAKEFULNESS_" }, value = {
WAKEFULNESS_ASLEEP,
WAKEFULNESS_WAKING,
WAKEFULNESS_AWAKE,
WAKEFULNESS_GOING_TO_SLEEP,
})
@Retention(RetentionPolicy.SOURCE)
public @interface Wakefulness {}
public static final int WAKEFULNESS_ASLEEP = 0;
public static final int WAKEFULNESS_WAKING = 1;
public static final int WAKEFULNESS_AWAKE = 2;
public static final int WAKEFULNESS_GOING_TO_SLEEP = 3;
private final Context mContext;
private final DisplayMetrics mDisplayMetrics;
@Nullable
private final IWallpaperManager mWallpaperManagerService;
private int mWakefulness = WAKEFULNESS_AWAKE;
private @PowerManager.WakeReason int mLastWakeReason = PowerManager.WAKE_REASON_UNKNOWN;
@Nullable
private Point mLastWakeOriginLocation = null;
private @PowerManager.GoToSleepReason int mLastSleepReason =
PowerManager.GO_TO_SLEEP_REASON_MIN;
@Nullable
private Point mLastSleepOriginLocation = null;
@Inject
public WakefulnessLifecycle(
Context context,
@Nullable IWallpaperManager wallpaperManagerService) {
mContext = context;
mDisplayMetrics = context.getResources().getDisplayMetrics();
mWallpaperManagerService = wallpaperManagerService;
}
public @Wakefulness int getWakefulness() {
return mWakefulness;
}
/**
* Returns the most recent reason the device woke up. This is one of PowerManager.WAKE_REASON_*.
*/
public @PowerManager.WakeReason int getLastWakeReason() {
return mLastWakeReason;
}
/**
* Returns the most recent reason the device went to sleep up. This is one of
* PowerManager.GO_TO_SLEEP_REASON_*.
*/
public @PowerManager.GoToSleepReason int getLastSleepReason() {
return mLastSleepReason;
}
public void dispatchStartedWakingUp(@PowerManager.WakeReason int pmWakeReason) {
if (getWakefulness() == WAKEFULNESS_WAKING) {
return;
}
setWakefulness(WAKEFULNESS_WAKING);
mLastWakeReason = pmWakeReason;
updateLastWakeOriginLocation();
if (mWallpaperManagerService != null) {
try {
mWallpaperManagerService.notifyWakingUp(
mLastWakeOriginLocation.x, mLastWakeOriginLocation.y, new Bundle());
} catch (RemoteException e) {
e.printStackTrace();
}
}
dispatch(Observer::onStartedWakingUp);
}
public void dispatchFinishedWakingUp() {
if (getWakefulness() == WAKEFULNESS_AWAKE) {
return;
}
setWakefulness(WAKEFULNESS_AWAKE);
dispatch(Observer::onFinishedWakingUp);
}
public void dispatchStartedGoingToSleep(@PowerManager.GoToSleepReason int pmSleepReason) {
if (getWakefulness() == WAKEFULNESS_GOING_TO_SLEEP) {
return;
}
setWakefulness(WAKEFULNESS_GOING_TO_SLEEP);
mLastSleepReason = pmSleepReason;
updateLastSleepOriginLocation();
if (mWallpaperManagerService != null) {
try {
mWallpaperManagerService.notifyGoingToSleep(
mLastSleepOriginLocation.x, mLastSleepOriginLocation.y, new Bundle());
} catch (RemoteException e) {
e.printStackTrace();
}
}
dispatch(Observer::onStartedGoingToSleep);
}
public void dispatchFinishedGoingToSleep() {
if (getWakefulness() == WAKEFULNESS_ASLEEP) {
return;
}
setWakefulness(WAKEFULNESS_ASLEEP);
dispatch(Observer::onFinishedGoingToSleep);
}
@Override
public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
pw.println("WakefulnessLifecycle:");
pw.println(" mWakefulness=" + mWakefulness);
}
private void setWakefulness(@Wakefulness int wakefulness) {
mWakefulness = wakefulness;
Trace.traceCounter(Trace.TRACE_TAG_APP, "wakefulness", wakefulness);
}
private void updateLastWakeOriginLocation() {
mLastWakeOriginLocation = null;
switch (mLastWakeReason) {
case PowerManager.WAKE_REASON_POWER_BUTTON:
mLastWakeOriginLocation = getPowerButtonOrigin();
break;
default:
mLastWakeOriginLocation = getDefaultWakeSleepOrigin();
break;
}
}
private void updateLastSleepOriginLocation() {
mLastSleepOriginLocation = null;
switch (mLastSleepReason) {
case PowerManager.GO_TO_SLEEP_REASON_POWER_BUTTON:
mLastSleepOriginLocation = getPowerButtonOrigin();
break;
default:
mLastSleepOriginLocation = getDefaultWakeSleepOrigin();
break;
}
}
/**
* Returns the point on the screen closest to the physical power button.
*/
private Point getPowerButtonOrigin() {
final boolean isPortrait = mContext.getResources().getConfiguration().orientation
== Configuration.ORIENTATION_PORTRAIT;
if (isPortrait) {
return new Point(
mDisplayMetrics.widthPixels,
mContext.getResources().getDimensionPixelSize(
R.dimen.physical_power_button_center_screen_location_y));
} else {
return new Point(
mContext.getResources().getDimensionPixelSize(
R.dimen.physical_power_button_center_screen_location_y),
mDisplayMetrics.heightPixels);
}
}
/**
* Returns the point on the screen used as the default origin for wake/sleep events. This is the
* middle-bottom of the screen.
*/
private Point getDefaultWakeSleepOrigin() {
return new Point(mDisplayMetrics.widthPixels / 2, mDisplayMetrics.heightPixels);
}
public interface Observer {
default void onStartedWakingUp() {}
default void onFinishedWakingUp() {}
default void onStartedGoingToSleep() {}
default void onFinishedGoingToSleep() {}
}
}