Keyguard: Factor out Screen and Wakefulness lifecycles

Test: runtest systemui
Bug: 62446740
Change-Id: Ife34c1f4299b152a6352445adc8c9fc3c757e87c
diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitorCallback.java b/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitorCallback.java
index 14d6b59..5a02178 100644
--- a/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitorCallback.java
+++ b/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitorCallback.java
@@ -154,13 +154,19 @@
 
     /**
      * Called when the device has started waking up.
+     *
+     * @deprecated use {@link com.android.systemui.keyguard.WakefulnessLifecycle}.
      */
+    @Deprecated
     public void onStartedWakingUp() { }
 
     /**
      * Called when the device has started going to sleep.
      * @param why see {@link #onFinishedGoingToSleep(int)}
+     *
+     * @deprecated use {@link com.android.systemui.keyguard.WakefulnessLifecycle}.
      */
+    @Deprecated
     public void onStartedGoingToSleep(int why) { }
 
     /**
@@ -168,17 +174,26 @@
      * @param why either {@link WindowManagerPolicy#OFF_BECAUSE_OF_ADMIN},
      * {@link WindowManagerPolicy#OFF_BECAUSE_OF_USER}, or
      * {@link WindowManagerPolicy#OFF_BECAUSE_OF_TIMEOUT}.
+     *
+     * @deprecated use {@link com.android.systemui.keyguard.WakefulnessLifecycle}.
      */
+    @Deprecated
     public void onFinishedGoingToSleep(int why) { }
 
     /**
      * Called when the screen has been turned on.
+     *
+     * @deprecated use {@link com.android.systemui.keyguard.ScreenLifecycle}.
      */
+    @Deprecated
     public void onScreenTurnedOn() { }
 
     /**
      * Called when the screen has been turned off.
+     *
+     * @deprecated use {@link com.android.systemui.keyguard.ScreenLifecycle}.
      */
+    @Deprecated
     public void onScreenTurnedOff() { }
 
     /**
diff --git a/packages/SystemUI/src/com/android/systemui/Dependency.java b/packages/SystemUI/src/com/android/systemui/Dependency.java
index 776d076..e5c729f 100644
--- a/packages/SystemUI/src/com/android/systemui/Dependency.java
+++ b/packages/SystemUI/src/com/android/systemui/Dependency.java
@@ -30,6 +30,8 @@
 import com.android.systemui.assist.AssistManager;
 import com.android.systemui.colorextraction.SysuiColorExtractor;
 import com.android.systemui.fragments.FragmentService;
+import com.android.systemui.keyguard.ScreenLifecycle;
+import com.android.systemui.keyguard.WakefulnessLifecycle;
 import com.android.systemui.plugins.ActivityStarter;
 import com.android.systemui.plugins.PluginActivityManager;
 import com.android.systemui.plugins.PluginDependencyProvider;
@@ -248,6 +250,12 @@
         mProviders.put(StatusBarIconController.class, () ->
                 new StatusBarIconControllerImpl(mContext));
 
+        mProviders.put(ScreenLifecycle.class, () ->
+                new ScreenLifecycle());
+
+        mProviders.put(WakefulnessLifecycle.class, () ->
+                new WakefulnessLifecycle());
+
         mProviders.put(FragmentService.class, () ->
                 new FragmentService(mContext));
 
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardLifecyclesDispatcher.java b/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardLifecyclesDispatcher.java
new file mode 100644
index 0000000..4c98c08
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardLifecyclesDispatcher.java
@@ -0,0 +1,86 @@
+/*
+ * 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.os.Handler;
+import android.os.Message;
+
+import com.android.internal.policy.IKeyguardDrawnCallback;
+
+/**
+ * Dispatches the lifecycles keyguard gets from WindowManager on the main thread.
+ */
+public class KeyguardLifecyclesDispatcher {
+
+    static final int SCREEN_TURNING_ON = 0;
+    static final int SCREEN_TURNED_ON = 1;
+    static final int SCREEN_TURNING_OFF = 2;
+    static final int SCREEN_TURNED_OFF = 3;
+
+    static final int STARTED_WAKING_UP = 4;
+    static final int FINISHED_WAKING_UP = 5;
+    static final int STARTED_GOING_TO_SLEEP = 6;
+    static final int FINISHED_GOING_TO_SLEEP = 7;
+
+    private final ScreenLifecycle mScreenLifecycle;
+    private final WakefulnessLifecycle mWakefulnessLifecycle;
+
+    public KeyguardLifecyclesDispatcher(ScreenLifecycle screenLifecycle,
+            WakefulnessLifecycle wakefulnessLifecycle) {
+        mScreenLifecycle = screenLifecycle;
+        mWakefulnessLifecycle = wakefulnessLifecycle;
+    }
+
+    void dispatch(int what) {
+        mHandler.obtainMessage(what).sendToTarget();
+    }
+
+    private Handler mHandler = new Handler() {
+        @Override
+        public void handleMessage(Message msg) {
+            switch (msg.what) {
+                case SCREEN_TURNING_ON:
+                    mScreenLifecycle.dispatchScreenTurningOn();
+                    break;
+                case SCREEN_TURNED_ON:
+                    mScreenLifecycle.dispatchScreenTurnedOn();
+                    break;
+                case SCREEN_TURNING_OFF:
+                    mScreenLifecycle.dispatchScreenTurningOff();
+                    break;
+                case SCREEN_TURNED_OFF:
+                    mScreenLifecycle.dispatchScreenTurnedOff();
+                    break;
+                case STARTED_WAKING_UP:
+                    mWakefulnessLifecycle.dispatchStartedWakingUp();
+                    break;
+                case FINISHED_WAKING_UP:
+                    mWakefulnessLifecycle.dispatchFinishedWakingUp();
+                    break;
+                case STARTED_GOING_TO_SLEEP:
+                    mWakefulnessLifecycle.dispatchStartedGoingToSleep();
+                    break;
+                case FINISHED_GOING_TO_SLEEP:
+                    mWakefulnessLifecycle.dispatchFinishedGoingToSleep();
+                    break;
+                default:
+                    throw new IllegalArgumentException("Unknown message: " + msg);
+            }
+        }
+    };
+
+}
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardService.java b/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardService.java
index 2d5d198..2a5ae0d 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardService.java
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardService.java
@@ -31,6 +31,7 @@
 import com.android.internal.policy.IKeyguardExitCallback;
 import com.android.internal.policy.IKeyguardService;
 import com.android.internal.policy.IKeyguardStateCallback;
+import com.android.systemui.Dependency;
 import com.android.systemui.SystemUIApplication;
 
 import static android.content.pm.PackageManager.PERMISSION_GRANTED;
@@ -40,12 +41,17 @@
     static final String PERMISSION = android.Manifest.permission.CONTROL_KEYGUARD;
 
     private KeyguardViewMediator mKeyguardViewMediator;
+    private KeyguardLifecyclesDispatcher mKeyguardLifecyclesDispatcher;
 
     @Override
     public void onCreate() {
         ((SystemUIApplication) getApplication()).startServicesIfNeeded();
         mKeyguardViewMediator =
                 ((SystemUIApplication) getApplication()).getComponent(KeyguardViewMediator.class);
+        mKeyguardLifecyclesDispatcher = new KeyguardLifecyclesDispatcher(
+                Dependency.get(ScreenLifecycle.class),
+                Dependency.get(WakefulnessLifecycle.class));
+
     }
 
     @Override
@@ -111,12 +117,16 @@
         public void onStartedGoingToSleep(int reason) {
             checkPermission();
             mKeyguardViewMediator.onStartedGoingToSleep(reason);
+            mKeyguardLifecyclesDispatcher.dispatch(
+                    KeyguardLifecyclesDispatcher.STARTED_GOING_TO_SLEEP);
         }
 
         @Override // Binder interface
         public void onFinishedGoingToSleep(int reason, boolean cameraGestureTriggered) {
             checkPermission();
             mKeyguardViewMediator.onFinishedGoingToSleep(reason, cameraGestureTriggered);
+            mKeyguardLifecyclesDispatcher.dispatch(
+                    KeyguardLifecyclesDispatcher.FINISHED_GOING_TO_SLEEP);
         }
 
         @Override // Binder interface
@@ -124,6 +134,15 @@
             Trace.beginSection("KeyguardService.mBinder#onStartedWakingUp");
             checkPermission();
             mKeyguardViewMediator.onStartedWakingUp();
+            mKeyguardLifecyclesDispatcher.dispatch(KeyguardLifecyclesDispatcher.STARTED_WAKING_UP);
+            Trace.endSection();
+        }
+
+        @Override // Binder interface
+        public void onFinishedWakingUp() {
+            Trace.beginSection("KeyguardService.mBinder#onFinishedWakingUp");
+            checkPermission();
+            mKeyguardLifecyclesDispatcher.dispatch(KeyguardLifecyclesDispatcher.FINISHED_WAKING_UP);
             Trace.endSection();
         }
 
@@ -132,6 +151,7 @@
             Trace.beginSection("KeyguardService.mBinder#onScreenTurningOn");
             checkPermission();
             mKeyguardViewMediator.onScreenTurningOn(callback);
+            mKeyguardLifecyclesDispatcher.dispatch(KeyguardLifecyclesDispatcher.SCREEN_TURNING_ON);
             Trace.endSection();
         }
 
@@ -140,13 +160,21 @@
             Trace.beginSection("KeyguardService.mBinder#onScreenTurnedOn");
             checkPermission();
             mKeyguardViewMediator.onScreenTurnedOn();
+            mKeyguardLifecyclesDispatcher.dispatch(KeyguardLifecyclesDispatcher.SCREEN_TURNED_ON);
             Trace.endSection();
         }
 
         @Override // Binder interface
+        public void onScreenTurningOff() {
+            checkPermission();
+            mKeyguardLifecyclesDispatcher.dispatch(KeyguardLifecyclesDispatcher.SCREEN_TURNING_OFF);
+        }
+
+        @Override // Binder interface
         public void onScreenTurnedOff() {
             checkPermission();
             mKeyguardViewMediator.onScreenTurnedOff();
+            mKeyguardLifecyclesDispatcher.dispatch(KeyguardLifecyclesDispatcher.SCREEN_TURNED_OFF);
         }
 
         @Override // Binder interface
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/Lifecycle.java b/packages/SystemUI/src/com/android/systemui/keyguard/Lifecycle.java
new file mode 100644
index 0000000..1b20cfb
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/Lifecycle.java
@@ -0,0 +1,42 @@
+/*
+ * 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 java.util.ArrayList;
+import java.util.function.Consumer;
+
+/**
+ * Base class for lifecycles with observers.
+ */
+public class Lifecycle<T> {
+
+    private ArrayList<T> mObservers = new ArrayList<>();
+
+    public void addObserver(T observer) {
+        mObservers.add(observer);
+    }
+
+    public void removeObserver(T observer) {
+        mObservers.remove(observer);
+    }
+
+    public void dispatch(Consumer<T> consumer) {
+        for (int i = 0; i < mObservers.size(); i++) {
+            consumer.accept(mObservers.get(i));
+        }
+    }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/ScreenLifecycle.java b/packages/SystemUI/src/com/android/systemui/keyguard/ScreenLifecycle.java
new file mode 100644
index 0000000..3f39dfe
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/ScreenLifecycle.java
@@ -0,0 +1,73 @@
+/*
+ * 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 com.android.systemui.Dumpable;
+
+import java.io.FileDescriptor;
+import java.io.PrintWriter;
+
+/**
+ * Tracks the screen lifecycle.
+ */
+public class ScreenLifecycle extends Lifecycle<ScreenLifecycle.Observer> implements Dumpable {
+
+    public static final int SCREEN_OFF = 0;
+    public static final int SCREEN_TURNING_ON = 1;
+    public static final int SCREEN_ON = 2;
+    public static final int SCREEN_TURNING_OFF = 3;
+
+    private int mScreenState = SCREEN_OFF;
+
+    public int getScreenState() {
+        return mScreenState;
+    }
+
+    public void dispatchScreenTurningOn() {
+        mScreenState = SCREEN_TURNING_ON;
+        dispatch(Observer::onScreenTurningOn);
+    }
+
+    public void dispatchScreenTurnedOn() {
+        mScreenState = SCREEN_ON;
+        dispatch(Observer::onScreenTurnedOn);
+    }
+
+    public void dispatchScreenTurningOff() {
+        mScreenState = SCREEN_TURNING_OFF;
+        dispatch(Observer::onScreenTurningOff);
+    }
+
+    public void dispatchScreenTurnedOff() {
+        mScreenState = SCREEN_OFF;
+        dispatch(Observer::onScreenTurnedOff);
+    }
+
+    @Override
+    public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
+        pw.println("ScreenLifecycle:");
+        pw.println("  mScreenState=" + mScreenState);
+    }
+
+    public interface Observer {
+        default void onScreenTurningOn() {}
+        default void onScreenTurnedOn() {}
+        default void onScreenTurningOff() {}
+        default void onScreenTurnedOff() {}
+    }
+
+}
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/WakefulnessLifecycle.java b/packages/SystemUI/src/com/android/systemui/keyguard/WakefulnessLifecycle.java
new file mode 100644
index 0000000..578e6fb
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/WakefulnessLifecycle.java
@@ -0,0 +1,73 @@
+/*
+ * 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 com.android.systemui.Dumpable;
+
+import java.io.FileDescriptor;
+import java.io.PrintWriter;
+
+/**
+ * Tracks the wakefulness lifecycle.
+ */
+public class WakefulnessLifecycle extends Lifecycle<WakefulnessLifecycle.Observer> implements
+        Dumpable {
+
+    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 int mWakefulness = WAKEFULNESS_ASLEEP;
+
+    public int getWakefulness() {
+        return mWakefulness;
+    }
+
+    public void dispatchStartedWakingUp() {
+        mWakefulness = WAKEFULNESS_WAKING;
+        dispatch(Observer::onStartedWakingUp);
+    }
+
+    public void dispatchFinishedWakingUp() {
+        mWakefulness = WAKEFULNESS_AWAKE;
+        dispatch(Observer::onFinishedWakingUp);
+    }
+
+    public void dispatchStartedGoingToSleep() {
+        mWakefulness = WAKEFULNESS_GOING_TO_SLEEP;
+        dispatch(Observer::onStartedGoingToSleep);
+    }
+
+    public void dispatchFinishedGoingToSleep() {
+        mWakefulness = WAKEFULNESS_ASLEEP;
+        dispatch(Observer::onFinishedGoingToSleep);
+    }
+
+    @Override
+    public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
+        pw.println("WakefulnessLifecycle:");
+        pw.println("  mWakefulness=" + mWakefulness);
+    }
+
+    public interface Observer {
+        default void onStartedWakingUp() {}
+        default void onFinishedWakingUp() {}
+        default void onStartedGoingToSleep() {}
+        default void onFinishedGoingToSleep() {}
+    }
+}