Merge "Launch AoD override the settings"

This commit is contained in:
TreeHugger Robot
2018-12-26 05:56:11 +00:00
committed by Android (Google) Code Review
10 changed files with 408 additions and 8 deletions

View File

@@ -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);
}
}

View File

@@ -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;
}
}
}

View File

@@ -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;

View File

@@ -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.

View File

@@ -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);
}

View File

@@ -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());

View File

@@ -4065,6 +4065,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

View File

@@ -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);
}
}

View File

@@ -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));
}
}

View File

@@ -17,7 +17,6 @@
package com.android.systemui.doze;
import android.annotation.NonNull;
import android.app.PendingIntent;
/**
* A rudimentary fake for DozeHost.
@@ -91,6 +90,9 @@ class DozeHostFake implements DozeHost {
pulseExtended = true;
}
@Override
public void stopPulsing() {}
@Override
public void setAnimateWakeup(boolean animateWakeup) {
this.animateWakeup = animateWakeup;