package com.android.server.wm;
import static android.view.SurfaceControl.HIDDEN;
import android.graphics.Rect;
import android.view.SurfaceControl;
import java.util.function.Supplier;
public class Letterbox {
private static final Rect EMPTY_RECT = new Rect();
private final SuppliermFactory;
private final Rect mOuter = new Rect();
private final Rect mInner = new Rect();
private final LetterboxSurface mTop = new LetterboxSurface("top");
private final LetterboxSurface mLeft = new LetterboxSurface("left");
private final LetterboxSurface mBottom = new LetterboxSurface("bottom");
private final LetterboxSurface mRight = new LetterboxSurface("right");
public Letterbox(SuppliersurfaceControlFactory) {
mFactory = surfaceControlFactory;
}
public void layout(Rect outer, Rect inner) {
mOuter.set(outer);
mInner.set(inner);
mTop.layout(outer.left, outer.top, inner.right, inner.top);
mLeft.layout(outer.left, inner.top, inner.left, outer.bottom);
mBottom.layout(inner.left, inner.bottom, outer.right, outer.bottom);
mRight.layout(inner.right, outer.top, outer.right, inner.bottom);
}
public Rect getInsets() {
return new Rect(
mLeft.getWidth(),
mTop.getHeight(),
mRight.getWidth(),
mBottom.getHeight());
}
public boolean isOverlappingWith(Rect rect) {
return mTop.isOverlappingWith(rect) || mLeft.isOverlappingWith(rect)
|| mBottom.isOverlappingWith(rect) || mRight.isOverlappingWith(rect);
}
public void hide() {
layout(EMPTY_RECT, EMPTY_RECT);
}
public void destroy() {
mOuter.setEmpty();
mInner.setEmpty();
mTop.destroy();
mLeft.destroy();
mBottom.destroy();
mRight.destroy();
}
public boolean needsApplySurfaceChanges() {
return mTop.needsApplySurfaceChanges()
|| mLeft.needsApplySurfaceChanges()
|| mBottom.needsApplySurfaceChanges()
|| mRight.needsApplySurfaceChanges();
}
public void applySurfaceChanges(SurfaceControl.Transaction t) {
mTop.applySurfaceChanges(t);
mLeft.applySurfaceChanges(t);
mBottom.applySurfaceChanges(t);
mRight.applySurfaceChanges(t);
}
private class LetterboxSurface {
private final String mType;
private SurfaceControl mSurface;
private final Rect mSurfaceFrame = new Rect();
private final Rect mLayoutFrame = new Rect();
public LetterboxSurface(String type) {
mType = type;
}
public void layout(int left, int top, int right, int bottom) {
if (mLayoutFrame.left == left && mLayoutFrame.top == top
&& mLayoutFrame.right == right && mLayoutFrame.bottom == bottom) {
// Nothing changed.
return;
}
mLayoutFrame.set(left, top, right, bottom);
}
private void createSurface() {
mSurface = mFactory.get().setName("Letterbox - " + mType)
.setFlags(HIDDEN).setColorLayer(true).build();
mSurface.setLayer(-1);
mSurface.setColor(new float[]{0, 0, 0});
}
public void destroy() {
if (mSurface != null) {
mSurface.destroy();
mSurface = null;
}
}
public int getWidth() {
return Math.max(0, mLayoutFrame.width());
}
public int getHeight() {
return Math.max(0, mLayoutFrame.height());
}
public boolean isOverlappingWith(Rect rect) {
if (getWidth() <= 0 || getHeight() <= 0) {
return false;
}
return Rect.intersects(rect, mLayoutFrame);
}
public void applySurfaceChanges(SurfaceControl.Transaction t) {
if (mSurfaceFrame.equals(mLayoutFrame)) {
// Nothing changed.
return;
}
mSurfaceFrame.set(mLayoutFrame);
if (!mSurfaceFrame.isEmpty()) {
if (mSurface == null) {
createSurface();
}
t.setPosition(mSurface, mSurfaceFrame.left, mSurfaceFrame.top);
t.setSize(mSurface, mSurfaceFrame.width(), mSurfaceFrame.height());
t.show(mSurface);
} else if (mSurface != null) {
t.hide(mSurface);
}
}
public boolean needsApplySurfaceChanges() {
return !mSurfaceFrame.equals(mLayoutFrame);
}
}
}
Java程式
|
201行
|
6.49 KB
package com.android.server.wm;
import static android.view.SurfaceControl.HIDDEN;
import android.graphics.Rect;
import android.view.SurfaceControl;
import java.util.function.Supplier;
public class Letterbox {
private static final Rect EMPTY_RECT = new Rect();
private final Supplier mFactory;
private final Rect mOuter = new Rect();
private final Rect mInner = new Rect();
private final LetterboxSurface mTop = new LetterboxSurface("top");
private final LetterboxSurface mLeft = new LetterboxSurface("left");
private final LetterboxSurface mBottom = new LetterboxSurface("bottom");
private final LetterboxSurface mRight = new LetterboxSurface("right");
public Letterbox(Supplier surfaceControlFactory) {
mFactory = surfaceControlFactory;
}
public void layout(Rect outer, Rect inner) {
mOuter.set(outer);
mInner.set(inner);
mTop.layout(outer.left, outer.top, inner.right, inner.top);
mLeft.layout(outer.left, inner.top, inner.left, outer.bottom);
mBottom.layout(inner.left, inner.bottom, outer.right, outer.bottom);
mRight.layout(inner.right, outer.top, outer.right, inner.bottom);
}
public Rect getInsets() {
return new Rect(
mLeft.getWidth(),
mTop.getHeight(),
mRight.getWidth(),
mBottom.getHeight());
}
public boolean isOverlappingWith(Rect rect) {
return mTop.isOverlappingWith(rect) || mLeft.isOverlappingWith(rect)
|| mBottom.isOverlappingWith(rect) || mRight.isOverlappingWith(rect);
}
public void hide() {
layout(EMPTY_RECT, EMPTY_RECT);
}
public void destroy() {
mOuter.setEmpty();
mInner.setEmpty();
mTop.destroy();
mLeft.destroy();
mBottom.destroy();
mRight.destroy();
}
public boolean needsApplySurfaceChanges() {
return mTop.needsApplySurfaceChanges()
|| mLeft.needsApplySurfaceChanges()
|| mBottom.needsApplySurfaceChanges()
|| mRight.needsApplySurfaceChanges();
}
public void applySurfaceChanges(SurfaceControl.Transaction t) {
mTop.applySurfaceChanges(t);
mLeft.applySurfaceChanges(t);
mBottom.applySurfaceChanges(t);
mRight.applySurfaceChanges(t);
}
private class LetterboxSurface {
private final String mType;
private SurfaceControl mSurface;
private final Rect mSurfaceFrame = new Rect();
private final Rect mLayoutFrame = new Rect();
public LetterboxSurface(String type) {
mType = type;
}
public void layout(int left, int top, int right, int bottom) {
if (mLayoutFrame.left == left && mLayoutFrame.top == top
&& mLayoutFrame.right == right && mLayoutFrame.bottom == bottom) {
// Nothing changed.
return;
}
mLayoutFrame.set(left, top, right, bottom);
}
private void createSurface() {
mSurface = mFactory.get().setName("Letterbox - " + mType)
.setFlags(HIDDEN).setColorLayer(true).build();
mSurface.setLayer(-1);
mSurface.setColor(new float[]{0, 0, 0});
}
public void destroy() {
if (mSurface != null) {
mSurface.destroy();
mSurface = null;
}
}
public int getWidth() {
return Math.max(0, mLayoutFrame.width());
}
public int getHeight() {
return Math.max(0, mLayoutFrame.height());
}
public boolean isOverlappingWith(Rect rect) {
if (getWidth() <= 0 || getHeight() <= 0) {
return false;
}
return Rect.intersects(rect, mLayoutFrame);
}
public void applySurfaceChanges(SurfaceControl.Transaction t) {
if (mSurfaceFrame.equals(mLayoutFrame)) {
// Nothing changed.
return;
}
mSurfaceFrame.set(mLayoutFrame);
if (!mSurfaceFrame.isEmpty()) {
if (mSurface == null) {
createSurface();
}
t.setPosition(mSurface, mSurfaceFrame.left, mSurfaceFrame.top);
t.setSize(mSurface, mSurfaceFrame.width(), mSurfaceFrame.height());
t.show(mSurface);
} else if (mSurface != null) {
t.hide(mSurface);
}
}
public boolean needsApplySurfaceChanges() {
return !mSurfaceFrame.equals(mLayoutFrame);
}
}
}