blob: 8ab17950f4fc4d9a067b708deb27f00ef6287efc [file] [log] [blame]
/*
* Copyright (C) 2011 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
*
* 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.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.android.server.wm;
import static com.android.server.wm.ProtoLogGroup.WM_SHOW_SURFACE_ALLOC;
import android.graphics.Rect;
import android.view.Surface.OutOfResourcesException;
import android.view.SurfaceControl;
import com.android.server.protolog.common.ProtoLog;
import java.io.PrintWriter;
import java.util.function.Supplier;
/**
* Four black surfaces put together to make a black frame.
*/
public class BlackFrame {
static class BlackSurface {
final int left;
final int top;
final int layer;
final SurfaceControl surface;
BlackSurface(SurfaceControl.Transaction transaction, int layer,
int l, int t, int r, int b, DisplayContent dc,
SurfaceControl surfaceControl) throws OutOfResourcesException {
left = l;
top = t;
this.layer = layer;
int w = r-l;
int h = b-t;
surface = dc.makeOverlay()
.setName("BlackSurface")
.setColorLayer()
.setParent(surfaceControl)
.build();
transaction.setWindowCrop(surface, w, h);
transaction.setAlpha(surface, 1);
transaction.setLayer(surface, layer);
transaction.setPosition(surface, left, top);
transaction.show(surface);
ProtoLog.i(WM_SHOW_SURFACE_ALLOC,
" BLACK %s: CREATE layer=%d", surface, layer);
}
}
private final Rect mOuterRect;
private final Rect mInnerRect;
private final BlackSurface[] mBlackSurfaces = new BlackSurface[4];
private final Supplier<SurfaceControl.Transaction> mTransactionFactory;
public void printTo(String prefix, PrintWriter pw) {
pw.print(prefix); pw.print("Outer: "); mOuterRect.printShortString(pw);
pw.print(" / Inner: "); mInnerRect.printShortString(pw);
pw.println();
for (int i=0; i<mBlackSurfaces.length; i++) {
BlackSurface bs = mBlackSurfaces[i];
pw.print(prefix); pw.print("#"); pw.print(i);
pw.print(": "); pw.print(bs.surface);
pw.print(" left="); pw.print(bs.left);
pw.print(" top="); pw.println(bs.top);
}
}
public BlackFrame(Supplier<SurfaceControl.Transaction> factory, SurfaceControl.Transaction t,
Rect outer, Rect inner, int layer, DisplayContent dc, boolean forceDefaultOrientation,
SurfaceControl surfaceControl)
throws OutOfResourcesException {
boolean success = false;
mTransactionFactory = factory;
// TODO: Why do we use 4 surfaces instead of just one big one behind the screenshot?
// b/68253229
mOuterRect = new Rect(outer);
mInnerRect = new Rect(inner);
try {
if (outer.top < inner.top) {
mBlackSurfaces[0] = new BlackSurface(t, layer,
outer.left, outer.top, inner.right, inner.top, dc, surfaceControl);
}
if (outer.left < inner.left) {
mBlackSurfaces[1] = new BlackSurface(t, layer,
outer.left, inner.top, inner.left, outer.bottom, dc, surfaceControl);
}
if (outer.bottom > inner.bottom) {
mBlackSurfaces[2] = new BlackSurface(t, layer,
inner.left, inner.bottom, outer.right, outer.bottom, dc,
surfaceControl);
}
if (outer.right > inner.right) {
mBlackSurfaces[3] = new BlackSurface(t, layer,
inner.right, outer.top, outer.right, inner.bottom, dc, surfaceControl);
}
success = true;
} finally {
if (!success) {
kill();
}
}
}
public void kill() {
SurfaceControl.Transaction t = mTransactionFactory.get();
for (int i = 0; i < mBlackSurfaces.length; i++) {
if (mBlackSurfaces[i] != null) {
ProtoLog.i(WM_SHOW_SURFACE_ALLOC, " BLACK %s: DESTROY", mBlackSurfaces[i].surface);
t.remove(mBlackSurfaces[i].surface);
mBlackSurfaces[i] = null;
}
}
t.apply();
}
}