summaryrefslogtreecommitdiff
path: root/core/java/android
diff options
context:
space:
mode:
authorchaviw <chaviw@google.com>2018-11-02 11:11:27 -0700
committerchaviw <chaviw@google.com>2018-11-30 10:48:28 -0800
commitff2e7d8f41d75c5437f1fac199a280e650eb79ae (patch)
treefb4a9503fbd1a7563b138c09e02b396747122007 /core/java/android
parent5b1d16409a639f82d76dc1d0802d584bf3de717d (diff)
Reparent DisplayContent layers to SurfaceControl for ActivityView
With the current implementation, when an ActivityView is created, it creates a new Display in both DisplayManager and SurfaceFlinger. Then it attaches the SurfaceView's surface to the Display so the content generated for the second display renders into the SurfaceView. However, this is inefficient since it requires the rendered content to get copied over. With this change, the ActivityView creates a VirtualDisplay but also creates a new SurfaceControl. It then notifies WindowManager so WM can instead reparent the windows that represent the new VirtualDispay to be a child of the SurfaceControl passed in. The SurfaceControl passed in is a child of the SurfaceView's SC so the content in the new VirtualDisplay will just automatically render onto the main display without having to copy. The SF hierarchy will have the VirtualDisplay's surfaces as children of the SurfaceView, but the WM will still represent the VirtualDisplay as a second display. Test: Run app with ActivityView and launch Activity in AV Change-Id: I21c9bb189b6c12b0d98c67c8e68f53c621a4a802 Fixes: 111440225
Diffstat (limited to 'core/java/android')
-rw-r--r--core/java/android/app/ActivityView.java52
-rw-r--r--core/java/android/view/IWindowManager.aidl12
-rw-r--r--core/java/android/view/SurfaceView.java7
3 files changed, 58 insertions, 13 deletions
diff --git a/core/java/android/app/ActivityView.java b/core/java/android/app/ActivityView.java
index c879db8967d3..446d98e97936 100644
--- a/core/java/android/app/ActivityView.java
+++ b/core/java/android/app/ActivityView.java
@@ -34,7 +34,9 @@ import android.view.InputDevice;
import android.view.InputEvent;
import android.view.MotionEvent;
import android.view.Surface;
+import android.view.SurfaceControl;
import android.view.SurfaceHolder;
+import android.view.SurfaceSession;
import android.view.SurfaceView;
import android.view.ViewGroup;
import android.view.WindowManager;
@@ -59,12 +61,16 @@ public class ActivityView extends ViewGroup {
private VirtualDisplay mVirtualDisplay;
private final SurfaceView mSurfaceView;
- private Surface mSurface;
+
+ /**
+ * This is the root surface for the VirtualDisplay. The VirtualDisplay child surfaces will be
+ * re-parented to this surface. This will also be a child of the SurfaceView's SurfaceControl.
+ */
+ private SurfaceControl mRootSurfaceControl;
private final SurfaceCallback mSurfaceCallback;
private StateCallback mActivityViewCallback;
- private IActivityManager mActivityManager;
private IActivityTaskManager mActivityTaskManager;
private IInputForwarder mInputForwarder;
// Temp container to store view coordinates on screen.
@@ -75,6 +81,9 @@ public class ActivityView extends ViewGroup {
private final CloseGuard mGuard = CloseGuard.get();
private boolean mOpened; // Protected by mGuard.
+ private final SurfaceControl.Transaction mTmpTransaction = new SurfaceControl.Transaction();
+ private Surface mTmpSurface = new Surface();
+
@UnsupportedAppUsage
public ActivityView(Context context) {
this(context, null /* attrs */);
@@ -87,7 +96,6 @@ public class ActivityView extends ViewGroup {
public ActivityView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
- mActivityManager = ActivityManager.getService();
mActivityTaskManager = ActivityTaskManager.getService();
mSurfaceView = new SurfaceView(context);
mSurfaceCallback = new SurfaceCallback();
@@ -297,14 +305,19 @@ public class ActivityView extends ViewGroup {
private class SurfaceCallback implements SurfaceHolder.Callback {
@Override
public void surfaceCreated(SurfaceHolder surfaceHolder) {
- mSurface = mSurfaceView.getHolder().getSurface();
+ mTmpSurface = new Surface();
if (mVirtualDisplay == null) {
- initVirtualDisplay();
+ initVirtualDisplay(new SurfaceSession(surfaceHolder.getSurface()));
if (mVirtualDisplay != null && mActivityViewCallback != null) {
mActivityViewCallback.onActivityViewReady(ActivityView.this);
}
} else {
- mVirtualDisplay.setSurface(surfaceHolder.getSurface());
+ // TODO (b/119209373): DisplayManager determines if a VirtualDisplay is on by
+ // whether it has a surface. Setting a fake surface here so DisplayManager will
+ // consider this display on.
+ mVirtualDisplay.setSurface(mTmpSurface);
+ mTmpTransaction.reparent(mRootSurfaceControl,
+ mSurfaceView.getSurfaceControl().getHandle()).apply();
}
updateLocation();
}
@@ -319,8 +332,8 @@ public class ActivityView extends ViewGroup {
@Override
public void surfaceDestroyed(SurfaceHolder surfaceHolder) {
- mSurface.release();
- mSurface = null;
+ mTmpSurface.release();
+ mTmpSurface = null;
if (mVirtualDisplay != null) {
mVirtualDisplay.setSurface(null);
}
@@ -328,7 +341,7 @@ public class ActivityView extends ViewGroup {
}
}
- private void initVirtualDisplay() {
+ private void initVirtualDisplay(SurfaceSession surfaceSession) {
if (mVirtualDisplay != null) {
throw new IllegalStateException("Trying to initialize for the second time.");
}
@@ -336,9 +349,13 @@ public class ActivityView extends ViewGroup {
final int width = mSurfaceView.getWidth();
final int height = mSurfaceView.getHeight();
final DisplayManager displayManager = mContext.getSystemService(DisplayManager.class);
+
+ // TODO (b/119209373): DisplayManager determines if a VirtualDisplay is on by
+ // whether it has a surface. Setting a fake surface here so DisplayManager will consider
+ // this display on.
mVirtualDisplay = displayManager.createVirtualDisplay(
DISPLAY_NAME + "@" + System.identityHashCode(this),
- width, height, getBaseDisplayDensity(), mSurface,
+ width, height, getBaseDisplayDensity(), mTmpSurface,
DisplayManager.VIRTUAL_DISPLAY_FLAG_PUBLIC
| DisplayManager.VIRTUAL_DISPLAY_FLAG_OWN_CONTENT_ONLY);
if (mVirtualDisplay == null) {
@@ -348,11 +365,20 @@ public class ActivityView extends ViewGroup {
final int displayId = mVirtualDisplay.getDisplay().getDisplayId();
final IWindowManager wm = WindowManagerGlobal.getWindowManagerService();
+
+ mRootSurfaceControl = new SurfaceControl.Builder(surfaceSession)
+ .setContainerLayer(true)
+ .setName(DISPLAY_NAME)
+ .build();
+
try {
+ wm.reparentDisplayContent(displayId, mRootSurfaceControl.getHandle());
wm.dontOverrideDisplayInfo(displayId);
} catch (RemoteException e) {
e.rethrowAsRuntimeException();
}
+
+ mTmpTransaction.show(mRootSurfaceControl).apply();
mInputForwarder = InputManager.getInstance().createInputForwarder(displayId);
mTaskStackListener = new TaskStackListenerImpl();
try {
@@ -392,9 +418,9 @@ public class ActivityView extends ViewGroup {
displayReleased = false;
}
- if (mSurface != null) {
- mSurface.release();
- mSurface = null;
+ if (mTmpSurface != null) {
+ mTmpSurface.release();
+ mTmpSurface = null;
}
if (displayReleased && mActivityViewCallback != null) {
diff --git a/core/java/android/view/IWindowManager.aidl b/core/java/android/view/IWindowManager.aidl
index dace388b66f6..0e6a520d5fc1 100644
--- a/core/java/android/view/IWindowManager.aidl
+++ b/core/java/android/view/IWindowManager.aidl
@@ -551,4 +551,16 @@ interface IWindowManager
* @see KeyguardManager#isDeviceLocked()
*/
void setShouldShowIme(int displayId, boolean shouldShow);
+
+ /**
+ * Reparent the top layers for a display to the requested surfaceControl. The display that
+ * is going to be re-parented (the displayId passed in) needs to have been created by the same
+ * process that is requesting the re-parent. This is to ensure clients can't just re-parent
+ * display content info to any SurfaceControl, as this would be a security issue.
+ *
+ * @param displayId The id of the display.
+ * @param surfaceControlHandle The SurfaceControl handle that the top level layers for the
+ * display should be re-parented to.
+ */
+ void reparentDisplayContent(int displayId, in IBinder surfaceControlHandle);
}
diff --git a/core/java/android/view/SurfaceView.java b/core/java/android/view/SurfaceView.java
index 3c4ce8f7cfad..797d1c5f47aa 100644
--- a/core/java/android/view/SurfaceView.java
+++ b/core/java/android/view/SurfaceView.java
@@ -1126,6 +1126,13 @@ public class SurfaceView extends View implements ViewRootImpl.WindowStoppedCallb
}
};
+ /**
+ * @hide
+ */
+ public SurfaceControl getSurfaceControl() {
+ return mSurfaceControl;
+ }
+
class SurfaceControlWithBackground extends SurfaceControl {
SurfaceControl mBackgroundControl;
private boolean mOpaque = true;