diff --git a/core/java/android/service/dreams/Sandman.java b/core/java/android/service/dreams/Sandman.java
index fae72a2e91a89..ced2a01cb1d0d 100644
--- a/core/java/android/service/dreams/Sandman.java
+++ b/core/java/android/service/dreams/Sandman.java
@@ -20,13 +20,13 @@ import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.os.PowerManager;
+import android.os.RemoteException;
+import android.os.ServiceManager;
import android.os.SystemClock;
import android.os.UserHandle;
import android.provider.Settings;
import android.util.Slog;
-import com.android.server.LocalServices;
-
/**
* Internal helper for launching dreams to ensure consistency between the
* UiModeManagerService system service and the Somnambulator activity.
@@ -75,28 +75,32 @@ public final class Sandman {
}
private static void startDream(Context context, boolean docked) {
- DreamManagerInternal dreamManagerService =
- LocalServices.getService(DreamManagerInternal.class);
- if (dreamManagerService != null && !dreamManagerService.isDreaming()) {
- if (docked) {
- Slog.i(TAG, "Activating dream while docked.");
+ try {
+ IDreamManager dreamManagerService = IDreamManager.Stub.asInterface(
+ ServiceManager.getService(DreamService.DREAM_SERVICE));
+ if (dreamManagerService != null && !dreamManagerService.isDreaming()) {
+ if (docked) {
+ Slog.i(TAG, "Activating dream while docked.");
- // Wake up.
- // The power manager will wake up the system automatically when it starts
- // receiving power from a dock but there is a race between that happening
- // and the UI mode manager starting a dream. We want the system to already
- // be awake by the time this happens. Otherwise the dream may not start.
- PowerManager powerManager =
- context.getSystemService(PowerManager.class);
- powerManager.wakeUp(SystemClock.uptimeMillis(),
- PowerManager.WAKE_REASON_PLUGGED_IN,
- "android.service.dreams:DREAM");
- } else {
- Slog.i(TAG, "Activating dream by user request.");
+ // Wake up.
+ // The power manager will wake up the system automatically when it starts
+ // receiving power from a dock but there is a race between that happening
+ // and the UI mode manager starting a dream. We want the system to already
+ // be awake by the time this happens. Otherwise the dream may not start.
+ PowerManager powerManager =
+ context.getSystemService(PowerManager.class);
+ powerManager.wakeUp(SystemClock.uptimeMillis(),
+ PowerManager.WAKE_REASON_PLUGGED_IN,
+ "android.service.dreams:DREAM");
+ } else {
+ Slog.i(TAG, "Activating dream by user request.");
+ }
+
+ // Dream.
+ dreamManagerService.dream();
}
-
- // Dream.
- dreamManagerService.requestDream();
+ } catch (RemoteException ex) {
+ Slog.e(TAG, "Could not start dream when docked.", ex);
}
}
diff --git a/services/core/java/com/android/server/UiModeManagerService.java b/services/core/java/com/android/server/UiModeManagerService.java
index e9dd836e527af..8d878af4b788d 100644
--- a/services/core/java/com/android/server/UiModeManagerService.java
+++ b/services/core/java/com/android/server/UiModeManagerService.java
@@ -1831,7 +1831,7 @@ final class UiModeManagerService extends SystemService {
if (category != null && !dockAppStarted && (mStartDreamImmediatelyOnDock
|| mWindowManager.isKeyguardShowingAndNotOccluded()
|| !mPowerManager.isInteractive())) {
- Sandman.startDreamWhenDockedIfAppropriate(getContext());
+ mInjector.startDreamWhenDockedIfAppropriate(getContext());
}
}
@@ -2145,5 +2145,9 @@ final class UiModeManagerService extends SystemService {
public int getCallingUid() {
return Binder.getCallingUid();
}
+
+ public void startDreamWhenDockedIfAppropriate(Context context) {
+ Sandman.startDreamWhenDockedIfAppropriate(context);
+ }
}
}
diff --git a/services/tests/uiservicestests/src/com/android/server/UiModeManagerServiceTest.java b/services/tests/uiservicestests/src/com/android/server/UiModeManagerServiceTest.java
index 617a34f44bff4..91c2fe0eb262c 100644
--- a/services/tests/uiservicestests/src/com/android/server/UiModeManagerServiceTest.java
+++ b/services/tests/uiservicestests/src/com/android/server/UiModeManagerServiceTest.java
@@ -54,6 +54,7 @@ import static org.mockito.Mockito.doReturn;
import static org.mockito.Mockito.doThrow;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.never;
+import static org.mockito.Mockito.spy;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.verifyNoMoreInteractions;
@@ -83,7 +84,6 @@ import android.os.Process;
import android.os.RemoteException;
import android.os.UserHandle;
import android.provider.Settings;
-import android.service.dreams.DreamManagerInternal;
import android.test.mock.MockContentResolver;
import android.testing.AndroidTestingRunner;
import android.testing.TestableLooper;
@@ -101,6 +101,7 @@ import org.junit.runner.RunWith;
import org.mockito.ArgumentCaptor;
import org.mockito.Captor;
import org.mockito.Mock;
+import org.mockito.Spy;
import java.time.LocalDateTime;
import java.time.LocalTime;
@@ -137,8 +138,8 @@ public class UiModeManagerServiceTest extends UiServiceTestCase {
private PackageManager mPackageManager;
@Mock
private IBinder mBinder;
- @Mock
- private DreamManagerInternal mDreamManager;
+ @Spy
+ private TestInjector mInjector;
@Captor
private ArgumentCaptor mOrderedBroadcastIntent;
@Captor
@@ -207,10 +208,10 @@ public class UiModeManagerServiceTest extends UiServiceTestCase {
addLocalService(WindowManagerInternal.class, mWindowManager);
addLocalService(PowerManagerInternal.class, mLocalPowerManager);
addLocalService(TwilightManager.class, mTwilightManager);
- addLocalService(DreamManagerInternal.class, mDreamManager);
-
+
+ mInjector = spy(new TestInjector());
mUiManagerService = new UiModeManagerService(mContext, /* setupWizardComplete= */ true,
- mTwilightManager, new TestInjector());
+ mTwilightManager, mInjector);
try {
mUiManagerService.onBootPhase(SystemService.PHASE_SYSTEM_SERVICES_READY);
} catch (SecurityException e) {/* ignore for permission denial */}
@@ -1321,84 +1322,53 @@ public class UiModeManagerServiceTest extends UiServiceTestCase {
@Test
public void dreamWhenDocked() {
- setScreensaverActivateOnDock(true);
- setScreensaverEnabled(true);
-
triggerDockIntent();
verifyAndSendResultBroadcast();
- verify(mDreamManager).requestDream();
- }
-
- @Test
- public void noDreamWhenDocked_dreamsDisabled() {
- setScreensaverActivateOnDock(true);
- setScreensaverEnabled(false);
-
- triggerDockIntent();
- verifyAndSendResultBroadcast();
- verify(mDreamManager, never()).requestDream();
- }
-
- @Test
- public void noDreamWhenDocked_dreamsWhenDockedDisabled() {
- setScreensaverActivateOnDock(false);
- setScreensaverEnabled(true);
-
- triggerDockIntent();
- verifyAndSendResultBroadcast();
- verify(mDreamManager, never()).requestDream();
+ verify(mInjector).startDreamWhenDockedIfAppropriate(mContext);
}
@Test
public void noDreamWhenDocked_keyguardNotShowing_interactive() {
- setScreensaverActivateOnDock(true);
- setScreensaverEnabled(true);
mUiManagerService.setStartDreamImmediatelyOnDock(false);
when(mWindowManager.isKeyguardShowingAndNotOccluded()).thenReturn(false);
when(mPowerManager.isInteractive()).thenReturn(true);
triggerDockIntent();
verifyAndSendResultBroadcast();
- verify(mDreamManager, never()).requestDream();
+ verify(mInjector, never()).startDreamWhenDockedIfAppropriate(mContext);
}
@Test
public void dreamWhenDocked_keyguardShowing_interactive() {
- setScreensaverActivateOnDock(true);
- setScreensaverEnabled(true);
mUiManagerService.setStartDreamImmediatelyOnDock(false);
when(mWindowManager.isKeyguardShowingAndNotOccluded()).thenReturn(true);
when(mPowerManager.isInteractive()).thenReturn(false);
triggerDockIntent();
verifyAndSendResultBroadcast();
- verify(mDreamManager).requestDream();
+ verify(mInjector).startDreamWhenDockedIfAppropriate(mContext);
}
@Test
public void dreamWhenDocked_keyguardNotShowing_notInteractive() {
- setScreensaverActivateOnDock(true);
- setScreensaverEnabled(true);
mUiManagerService.setStartDreamImmediatelyOnDock(false);
when(mWindowManager.isKeyguardShowingAndNotOccluded()).thenReturn(false);
when(mPowerManager.isInteractive()).thenReturn(false);
triggerDockIntent();
verifyAndSendResultBroadcast();
- verify(mDreamManager).requestDream();
+ verify(mInjector).startDreamWhenDockedIfAppropriate(mContext);
}
@Test
public void dreamWhenDocked_keyguardShowing_notInteractive() {
- setScreensaverActivateOnDock(true);
- setScreensaverEnabled(true);
mUiManagerService.setStartDreamImmediatelyOnDock(false);
when(mWindowManager.isKeyguardShowingAndNotOccluded()).thenReturn(true);
when(mPowerManager.isInteractive()).thenReturn(false);
triggerDockIntent();
verifyAndSendResultBroadcast();
- verify(mDreamManager).requestDream();
+ verify(mInjector).startDreamWhenDockedIfAppropriate(mContext);
}
private void triggerDockIntent() {
@@ -1435,22 +1405,6 @@ public class UiModeManagerServiceTest extends UiServiceTestCase {
mOrderedBroadcastIntent.getValue());
}
- private void setScreensaverEnabled(boolean enable) {
- Settings.Secure.putIntForUser(
- mContentResolver,
- Settings.Secure.SCREENSAVER_ENABLED,
- enable ? 1 : 0,
- UserHandle.USER_CURRENT);
- }
-
- private void setScreensaverActivateOnDock(boolean enable) {
- Settings.Secure.putIntForUser(
- mContentResolver,
- Settings.Secure.SCREENSAVER_ACTIVATE_ON_DOCK,
- enable ? 1 : 0,
- UserHandle.USER_CURRENT);
- }
-
private void requestAllPossibleProjectionTypes() throws RemoteException {
for (int i = 0; i < Integer.SIZE; ++i) {
mService.requestProjection(mBinder, 1 << i, PACKAGE_NAME);
@@ -1467,11 +1421,17 @@ public class UiModeManagerServiceTest extends UiServiceTestCase {
}
public TestInjector(int callingUid) {
- this.callingUid = callingUid;
+ this.callingUid = callingUid;
}
+ @Override
public int getCallingUid() {
return callingUid;
}
+
+ @Override
+ public void startDreamWhenDockedIfAppropriate(Context context) {
+ // do nothing
+ }
}
}