Loading services/core/java/com/android/server/display/DisplayManagerService.java +30 −18 Original line number Diff line number Diff line Loading @@ -132,7 +132,7 @@ public final class DisplayManagerService extends SystemService { private static final long WAIT_FOR_DEFAULT_DISPLAY_TIMEOUT = 10000; private static final int MSG_REGISTER_DEFAULT_DISPLAY_ADAPTER = 1; private static final int MSG_REGISTER_DEFAULT_DISPLAY_ADAPTERS = 1; private static final int MSG_REGISTER_ADDITIONAL_DISPLAY_ADAPTERS = 2; private static final int MSG_DELIVER_DISPLAY_EVENT = 3; private static final int MSG_REQUEST_TRAVERSAL = 4; Loading Loading @@ -266,7 +266,6 @@ public final class DisplayManagerService extends SystemService { PowerManager pm = (PowerManager) mContext.getSystemService(Context.POWER_SERVICE); mGlobalDisplayBrightness = pm.getDefaultScreenBrightnessSetting(); } public void setupSchedulerPolicies() { Loading @@ -284,9 +283,9 @@ public final class DisplayManagerService extends SystemService { // We need to pre-load the persistent data store so it's ready before the default display // adapter is up so that we have it's configuration. We could load it lazily, but since // we're going to have to read it in eventually we may as well do it here rather than after // we've waited for the diplay to register itself with us. // we've waited for the display to register itself with us. mPersistentDataStore.loadIfNeeded(); mHandler.sendEmptyMessage(MSG_REGISTER_DEFAULT_DISPLAY_ADAPTER); mHandler.sendEmptyMessage(MSG_REGISTER_DEFAULT_DISPLAY_ADAPTERS); publishBinderService(Context.DISPLAY_SERVICE, new BinderService(), true /*allowIsolated*/); Loading @@ -298,12 +297,16 @@ public final class DisplayManagerService extends SystemService { public void onBootPhase(int phase) { if (phase == PHASE_WAIT_FOR_DEFAULT_DISPLAY) { synchronized (mSyncRoot) { long timeout = SystemClock.uptimeMillis() + WAIT_FOR_DEFAULT_DISPLAY_TIMEOUT; while (mLogicalDisplays.get(Display.DEFAULT_DISPLAY) == null) { long timeout = SystemClock.uptimeMillis() + mInjector.getDefaultDisplayDelayTimeout(); while (mLogicalDisplays.get(Display.DEFAULT_DISPLAY) == null || mVirtualDisplayAdapter == null) { long delay = timeout - SystemClock.uptimeMillis(); if (delay <= 0) { throw new RuntimeException("Timeout waiting for default display " + "to be initialized."); + "to be initialized. DefaultDisplay=" + mLogicalDisplays.get(Display.DEFAULT_DISPLAY) + ", mVirtualDisplayAdapter=" + mVirtualDisplayAdapter); } if (DEBUG) { Slog.d(TAG, "waitForDefaultDisplay: waiting, timeout=" + delay); Loading Loading @@ -685,11 +688,23 @@ public final class DisplayManagerService extends SystemService { } } private void registerDefaultDisplayAdapter() { // Register default display adapter. private void registerDefaultDisplayAdapters() { // Register default display adapters. synchronized (mSyncRoot) { // main display adapter registerDisplayAdapterLocked(new LocalDisplayAdapter( mSyncRoot, mContext, mHandler, mDisplayAdapterListener)); // Standalone VR devices rely on a virtual display as their primary display for // 2D UI. We register virtual display adapter along side the main display adapter // here so that it is ready by the time the system sends the home Intent for // early apps like SetupWizard/Launcher. In particular, SUW is displayed using // the virtual display inside VR before any VR-specific apps even run. mVirtualDisplayAdapter = mInjector.getVirtualDisplayAdapter(mSyncRoot, mContext, mHandler, mDisplayAdapterListener); if (mVirtualDisplayAdapter != null) { registerDisplayAdapterLocked(mVirtualDisplayAdapter); } } } Loading @@ -698,7 +713,6 @@ public final class DisplayManagerService extends SystemService { if (shouldRegisterNonEssentialDisplayAdaptersLocked()) { registerOverlayDisplayAdapterLocked(); registerWifiDisplayAdapterLocked(); registerVirtualDisplayAdapterLocked(); } } } Loading @@ -719,12 +733,6 @@ public final class DisplayManagerService extends SystemService { } } private void registerVirtualDisplayAdapterLocked() { mVirtualDisplayAdapter = mInjector.getVirtualDisplayAdapter(mSyncRoot, mContext, mHandler, mDisplayAdapterListener); registerDisplayAdapterLocked(mVirtualDisplayAdapter); } private boolean shouldRegisterNonEssentialDisplayAdaptersLocked() { // In safe mode, we disable non-essential display adapters to give the user // an opportunity to fix broken settings or other problems that might affect Loading Loading @@ -1219,6 +1227,10 @@ public final class DisplayManagerService extends SystemService { Handler handler, DisplayAdapter.Listener displayAdapterListener) { return new VirtualDisplayAdapter(syncRoot, context, handler, displayAdapterListener); } long getDefaultDisplayDelayTimeout() { return WAIT_FOR_DEFAULT_DISPLAY_TIMEOUT; } } @VisibleForTesting Loading @@ -1241,8 +1253,8 @@ public final class DisplayManagerService extends SystemService { @Override public void handleMessage(Message msg) { switch (msg.what) { case MSG_REGISTER_DEFAULT_DISPLAY_ADAPTER: registerDefaultDisplayAdapter(); case MSG_REGISTER_DEFAULT_DISPLAY_ADAPTERS: registerDefaultDisplayAdapters(); break; case MSG_REGISTER_ADDITIONAL_DISPLAY_ADAPTERS: Loading services/core/java/com/android/server/vr/Vr2dDisplay.java +30 −16 Original line number Diff line number Diff line Loading @@ -35,7 +35,6 @@ class Vr2dDisplay { private final static String TAG = "Vr2dDisplay"; private final static boolean DEBUG = false; // TODO: Go over these values and figure out what is best private int mVirtualDisplayHeight; private int mVirtualDisplayWidth; private int mVirtualDisplayDpi; Loading @@ -55,17 +54,17 @@ class Vr2dDisplay { /** * The default width of the VR virtual display */ public static final int DEFAULT_VR_DISPLAY_WIDTH = 1400; public static final int DEFAULT_VIRTUAL_DISPLAY_WIDTH = 1400; /** * The default height of the VR virtual display */ public static final int DEFAULT_VR_DISPLAY_HEIGHT = 1800; public static final int DEFAULT_VIRTUAL_DISPLAY_HEIGHT = 1400; /** * The default height of the VR virtual dpi. */ public static final int DEFAULT_VR_DISPLAY_DPI = 320; public static final int DEFAULT_VIRTUAL_DISPLAY_DPI = 320; /** * The minimum height, width and dpi of VR virtual display. Loading @@ -87,8 +86,8 @@ class Vr2dDisplay { new IPersistentVrStateCallbacks.Stub() { @Override public void onPersistentVrStateChanged(boolean enabled) { if (enabled != mIsVrModeEnabled) { mIsVrModeEnabled = enabled; if (enabled != mIsPersistentVrModeEnabled) { mIsPersistentVrModeEnabled = enabled; updateVirtualDisplay(); } } Loading @@ -98,26 +97,33 @@ class Vr2dDisplay { private Surface mSurface; private ImageReader mImageReader; private Runnable mStopVDRunnable; private boolean mIsVrModeOverrideEnabled; private boolean mIsVrModeEnabled; private boolean mIsVirtualDisplayAllowed = true; private boolean mIsVrModeOverrideEnabled; // debug override to set vr mode. private boolean mIsVirtualDisplayAllowed = true; // Virtual-display feature toggle private boolean mIsPersistentVrModeEnabled; // indicates we are in vr persistent mode. private boolean mBootsToVr = false; // The device boots into VR (standalone VR device) public Vr2dDisplay(DisplayManager displayManager, ActivityManagerInternal activityManagerInternal, IVrManager vrManager) { mDisplayManager = displayManager; mActivityManagerInternal = activityManagerInternal; mVrManager = vrManager; mVirtualDisplayWidth = DEFAULT_VR_DISPLAY_WIDTH; mVirtualDisplayHeight = DEFAULT_VR_DISPLAY_HEIGHT; mVirtualDisplayDpi = DEFAULT_VR_DISPLAY_DPI; mVirtualDisplayWidth = DEFAULT_VIRTUAL_DISPLAY_WIDTH; mVirtualDisplayHeight = DEFAULT_VIRTUAL_DISPLAY_HEIGHT; mVirtualDisplayDpi = DEFAULT_VIRTUAL_DISPLAY_DPI; } /** * Initializes the compabilitiy display by listening to VR mode changes. */ public void init(Context context) { public void init(Context context, boolean bootsToVr) { startVrModeListener(); startDebugOnlyBroadcastReceiver(context); mBootsToVr = bootsToVr; if (mBootsToVr) { // If we are booting into VR, we need to start the virtual display immediately. This // ensures that the virtual display is up by the time Setup Wizard is started. updateVirtualDisplay(); } } /** Loading @@ -125,11 +131,13 @@ class Vr2dDisplay { */ private void updateVirtualDisplay() { if (DEBUG) { Log.i(TAG, "isVrMode: " + mIsVrModeEnabled + ", override: " + mIsVrModeOverrideEnabled + ", isAllowed: " + mIsVirtualDisplayAllowed); Log.i(TAG, "isVrMode: " + mIsPersistentVrModeEnabled + ", override: " + mIsVrModeOverrideEnabled + ", isAllowed: " + mIsVirtualDisplayAllowed + ", bootsToVr: " + mBootsToVr); } if (shouldRunVirtualDisplay()) { Log.i(TAG, "Attempting to start virtual display"); // TODO: Consider not creating the display until ActivityManager needs one on // which to display a 2D application. startVirtualDisplay(); Loading Loading @@ -383,6 +391,12 @@ class Vr2dDisplay { } private boolean shouldRunVirtualDisplay() { return mIsVirtualDisplayAllowed && (mIsVrModeEnabled || mIsVrModeOverrideEnabled); // Virtual Display should run whenever: // * Virtual Display is allowed/enabled AND // (1) BootsToVr is set indicating the device never leaves VR // (2) VR (persistent) mode is enabled // (3) VR mode is overridden to be enabled. return mIsVirtualDisplayAllowed && (mBootsToVr || mIsPersistentVrModeEnabled || mIsVrModeOverrideEnabled); } } services/core/java/com/android/server/vr/VrManagerService.java +1 −1 Original line number Diff line number Diff line Loading @@ -619,7 +619,7 @@ public class VrManagerService extends SystemService implements EnabledComponentC (DisplayManager) getContext().getSystemService(Context.DISPLAY_SERVICE); ActivityManagerInternal ami = LocalServices.getService(ActivityManagerInternal.class); mVr2dDisplay = new Vr2dDisplay(dm, ami, mVrManager); mVr2dDisplay.init(getContext()); mVr2dDisplay.init(getContext(), mBootsToVr); IntentFilter intentFilter = new IntentFilter(); intentFilter.addAction(Intent.ACTION_USER_UNLOCKED); Loading services/tests/servicestests/src/com/android/server/display/DisplayManagerServiceTest.java +113 −22 Original line number Diff line number Diff line Loading @@ -29,9 +29,11 @@ import android.view.SurfaceControl; import android.view.WindowManagerInternal; import com.android.server.LocalServices; import com.android.server.SystemService; import com.android.server.display.DisplayDeviceInfo; import com.android.server.display.DisplayManagerService.SyncRoot; import com.android.server.display.VirtualDisplayAdapter.SurfaceControlDisplayFactory; import com.android.server.lights.LightsManager; import org.mockito.ArgumentCaptor; import org.mockito.Mock; Loading @@ -45,35 +47,51 @@ import static org.mockito.Mockito.when; @SmallTest public class DisplayManagerServiceTest extends AndroidTestCase { private Handler mHandler; private DisplayManagerService mDisplayManager; private static final int MSG_REGISTER_DEFAULT_DISPLAY_ADAPTERS = 1; private static final long SHORT_DEFAULT_DISPLAY_TIMEOUT_MILLIS = 10; private final DisplayManagerService.Injector mShortMockedInjector = new DisplayManagerService.Injector() { @Override VirtualDisplayAdapter getVirtualDisplayAdapter(SyncRoot syncRoot, Context context, Handler handler, DisplayAdapter.Listener listener) { return mMockVirtualDisplayAdapter; } @Override long getDefaultDisplayDelayTimeout() { return SHORT_DEFAULT_DISPLAY_TIMEOUT_MILLIS; } }; private final DisplayManagerService.Injector mBasicInjector = new DisplayManagerService.Injector() { @Override VirtualDisplayAdapter getVirtualDisplayAdapter(SyncRoot syncRoot, Context context, Handler handler, DisplayAdapter.Listener displayAdapterListener) { return new VirtualDisplayAdapter(syncRoot, context, handler, displayAdapterListener, (String name, boolean secure) -> mMockDisplayToken); } }; @Mock InputManagerInternal mMockInputManagerInternal; @Mock IVirtualDisplayCallback.Stub mMockAppToken; @Mock WindowManagerInternal mMockWindowManagerInternal; @Mock LightsManager mMockLightsManager; @Mock VirtualDisplayAdapter mMockVirtualDisplayAdapter; @Mock IBinder mMockDisplayToken; @Override protected void setUp() throws Exception { MockitoAnnotations.initMocks(this); mDisplayManager = new DisplayManagerService(mContext, new DisplayManagerService.Injector() { @Override VirtualDisplayAdapter getVirtualDisplayAdapter(SyncRoot syncRoot, Context context, Handler handler, DisplayAdapter.Listener displayAdapterListener) { return new VirtualDisplayAdapter(syncRoot, context, handler, displayAdapterListener, (String name, boolean secure) -> mMockDisplayToken); } }); mHandler = mDisplayManager.getDisplayHandler(); LocalServices.removeServiceForTest(InputManagerInternal.class); LocalServices.addService(InputManagerInternal.class, mMockInputManagerInternal); LocalServices.removeServiceForTest(WindowManagerInternal.class); LocalServices.addService(WindowManagerInternal.class, mMockWindowManagerInternal); mDisplayManager.systemReady(false /* safeMode */, false /* onlyCore */); mDisplayManager.windowManagerAndInputReady(); LocalServices.removeServiceForTest(LightsManager.class); LocalServices.addService(LightsManager.class, mMockLightsManager); super.setUp(); } Loading @@ -83,8 +101,14 @@ public class DisplayManagerServiceTest extends AndroidTestCase { } public void testCreateVirtualDisplay_sentToInputManager() throws Exception { DisplayManagerService displayManager = new DisplayManagerService(mContext, mBasicInjector); registerDefaultDisplays(displayManager); displayManager.systemReady(false /* safeMode */, true /* onlyCore */); displayManager.windowManagerAndInputReady(); // This is effectively the DisplayManager service published to ServiceManager. DisplayManagerService.BinderService bs = mDisplayManager.new BinderService(); DisplayManagerService.BinderService bs = displayManager.new BinderService(); String uniqueId = "uniqueId --- Test"; String uniqueIdPrefix = "virtual:" + mContext.getPackageName() + ":"; Loading @@ -99,10 +123,10 @@ public class DisplayManagerServiceTest extends AndroidTestCase { "Test Virtual Display", width, height, dpi, null /* surface */, flags /* flags */, uniqueId); mDisplayManager.performTraversalInTransactionFromWindowManagerInternal(); displayManager.performTraversalInTransactionFromWindowManagerInternal(); // flush the handler mHandler.runWithScissors(() -> {}, 0 /* now */); displayManager.getDisplayHandler().runWithScissors(() -> {}, 0 /* now */); ArgumentCaptor<List<DisplayViewport>> virtualViewportCaptor = ArgumentCaptor.forClass(List.class); Loading @@ -118,8 +142,12 @@ public class DisplayManagerServiceTest extends AndroidTestCase { } public void testCreateVirtualDisplayRotatesWithContent() throws Exception { DisplayManagerService displayManager = new DisplayManagerService(mContext, mBasicInjector); registerDefaultDisplays(displayManager); // This is effectively the DisplayManager service published to ServiceManager. DisplayManagerService.BinderService bs = mDisplayManager.new BinderService(); DisplayManagerService.BinderService bs = displayManager.new BinderService(); String uniqueId = "uniqueId --- Rotates With Content Test"; int width = 600; Loading @@ -133,13 +161,76 @@ public class DisplayManagerServiceTest extends AndroidTestCase { "Test Virtual Display", width, height, dpi, null /* surface */, flags /* flags */, uniqueId); mDisplayManager.performTraversalInTransactionFromWindowManagerInternal(); displayManager.performTraversalInTransactionFromWindowManagerInternal(); // flush the handler mHandler.runWithScissors(() -> {}, 0 /* now */); displayManager.getDisplayHandler().runWithScissors(() -> {}, 0 /* now */); DisplayDeviceInfo ddi = mDisplayManager.getDisplayDeviceInfoInternal(displayId); DisplayDeviceInfo ddi = displayManager.getDisplayDeviceInfoInternal(displayId); assertNotNull(ddi); assertTrue((ddi.flags & DisplayDeviceInfo.FLAG_ROTATES_WITH_CONTENT) != 0); } /** * Tests that the virtual display is created along-side the default display. */ public void testStartVirtualDisplayWithDefaultDisplay_Succeeds() throws Exception { DisplayManagerService displayManager = new DisplayManagerService(mContext, mShortMockedInjector); registerDefaultDisplays(displayManager); displayManager.onBootPhase(SystemService.PHASE_WAIT_FOR_DEFAULT_DISPLAY); } /** * Tests that we get a Runtime exception when we cannot initialize the default display. */ public void testStartVirtualDisplayWithDefDisplay_NoDefaultDisplay() throws Exception { DisplayManagerService displayManager = new DisplayManagerService(mContext, mShortMockedInjector); Handler handler = displayManager.getDisplayHandler(); handler.runWithScissors(() -> {}, 0 /* now */); try { displayManager.onBootPhase(SystemService.PHASE_WAIT_FOR_DEFAULT_DISPLAY); } catch (RuntimeException e) { return; } fail("Expected DisplayManager to throw RuntimeException when it cannot initialize the" + " default display"); } /** * Tests that we get a Runtime exception when we cannot initialize the virtual display. */ public void testStartVirtualDisplayWithDefDisplay_NoVirtualDisplayAdapter() throws Exception { DisplayManagerService displayManager = new DisplayManagerService(mContext, new DisplayManagerService.Injector() { @Override VirtualDisplayAdapter getVirtualDisplayAdapter(SyncRoot syncRoot, Context context, Handler handler, DisplayAdapter.Listener listener) { return null; // return null for the adapter. This should cause a failure. } @Override long getDefaultDisplayDelayTimeout() { return SHORT_DEFAULT_DISPLAY_TIMEOUT_MILLIS; } }); try { displayManager.onBootPhase(SystemService.PHASE_WAIT_FOR_DEFAULT_DISPLAY); } catch (RuntimeException e) { return; } fail("Expected DisplayManager to throw RuntimeException when it cannot initialize the" + " virtual display adapter"); } private void registerDefaultDisplays(DisplayManagerService displayManager) { Handler handler = displayManager.getDisplayHandler(); // Would prefer to call displayManager.onStart() directly here but it performs binderService // registration which triggers security exceptions when running from a test. handler.sendEmptyMessage(MSG_REGISTER_DEFAULT_DISPLAY_ADAPTERS); // flush the handler handler.runWithScissors(() -> {}, 0 /* now */); } } Loading
services/core/java/com/android/server/display/DisplayManagerService.java +30 −18 Original line number Diff line number Diff line Loading @@ -132,7 +132,7 @@ public final class DisplayManagerService extends SystemService { private static final long WAIT_FOR_DEFAULT_DISPLAY_TIMEOUT = 10000; private static final int MSG_REGISTER_DEFAULT_DISPLAY_ADAPTER = 1; private static final int MSG_REGISTER_DEFAULT_DISPLAY_ADAPTERS = 1; private static final int MSG_REGISTER_ADDITIONAL_DISPLAY_ADAPTERS = 2; private static final int MSG_DELIVER_DISPLAY_EVENT = 3; private static final int MSG_REQUEST_TRAVERSAL = 4; Loading Loading @@ -266,7 +266,6 @@ public final class DisplayManagerService extends SystemService { PowerManager pm = (PowerManager) mContext.getSystemService(Context.POWER_SERVICE); mGlobalDisplayBrightness = pm.getDefaultScreenBrightnessSetting(); } public void setupSchedulerPolicies() { Loading @@ -284,9 +283,9 @@ public final class DisplayManagerService extends SystemService { // We need to pre-load the persistent data store so it's ready before the default display // adapter is up so that we have it's configuration. We could load it lazily, but since // we're going to have to read it in eventually we may as well do it here rather than after // we've waited for the diplay to register itself with us. // we've waited for the display to register itself with us. mPersistentDataStore.loadIfNeeded(); mHandler.sendEmptyMessage(MSG_REGISTER_DEFAULT_DISPLAY_ADAPTER); mHandler.sendEmptyMessage(MSG_REGISTER_DEFAULT_DISPLAY_ADAPTERS); publishBinderService(Context.DISPLAY_SERVICE, new BinderService(), true /*allowIsolated*/); Loading @@ -298,12 +297,16 @@ public final class DisplayManagerService extends SystemService { public void onBootPhase(int phase) { if (phase == PHASE_WAIT_FOR_DEFAULT_DISPLAY) { synchronized (mSyncRoot) { long timeout = SystemClock.uptimeMillis() + WAIT_FOR_DEFAULT_DISPLAY_TIMEOUT; while (mLogicalDisplays.get(Display.DEFAULT_DISPLAY) == null) { long timeout = SystemClock.uptimeMillis() + mInjector.getDefaultDisplayDelayTimeout(); while (mLogicalDisplays.get(Display.DEFAULT_DISPLAY) == null || mVirtualDisplayAdapter == null) { long delay = timeout - SystemClock.uptimeMillis(); if (delay <= 0) { throw new RuntimeException("Timeout waiting for default display " + "to be initialized."); + "to be initialized. DefaultDisplay=" + mLogicalDisplays.get(Display.DEFAULT_DISPLAY) + ", mVirtualDisplayAdapter=" + mVirtualDisplayAdapter); } if (DEBUG) { Slog.d(TAG, "waitForDefaultDisplay: waiting, timeout=" + delay); Loading Loading @@ -685,11 +688,23 @@ public final class DisplayManagerService extends SystemService { } } private void registerDefaultDisplayAdapter() { // Register default display adapter. private void registerDefaultDisplayAdapters() { // Register default display adapters. synchronized (mSyncRoot) { // main display adapter registerDisplayAdapterLocked(new LocalDisplayAdapter( mSyncRoot, mContext, mHandler, mDisplayAdapterListener)); // Standalone VR devices rely on a virtual display as their primary display for // 2D UI. We register virtual display adapter along side the main display adapter // here so that it is ready by the time the system sends the home Intent for // early apps like SetupWizard/Launcher. In particular, SUW is displayed using // the virtual display inside VR before any VR-specific apps even run. mVirtualDisplayAdapter = mInjector.getVirtualDisplayAdapter(mSyncRoot, mContext, mHandler, mDisplayAdapterListener); if (mVirtualDisplayAdapter != null) { registerDisplayAdapterLocked(mVirtualDisplayAdapter); } } } Loading @@ -698,7 +713,6 @@ public final class DisplayManagerService extends SystemService { if (shouldRegisterNonEssentialDisplayAdaptersLocked()) { registerOverlayDisplayAdapterLocked(); registerWifiDisplayAdapterLocked(); registerVirtualDisplayAdapterLocked(); } } } Loading @@ -719,12 +733,6 @@ public final class DisplayManagerService extends SystemService { } } private void registerVirtualDisplayAdapterLocked() { mVirtualDisplayAdapter = mInjector.getVirtualDisplayAdapter(mSyncRoot, mContext, mHandler, mDisplayAdapterListener); registerDisplayAdapterLocked(mVirtualDisplayAdapter); } private boolean shouldRegisterNonEssentialDisplayAdaptersLocked() { // In safe mode, we disable non-essential display adapters to give the user // an opportunity to fix broken settings or other problems that might affect Loading Loading @@ -1219,6 +1227,10 @@ public final class DisplayManagerService extends SystemService { Handler handler, DisplayAdapter.Listener displayAdapterListener) { return new VirtualDisplayAdapter(syncRoot, context, handler, displayAdapterListener); } long getDefaultDisplayDelayTimeout() { return WAIT_FOR_DEFAULT_DISPLAY_TIMEOUT; } } @VisibleForTesting Loading @@ -1241,8 +1253,8 @@ public final class DisplayManagerService extends SystemService { @Override public void handleMessage(Message msg) { switch (msg.what) { case MSG_REGISTER_DEFAULT_DISPLAY_ADAPTER: registerDefaultDisplayAdapter(); case MSG_REGISTER_DEFAULT_DISPLAY_ADAPTERS: registerDefaultDisplayAdapters(); break; case MSG_REGISTER_ADDITIONAL_DISPLAY_ADAPTERS: Loading
services/core/java/com/android/server/vr/Vr2dDisplay.java +30 −16 Original line number Diff line number Diff line Loading @@ -35,7 +35,6 @@ class Vr2dDisplay { private final static String TAG = "Vr2dDisplay"; private final static boolean DEBUG = false; // TODO: Go over these values and figure out what is best private int mVirtualDisplayHeight; private int mVirtualDisplayWidth; private int mVirtualDisplayDpi; Loading @@ -55,17 +54,17 @@ class Vr2dDisplay { /** * The default width of the VR virtual display */ public static final int DEFAULT_VR_DISPLAY_WIDTH = 1400; public static final int DEFAULT_VIRTUAL_DISPLAY_WIDTH = 1400; /** * The default height of the VR virtual display */ public static final int DEFAULT_VR_DISPLAY_HEIGHT = 1800; public static final int DEFAULT_VIRTUAL_DISPLAY_HEIGHT = 1400; /** * The default height of the VR virtual dpi. */ public static final int DEFAULT_VR_DISPLAY_DPI = 320; public static final int DEFAULT_VIRTUAL_DISPLAY_DPI = 320; /** * The minimum height, width and dpi of VR virtual display. Loading @@ -87,8 +86,8 @@ class Vr2dDisplay { new IPersistentVrStateCallbacks.Stub() { @Override public void onPersistentVrStateChanged(boolean enabled) { if (enabled != mIsVrModeEnabled) { mIsVrModeEnabled = enabled; if (enabled != mIsPersistentVrModeEnabled) { mIsPersistentVrModeEnabled = enabled; updateVirtualDisplay(); } } Loading @@ -98,26 +97,33 @@ class Vr2dDisplay { private Surface mSurface; private ImageReader mImageReader; private Runnable mStopVDRunnable; private boolean mIsVrModeOverrideEnabled; private boolean mIsVrModeEnabled; private boolean mIsVirtualDisplayAllowed = true; private boolean mIsVrModeOverrideEnabled; // debug override to set vr mode. private boolean mIsVirtualDisplayAllowed = true; // Virtual-display feature toggle private boolean mIsPersistentVrModeEnabled; // indicates we are in vr persistent mode. private boolean mBootsToVr = false; // The device boots into VR (standalone VR device) public Vr2dDisplay(DisplayManager displayManager, ActivityManagerInternal activityManagerInternal, IVrManager vrManager) { mDisplayManager = displayManager; mActivityManagerInternal = activityManagerInternal; mVrManager = vrManager; mVirtualDisplayWidth = DEFAULT_VR_DISPLAY_WIDTH; mVirtualDisplayHeight = DEFAULT_VR_DISPLAY_HEIGHT; mVirtualDisplayDpi = DEFAULT_VR_DISPLAY_DPI; mVirtualDisplayWidth = DEFAULT_VIRTUAL_DISPLAY_WIDTH; mVirtualDisplayHeight = DEFAULT_VIRTUAL_DISPLAY_HEIGHT; mVirtualDisplayDpi = DEFAULT_VIRTUAL_DISPLAY_DPI; } /** * Initializes the compabilitiy display by listening to VR mode changes. */ public void init(Context context) { public void init(Context context, boolean bootsToVr) { startVrModeListener(); startDebugOnlyBroadcastReceiver(context); mBootsToVr = bootsToVr; if (mBootsToVr) { // If we are booting into VR, we need to start the virtual display immediately. This // ensures that the virtual display is up by the time Setup Wizard is started. updateVirtualDisplay(); } } /** Loading @@ -125,11 +131,13 @@ class Vr2dDisplay { */ private void updateVirtualDisplay() { if (DEBUG) { Log.i(TAG, "isVrMode: " + mIsVrModeEnabled + ", override: " + mIsVrModeOverrideEnabled + ", isAllowed: " + mIsVirtualDisplayAllowed); Log.i(TAG, "isVrMode: " + mIsPersistentVrModeEnabled + ", override: " + mIsVrModeOverrideEnabled + ", isAllowed: " + mIsVirtualDisplayAllowed + ", bootsToVr: " + mBootsToVr); } if (shouldRunVirtualDisplay()) { Log.i(TAG, "Attempting to start virtual display"); // TODO: Consider not creating the display until ActivityManager needs one on // which to display a 2D application. startVirtualDisplay(); Loading Loading @@ -383,6 +391,12 @@ class Vr2dDisplay { } private boolean shouldRunVirtualDisplay() { return mIsVirtualDisplayAllowed && (mIsVrModeEnabled || mIsVrModeOverrideEnabled); // Virtual Display should run whenever: // * Virtual Display is allowed/enabled AND // (1) BootsToVr is set indicating the device never leaves VR // (2) VR (persistent) mode is enabled // (3) VR mode is overridden to be enabled. return mIsVirtualDisplayAllowed && (mBootsToVr || mIsPersistentVrModeEnabled || mIsVrModeOverrideEnabled); } }
services/core/java/com/android/server/vr/VrManagerService.java +1 −1 Original line number Diff line number Diff line Loading @@ -619,7 +619,7 @@ public class VrManagerService extends SystemService implements EnabledComponentC (DisplayManager) getContext().getSystemService(Context.DISPLAY_SERVICE); ActivityManagerInternal ami = LocalServices.getService(ActivityManagerInternal.class); mVr2dDisplay = new Vr2dDisplay(dm, ami, mVrManager); mVr2dDisplay.init(getContext()); mVr2dDisplay.init(getContext(), mBootsToVr); IntentFilter intentFilter = new IntentFilter(); intentFilter.addAction(Intent.ACTION_USER_UNLOCKED); Loading
services/tests/servicestests/src/com/android/server/display/DisplayManagerServiceTest.java +113 −22 Original line number Diff line number Diff line Loading @@ -29,9 +29,11 @@ import android.view.SurfaceControl; import android.view.WindowManagerInternal; import com.android.server.LocalServices; import com.android.server.SystemService; import com.android.server.display.DisplayDeviceInfo; import com.android.server.display.DisplayManagerService.SyncRoot; import com.android.server.display.VirtualDisplayAdapter.SurfaceControlDisplayFactory; import com.android.server.lights.LightsManager; import org.mockito.ArgumentCaptor; import org.mockito.Mock; Loading @@ -45,35 +47,51 @@ import static org.mockito.Mockito.when; @SmallTest public class DisplayManagerServiceTest extends AndroidTestCase { private Handler mHandler; private DisplayManagerService mDisplayManager; private static final int MSG_REGISTER_DEFAULT_DISPLAY_ADAPTERS = 1; private static final long SHORT_DEFAULT_DISPLAY_TIMEOUT_MILLIS = 10; private final DisplayManagerService.Injector mShortMockedInjector = new DisplayManagerService.Injector() { @Override VirtualDisplayAdapter getVirtualDisplayAdapter(SyncRoot syncRoot, Context context, Handler handler, DisplayAdapter.Listener listener) { return mMockVirtualDisplayAdapter; } @Override long getDefaultDisplayDelayTimeout() { return SHORT_DEFAULT_DISPLAY_TIMEOUT_MILLIS; } }; private final DisplayManagerService.Injector mBasicInjector = new DisplayManagerService.Injector() { @Override VirtualDisplayAdapter getVirtualDisplayAdapter(SyncRoot syncRoot, Context context, Handler handler, DisplayAdapter.Listener displayAdapterListener) { return new VirtualDisplayAdapter(syncRoot, context, handler, displayAdapterListener, (String name, boolean secure) -> mMockDisplayToken); } }; @Mock InputManagerInternal mMockInputManagerInternal; @Mock IVirtualDisplayCallback.Stub mMockAppToken; @Mock WindowManagerInternal mMockWindowManagerInternal; @Mock LightsManager mMockLightsManager; @Mock VirtualDisplayAdapter mMockVirtualDisplayAdapter; @Mock IBinder mMockDisplayToken; @Override protected void setUp() throws Exception { MockitoAnnotations.initMocks(this); mDisplayManager = new DisplayManagerService(mContext, new DisplayManagerService.Injector() { @Override VirtualDisplayAdapter getVirtualDisplayAdapter(SyncRoot syncRoot, Context context, Handler handler, DisplayAdapter.Listener displayAdapterListener) { return new VirtualDisplayAdapter(syncRoot, context, handler, displayAdapterListener, (String name, boolean secure) -> mMockDisplayToken); } }); mHandler = mDisplayManager.getDisplayHandler(); LocalServices.removeServiceForTest(InputManagerInternal.class); LocalServices.addService(InputManagerInternal.class, mMockInputManagerInternal); LocalServices.removeServiceForTest(WindowManagerInternal.class); LocalServices.addService(WindowManagerInternal.class, mMockWindowManagerInternal); mDisplayManager.systemReady(false /* safeMode */, false /* onlyCore */); mDisplayManager.windowManagerAndInputReady(); LocalServices.removeServiceForTest(LightsManager.class); LocalServices.addService(LightsManager.class, mMockLightsManager); super.setUp(); } Loading @@ -83,8 +101,14 @@ public class DisplayManagerServiceTest extends AndroidTestCase { } public void testCreateVirtualDisplay_sentToInputManager() throws Exception { DisplayManagerService displayManager = new DisplayManagerService(mContext, mBasicInjector); registerDefaultDisplays(displayManager); displayManager.systemReady(false /* safeMode */, true /* onlyCore */); displayManager.windowManagerAndInputReady(); // This is effectively the DisplayManager service published to ServiceManager. DisplayManagerService.BinderService bs = mDisplayManager.new BinderService(); DisplayManagerService.BinderService bs = displayManager.new BinderService(); String uniqueId = "uniqueId --- Test"; String uniqueIdPrefix = "virtual:" + mContext.getPackageName() + ":"; Loading @@ -99,10 +123,10 @@ public class DisplayManagerServiceTest extends AndroidTestCase { "Test Virtual Display", width, height, dpi, null /* surface */, flags /* flags */, uniqueId); mDisplayManager.performTraversalInTransactionFromWindowManagerInternal(); displayManager.performTraversalInTransactionFromWindowManagerInternal(); // flush the handler mHandler.runWithScissors(() -> {}, 0 /* now */); displayManager.getDisplayHandler().runWithScissors(() -> {}, 0 /* now */); ArgumentCaptor<List<DisplayViewport>> virtualViewportCaptor = ArgumentCaptor.forClass(List.class); Loading @@ -118,8 +142,12 @@ public class DisplayManagerServiceTest extends AndroidTestCase { } public void testCreateVirtualDisplayRotatesWithContent() throws Exception { DisplayManagerService displayManager = new DisplayManagerService(mContext, mBasicInjector); registerDefaultDisplays(displayManager); // This is effectively the DisplayManager service published to ServiceManager. DisplayManagerService.BinderService bs = mDisplayManager.new BinderService(); DisplayManagerService.BinderService bs = displayManager.new BinderService(); String uniqueId = "uniqueId --- Rotates With Content Test"; int width = 600; Loading @@ -133,13 +161,76 @@ public class DisplayManagerServiceTest extends AndroidTestCase { "Test Virtual Display", width, height, dpi, null /* surface */, flags /* flags */, uniqueId); mDisplayManager.performTraversalInTransactionFromWindowManagerInternal(); displayManager.performTraversalInTransactionFromWindowManagerInternal(); // flush the handler mHandler.runWithScissors(() -> {}, 0 /* now */); displayManager.getDisplayHandler().runWithScissors(() -> {}, 0 /* now */); DisplayDeviceInfo ddi = mDisplayManager.getDisplayDeviceInfoInternal(displayId); DisplayDeviceInfo ddi = displayManager.getDisplayDeviceInfoInternal(displayId); assertNotNull(ddi); assertTrue((ddi.flags & DisplayDeviceInfo.FLAG_ROTATES_WITH_CONTENT) != 0); } /** * Tests that the virtual display is created along-side the default display. */ public void testStartVirtualDisplayWithDefaultDisplay_Succeeds() throws Exception { DisplayManagerService displayManager = new DisplayManagerService(mContext, mShortMockedInjector); registerDefaultDisplays(displayManager); displayManager.onBootPhase(SystemService.PHASE_WAIT_FOR_DEFAULT_DISPLAY); } /** * Tests that we get a Runtime exception when we cannot initialize the default display. */ public void testStartVirtualDisplayWithDefDisplay_NoDefaultDisplay() throws Exception { DisplayManagerService displayManager = new DisplayManagerService(mContext, mShortMockedInjector); Handler handler = displayManager.getDisplayHandler(); handler.runWithScissors(() -> {}, 0 /* now */); try { displayManager.onBootPhase(SystemService.PHASE_WAIT_FOR_DEFAULT_DISPLAY); } catch (RuntimeException e) { return; } fail("Expected DisplayManager to throw RuntimeException when it cannot initialize the" + " default display"); } /** * Tests that we get a Runtime exception when we cannot initialize the virtual display. */ public void testStartVirtualDisplayWithDefDisplay_NoVirtualDisplayAdapter() throws Exception { DisplayManagerService displayManager = new DisplayManagerService(mContext, new DisplayManagerService.Injector() { @Override VirtualDisplayAdapter getVirtualDisplayAdapter(SyncRoot syncRoot, Context context, Handler handler, DisplayAdapter.Listener listener) { return null; // return null for the adapter. This should cause a failure. } @Override long getDefaultDisplayDelayTimeout() { return SHORT_DEFAULT_DISPLAY_TIMEOUT_MILLIS; } }); try { displayManager.onBootPhase(SystemService.PHASE_WAIT_FOR_DEFAULT_DISPLAY); } catch (RuntimeException e) { return; } fail("Expected DisplayManager to throw RuntimeException when it cannot initialize the" + " virtual display adapter"); } private void registerDefaultDisplays(DisplayManagerService displayManager) { Handler handler = displayManager.getDisplayHandler(); // Would prefer to call displayManager.onStart() directly here but it performs binderService // registration which triggers security exceptions when running from a test. handler.sendEmptyMessage(MSG_REGISTER_DEFAULT_DISPLAY_ADAPTERS); // flush the handler handler.runWithScissors(() -> {}, 0 /* now */); } }