Merge "Prevent SurfaceView from drawing over parent surface insets"

This commit is contained in:
TreeHugger Robot
2019-06-19 01:31:00 +00:00
committed by Android (Google) Code Review
11 changed files with 192 additions and 106 deletions

View File

@@ -105,7 +105,7 @@ public abstract class WallpaperService extends Service {
static final String TAG = "WallpaperService";
static final boolean DEBUG = false;
private static final int DO_ATTACH = 10;
private static final int DO_DETACH = 20;
private static final int DO_SET_DESIRED_SIZE = 30;
@@ -126,7 +126,7 @@ public abstract class WallpaperService extends Service {
private final ArrayList<Engine> mActiveEngines
= new ArrayList<Engine>();
static final class WallpaperCommand {
String action;
int x;
@@ -145,7 +145,7 @@ public abstract class WallpaperService extends Service {
*/
public class Engine {
IWallpaperEngineWrapper mIWallpaperEngine;
// Copies from mIWallpaperEngine.
HandlerCaller mCaller;
IWallpaperConnection mConnection;
@@ -155,7 +155,7 @@ public abstract class WallpaperService extends Service {
boolean mVisible;
boolean mReportedVisible;
boolean mDestroyed;
// Current window state.
boolean mCreated;
boolean mSurfaceCreated;
@@ -258,7 +258,7 @@ public abstract class WallpaperService extends Service {
}
super.setFixedSize(width, height);
}
public void setKeepScreenOn(boolean screenOn) {
throw new UnsupportedOperationException(
"Wallpapers do not support keep screen on");
@@ -403,14 +403,14 @@ public abstract class WallpaperService extends Service {
mClockFunction = clockFunction;
mHandler = handler;
}
/**
* Provides access to the surface in which this wallpaper is drawn.
*/
public SurfaceHolder getSurfaceHolder() {
return mSurfaceHolder;
}
/**
* Convenience for {@link WallpaperManager#getDesiredMinimumWidth()
* WallpaperManager.getDesiredMinimumWidth()}, returning the width
@@ -419,7 +419,7 @@ public abstract class WallpaperService extends Service {
public int getDesiredMinimumWidth() {
return mIWallpaperEngine.mReqWidth;
}
/**
* Convenience for {@link WallpaperManager#getDesiredMinimumHeight()
* WallpaperManager.getDesiredMinimumHeight()}, returning the height
@@ -437,7 +437,7 @@ public abstract class WallpaperService extends Service {
public boolean isVisible() {
return mReportedVisible;
}
/**
* Returns true if this engine is running in preview mode -- that is,
* it is being shown to the user before they select it as the actual
@@ -456,7 +456,7 @@ public abstract class WallpaperService extends Service {
public boolean isInAmbientMode() {
return mIsInAmbientMode;
}
/**
* Control whether this wallpaper will receive raw touch events
* from the window manager as the user interacts with the window
@@ -557,7 +557,7 @@ public abstract class WallpaperService extends Service {
* {@link WallpaperManager#sendWallpaperCommand}.
* The default implementation does nothing, and always returns null
* as the result.
*
*
* @param action The name of the command to perform. This tells you
* what to do and how to interpret the rest of the arguments.
* @param x Generic integer parameter.
@@ -794,7 +794,7 @@ public abstract class WallpaperService extends Service {
}
mLayout.format = mFormat;
mCurWindowFlags = mWindowFlags;
mLayout.flags = mWindowFlags
| WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS
@@ -1020,7 +1020,7 @@ public abstract class WallpaperService extends Service {
mIsCreating = false;
mSurfaceCreated = true;
if (redrawNeeded) {
mSession.finishDrawing(mWindow);
mSession.finishDrawing(mWindow, null /* postDrawTransaction */);
}
mIWallpaperEngine.reportShown();
}
@@ -1045,7 +1045,7 @@ public abstract class WallpaperService extends Service {
mSurfaceHolder.setSizeFromLayout();
mInitializing = true;
mSession = WindowManagerGlobal.getWindowSession();
mWindow.setSession(mSession);
mLayout.packageName = getPackageName();
@@ -1149,7 +1149,7 @@ public abstract class WallpaperService extends Service {
}
}
}
void doOffsetsChanged(boolean always) {
if (mDestroyed) {
return;
@@ -1187,7 +1187,7 @@ public abstract class WallpaperService extends Service {
mOffsetsChanged = true;
}
}
if (sync) {
try {
if (DEBUG) Log.v(TAG, "Reporting offsets change complete");
@@ -1196,7 +1196,7 @@ public abstract class WallpaperService extends Service {
}
}
}
void doCommand(WallpaperCommand cmd) {
Bundle result;
if (!mDestroyed) {
@@ -1213,7 +1213,7 @@ public abstract class WallpaperService extends Service {
}
}
}
void reportSurfaceDestroyed() {
if (mSurfaceCreated) {
mSurfaceCreated = false;
@@ -1229,12 +1229,12 @@ public abstract class WallpaperService extends Service {
onSurfaceDestroyed(mSurfaceHolder);
}
}
void detach() {
if (mDestroyed) {
return;
}
mDestroyed = true;
if (mIWallpaperEngine.mDisplayManager != null) {
@@ -1246,9 +1246,9 @@ public abstract class WallpaperService extends Service {
if (DEBUG) Log.v(TAG, "onVisibilityChanged(false): " + this);
onVisibilityChanged(false);
}
reportSurfaceDestroyed();
if (DEBUG) Log.v(TAG, "onDestroy(): " + this);
onDestroy();
@@ -1256,18 +1256,18 @@ public abstract class WallpaperService extends Service {
try {
if (DEBUG) Log.v(TAG, "Removing window and destroying surface "
+ mSurfaceHolder.getSurface() + " of: " + this);
if (mInputEventReceiver != null) {
mInputEventReceiver.dispose();
mInputEventReceiver = null;
}
mSession.remove(mWindow);
} catch (RemoteException e) {
}
mSurfaceHolder.mSurface.release();
mCreated = false;
// Dispose the input channel after removing the window so the Window Manager
// doesn't interpret the input channel being closed as an abnormal termination.
if (mInputChannel != null) {

View File

@@ -2,15 +2,15 @@
**
** Copyright 2006, 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
** 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
** 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.
** 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.
*/
@@ -31,6 +31,7 @@ import android.view.WindowManager;
import android.view.InsetsState;
import android.view.Surface;
import android.view.SurfaceControl;
import android.view.Transaction;
import java.util.List;
@@ -57,7 +58,7 @@ interface IWindowSession {
* position should be ignored) and surface of the window. The surface
* will be invalid if the window is currently hidden, else you can use it
* to draw the window's contents.
*
*
* @param window The window being modified.
* @param seq Ordering sequence number.
* @param attrs If non-null, new attributes to apply to the window.
@@ -147,8 +148,15 @@ interface IWindowSession {
*/
void getDisplayFrame(IWindow window, out Rect outDisplayFrame);
/**
* Called when the client has finished drawing the surface, if needed.
*
* @param postDrawTransaction transaction filled by the client that can be
* used to synchronize any post draw transactions with the server. Transaction
* is null if there is no sync required.
*/
@UnsupportedAppUsage
void finishDrawing(IWindow window);
void finishDrawing(IWindow window, in Transaction postDrawTransaction);
@UnsupportedAppUsage
void setInTouchMode(boolean showFocus);

View File

@@ -2693,6 +2693,14 @@ public final class SurfaceControl implements Parcelable {
return this;
}
/**
* Writes the transaction to parcel, clearing the transaction as if it had been applied so
* it can be used to store future transactions. It's the responsibility of the parcel
* reader to apply the original transaction.
*
* @param dest parcel to write the transaction to
* @param flags
*/
@Override
public void writeToParcel(@NonNull Parcel dest, @WriteFlags int flags) {
if (mNativeObject == 0) {

View File

@@ -98,7 +98,8 @@ import java.util.concurrent.locks.ReentrantLock;
* artifacts may occur on previous versions of the platform when its window is
* positioned asynchronously.</p>
*/
public class SurfaceView extends View implements ViewRootImpl.WindowStoppedCallback {
public class SurfaceView extends View
implements ViewRootImpl.WindowStoppedCallback, ViewRootImpl.SurfaceChangedCallback {
private static final String TAG = "SurfaceView";
private static final boolean DEBUG = false;
@@ -120,7 +121,7 @@ public class SurfaceView extends View implements ViewRootImpl.WindowStoppedCallb
boolean mDrawFinished = false;
final Rect mScreenRect = new Rect();
SurfaceSession mSurfaceSession;
final SurfaceSession mSurfaceSession = new SurfaceSession();
SurfaceControl mSurfaceControl;
// In the case of format changes we switch out the surface in-place
@@ -266,11 +267,22 @@ public class SurfaceView extends View implements ViewRootImpl.WindowStoppedCallb
updateSurface();
}
/** @hide */
@Override
public void surfaceChangedCallback(SurfaceControl.Transaction transaction) {
if (getViewRootImpl() != null && mBackgroundControl != null && mSurfaceControl != null) {
SurfaceControl sc = getViewRootImpl().getSurfaceControl();
transaction.setRelativeLayer(mBackgroundControl, sc, Integer.MIN_VALUE);
transaction.setRelativeLayer(mSurfaceControl, sc, mSubLayer);
}
}
@Override
protected void onAttachedToWindow() {
super.onAttachedToWindow();
getViewRootImpl().addWindowStoppedCallback(this);
getViewRootImpl().addSurfaceChangedCallback(this);
mWindowStopped = false;
mViewVisibility = getVisibility() == VISIBLE;
@@ -356,6 +368,7 @@ public class SurfaceView extends View implements ViewRootImpl.WindowStoppedCallb
// the SurfaceHolder forward, most live wallpapers do it.
if (viewRoot != null) {
viewRoot.removeWindowStoppedCallback(this);
viewRoot.removeSurfaceChangedCallback(this);
}
mAttachedToWindow = false;
@@ -637,21 +650,34 @@ public class SurfaceView extends View implements ViewRootImpl.WindowStoppedCallb
mScreenRect.offset(surfaceInsets.left, surfaceInsets.top);
if (creating) {
viewRoot.createBoundsSurface(mSubLayer);
mSurfaceSession = new SurfaceSession();
mDeferredDestroySurfaceControl = mSurfaceControl;
updateOpaqueFlag();
// SurfaceView hierarchy
// ViewRootImpl surface
// - bounds layer (crops all child surfaces to parent surface insets)
// - SurfaceView surface (drawn relative to ViewRootImpl surface)
// - Background color layer (drawn behind all SurfaceView surfaces)
//
// The bounds layer is used to crop the surface view so it does not draw into
// the parent surface inset region. Since there can be multiple surface views
// below or above the parent surface, one option is to create multiple bounds
// layer for each z order. The other option, the one implement is to create
// a single bounds layer and set z order for each child surface relative to the
// parent surface.
// When creating the surface view, we parent it to the bounds layer and then
// set the relative z order. When the parent surface changes, we have to
// make sure to update the relative z via ViewRootImpl.SurfaceChangedCallback.
final String name = "SurfaceView - " + viewRoot.getTitle().toString();
mSurfaceControl = new SurfaceControl.Builder(mSurfaceSession)
.setName(name)
.setOpaque((mSurfaceFlags & SurfaceControl.OPAQUE) != 0)
.setBufferSize(mSurfaceWidth, mSurfaceHeight)
.setFormat(mFormat)
.setParent(viewRoot.getSurfaceControl())
.setFlags(mSurfaceFlags)
.build();
mSurfaceControl =
new SurfaceControl.Builder(mSurfaceSession)
.setName(name)
.setOpaque((mSurfaceFlags & SurfaceControl.OPAQUE) != 0)
.setBufferSize(mSurfaceWidth, mSurfaceHeight)
.setFormat(mFormat)
.setParent(viewRoot.getBoundsLayer())
.setFlags(mSurfaceFlags)
.build();
mBackgroundControl = new SurfaceControl.Builder(mSurfaceSession)
.setName("Background for -" + name)
.setOpaque(true)
@@ -674,7 +700,7 @@ public class SurfaceView extends View implements ViewRootImpl.WindowStoppedCallb
SurfaceControl.openTransaction();
try {
mSurfaceControl.setLayer(mSubLayer);
mSurfaceControl.setRelativeLayer(viewRoot.getSurfaceControl(), mSubLayer);
if (mViewVisibility) {
mSurfaceControl.show();

View File

@@ -68,6 +68,7 @@ import android.os.Build;
import android.os.Bundle;
import android.os.Debug;
import android.os.Handler;
import android.os.IBinder;
import android.os.Looper;
import android.os.Message;
import android.os.ParcelFileDescriptor;
@@ -476,17 +477,19 @@ public final class ViewRootImpl implements ViewParent,
@UnsupportedAppUsage
public final Surface mSurface = new Surface();
private final SurfaceControl mSurfaceControl = new SurfaceControl();
private IBinder mPreviousSurfaceControlHandle = null;
private final Transaction mChangeSurfaceTransaction = new Transaction();
private final SurfaceSession mSurfaceSession = new SurfaceSession();
/**
* Child surface of {@code mSurface} with the same bounds as its parent, and crop bounds
* are set to the parent's bounds adjusted for surface insets. This surface is created when
* {@link ViewRootImpl#createBoundsSurface(int)} is called.
* By parenting to this bounds surface, child surfaces can ensure they do not draw into the
* surface inset regions set by the parent window.
* Child container layer of {@code mSurface} with the same bounds as its parent, and cropped to
* the surface insets. This surface is created only if a client requests it via {@link
* #getBoundsLayer()}. By parenting to this bounds surface, child surfaces can ensure they do
* not draw into the surface inset regions set by the parent window.
*/
public final Surface mBoundsSurface = new Surface();
private SurfaceSession mSurfaceSession;
private SurfaceControl mBoundsSurfaceControl;
private SurfaceControl mBoundsLayer;
private final Transaction mTransaction = new Transaction();
@UnsupportedAppUsage
@@ -1576,65 +1579,76 @@ public final class ViewRootImpl implements ViewParent,
}
}
/**
* Creates a surface as a child of {@code mSurface} with the same bounds as its parent and
* crop bounds set to the parent's bounds adjusted for surface insets.
*
* @param zOrderLayer Z order relative to the parent surface.
*/
public void createBoundsSurface(int zOrderLayer) {
if (mSurfaceSession == null) {
mSurfaceSession = new SurfaceSession();
}
if (mBoundsSurfaceControl != null && mBoundsSurface.isValid()) {
return; // surface control for bounds surface already exists.
}
/** Register callback to be notified when the ViewRootImpl surface changes. */
interface SurfaceChangedCallback {
void surfaceChangedCallback(SurfaceControl.Transaction transaction);
}
mBoundsSurfaceControl = new SurfaceControl.Builder(mSurfaceSession)
private final ArrayList<SurfaceChangedCallback> mSurfaceChangedCallbacks = new ArrayList<>();
void addSurfaceChangedCallback(SurfaceChangedCallback c) {
mSurfaceChangedCallbacks.add(c);
}
void removeSurfaceChangedCallback(SurfaceChangedCallback c) {
mSurfaceChangedCallbacks.remove(c);
}
private void notifySurfaceChanged(SurfaceControl.Transaction transaction) {
for (int i = 0; i < mSurfaceChangedCallbacks.size(); i++) {
mSurfaceChangedCallbacks.get(i).surfaceChangedCallback(transaction);
}
}
/**
* Returns a child layer with the same bounds as its parent {@code mSurface} and cropped to the
* surface insets. If the layer does not exist, it is created.
*
* <p>Parenting to this layer will ensure that its children are cropped by the view's surface
* insets.
*/
public SurfaceControl getBoundsLayer() {
if (mBoundsLayer == null) {
mBoundsLayer = new SurfaceControl.Builder(mSurfaceSession)
.setContainerLayer()
.setName("Bounds for - " + getTitle().toString())
.setParent(mSurfaceControl)
.build();
setBoundsSurfaceCrop();
mTransaction.setLayer(mBoundsSurfaceControl, zOrderLayer)
.show(mBoundsSurfaceControl)
.apply();
mBoundsSurface.copyFrom(mBoundsSurfaceControl);
setBoundsLayerCrop(mTransaction);
mTransaction.show(mBoundsLayer).apply();
}
return mBoundsLayer;
}
private void setBoundsSurfaceCrop() {
private void setBoundsLayerCrop(Transaction t) {
// mWinFrame is already adjusted for surface insets. So offset it and use it as
// the cropping bounds.
mTempBoundsRect.set(mWinFrame);
mTempBoundsRect.offsetTo(mWindowAttributes.surfaceInsets.left,
mWindowAttributes.surfaceInsets.top);
mTransaction.setWindowCrop(mBoundsSurfaceControl, mTempBoundsRect);
t.setWindowCrop(mBoundsLayer, mTempBoundsRect);
}
/**
* Called after window layout to update the bounds surface. If the surface insets have
* changed or the surface has resized, update the bounds surface.
* Called after window layout to update the bounds surface. If the surface insets have changed
* or the surface has resized, update the bounds surface.
*/
private void updateBoundsSurface() {
if (mBoundsSurfaceControl != null && mSurface.isValid()) {
setBoundsSurfaceCrop();
mTransaction.deferTransactionUntilSurface(mBoundsSurfaceControl,
private void updateBoundsLayer() {
if (mBoundsLayer != null) {
setBoundsLayerCrop(mTransaction);
mTransaction.deferTransactionUntilSurface(mBoundsLayer,
mSurface, mSurface.getNextFrameNumber())
.apply();
}
}
private void destroySurface() {
if (mBoundsLayer != null) {
mBoundsLayer.release();
mBoundsLayer = null;
}
mSurface.release();
mSurfaceControl.release();
mSurfaceSession = null;
if (mBoundsSurfaceControl != null) {
mBoundsSurfaceControl.remove();
mBoundsSurface.release();
mBoundsSurfaceControl = null;
}
}
/**
@@ -2598,7 +2612,7 @@ public final class ViewRootImpl implements ViewParent,
}
if (surfaceSizeChanged) {
updateBoundsSurface();
updateBoundsLayer();
}
final boolean didLayout = layoutRequested && (!mStopped || mReportNextDraw);
@@ -3438,7 +3452,9 @@ public final class ViewRootImpl implements ViewParent,
private void reportDrawFinished() {
try {
mDrawsNeededToReport = 0;
mWindowSession.finishDrawing(mWindow);
if (mSurfaceControl.isValid()) {
mWindowSession.finishDrawing(mWindow, mChangeSurfaceTransaction);
}
} catch (RemoteException e) {
// Have fun!
}
@@ -7089,6 +7105,9 @@ public final class ViewRootImpl implements ViewParent,
frameNumber = mSurface.getNextFrameNumber();
}
mPreviousSurfaceControlHandle = mSurfaceControl.isValid()
? mSurfaceControl.getHandle() : null;
int relayoutResult = mWindowSession.relayout(mWindow, mSeq, params,
(int) (mView.getMeasuredWidth() * appScale + 0.5f),
(int) (mView.getMeasuredHeight() * appScale + 0.5f), viewVisibility,
@@ -7102,6 +7121,11 @@ public final class ViewRootImpl implements ViewParent,
destroySurface();
}
if (mPreviousSurfaceControlHandle != null && mSurfaceControl.isValid()
&& mPreviousSurfaceControlHandle != mSurfaceControl.getHandle()) {
notifySurfaceChanged(mChangeSurfaceTransaction);
}
mPendingAlwaysConsumeSystemBars =
(relayoutResult & WindowManagerGlobal.RELAYOUT_RES_CONSUME_ALWAYS_SYSTEM_BARS) != 0;
@@ -7326,7 +7350,8 @@ public final class ViewRootImpl implements ViewParent,
try {
if ((relayoutWindow(mWindowAttributes, viewVisibility, false)
& WindowManagerGlobal.RELAYOUT_RES_FIRST_TIME) != 0) {
mWindowSession.finishDrawing(mWindow);
mWindowSession.finishDrawing(
mWindow, null /* postDrawTransaction */);
}
} catch (RemoteException e) {
}

View File

@@ -49,7 +49,7 @@ public class BaseIWindow extends IWindow.Stub {
DisplayCutout.ParcelableWrapper displayCutout) {
if (reportDraw) {
try {
mSession.finishDrawing(this);
mSession.finishDrawing(this, null /* postDrawTransaction */);
} catch (RemoteException e) {
}
}

View File

@@ -1266,6 +1266,7 @@ static void nativeWriteTransactionToParcel(JNIEnv* env, jclass clazz, jlong nati
reinterpret_cast<SurfaceComposerClient::Transaction *>(nativeObject);
if (self != nullptr) {
self->writeToParcel(parcel);
self->clear();
}
}

View File

@@ -28,6 +28,7 @@ import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_TASK_POSITION
import static com.android.server.wm.WindowManagerDebugConfig.SHOW_TRANSACTIONS;
import static com.android.server.wm.WindowManagerDebugConfig.TAG_WM;
import android.annotation.Nullable;
import android.content.ClipData;
import android.graphics.Rect;
import android.graphics.Region;
@@ -225,10 +226,11 @@ class Session extends IWindowSession.Stub implements IBinder.DeathRecipient {
}
@Override
public void finishDrawing(IWindow window) {
public void finishDrawing(IWindow window,
@Nullable SurfaceControl.Transaction postDrawTransaction) {
if (WindowManagerService.localLOGV) Slog.v(
TAG_WM, "IWindow finishDrawing called for " + window);
mService.finishDrawingWindow(this, window);
mService.finishDrawingWindow(this, window, postDrawTransaction);
}
@Override

View File

@@ -418,7 +418,7 @@ class TaskSnapshotSurface implements StartingSurface {
private void reportDrawn() {
try {
mSession.finishDrawing(mWindow);
mSession.finishDrawing(mWindow, null /* postDrawTransaction */);
} catch (RemoteException e) {
// Local call.
}

View File

@@ -2356,14 +2356,15 @@ public class WindowManagerService extends IWindowManager.Stub
}
}
void finishDrawingWindow(Session session, IWindow client) {
void finishDrawingWindow(Session session, IWindow client,
@Nullable SurfaceControl.Transaction postDrawTransaction) {
final long origId = Binder.clearCallingIdentity();
try {
synchronized (mGlobalLock) {
WindowState win = windowForClientLocked(session, client, false);
if (DEBUG_ADD_REMOVE) Slog.d(TAG_WM, "finishDrawingWindow: " + win + " mDrawState="
+ (win != null ? win.mWinAnimator.drawStateToString() : "null"));
if (win != null && win.mWinAnimator.finishDrawingLocked()) {
if (win != null && win.mWinAnimator.finishDrawingLocked(postDrawTransaction)) {
if ((win.mAttrs.flags & FLAG_SHOW_WALLPAPER) != 0) {
win.getDisplayContent().pendingLayoutChanges |=
WindowManagerPolicy.FINISH_LAYOUT_REDO_WALLPAPER;

View File

@@ -220,7 +220,16 @@ class WindowStateAnimator {
private final Rect mTmpSize = new Rect();
private final SurfaceControl.Transaction mReparentTransaction = new SurfaceControl.Transaction();
/**
* Handles surface changes synchronized to after the client has drawn the surface. This
* transaction is currently used to reparent the old surface children to the new surface once
* the client has completed drawing to the new surface.
* This transaction is also used to merge transactions parceled in by the client. The client
* uses the transaction to update the relative z of its children from the old parent surface
* to the new parent surface once window manager reparents its children.
*/
private final SurfaceControl.Transaction mPostDrawTransaction =
new SurfaceControl.Transaction();
// Used to track whether we have called detach children on the way to invisibility, in which
// case we need to give the client a new Surface if it lays back out to a visible state.
@@ -301,7 +310,7 @@ class WindowStateAnimator {
SurfaceControl.mergeToGlobalTransaction(mTmpTransaction);
}
boolean finishDrawingLocked() {
boolean finishDrawingLocked(SurfaceControl.Transaction postDrawTransaction) {
final boolean startingWindow =
mWin.mAttrs.type == WindowManager.LayoutParams.TYPE_APPLICATION_STARTING;
if (DEBUG_STARTING_WINDOW && startingWindow) {
@@ -321,6 +330,9 @@ class WindowStateAnimator {
mDrawState = COMMIT_DRAW_PENDING;
layoutNeeded = true;
}
if (postDrawTransaction != null) {
mPostDrawTransaction.merge(postDrawTransaction);
}
return layoutNeeded;
}
@@ -385,7 +397,7 @@ class WindowStateAnimator {
// child layers need to be reparented to the new surface to make this
// transparent to the app.
if (mWin.mAppToken == null || mWin.mAppToken.isRelaunching() == false) {
mReparentTransaction.reparentChildren(mPendingDestroySurface.mSurfaceControl,
mPostDrawTransaction.reparentChildren(mPendingDestroySurface.mSurfaceControl,
mSurfaceController.mSurfaceControl.getHandle())
.apply();
}
@@ -1150,7 +1162,7 @@ class WindowStateAnimator {
// LogicalDisplay.
mAnimator.setPendingLayoutChanges(w.getDisplayId(),
FINISH_LAYOUT_REDO_ANIM);
if (DEBUG_LAYOUT_REPEATS) {
if (DEBUG_LAYOUT_REPEATS) {
mService.mWindowPlacerLocked.debugLayoutRepeats(
"showSurfaceRobustlyLocked " + w,
mAnimator.getPendingLayoutChanges(w.getDisplayId()));
@@ -1281,10 +1293,13 @@ class WindowStateAnimator {
// If we had a preserved surface it's no longer needed, and it may be harmful
// if we are transparent.
if (mPendingDestroySurface != null && mDestroyPreservedSurfaceUponRedraw) {
mPendingDestroySurface.mSurfaceControl.hide();
mPendingDestroySurface.reparentChildrenInTransaction(mSurfaceController);
final SurfaceControl pendingSurfaceControl = mPendingDestroySurface.mSurfaceControl;
mPostDrawTransaction.hide(pendingSurfaceControl);
mPostDrawTransaction.reparentChildren(pendingSurfaceControl,
mSurfaceController.getHandle());
}
mPostDrawTransaction.apply();
return true;
}