summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--packages/SystemUI/src/com/android/systemui/dock/DockManager.java60
-rw-r--r--packages/SystemUI/src/com/android/systemui/doze/DozeDockHandler.java144
-rw-r--r--packages/SystemUI/src/com/android/systemui/doze/DozeFactory.java3
-rw-r--r--packages/SystemUI/src/com/android/systemui/doze/DozeHost.java5
-rw-r--r--packages/SystemUI/src/com/android/systemui/doze/DozeLog.java6
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/phone/DozeScrimController.java9
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java7
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/dock/DockManagerFake.java38
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/doze/DozeDockHandlerTest.java140
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/doze/DozeHostFake.java4
10 files changed, 408 insertions, 8 deletions
diff --git a/packages/SystemUI/src/com/android/systemui/dock/DockManager.java b/packages/SystemUI/src/com/android/systemui/dock/DockManager.java
new file mode 100644
index 000000000000..233b9c678085
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/dock/DockManager.java
@@ -0,0 +1,60 @@
+/*
+ * Copyright (C) 2018 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.dock;
+
+/**
+ * Allows an app to handle dock events
+ */
+public interface DockManager {
+
+ /**
+ * Uninitialized / unknow dock states
+ */
+ int STATE_NONE = 0;
+ /**
+ * The state for docking
+ */
+ int STATE_DOCKING = 1;
+ /**
+ * The state for undocking
+ */
+ int STATE_UNDOCKING = 2;
+
+ /**
+ * Add a dock event listener into manager
+ *
+ * @param callback A {@link #DockEventListener} which want to add
+ */
+ void addListener(DockEventListener callback);
+
+ /**
+ * Remove the added listener from dock manager
+ *
+ * @param callback A {@link #DockEventListener} which want to remove
+ */
+ void removeListener(DockEventListener callback);
+
+ /** Callback for receiving dock events */
+ interface DockEventListener {
+ /**
+ * Override to handle dock events
+ *
+ * Events reference: {@link #DockState}
+ */
+ void onEvent(int event);
+ }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/doze/DozeDockHandler.java b/packages/SystemUI/src/com/android/systemui/doze/DozeDockHandler.java
new file mode 100644
index 000000000000..fa33cb847880
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/doze/DozeDockHandler.java
@@ -0,0 +1,144 @@
+/*
+ * Copyright (C) 2018 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.doze;
+
+import android.content.Context;
+import android.os.Handler;
+import android.util.Log;
+
+import com.android.internal.hardware.AmbientDisplayConfiguration;
+import com.android.systemui.SysUiServiceProvider;
+import com.android.systemui.dock.DockManager;
+
+import java.io.PrintWriter;
+
+/**
+ * Handles dock events for ambient state changes.
+ */
+public class DozeDockHandler implements DozeMachine.Part {
+
+ private static final String TAG = "DozeDockHandler";
+ private static final boolean DEBUG = DozeService.DEBUG;
+
+ private final Context mContext;
+ private final DozeMachine mMachine;
+ private final DozeHost mDozeHost;
+ private final AmbientDisplayConfiguration mConfig;
+ private final Handler mHandler;
+ private final DockEventListener mDockEventListener = new DockEventListener();
+ private final DockManager mDockManager;
+
+ private boolean mDocking;
+
+ public DozeDockHandler(Context context, DozeMachine machine, DozeHost dozeHost,
+ AmbientDisplayConfiguration config, Handler handler) {
+ mContext = context;
+ mMachine = machine;
+ mDozeHost = dozeHost;
+ mConfig = config;
+ mHandler = handler;
+ mDockManager = SysUiServiceProvider.getComponent(context, DockManager.class);
+ }
+
+ @Override
+ public void transitionTo(DozeMachine.State oldState, DozeMachine.State newState) {
+ switch (newState) {
+ case INITIALIZED:
+ mDockEventListener.register();
+ break;
+ case DOZE:
+ case DOZE_AOD:
+ mHandler.post(() -> requestPulse());
+ break;
+ case FINISH:
+ mDockEventListener.unregister();
+ break;
+ default:
+ }
+ }
+
+ private void requestPulse() {
+ if (!mDocking || mDozeHost.isPulsingBlocked() || !canPulse()) {
+ return;
+ }
+
+ mMachine.requestPulse(DozeLog.PULSE_REASON_DOCKING);
+ }
+
+ private boolean canPulse() {
+ return mMachine.getState() == DozeMachine.State.DOZE
+ || mMachine.getState() == DozeMachine.State.DOZE_AOD;
+ }
+
+ private void requestPulseOutNow() {
+ final DozeMachine.State state = mMachine.getState();
+ final int pulseReason = mMachine.getPulseReason();
+
+ if ((state == DozeMachine.State.DOZE_PULSING
+ || state == DozeMachine.State.DOZE_REQUEST_PULSE)
+ && pulseReason == DozeLog.PULSE_REASON_DOCKING) {
+ mDozeHost.stopPulsing();
+ }
+ }
+
+ @Override
+ public void dump(PrintWriter pw) {
+ pw.print(" DozeDockTriggers docking="); pw.println(mDocking);
+ }
+
+ private class DockEventListener implements DockManager.DockEventListener {
+ private boolean mRegistered;
+
+ @Override
+ public void onEvent(int event) {
+ if (DEBUG) Log.d(TAG, "dock event = " + event);
+ switch (event) {
+ case DockManager.STATE_DOCKING:
+ mDocking = true;
+ requestPulse();
+ break;
+ case DockManager.STATE_UNDOCKING:
+ mDocking = false;
+ requestPulseOutNow();
+ break;
+ default:
+ // no-op
+ }
+ }
+
+ void register() {
+ if (mRegistered) {
+ return;
+ }
+
+ if (mDockManager != null) {
+ mDockManager.addListener(this);
+ }
+ mRegistered = true;
+ }
+
+ void unregister() {
+ if (!mRegistered) {
+ return;
+ }
+ if (mDockManager != null) {
+ mDockManager.removeListener(this);
+ }
+ mRegistered = false;
+ }
+ }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/doze/DozeFactory.java b/packages/SystemUI/src/com/android/systemui/doze/DozeFactory.java
index d93ed1785a0a..58ae555dbff1 100644
--- a/packages/SystemUI/src/com/android/systemui/doze/DozeFactory.java
+++ b/packages/SystemUI/src/com/android/systemui/doze/DozeFactory.java
@@ -68,7 +68,8 @@ public class DozeFactory {
new DozeScreenState(wrappedService, handler, params, wakeLock),
createDozeScreenBrightness(context, wrappedService, sensorManager, host, params,
handler),
- new DozeWallpaperState(context)
+ new DozeWallpaperState(context),
+ new DozeDockHandler(context, machine, host, config, handler)
});
return machine;
diff --git a/packages/SystemUI/src/com/android/systemui/doze/DozeHost.java b/packages/SystemUI/src/com/android/systemui/doze/DozeHost.java
index 461aef1fa54c..4cb1feebcce4 100644
--- a/packages/SystemUI/src/com/android/systemui/doze/DozeHost.java
+++ b/packages/SystemUI/src/com/android/systemui/doze/DozeHost.java
@@ -45,6 +45,11 @@ public interface DozeHost {
void onIgnoreTouchWhilePulsing(boolean ignore);
+ /**
+ * Leaves pulsing state, going back to ambient UI.
+ */
+ void stopPulsing();
+
interface Callback {
/**
* Called when a high priority notification is added.
diff --git a/packages/SystemUI/src/com/android/systemui/doze/DozeLog.java b/packages/SystemUI/src/com/android/systemui/doze/DozeLog.java
index 974cd8804841..ab77e553303b 100644
--- a/packages/SystemUI/src/com/android/systemui/doze/DozeLog.java
+++ b/packages/SystemUI/src/com/android/systemui/doze/DozeLog.java
@@ -35,7 +35,7 @@ public class DozeLog {
private static final int SIZE = Build.IS_DEBUGGABLE ? 400 : 50;
static final SimpleDateFormat FORMAT = new SimpleDateFormat("MM-dd HH:mm:ss.SSS");
- private static final int REASONS = 7;
+ private static final int REASONS = 8;
public static final int PULSE_REASON_NONE = -1;
public static final int PULSE_REASON_INTENT = 0;
@@ -44,7 +44,8 @@ public class DozeLog {
public static final int PULSE_REASON_SENSOR_PICKUP = 3;
public static final int PULSE_REASON_SENSOR_DOUBLE_TAP = 4;
public static final int PULSE_REASON_SENSOR_LONG_PRESS = 5;
- public static final int REASON_SENSOR_WAKE_UP = 6;
+ public static final int PULSE_REASON_DOCKING = 6;
+ public static final int REASON_SENSOR_WAKE_UP = 7;
private static boolean sRegisterKeyguardCallback = true;
@@ -211,6 +212,7 @@ public class DozeLog {
case PULSE_REASON_SENSOR_PICKUP: return "pickup";
case PULSE_REASON_SENSOR_DOUBLE_TAP: return "doubletap";
case PULSE_REASON_SENSOR_LONG_PRESS: return "longpress";
+ case PULSE_REASON_DOCKING: return "docking";
case REASON_SENSOR_WAKE_UP: return "wakeup";
default: throw new IllegalArgumentException("bad reason: " + pulseReason);
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/DozeScrimController.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/DozeScrimController.java
index cfa751cec613..280dda0cd1dc 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/DozeScrimController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/DozeScrimController.java
@@ -65,10 +65,11 @@ public class DozeScrimController implements StateListener {
if (!mDozing) {
return;
}
- // All pulses except notifications should time out on their own. Pulses due to
- // notifications should instead be managed externally based off the notification's
- // lifetime.
- if (mPulseReason != DozeLog.PULSE_REASON_NOTIFICATION) {
+ // Notifications should time out on their own. Pulses due to notifications should
+ // instead be managed externally based off the notification's lifetime.
+ // Dock also controls the time out by self.
+ if (mPulseReason != DozeLog.PULSE_REASON_NOTIFICATION
+ && mPulseReason != DozeLog.PULSE_REASON_DOCKING) {
mHandler.postDelayed(mPulseOut, mDozeParameters.getPulseVisibleDuration());
mHandler.postDelayed(mPulseOutExtended,
mDozeParameters.getPulseVisibleDurationExtended());
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java
index 465187d038ad..40e2aaec44dd 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java
@@ -4066,6 +4066,13 @@ public class StatusBar extends SystemUI implements DemoMode,
}
@Override
+ public void stopPulsing() {
+ if (mDozeScrimController.isPulsing()) {
+ mDozeScrimController.pulseOutNow();
+ }
+ }
+
+ @Override
public void setAnimateWakeup(boolean animateWakeup) {
if (mWakefulnessLifecycle.getWakefulness() == WAKEFULNESS_AWAKE
|| mWakefulnessLifecycle.getWakefulness() == WAKEFULNESS_WAKING) {
diff --git a/packages/SystemUI/tests/src/com/android/systemui/dock/DockManagerFake.java b/packages/SystemUI/tests/src/com/android/systemui/dock/DockManagerFake.java
new file mode 100644
index 000000000000..b368876d2ae7
--- /dev/null
+++ b/packages/SystemUI/tests/src/com/android/systemui/dock/DockManagerFake.java
@@ -0,0 +1,38 @@
+/*
+ * Copyright (C) 2018 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.dock;
+
+/**
+ * A rudimentary fake for DockManager.
+ */
+public class DockManagerFake implements DockManager {
+ DockEventListener mCallback;
+
+ @Override
+ public void addListener(DockEventListener callback) {
+ this.mCallback = callback;
+ }
+
+ @Override
+ public void removeListener(DockEventListener callback) {
+ this.mCallback = null;
+ }
+
+ public void setDockEvent(int event) {
+ mCallback.onEvent(event);
+ }
+}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/doze/DozeDockHandlerTest.java b/packages/SystemUI/tests/src/com/android/systemui/doze/DozeDockHandlerTest.java
new file mode 100644
index 000000000000..e1c0cd4dc7e9
--- /dev/null
+++ b/packages/SystemUI/tests/src/com/android/systemui/doze/DozeDockHandlerTest.java
@@ -0,0 +1,140 @@
+/*
+ * Copyright (C) 2018 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.doze;
+
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.ArgumentMatchers.eq;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.never;
+import static org.mockito.Mockito.spy;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
+import android.app.Instrumentation;
+import android.os.Handler;
+import android.os.Looper;
+import android.support.test.InstrumentationRegistry;
+import android.support.test.filters.SmallTest;
+import android.testing.AndroidTestingRunner;
+import android.testing.TestableLooper;
+import android.testing.TestableLooper.RunWithLooper;
+
+import com.android.internal.hardware.AmbientDisplayConfiguration;
+import com.android.systemui.SysuiTestCase;
+import com.android.systemui.dock.DockManager;
+import com.android.systemui.dock.DockManagerFake;
+
+import org.junit.Before;
+import org.junit.BeforeClass;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+@SmallTest
+@RunWith(AndroidTestingRunner.class)
+@RunWithLooper
+public class DozeDockHandlerTest extends SysuiTestCase {
+ private DozeDockHandler mDockHandler;
+ private DozeMachine mMachine;
+ private DozeHostFake mHost;
+ private AmbientDisplayConfiguration mConfig;
+ private Instrumentation mInstrumentation;
+ private DockManagerFake mDockManagerFake;
+
+ @BeforeClass
+ public static void setupSuite() {
+ // We can't use KeyguardUpdateMonitor from tests.
+ DozeLog.setRegisterKeyguardCallback(false);
+ }
+
+ @Before
+ public void setUp() throws Exception {
+ mInstrumentation = InstrumentationRegistry.getInstrumentation();
+ mMachine = mock(DozeMachine.class);
+ mHost = spy(new DozeHostFake());
+ mConfig = DozeConfigurationUtil.createMockConfig();
+
+ mDockManagerFake = spy(new DockManagerFake());
+ mContext.putComponent(DockManager.class, mDockManagerFake);
+
+ mDockHandler = new DozeDockHandler(mContext, mMachine, mHost, mConfig,
+ Handler.createAsync(Looper.myLooper()));
+ }
+
+ @Test
+ public void testDockEventListener_registerAndUnregister() throws Exception {
+ mDockHandler.transitionTo(DozeMachine.State.UNINITIALIZED, DozeMachine.State.INITIALIZED);
+
+ verify(mDockManagerFake).addListener(any());
+
+ mDockHandler.transitionTo(DozeMachine.State.DOZE, DozeMachine.State.FINISH);
+
+ verify(mDockManagerFake).removeListener(any());
+ }
+
+ @Test
+ public void testOnEvent_dockingWhenDoze_requestPulse() throws Exception {
+ mDockHandler.transitionTo(DozeMachine.State.UNINITIALIZED, DozeMachine.State.INITIALIZED);
+ when(mMachine.getState()).thenReturn(DozeMachine.State.DOZE);
+
+ mDockManagerFake.setDockEvent(DockManager.STATE_DOCKING);
+
+ verify(mMachine).requestPulse(eq(DozeLog.PULSE_REASON_DOCKING));
+ }
+
+ @Test
+ public void testOnEvent_dockingWhenPausing_neverRequestPulse() throws Exception {
+ mDockHandler.transitionTo(DozeMachine.State.UNINITIALIZED, DozeMachine.State.INITIALIZED);
+ when(mMachine.getState()).thenReturn(DozeMachine.State.DOZE_AOD_PAUSING);
+
+ mDockManagerFake.setDockEvent(DockManager.STATE_DOCKING);
+
+ verify(mMachine, never()).requestPulse(eq(DozeLog.PULSE_REASON_DOCKING));
+ }
+
+ @Test
+ public void testOnEvent_undockedWhenPulsing_requestPulseOut() throws Exception {
+ mDockHandler.transitionTo(DozeMachine.State.UNINITIALIZED, DozeMachine.State.INITIALIZED);
+ when(mMachine.getState()).thenReturn(DozeMachine.State.DOZE_PULSING);
+ when(mMachine.getPulseReason()).thenReturn(DozeLog.PULSE_REASON_DOCKING);
+
+ mDockManagerFake.setDockEvent(DockManager.STATE_UNDOCKING);
+
+ verify(mHost).stopPulsing();
+ }
+
+ @Test
+ public void testOnEvent_undockedWhenDoze_neverRequestPulseOut() throws Exception {
+ mDockHandler.transitionTo(DozeMachine.State.UNINITIALIZED, DozeMachine.State.INITIALIZED);
+ when(mMachine.getState()).thenReturn(DozeMachine.State.DOZE_PULSING);
+
+ mDockManagerFake.setDockEvent(DockManager.STATE_UNDOCKING);
+
+ verify(mHost, never()).stopPulsing();
+ }
+
+ @Test
+ public void testTransitionToDozeWhenDocking_RequestPulse() throws Exception {
+ mDockHandler.transitionTo(DozeMachine.State.UNINITIALIZED, DozeMachine.State.INITIALIZED);
+ mDockManagerFake.setDockEvent(DockManager.STATE_DOCKING);
+ mDockHandler.transitionTo(DozeMachine.State.DOZE_AOD_PAUSING, DozeMachine.State.DOZE);
+ when(mMachine.getState()).thenReturn(DozeMachine.State.DOZE);
+
+ TestableLooper.get(this).processAllMessages();
+
+ verify(mMachine).requestPulse(eq(DozeLog.PULSE_REASON_DOCKING));
+ }
+}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/doze/DozeHostFake.java b/packages/SystemUI/tests/src/com/android/systemui/doze/DozeHostFake.java
index f3cb27f8d010..ce28b50436eb 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/doze/DozeHostFake.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/doze/DozeHostFake.java
@@ -17,7 +17,6 @@
package com.android.systemui.doze;
import android.annotation.NonNull;
-import android.app.PendingIntent;
/**
* A rudimentary fake for DozeHost.
@@ -92,6 +91,9 @@ class DozeHostFake implements DozeHost {
}
@Override
+ public void stopPulsing() {}
+
+ @Override
public void setAnimateWakeup(boolean animateWakeup) {
this.animateWakeup = animateWakeup;
}