Merge changes Idd362f88,Ifb1e1266 into udc-dev
* changes: Use KeyguardUpdateMonitor in DreamCondition. Send dream state updates through DreamManagerStateListener.
This commit is contained in:
@@ -84,6 +84,19 @@ public abstract class DreamManagerInternal {
|
||||
*
|
||||
* @param keepDreaming True if the current dream should continue when undocking.
|
||||
*/
|
||||
void onKeepDreamingWhenUnpluggingChanged(boolean keepDreaming);
|
||||
default void onKeepDreamingWhenUnpluggingChanged(boolean keepDreaming) {
|
||||
}
|
||||
|
||||
/**
|
||||
* Called when dreaming has started.
|
||||
*/
|
||||
default void onDreamingStarted() {
|
||||
}
|
||||
|
||||
/**
|
||||
* Called when dreaming has stopped.
|
||||
*/
|
||||
default void onDreamingStopped() {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -16,12 +16,9 @@
|
||||
package com.android.systemui.dreams.conditions;
|
||||
|
||||
import android.app.DreamManager;
|
||||
import android.content.BroadcastReceiver;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.content.IntentFilter;
|
||||
import android.text.TextUtils;
|
||||
|
||||
import com.android.keyguard.KeyguardUpdateMonitor;
|
||||
import com.android.keyguard.KeyguardUpdateMonitorCallback;
|
||||
import com.android.systemui.shared.condition.Condition;
|
||||
|
||||
import javax.inject.Inject;
|
||||
@@ -30,48 +27,33 @@ import javax.inject.Inject;
|
||||
* {@link DreamCondition} provides a signal when a dream begins and ends.
|
||||
*/
|
||||
public class DreamCondition extends Condition {
|
||||
private final Context mContext;
|
||||
private final DreamManager mDreamManager;
|
||||
|
||||
private final BroadcastReceiver mReceiver = new BroadcastReceiver() {
|
||||
@Override
|
||||
public void onReceive(Context context, Intent intent) {
|
||||
processIntent(intent);
|
||||
}
|
||||
};
|
||||
private final KeyguardUpdateMonitor mUpdateMonitor;
|
||||
|
||||
|
||||
private final KeyguardUpdateMonitorCallback mUpdateCallback =
|
||||
new KeyguardUpdateMonitorCallback() {
|
||||
@Override
|
||||
public void onDreamingStateChanged(boolean dreaming) {
|
||||
updateCondition(dreaming);
|
||||
}
|
||||
};
|
||||
|
||||
@Inject
|
||||
public DreamCondition(Context context,
|
||||
DreamManager dreamManager) {
|
||||
mContext = context;
|
||||
public DreamCondition(DreamManager dreamManager, KeyguardUpdateMonitor monitor) {
|
||||
mDreamManager = dreamManager;
|
||||
}
|
||||
|
||||
private void processIntent(Intent intent) {
|
||||
// In the case of a non-existent sticky broadcast, ignore when there is no intent.
|
||||
if (intent == null) {
|
||||
return;
|
||||
}
|
||||
if (TextUtils.equals(intent.getAction(), Intent.ACTION_DREAMING_STARTED)) {
|
||||
updateCondition(true);
|
||||
} else if (TextUtils.equals(intent.getAction(), Intent.ACTION_DREAMING_STOPPED)) {
|
||||
updateCondition(false);
|
||||
} else {
|
||||
throw new IllegalStateException("unexpected intent:" + intent);
|
||||
}
|
||||
mUpdateMonitor = monitor;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void start() {
|
||||
final IntentFilter filter = new IntentFilter();
|
||||
filter.addAction(Intent.ACTION_DREAMING_STARTED);
|
||||
filter.addAction(Intent.ACTION_DREAMING_STOPPED);
|
||||
mContext.registerReceiver(mReceiver, filter);
|
||||
mUpdateMonitor.registerCallback(mUpdateCallback);
|
||||
updateCondition(mDreamManager.isDreaming());
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void stop() {
|
||||
mContext.unregisterReceiver(mReceiver);
|
||||
mUpdateMonitor.removeCallback(mUpdateCallback);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -18,7 +18,6 @@ package com.android.systemui.dreams.conditions;
|
||||
|
||||
import static com.google.common.truth.Truth.assertThat;
|
||||
|
||||
import static org.mockito.ArgumentMatchers.any;
|
||||
import static org.mockito.ArgumentMatchers.eq;
|
||||
import static org.mockito.Mockito.clearInvocations;
|
||||
import static org.mockito.Mockito.never;
|
||||
@@ -26,13 +25,13 @@ import static org.mockito.Mockito.verify;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
import android.app.DreamManager;
|
||||
import android.content.BroadcastReceiver;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.testing.AndroidTestingRunner;
|
||||
|
||||
import androidx.test.filters.SmallTest;
|
||||
|
||||
import com.android.keyguard.KeyguardUpdateMonitor;
|
||||
import com.android.keyguard.KeyguardUpdateMonitorCallback;
|
||||
import com.android.systemui.SysuiTestCase;
|
||||
import com.android.systemui.shared.condition.Condition;
|
||||
|
||||
@@ -55,6 +54,9 @@ public class DreamConditionTest extends SysuiTestCase {
|
||||
@Mock
|
||||
DreamManager mDreamManager;
|
||||
|
||||
@Mock
|
||||
KeyguardUpdateMonitor mKeyguardUpdateMonitor;
|
||||
|
||||
@Before
|
||||
public void setup() {
|
||||
MockitoAnnotations.initMocks(this);
|
||||
@@ -66,7 +68,7 @@ public class DreamConditionTest extends SysuiTestCase {
|
||||
@Test
|
||||
public void testInitialDreamingState() {
|
||||
when(mDreamManager.isDreaming()).thenReturn(true);
|
||||
final DreamCondition condition = new DreamCondition(mContext, mDreamManager);
|
||||
final DreamCondition condition = new DreamCondition(mDreamManager, mKeyguardUpdateMonitor);
|
||||
condition.addCallback(mCallback);
|
||||
|
||||
verify(mCallback).onConditionChanged(eq(condition));
|
||||
@@ -79,7 +81,7 @@ public class DreamConditionTest extends SysuiTestCase {
|
||||
@Test
|
||||
public void testInitialNonDreamingState() {
|
||||
when(mDreamManager.isDreaming()).thenReturn(false);
|
||||
final DreamCondition condition = new DreamCondition(mContext, mDreamManager);
|
||||
final DreamCondition condition = new DreamCondition(mDreamManager, mKeyguardUpdateMonitor);
|
||||
condition.addCallback(mCallback);
|
||||
|
||||
verify(mCallback, never()).onConditionChanged(eq(condition));
|
||||
@@ -91,15 +93,21 @@ public class DreamConditionTest extends SysuiTestCase {
|
||||
*/
|
||||
@Test
|
||||
public void testChange() {
|
||||
final ArgumentCaptor<BroadcastReceiver> receiverCaptor =
|
||||
ArgumentCaptor.forClass(BroadcastReceiver.class);
|
||||
final ArgumentCaptor<KeyguardUpdateMonitorCallback> callbackCaptor =
|
||||
ArgumentCaptor.forClass(KeyguardUpdateMonitorCallback.class);
|
||||
when(mDreamManager.isDreaming()).thenReturn(true);
|
||||
final DreamCondition condition = new DreamCondition(mContext, mDreamManager);
|
||||
final DreamCondition condition = new DreamCondition(mDreamManager, mKeyguardUpdateMonitor);
|
||||
condition.addCallback(mCallback);
|
||||
verify(mContext).registerReceiver(receiverCaptor.capture(), any());
|
||||
verify(mKeyguardUpdateMonitor).registerCallback(callbackCaptor.capture());
|
||||
|
||||
clearInvocations(mCallback);
|
||||
receiverCaptor.getValue().onReceive(mContext, new Intent(Intent.ACTION_DREAMING_STOPPED));
|
||||
callbackCaptor.getValue().onDreamingStateChanged(false);
|
||||
verify(mCallback).onConditionChanged(eq(condition));
|
||||
assertThat(condition.isConditionMet()).isFalse();
|
||||
|
||||
clearInvocations(mCallback);
|
||||
callbackCaptor.getValue().onDreamingStateChanged(true);
|
||||
verify(mCallback).onConditionChanged(eq(condition));
|
||||
assertThat(condition.isConditionMet()).isTrue();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -345,6 +345,7 @@ final class DreamController {
|
||||
if (!mCurrentDream.mIsPreviewMode && !mSentStartBroadcast) {
|
||||
mContext.sendBroadcastAsUser(mDreamingStartedIntent, UserHandle.ALL,
|
||||
null /* receiverPermission */, mDreamingStartedStoppedOptions);
|
||||
mListener.onDreamStarted(mCurrentDream.mToken);
|
||||
mSentStartBroadcast = true;
|
||||
}
|
||||
}
|
||||
@@ -353,6 +354,7 @@ final class DreamController {
|
||||
* Callback interface to be implemented by the {@link DreamManagerService}.
|
||||
*/
|
||||
public interface Listener {
|
||||
void onDreamStarted(Binder token);
|
||||
void onDreamStopped(Binder token);
|
||||
}
|
||||
|
||||
|
||||
@@ -84,6 +84,7 @@ import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
import java.util.concurrent.CopyOnWriteArrayList;
|
||||
import java.util.function.Consumer;
|
||||
|
||||
/**
|
||||
* Service api for managing dreams.
|
||||
@@ -341,10 +342,24 @@ public final class DreamManagerService extends SystemService {
|
||||
}
|
||||
|
||||
private void reportKeepDreamingWhenUnpluggingChanged(boolean keepDreaming) {
|
||||
notifyDreamStateListeners(
|
||||
listener -> listener.onKeepDreamingWhenUnpluggingChanged(keepDreaming));
|
||||
}
|
||||
|
||||
private void reportDreamingStarted() {
|
||||
notifyDreamStateListeners(listener -> listener.onDreamingStarted());
|
||||
}
|
||||
|
||||
private void reportDreamingStopped() {
|
||||
notifyDreamStateListeners(listener -> listener.onDreamingStopped());
|
||||
}
|
||||
|
||||
private void notifyDreamStateListeners(
|
||||
Consumer<DreamManagerInternal.DreamManagerStateListener> notifier) {
|
||||
mHandler.post(() -> {
|
||||
for (DreamManagerInternal.DreamManagerStateListener listener
|
||||
: mDreamManagerStateListeners) {
|
||||
listener.onKeepDreamingWhenUnpluggingChanged(keepDreaming);
|
||||
notifier.accept(listener);
|
||||
}
|
||||
});
|
||||
}
|
||||
@@ -766,6 +781,15 @@ public final class DreamManagerService extends SystemService {
|
||||
}
|
||||
|
||||
private final DreamController.Listener mControllerListener = new DreamController.Listener() {
|
||||
@Override
|
||||
public void onDreamStarted(Binder token) {
|
||||
// Note that this event is distinct from DreamManagerService#startDreamLocked as it
|
||||
// tracks the DreamService attach point from DreamController, closest to the broadcast
|
||||
// of ACTION_DREAMING_STARTED.
|
||||
|
||||
reportDreamingStarted();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDreamStopped(Binder token) {
|
||||
synchronized (mLock) {
|
||||
@@ -773,6 +797,8 @@ public final class DreamManagerService extends SystemService {
|
||||
cleanupDreamLocked();
|
||||
}
|
||||
}
|
||||
|
||||
reportDreamingStopped();
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@@ -2186,12 +2186,6 @@ public class PhoneWindowManager implements WindowManagerPolicy {
|
||||
Intent.EXTRA_DOCK_STATE_UNDOCKED));
|
||||
}
|
||||
|
||||
// register for dream-related broadcasts
|
||||
filter = new IntentFilter();
|
||||
filter.addAction(Intent.ACTION_DREAMING_STARTED);
|
||||
filter.addAction(Intent.ACTION_DREAMING_STOPPED);
|
||||
mContext.registerReceiver(mDreamReceiver, filter);
|
||||
|
||||
// register for multiuser-relevant broadcasts
|
||||
filter = new IntentFilter(Intent.ACTION_USER_SWITCHED);
|
||||
mContext.registerReceiver(mMultiuserReceiver, filter);
|
||||
@@ -4785,21 +4779,6 @@ public class PhoneWindowManager implements WindowManagerPolicy {
|
||||
}
|
||||
};
|
||||
|
||||
BroadcastReceiver mDreamReceiver = new BroadcastReceiver() {
|
||||
@Override
|
||||
public void onReceive(Context context, Intent intent) {
|
||||
if (Intent.ACTION_DREAMING_STARTED.equals(intent.getAction())) {
|
||||
if (mKeyguardDelegate != null) {
|
||||
mKeyguardDelegate.onDreamingStarted();
|
||||
}
|
||||
} else if (Intent.ACTION_DREAMING_STOPPED.equals(intent.getAction())) {
|
||||
if (mKeyguardDelegate != null) {
|
||||
mKeyguardDelegate.onDreamingStopped();
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
BroadcastReceiver mMultiuserReceiver = new BroadcastReceiver() {
|
||||
@Override
|
||||
public void onReceive(Context context, Intent intent) {
|
||||
|
||||
@@ -18,6 +18,7 @@ import android.os.IBinder;
|
||||
import android.os.PowerManager;
|
||||
import android.os.RemoteException;
|
||||
import android.os.UserHandle;
|
||||
import android.service.dreams.DreamManagerInternal;
|
||||
import android.util.Log;
|
||||
import android.util.Slog;
|
||||
import android.util.proto.ProtoOutputStream;
|
||||
@@ -27,6 +28,7 @@ import com.android.internal.policy.IKeyguardDismissCallback;
|
||||
import com.android.internal.policy.IKeyguardDrawnCallback;
|
||||
import com.android.internal.policy.IKeyguardExitCallback;
|
||||
import com.android.internal.policy.IKeyguardService;
|
||||
import com.android.server.LocalServices;
|
||||
import com.android.server.UiThread;
|
||||
import com.android.server.policy.WindowManagerPolicy.OnKeyguardExitResult;
|
||||
import com.android.server.wm.EventLogTags;
|
||||
@@ -60,6 +62,19 @@ public class KeyguardServiceDelegate {
|
||||
|
||||
private DrawnListener mDrawnListenerWhenConnect;
|
||||
|
||||
private final DreamManagerInternal.DreamManagerStateListener mDreamManagerStateListener =
|
||||
new DreamManagerInternal.DreamManagerStateListener() {
|
||||
@Override
|
||||
public void onDreamingStarted() {
|
||||
KeyguardServiceDelegate.this.onDreamingStarted();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDreamingStopped() {
|
||||
KeyguardServiceDelegate.this.onDreamingStopped();
|
||||
}
|
||||
};
|
||||
|
||||
private static final class KeyguardState {
|
||||
KeyguardState() {
|
||||
reset();
|
||||
@@ -158,6 +173,11 @@ public class KeyguardServiceDelegate {
|
||||
} else {
|
||||
if (DEBUG) Log.v(TAG, "*** Keyguard started");
|
||||
}
|
||||
|
||||
final DreamManagerInternal dreamManager =
|
||||
LocalServices.getService(DreamManagerInternal.class);
|
||||
|
||||
dreamManager.registerDreamManagerStateListener(mDreamManagerStateListener);
|
||||
}
|
||||
|
||||
private final ServiceConnection mKeyguardConnection = new ServiceConnection() {
|
||||
|
||||
@@ -25,6 +25,7 @@ import static org.mockito.Mockito.mock;
|
||||
import static org.mockito.Mockito.verify;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
import android.app.ActivityTaskManager;
|
||||
import android.content.ComponentName;
|
||||
import android.content.Context;
|
||||
import android.content.ServiceConnection;
|
||||
@@ -54,6 +55,10 @@ public class DreamControllerTest {
|
||||
private DreamController.Listener mListener;
|
||||
@Mock
|
||||
private Context mContext;
|
||||
|
||||
@Mock
|
||||
private ActivityTaskManager mActivityTaskManager;
|
||||
|
||||
@Mock
|
||||
private IBinder mIBinder;
|
||||
@Mock
|
||||
@@ -80,6 +85,10 @@ public class DreamControllerTest {
|
||||
when(mIDreamService.asBinder()).thenReturn(mIBinder);
|
||||
when(mIBinder.queryLocalInterface(anyString())).thenReturn(mIDreamService);
|
||||
when(mContext.bindServiceAsUser(any(), any(), anyInt(), any())).thenReturn(true);
|
||||
when(mContext.getSystemService(Context.ACTIVITY_TASK_SERVICE))
|
||||
.thenReturn(mActivityTaskManager);
|
||||
when(mContext.getSystemServiceName(ActivityTaskManager.class))
|
||||
.thenReturn(Context.ACTIVITY_TASK_SERVICE);
|
||||
|
||||
mToken = new Binder();
|
||||
mDreamName = ComponentName.unflattenFromString("dream");
|
||||
@@ -103,6 +112,37 @@ public class DreamControllerTest {
|
||||
eq(false) /*preview*/, any());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void startDream_dreamListenerNotified() {
|
||||
// Call dream controller to start dreaming.
|
||||
mDreamController.startDream(mToken, mDreamName, false /*isPreview*/, false /*doze*/,
|
||||
0 /*userId*/, null /*wakeLock*/, mOverlayName, "test" /*reason*/);
|
||||
|
||||
// Mock service connected.
|
||||
final ServiceConnection serviceConnection = captureServiceConnection();
|
||||
serviceConnection.onServiceConnected(mDreamName, mIBinder);
|
||||
mLooper.dispatchAll();
|
||||
|
||||
// Verify that dream service is called to attach.
|
||||
verify(mListener).onDreamStarted(any());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void stopDream_dreamListenerNotified() {
|
||||
// Start dream.
|
||||
mDreamController.startDream(mToken, mDreamName, false /*isPreview*/, false /*doze*/,
|
||||
0 /*userId*/, null /*wakeLock*/, mOverlayName, "test" /*reason*/);
|
||||
captureServiceConnection().onServiceConnected(mDreamName, mIBinder);
|
||||
mLooper.dispatchAll();
|
||||
|
||||
// Stop dream.
|
||||
mDreamController.stopDream(true /*immediate*/, "test stop dream" /*reason*/);
|
||||
mLooper.dispatchAll();
|
||||
|
||||
// Verify that dream service is called to detach.
|
||||
verify(mListener).onDreamStopped(any());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void startDream_attachOnServiceConnectedInPreviewMode() throws RemoteException {
|
||||
// Call dream controller to start dreaming.
|
||||
|
||||
Reference in New Issue
Block a user