Auto show-hide overlay window if only privacy dot
When only privacy dot on ScreenDecorations w/o rounded corners or cutout, enable auto show-hide for overlay window when privacy dot visibility changed. Bug: 216623905 Test: atest ScreenDecorationsTest PrivacyDotDecorProviderFactoryTest Change-Id: Ife0a6afecd366fe2dd9e3ce63bcb0f224c6010d9
This commit is contained in:
@@ -200,49 +200,45 @@ public class ScreenDecorations extends CoreStartable implements Tunable , Dumpab
|
||||
}
|
||||
};
|
||||
|
||||
private PrivacyDotViewController.ShowingListener mPrivacyDotShowingListener =
|
||||
@VisibleForTesting
|
||||
PrivacyDotViewController.ShowingListener mPrivacyDotShowingListener =
|
||||
new PrivacyDotViewController.ShowingListener() {
|
||||
@Override
|
||||
public void onPrivacyDotShown(@Nullable View v) {
|
||||
// We don't need to control the window visibility when the hwc doesn't support screen
|
||||
// decoration since the overlay windows are always visible in this case.
|
||||
if (mHwcScreenDecorationSupport == null || v == null) {
|
||||
return;
|
||||
}
|
||||
mExecutor.execute(() -> {
|
||||
for (int i = 0; i < BOUNDS_POSITION_LENGTH; i++) {
|
||||
if (mOverlays[i] == null) {
|
||||
continue;
|
||||
}
|
||||
final ViewGroup overlayView = mOverlays[i].getRootView();
|
||||
if (overlayView.findViewById(v.getId()) != null) {
|
||||
overlayView.setVisibility(View.VISIBLE);
|
||||
}
|
||||
}
|
||||
});
|
||||
setOverlayWindowVisibilityIfViewExist(v, View.VISIBLE);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onPrivacyDotHidden(@Nullable View v) {
|
||||
// We don't need to control the window visibility when the hwc doesn't support screen
|
||||
// decoration since the overlay windows are always visible in this case.
|
||||
if (mHwcScreenDecorationSupport == null || v == null) {
|
||||
return;
|
||||
}
|
||||
mExecutor.execute(() -> {
|
||||
for (int i = 0; i < BOUNDS_POSITION_LENGTH; i++) {
|
||||
if (mOverlays[i] == null) {
|
||||
continue;
|
||||
}
|
||||
final ViewGroup overlayView = mOverlays[i].getRootView();
|
||||
if (overlayView.findViewById(v.getId()) != null) {
|
||||
overlayView.setVisibility(View.INVISIBLE);
|
||||
}
|
||||
}
|
||||
});
|
||||
setOverlayWindowVisibilityIfViewExist(v, View.INVISIBLE);
|
||||
}
|
||||
};
|
||||
|
||||
@VisibleForTesting
|
||||
protected void setOverlayWindowVisibilityIfViewExist(@Nullable View view,
|
||||
@View.Visibility int visibility) {
|
||||
if (view == null) {
|
||||
return;
|
||||
}
|
||||
mExecutor.execute(() -> {
|
||||
// We don't need to control the window visibility if rounded corners or cutout is drawn
|
||||
// on sw layer since the overlay windows are always visible in this case.
|
||||
if (mOverlays == null || !isOnlyPrivacyDotInSwLayer()) {
|
||||
return;
|
||||
}
|
||||
|
||||
for (final OverlayWindow overlay : mOverlays) {
|
||||
if (overlay == null) {
|
||||
continue;
|
||||
}
|
||||
if (overlay.getView(view.getId()) != null) {
|
||||
overlay.getRootView().setVisibility(visibility);
|
||||
return;
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private static boolean eq(DisplayDecorationSupport a, DisplayDecorationSupport b) {
|
||||
if (a == null) return (b == null);
|
||||
if (b == null) return false;
|
||||
@@ -268,7 +264,6 @@ public class ScreenDecorations extends CoreStartable implements Tunable , Dumpab
|
||||
mDotViewController = dotViewController;
|
||||
mThreadFactory = threadFactory;
|
||||
mDotFactory = dotFactory;
|
||||
dotViewController.setShowingListener(mPrivacyDotShowingListener);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -425,18 +420,24 @@ public class ScreenDecorations extends CoreStartable implements Tunable , Dumpab
|
||||
removeHwcOverlay();
|
||||
}
|
||||
final DisplayCutout cutout = getCutout();
|
||||
final boolean isOnlyPrivacyDotInSwLayer = isOnlyPrivacyDotInSwLayer();
|
||||
for (int i = 0; i < BOUNDS_POSITION_LENGTH; i++) {
|
||||
if (shouldShowCutout(i, cutout) || shouldShowRoundedCorner(i, cutout)
|
||||
|| shouldShowPrivacyDot(i, cutout)) {
|
||||
if (shouldShowSwLayerCutout(i, cutout) || shouldShowSwLayerRoundedCorner(i, cutout)
|
||||
|| shouldShowSwLayerPrivacyDot(i, cutout)) {
|
||||
Pair<List<DecorProvider>, List<DecorProvider>> pair =
|
||||
DecorProviderKt.partitionAlignedBound(decorProviders, i);
|
||||
decorProviders = pair.getSecond();
|
||||
createOverlay(i, cutout, pair.getFirst());
|
||||
createOverlay(i, cutout, pair.getFirst(), isOnlyPrivacyDotInSwLayer);
|
||||
} else {
|
||||
removeOverlay(i);
|
||||
}
|
||||
}
|
||||
|
||||
if (isOnlyPrivacyDotInSwLayer) {
|
||||
mDotViewController.setShowingListener(mPrivacyDotShowingListener);
|
||||
} else {
|
||||
mDotViewController.setShowingListener(null);
|
||||
}
|
||||
final View tl, tr, bl, br;
|
||||
if ((tl = getOverlayView(R.id.privacy_dot_top_left_container)) != null
|
||||
&& (tr = getOverlayView(R.id.privacy_dot_top_right_container)) != null
|
||||
@@ -530,19 +531,51 @@ public class ScreenDecorations extends CoreStartable implements Tunable , Dumpab
|
||||
mOverlays[pos] = null;
|
||||
}
|
||||
|
||||
@View.Visibility
|
||||
private int getWindowVisibility(@NonNull OverlayWindow overlay,
|
||||
boolean isOnlyPrivacyDotInSwLayer) {
|
||||
if (!isOnlyPrivacyDotInSwLayer) {
|
||||
// Multiple views inside overlay, no need to optimize
|
||||
return View.VISIBLE;
|
||||
}
|
||||
|
||||
int[] ids = {
|
||||
R.id.privacy_dot_top_left_container,
|
||||
R.id.privacy_dot_top_right_container,
|
||||
R.id.privacy_dot_bottom_left_container,
|
||||
R.id.privacy_dot_bottom_right_container
|
||||
};
|
||||
for (int id: ids) {
|
||||
final View view = overlay.getView(id);
|
||||
if (view != null && view.getVisibility() == View.VISIBLE) {
|
||||
// Only privacy dot in sw layers, overlay shall be VISIBLE if one of privacy dot
|
||||
// views inside this overlay is VISIBLE
|
||||
return View.VISIBLE;
|
||||
}
|
||||
}
|
||||
// Only privacy dot in sw layers, overlay shall be INVISIBLE like default if no privacy dot
|
||||
// view inside this overlay is VISIBLE.
|
||||
return View.INVISIBLE;
|
||||
}
|
||||
|
||||
private void createOverlay(
|
||||
@BoundsPosition int pos,
|
||||
@Nullable DisplayCutout cutout,
|
||||
@NonNull List<DecorProvider> decorProviders) {
|
||||
@NonNull List<DecorProvider> decorProviders,
|
||||
boolean isOnlyPrivacyDotInSwLayer) {
|
||||
if (mOverlays == null) {
|
||||
mOverlays = new OverlayWindow[BOUNDS_POSITION_LENGTH];
|
||||
}
|
||||
|
||||
if (mOverlays[pos] != null) {
|
||||
// When mOverlay[pos] is not null and only privacy dot in sw layer, use privacy dot
|
||||
// view's visibility
|
||||
mOverlays[pos].getRootView().setVisibility(
|
||||
getWindowVisibility(mOverlays[pos], isOnlyPrivacyDotInSwLayer));
|
||||
return;
|
||||
}
|
||||
|
||||
mOverlays[pos] = overlayForPosition(pos, decorProviders);
|
||||
mOverlays[pos] = overlayForPosition(pos, decorProviders, isOnlyPrivacyDotInSwLayer);
|
||||
final ViewGroup overlayView = mOverlays[pos].getRootView();
|
||||
overlayView.setSystemUiVisibility(View.SYSTEM_UI_FLAG_LAYOUT_STABLE);
|
||||
overlayView.setAlpha(0);
|
||||
@@ -612,18 +645,18 @@ public class ScreenDecorations extends CoreStartable implements Tunable , Dumpab
|
||||
*/
|
||||
private OverlayWindow overlayForPosition(
|
||||
@BoundsPosition int pos,
|
||||
@NonNull List<DecorProvider> decorProviders) {
|
||||
@NonNull List<DecorProvider> decorProviders,
|
||||
boolean isOnlyPrivacyDotInSwLayer) {
|
||||
final OverlayWindow currentOverlay = new OverlayWindow(LayoutInflater.from(mContext), pos);
|
||||
decorProviders.forEach(provider -> {
|
||||
removeOverlayView(provider.getViewId());
|
||||
currentOverlay.addDecorProvider(provider, mRotation);
|
||||
// If the hwc supports screen decoration and privacy dot is enabled, it means there will
|
||||
// be only privacy dot in mOverlay. So set the initial visibility of mOverlays to
|
||||
// INVISIBLE and will only set it to VISIBLE when the privacy dot is showing.
|
||||
if (mHwcScreenDecorationSupport != null) {
|
||||
currentOverlay.getRootView().setVisibility(View.INVISIBLE);
|
||||
}
|
||||
});
|
||||
// When only privacy dot in mOverlay, set the initial visibility of mOverlays to
|
||||
// INVISIBLE and set it to VISIBLE when the privacy dot is showing.
|
||||
if (isOnlyPrivacyDotInSwLayer) {
|
||||
currentOverlay.getRootView().setVisibility(View.INVISIBLE);
|
||||
}
|
||||
return currentOverlay;
|
||||
}
|
||||
|
||||
@@ -842,6 +875,7 @@ public class ScreenDecorations extends CoreStartable implements Tunable , Dumpab
|
||||
pw.println("ScreenDecorations state:");
|
||||
pw.println(" DEBUG_DISABLE_SCREEN_DECORATIONS:" + DEBUG_DISABLE_SCREEN_DECORATIONS);
|
||||
pw.println(" mIsPrivacyDotEnabled:" + isPrivacyDotEnabled());
|
||||
pw.println(" isOnlyPrivacyDotInSwLayer:" + isOnlyPrivacyDotInSwLayer());
|
||||
pw.println(" mPendingRotationChange:" + mPendingRotationChange);
|
||||
if (mHwcScreenDecorationSupport != null) {
|
||||
pw.println(" mHwcScreenDecorationSupport:");
|
||||
@@ -923,7 +957,7 @@ public class ScreenDecorations extends CoreStartable implements Tunable , Dumpab
|
||||
return;
|
||||
}
|
||||
rounded.setVisibility(View.GONE);
|
||||
if (shouldShowRoundedCorner(pos, cutout)) {
|
||||
if (shouldShowSwLayerRoundedCorner(pos, cutout)) {
|
||||
final int gravity = getRoundedCornerGravity(pos, id == R.id.left);
|
||||
((FrameLayout.LayoutParams) rounded.getLayoutParams()).gravity = gravity;
|
||||
setRoundedCornerOrientation(rounded, gravity);
|
||||
@@ -997,23 +1031,32 @@ public class ScreenDecorations extends CoreStartable implements Tunable , Dumpab
|
||||
}
|
||||
}
|
||||
|
||||
private boolean shouldShowRoundedCorner(@BoundsPosition int pos,
|
||||
private boolean shouldShowSwLayerRoundedCorner(@BoundsPosition int pos,
|
||||
@Nullable DisplayCutout cutout) {
|
||||
return hasRoundedCorners() && isDefaultShownOverlayPos(pos, cutout)
|
||||
&& mHwcScreenDecorationSupport == null;
|
||||
}
|
||||
|
||||
private boolean shouldShowPrivacyDot(@BoundsPosition int pos, @Nullable DisplayCutout cutout) {
|
||||
private boolean shouldShowSwLayerPrivacyDot(@BoundsPosition int pos,
|
||||
@Nullable DisplayCutout cutout) {
|
||||
return isPrivacyDotEnabled() && isDefaultShownOverlayPos(pos, cutout);
|
||||
}
|
||||
|
||||
private boolean shouldShowCutout(@BoundsPosition int pos, @Nullable DisplayCutout cutout) {
|
||||
private boolean shouldShowSwLayerCutout(@BoundsPosition int pos,
|
||||
@Nullable DisplayCutout cutout) {
|
||||
final Rect[] bounds = cutout == null ? null : cutout.getBoundingRectsAll();
|
||||
final int rotatedPos = getBoundPositionFromRotation(pos, mRotation);
|
||||
return (bounds != null && !bounds[rotatedPos].isEmpty()
|
||||
&& mHwcScreenDecorationSupport == null);
|
||||
}
|
||||
|
||||
private boolean isOnlyPrivacyDotInSwLayer() {
|
||||
return isPrivacyDotEnabled()
|
||||
&& (mHwcScreenDecorationSupport != null
|
||||
|| (!hasRoundedCorners() && !shouldDrawCutout())
|
||||
);
|
||||
}
|
||||
|
||||
private boolean shouldDrawCutout() {
|
||||
return shouldDrawCutout(mContext);
|
||||
}
|
||||
|
||||
@@ -134,7 +134,7 @@ class PrivacyDotViewController @Inject constructor(
|
||||
uiExecutor = e
|
||||
}
|
||||
|
||||
fun setShowingListener(l: ShowingListener) {
|
||||
fun setShowingListener(l: ShowingListener?) {
|
||||
showingListener = l
|
||||
}
|
||||
|
||||
@@ -573,7 +573,7 @@ class PrivacyDotViewController @Inject constructor(
|
||||
}
|
||||
}
|
||||
|
||||
public interface ShowingListener {
|
||||
interface ShowingListener {
|
||||
fun onPrivacyDotShown(v: View?)
|
||||
fun onPrivacyDotHidden(v: View?)
|
||||
}
|
||||
|
||||
@@ -30,6 +30,7 @@ import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertNotNull;
|
||||
import static org.junit.Assert.assertNull;
|
||||
import static org.junit.Assert.assertThat;
|
||||
import static org.junit.Assert.fail;
|
||||
import static org.mockito.ArgumentMatchers.any;
|
||||
import static org.mockito.ArgumentMatchers.eq;
|
||||
import static org.mockito.ArgumentMatchers.isA;
|
||||
@@ -127,6 +128,7 @@ public class ScreenDecorationsTest extends SysuiTestCase {
|
||||
private CornerDecorProvider mPrivacyDotBottomRightDecorProvider;
|
||||
@Mock
|
||||
private Display.Mode mDisplayMode;
|
||||
private PrivacyDotViewController.ShowingListener mPrivacyDotShowingListener;
|
||||
|
||||
@Before
|
||||
public void setup() {
|
||||
@@ -195,10 +197,24 @@ public class ScreenDecorationsTest extends SysuiTestCase {
|
||||
super.onTuningChanged(key, newValue);
|
||||
mExecutor.runAllReady();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void setOverlayWindowVisibilityIfViewExist(@Nullable View view,
|
||||
@View.Visibility int visibility) {
|
||||
super.setOverlayWindowVisibilityIfViewExist(view, visibility);
|
||||
mExecutor.runAllReady();
|
||||
}
|
||||
});
|
||||
reset(mTunerService);
|
||||
}
|
||||
|
||||
try {
|
||||
mPrivacyDotShowingListener = mScreenDecorations.mPrivacyDotShowingListener.getClass()
|
||||
.getDeclaredConstructor(ScreenDecorations.class)
|
||||
.newInstance(mScreenDecorations);
|
||||
} catch (Exception e) {
|
||||
fail(e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
private void verifyRoundedCornerViewsVisibility(
|
||||
@DisplayCutout.BoundsPosition final int overlayId,
|
||||
@@ -277,43 +293,59 @@ public class ScreenDecorationsTest extends SysuiTestCase {
|
||||
verifyBottomDotViewsVisibility(visibility);
|
||||
}
|
||||
|
||||
private void verifyOverlaysExistAndAdded(final boolean left, final boolean top,
|
||||
final boolean right, final boolean bottom) {
|
||||
private void verifyOverlaysExistAndAdded(boolean left, boolean top, boolean right,
|
||||
boolean bottom, @Nullable Integer visibilityIfExist) {
|
||||
if (left || top || right || bottom) {
|
||||
assertNotNull(mScreenDecorations.mOverlays);
|
||||
} else {
|
||||
verify(mWindowManager, never()).addView(any(), any());
|
||||
assertNull(mScreenDecorations.mOverlays);
|
||||
return;
|
||||
}
|
||||
|
||||
if (left) {
|
||||
assertNotNull(mScreenDecorations.mOverlays[BOUNDS_POSITION_LEFT]);
|
||||
final OverlayWindow overlay = mScreenDecorations.mOverlays[BOUNDS_POSITION_LEFT];
|
||||
assertNotNull(overlay);
|
||||
verify(mWindowManager, times(1)).addView(
|
||||
eq(mScreenDecorations.mOverlays[BOUNDS_POSITION_LEFT].getRootView()), any());
|
||||
eq(overlay.getRootView()), any());
|
||||
if (visibilityIfExist != null) {
|
||||
assertEquals(visibilityIfExist.intValue(), overlay.getRootView().getVisibility());
|
||||
}
|
||||
} else {
|
||||
assertNull(mScreenDecorations.mOverlays[BOUNDS_POSITION_LEFT]);
|
||||
}
|
||||
|
||||
if (top) {
|
||||
assertNotNull(mScreenDecorations.mOverlays[BOUNDS_POSITION_TOP]);
|
||||
final OverlayWindow overlay = mScreenDecorations.mOverlays[BOUNDS_POSITION_TOP];
|
||||
assertNotNull(overlay);
|
||||
verify(mWindowManager, times(1)).addView(
|
||||
eq(mScreenDecorations.mOverlays[BOUNDS_POSITION_TOP].getRootView()), any());
|
||||
eq(overlay.getRootView()), any());
|
||||
if (visibilityIfExist != null) {
|
||||
assertEquals(visibilityIfExist.intValue(), overlay.getRootView().getVisibility());
|
||||
}
|
||||
} else {
|
||||
assertNull(mScreenDecorations.mOverlays[BOUNDS_POSITION_TOP]);
|
||||
}
|
||||
|
||||
if (right) {
|
||||
assertNotNull(mScreenDecorations.mOverlays[BOUNDS_POSITION_RIGHT]);
|
||||
final OverlayWindow overlay = mScreenDecorations.mOverlays[BOUNDS_POSITION_RIGHT];
|
||||
assertNotNull(overlay);
|
||||
verify(mWindowManager, times(1)).addView(
|
||||
eq(mScreenDecorations.mOverlays[BOUNDS_POSITION_RIGHT].getRootView()), any());
|
||||
eq(overlay.getRootView()), any());
|
||||
if (visibilityIfExist != null) {
|
||||
assertEquals(visibilityIfExist.intValue(), overlay.getRootView().getVisibility());
|
||||
}
|
||||
} else {
|
||||
assertNull(mScreenDecorations.mOverlays[BOUNDS_POSITION_RIGHT]);
|
||||
}
|
||||
|
||||
if (bottom) {
|
||||
assertNotNull(mScreenDecorations.mOverlays[BOUNDS_POSITION_BOTTOM]);
|
||||
final OverlayWindow overlay = mScreenDecorations.mOverlays[BOUNDS_POSITION_BOTTOM];
|
||||
assertNotNull(overlay);
|
||||
verify(mWindowManager, times(1)).addView(
|
||||
eq(mScreenDecorations.mOverlays[BOUNDS_POSITION_BOTTOM].getRootView()), any());
|
||||
eq(overlay.getRootView()), any());
|
||||
if (visibilityIfExist != null) {
|
||||
assertEquals(visibilityIfExist.intValue(), overlay.getRootView().getVisibility());
|
||||
}
|
||||
} else {
|
||||
assertNull(mScreenDecorations.mOverlays[BOUNDS_POSITION_BOTTOM]);
|
||||
}
|
||||
@@ -330,7 +362,7 @@ public class ScreenDecorationsTest extends SysuiTestCase {
|
||||
|
||||
mScreenDecorations.start();
|
||||
// No views added.
|
||||
verifyOverlaysExistAndAdded(false, false, false, false);
|
||||
verifyOverlaysExistAndAdded(false, false, false, false, null);
|
||||
// No Tuners tuned.
|
||||
verify(mTunerService, never()).addTunable(any(), any());
|
||||
// No dot controller init
|
||||
@@ -348,9 +380,12 @@ public class ScreenDecorationsTest extends SysuiTestCase {
|
||||
|
||||
mScreenDecorations.start();
|
||||
|
||||
// Top and bottom windows are created for privacy dot.
|
||||
// Top and bottom windows are created with INVISIBLE because of privacy dot only
|
||||
// Left and right window should be null.
|
||||
verifyOverlaysExistAndAdded(false, true, false, true);
|
||||
verifyOverlaysExistAndAdded(false, true, false, true, View.INVISIBLE);
|
||||
verify(mDotViewController, times(1)).initialize(any(), any(), any(), any());
|
||||
verify(mDotViewController, times(1)).setShowingListener(
|
||||
mScreenDecorations.mPrivacyDotShowingListener);
|
||||
|
||||
// Rounded corner views shall not exist
|
||||
verifyRoundedCornerViewsVisibility(BOUNDS_POSITION_TOP, View.GONE);
|
||||
@@ -379,7 +414,7 @@ public class ScreenDecorationsTest extends SysuiTestCase {
|
||||
|
||||
// Top and bottom windows are created for rounded corners.
|
||||
// Left and right window should be null.
|
||||
verifyOverlaysExistAndAdded(false, true, false, true);
|
||||
verifyOverlaysExistAndAdded(false, true, false, true, View.VISIBLE);
|
||||
|
||||
// Rounded corner views shall exist
|
||||
verifyRoundedCornerViewsVisibility(BOUNDS_POSITION_TOP, View.VISIBLE);
|
||||
@@ -407,7 +442,9 @@ public class ScreenDecorationsTest extends SysuiTestCase {
|
||||
|
||||
// Top and bottom windows are created for rounded corners.
|
||||
// Left and right window should be null.
|
||||
verifyOverlaysExistAndAdded(false, true, false, true);
|
||||
verifyOverlaysExistAndAdded(false, true, false, true, View.VISIBLE);
|
||||
verify(mDotViewController, times(1)).initialize(any(), any(), any(), any());
|
||||
verify(mDotViewController, times(1)).setShowingListener(null);
|
||||
|
||||
// Rounded corner views shall exist
|
||||
verifyRoundedCornerViewsVisibility(BOUNDS_POSITION_TOP, View.VISIBLE);
|
||||
@@ -522,7 +559,7 @@ public class ScreenDecorationsTest extends SysuiTestCase {
|
||||
mScreenDecorations.start();
|
||||
// Top and bottom windows are created for rounded corners.
|
||||
// Left and right window should be null.
|
||||
verifyOverlaysExistAndAdded(false, true, false, true);
|
||||
verifyOverlaysExistAndAdded(false, true, false, true, View.VISIBLE);
|
||||
|
||||
// Rounded corner views shall exist
|
||||
verifyRoundedCornerViewsVisibility(BOUNDS_POSITION_TOP, View.VISIBLE);
|
||||
@@ -556,7 +593,9 @@ public class ScreenDecorationsTest extends SysuiTestCase {
|
||||
mScreenDecorations.start();
|
||||
// Top and bottom windows are created for rounded corners.
|
||||
// Left and right window should be null.
|
||||
verifyOverlaysExistAndAdded(false, true, false, true);
|
||||
verifyOverlaysExistAndAdded(false, true, false, true, View.VISIBLE);
|
||||
verify(mDotViewController, times(1)).initialize(any(), any(), any(), any());
|
||||
verify(mDotViewController, times(1)).setShowingListener(null);
|
||||
|
||||
// Rounded corner views shall exist
|
||||
verifyRoundedCornerViewsVisibility(BOUNDS_POSITION_TOP, View.VISIBLE);
|
||||
@@ -591,7 +630,7 @@ public class ScreenDecorationsTest extends SysuiTestCase {
|
||||
mScreenDecorations.start();
|
||||
// Top window is created for top cutout.
|
||||
// Bottom, left, or right window should be null.
|
||||
verifyOverlaysExistAndAdded(false, true, false, false);
|
||||
verifyOverlaysExistAndAdded(false, true, false, false, View.VISIBLE);
|
||||
|
||||
// Privacy dots shall not exist because of no privacy
|
||||
verifyDotViewsNullable(true);
|
||||
@@ -615,7 +654,9 @@ public class ScreenDecorationsTest extends SysuiTestCase {
|
||||
// Top window is created for top cutout.
|
||||
// Bottom window is created for privacy dot.
|
||||
// Left or right window should be null.
|
||||
verifyOverlaysExistAndAdded(false, true, false, true);
|
||||
verifyOverlaysExistAndAdded(false, true, false, true, View.VISIBLE);
|
||||
verify(mDotViewController, times(1)).initialize(any(), any(), any(), any());
|
||||
verify(mDotViewController, times(1)).setShowingListener(null);
|
||||
|
||||
// Top rounded corner views shall exist because of cutout
|
||||
// but be gone because of no rounded corner
|
||||
@@ -646,7 +687,7 @@ public class ScreenDecorationsTest extends SysuiTestCase {
|
||||
mScreenDecorations.start();
|
||||
// Left window is created for left cutout.
|
||||
// Bottom, top, or right window should be null.
|
||||
verifyOverlaysExistAndAdded(true, false, false, false);
|
||||
verifyOverlaysExistAndAdded(true, false, false, false, View.VISIBLE);
|
||||
|
||||
// Left rounded corner views shall exist because of cutout
|
||||
// but be gone because of no rounded corner
|
||||
@@ -674,7 +715,9 @@ public class ScreenDecorationsTest extends SysuiTestCase {
|
||||
// Left window is created for left cutout.
|
||||
// Right window is created for privacy.
|
||||
// Bottom, or top window should be null.
|
||||
verifyOverlaysExistAndAdded(true, false, true, false);
|
||||
verifyOverlaysExistAndAdded(true, false, true, false, View.VISIBLE);
|
||||
verify(mDotViewController, times(1)).initialize(any(), any(), any(), any());
|
||||
verify(mDotViewController, times(1)).setShowingListener(null);
|
||||
|
||||
// Privacy dots shall exist but invisible
|
||||
verifyDotViewsVisibility(View.INVISIBLE);
|
||||
@@ -699,7 +742,7 @@ public class ScreenDecorationsTest extends SysuiTestCase {
|
||||
// Top window is created for rounded corner and top cutout.
|
||||
// Bottom window is created for rounded corner.
|
||||
// Left, or right window should be null.
|
||||
verifyOverlaysExistAndAdded(false, true, false, true);
|
||||
verifyOverlaysExistAndAdded(false, true, false, true, View.VISIBLE);
|
||||
|
||||
// Rounded corner views shall exist
|
||||
verifyRoundedCornerViewsVisibility(BOUNDS_POSITION_TOP, View.VISIBLE);
|
||||
@@ -727,7 +770,9 @@ public class ScreenDecorationsTest extends SysuiTestCase {
|
||||
// Top window is created for rounded corner and top cutout.
|
||||
// Bottom window is created for rounded corner.
|
||||
// Left, or right window should be null.
|
||||
verifyOverlaysExistAndAdded(false, true, false, true);
|
||||
verifyOverlaysExistAndAdded(false, true, false, true, View.VISIBLE);
|
||||
verify(mDotViewController, times(1)).initialize(any(), any(), any(), any());
|
||||
verify(mDotViewController, times(1)).setShowingListener(null);
|
||||
|
||||
// Rounded corner views shall exist
|
||||
verifyRoundedCornerViewsVisibility(BOUNDS_POSITION_TOP, View.VISIBLE);
|
||||
@@ -756,7 +801,7 @@ public class ScreenDecorationsTest extends SysuiTestCase {
|
||||
// Left window is created for rounded corner and left cutout.
|
||||
// Right window is created for rounded corner.
|
||||
// Top, or bottom window should be null.
|
||||
verifyOverlaysExistAndAdded(true, false, true, false);
|
||||
verifyOverlaysExistAndAdded(true, false, true, false, View.VISIBLE);
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -774,7 +819,9 @@ public class ScreenDecorationsTest extends SysuiTestCase {
|
||||
// Left window is created for rounded corner, left cutout, and privacy.
|
||||
// Right window is created for rounded corner and privacy dot.
|
||||
// Top, or bottom window should be null.
|
||||
verifyOverlaysExistAndAdded(true, false, true, false);
|
||||
verifyOverlaysExistAndAdded(true, false, true, false, View.VISIBLE);
|
||||
verify(mDotViewController, times(1)).initialize(any(), any(), any(), any());
|
||||
verify(mDotViewController, times(1)).setShowingListener(null);
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -793,7 +840,7 @@ public class ScreenDecorationsTest extends SysuiTestCase {
|
||||
// Bottom window is created for rounded corner.
|
||||
// Left window is created for left cutout.
|
||||
// Right window should be null.
|
||||
verifyOverlaysExistAndAdded(true, true, false, true);
|
||||
verifyOverlaysExistAndAdded(true, true, false, true, View.VISIBLE);
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -812,7 +859,9 @@ public class ScreenDecorationsTest extends SysuiTestCase {
|
||||
// Bottom window is created for rounded corner.
|
||||
// Left window is created for left cutout.
|
||||
// Right window should be null.
|
||||
verifyOverlaysExistAndAdded(true, true, false, true);
|
||||
verifyOverlaysExistAndAdded(true, true, false, true, View.VISIBLE);
|
||||
verify(mDotViewController, times(1)).initialize(any(), any(), any(), any());
|
||||
verify(mDotViewController, times(1)).setShowingListener(null);
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -827,7 +876,7 @@ public class ScreenDecorationsTest extends SysuiTestCase {
|
||||
.when(mScreenDecorations).getCutout();
|
||||
|
||||
mScreenDecorations.start();
|
||||
verifyOverlaysExistAndAdded(false, true, false, false);
|
||||
verifyOverlaysExistAndAdded(false, true, false, false, View.VISIBLE);
|
||||
|
||||
// Switch to long edge cutout(left).
|
||||
final Rect[] newBounds = {new Rect(0, 50, 1, 60), null, null, null};
|
||||
@@ -835,7 +884,7 @@ public class ScreenDecorationsTest extends SysuiTestCase {
|
||||
.when(mScreenDecorations).getCutout();
|
||||
|
||||
mScreenDecorations.onConfigurationChanged(new Configuration());
|
||||
verifyOverlaysExistAndAdded(true, false, false, false);
|
||||
verifyOverlaysExistAndAdded(true, false, false, false, View.VISIBLE);
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -850,7 +899,9 @@ public class ScreenDecorationsTest extends SysuiTestCase {
|
||||
.when(mScreenDecorations).getCutout();
|
||||
|
||||
mScreenDecorations.start();
|
||||
verifyOverlaysExistAndAdded(false, true, false, true);
|
||||
verifyOverlaysExistAndAdded(false, true, false, true, View.VISIBLE);
|
||||
verify(mDotViewController, times(1)).initialize(any(), any(), any(), any());
|
||||
verify(mDotViewController, times(1)).setShowingListener(null);
|
||||
|
||||
// Switch to long edge cutout(left).
|
||||
final Rect[] newBounds = {new Rect(0, 50, 1, 60), null, null, null};
|
||||
@@ -858,7 +909,9 @@ public class ScreenDecorationsTest extends SysuiTestCase {
|
||||
.when(mScreenDecorations).getCutout();
|
||||
|
||||
mScreenDecorations.onConfigurationChanged(new Configuration());
|
||||
verifyOverlaysExistAndAdded(true, false, true, false);
|
||||
verifyOverlaysExistAndAdded(true, false, true, false, View.VISIBLE);
|
||||
verify(mDotViewController, times(2)).initialize(any(), any(), any(), any());
|
||||
verify(mDotViewController, times(2)).setShowingListener(null);
|
||||
|
||||
// Verify each privacy dot id appears only once
|
||||
mDecorProviders.stream().map(DecorProvider::getViewId).forEach(viewId -> {
|
||||
@@ -889,7 +942,7 @@ public class ScreenDecorationsTest extends SysuiTestCase {
|
||||
.when(mScreenDecorations).getCutout();
|
||||
|
||||
mScreenDecorations.start();
|
||||
assertNull(mScreenDecorations.mOverlays);
|
||||
verifyOverlaysExistAndAdded(false, false, false, false, null);
|
||||
|
||||
when(mContext.getResources().getBoolean(
|
||||
com.android.internal.R.bool.config_fillMainBuiltInDisplayCutout))
|
||||
@@ -897,7 +950,7 @@ public class ScreenDecorationsTest extends SysuiTestCase {
|
||||
mScreenDecorations.onConfigurationChanged(new Configuration());
|
||||
|
||||
// Only top windows should be added.
|
||||
verifyOverlaysExistAndAdded(false, true, false, false);
|
||||
verifyOverlaysExistAndAdded(false, true, false, false, View.VISIBLE);
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -912,23 +965,27 @@ public class ScreenDecorationsTest extends SysuiTestCase {
|
||||
.when(mScreenDecorations).getCutout();
|
||||
|
||||
mScreenDecorations.start();
|
||||
// Both top and bottom windows should be added because of privacy dot,
|
||||
// but their visibility shall be gone because of no rounding.
|
||||
verifyOverlaysExistAndAdded(false, true, false, true);
|
||||
// Both top and bottom windows should be added with INVISIBLE because of only privacy dot,
|
||||
// but rounded corners visibility shall be gone because of no rounding.
|
||||
verifyOverlaysExistAndAdded(false, true, false, true, View.INVISIBLE);
|
||||
verifyRoundedCornerViewsVisibility(BOUNDS_POSITION_TOP, View.GONE);
|
||||
verifyRoundedCornerViewsVisibility(BOUNDS_POSITION_BOTTOM, View.GONE);
|
||||
verify(mDotViewController, times(1)).initialize(any(), any(), any(), any());
|
||||
verify(mDotViewController, times(1)).setShowingListener(
|
||||
mScreenDecorations.mPrivacyDotShowingListener);
|
||||
|
||||
when(mContext.getResources().getBoolean(
|
||||
com.android.internal.R.bool.config_fillMainBuiltInDisplayCutout))
|
||||
.thenReturn(true);
|
||||
mScreenDecorations.onConfigurationChanged(new Configuration());
|
||||
|
||||
assertNotNull(mScreenDecorations.mOverlays);
|
||||
// Both top and bottom windows should be added because of privacy dot,
|
||||
// but their visibility shall be gone because of no rounding.
|
||||
verifyOverlaysExistAndAdded(false, true, false, true);
|
||||
// Both top and bottom windows should be added with VISIBLE because of privacy dot and
|
||||
// cutout, but rounded corners visibility shall be gone because of no rounding.
|
||||
verifyOverlaysExistAndAdded(false, true, false, true, View.VISIBLE);
|
||||
verifyRoundedCornerViewsVisibility(BOUNDS_POSITION_TOP, View.GONE);
|
||||
verifyRoundedCornerViewsVisibility(BOUNDS_POSITION_BOTTOM, View.GONE);
|
||||
verify(mDotViewController, times(2)).initialize(any(), any(), any(), any());
|
||||
verify(mDotViewController, times(1)).setShowingListener(null);
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -1043,9 +1100,7 @@ public class ScreenDecorationsTest extends SysuiTestCase {
|
||||
mScreenDecorations.start();
|
||||
// should only inflate mOverlays when the hwc doesn't support screen decoration
|
||||
assertNull(mScreenDecorations.mScreenDecorHwcWindow);
|
||||
assertNotNull(mScreenDecorations.mOverlays);
|
||||
assertNotNull(mScreenDecorations.mOverlays[BOUNDS_POSITION_TOP]);
|
||||
assertNotNull(mScreenDecorations.mOverlays[BOUNDS_POSITION_BOTTOM]);
|
||||
verifyOverlaysExistAndAdded(false, true, false, true, View.VISIBLE);
|
||||
|
||||
final DisplayDecorationSupport decorationSupport = new DisplayDecorationSupport();
|
||||
decorationSupport.format = PixelFormat.R_8;
|
||||
@@ -1056,7 +1111,7 @@ public class ScreenDecorationsTest extends SysuiTestCase {
|
||||
|
||||
// should only inflate hwc layer when the hwc supports screen decoration
|
||||
assertNotNull(mScreenDecorations.mScreenDecorHwcWindow);
|
||||
assertNull(mScreenDecorations.mOverlays);
|
||||
verifyOverlaysExistAndAdded(false, false, false, false, null);
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -1076,7 +1131,7 @@ public class ScreenDecorationsTest extends SysuiTestCase {
|
||||
mScreenDecorations.start();
|
||||
// should only inflate hwc layer when the hwc supports screen decoration
|
||||
assertNotNull(mScreenDecorations.mScreenDecorHwcWindow);
|
||||
assertNull(mScreenDecorations.mOverlays);
|
||||
verifyOverlaysExistAndAdded(false, false, false, false, null);
|
||||
|
||||
doReturn(null).when(mDisplay).getDisplayDecorationSupport();
|
||||
// Trigger the support hwc screen decoration change by changing the display unique id
|
||||
@@ -1085,9 +1140,66 @@ public class ScreenDecorationsTest extends SysuiTestCase {
|
||||
|
||||
// should only inflate mOverlays when the hwc doesn't support screen decoration
|
||||
assertNull(mScreenDecorations.mScreenDecorHwcWindow);
|
||||
assertNotNull(mScreenDecorations.mOverlays);
|
||||
assertNotNull(mScreenDecorations.mOverlays[BOUNDS_POSITION_TOP]);
|
||||
assertNotNull(mScreenDecorations.mOverlays[BOUNDS_POSITION_BOTTOM]);
|
||||
verifyOverlaysExistAndAdded(false, true, false, true, View.VISIBLE);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testPrivacyDotShowingListenerWorkWellWithNullParameter() {
|
||||
mPrivacyDotShowingListener.onPrivacyDotShown(null);
|
||||
mPrivacyDotShowingListener.onPrivacyDotHidden(null);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testAutoShowHideOverlayWindowWhenSupportHwcLayer() {
|
||||
setupResources(0 /* radius */, 10 /* radiusTop */, 20 /* radiusBottom */,
|
||||
0 /* roundedPadding */, false /* multipleRadius */,
|
||||
true /* fillCutout */, true /* privacyDot */);
|
||||
final DisplayDecorationSupport decorationSupport = new DisplayDecorationSupport();
|
||||
decorationSupport.format = PixelFormat.R_8;
|
||||
doReturn(decorationSupport).when(mDisplay).getDisplayDecorationSupport();
|
||||
|
||||
// top cutout
|
||||
final Rect[] bounds = {null, new Rect(9, 0, 10, 1), null, null};
|
||||
doReturn(getDisplayCutoutForRotation(Insets.of(0, 1, 0, 0), bounds))
|
||||
.when(mScreenDecorations).getCutout();
|
||||
|
||||
mScreenDecorations.start();
|
||||
// Inflate top and bottom overlay with INVISIBLE because of only privacy dots on sw layer
|
||||
verifyOverlaysExistAndAdded(false, true, false, true, View.INVISIBLE);
|
||||
|
||||
// Make sure view found and window visibility changed as well
|
||||
final View view = mScreenDecorations.mOverlays[BOUNDS_POSITION_BOTTOM].getRootView()
|
||||
.findViewById(R.id.privacy_dot_bottom_right_container);
|
||||
mPrivacyDotShowingListener.onPrivacyDotShown(view);
|
||||
assertEquals(View.VISIBLE,
|
||||
mScreenDecorations.mOverlays[BOUNDS_POSITION_BOTTOM].getRootView().getVisibility());
|
||||
mPrivacyDotShowingListener.onPrivacyDotHidden(view);
|
||||
assertEquals(View.INVISIBLE,
|
||||
mScreenDecorations.mOverlays[BOUNDS_POSITION_BOTTOM].getRootView().getVisibility());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testAutoShowHideOverlayWindowWhenNoRoundedAndNoCutout() {
|
||||
setupResources(0 /* radius */, 0 /* radiusTop */, 0 /* radiusBottom */,
|
||||
0 /* roundedPadding */, false /* multipleRadius */,
|
||||
false /* fillCutout */, true /* privacyDot */);
|
||||
|
||||
// no cutout
|
||||
doReturn(null).when(mScreenDecorations).getCutout();
|
||||
|
||||
mScreenDecorations.start();
|
||||
// Inflate top and bottom overlay with INVISIBLE because of only privacy dots on sw layer
|
||||
verifyOverlaysExistAndAdded(false, true, false, true, View.INVISIBLE);
|
||||
|
||||
// Make sure view found and window visibility changed as well
|
||||
final View view = mScreenDecorations.mOverlays[BOUNDS_POSITION_BOTTOM].getRootView()
|
||||
.findViewById(R.id.privacy_dot_bottom_right_container);
|
||||
mPrivacyDotShowingListener.onPrivacyDotShown(view);
|
||||
assertEquals(View.VISIBLE,
|
||||
mScreenDecorations.mOverlays[BOUNDS_POSITION_BOTTOM].getRootView().getVisibility());
|
||||
mPrivacyDotShowingListener.onPrivacyDotHidden(view);
|
||||
assertEquals(View.INVISIBLE,
|
||||
mScreenDecorations.mOverlays[BOUNDS_POSITION_BOTTOM].getRootView().getVisibility());
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -1108,7 +1220,7 @@ public class ScreenDecorationsTest extends SysuiTestCase {
|
||||
|
||||
// Should only inflate hwc layer.
|
||||
assertNotNull(mScreenDecorations.mScreenDecorHwcWindow);
|
||||
assertNull(mScreenDecorations.mOverlays);
|
||||
verifyOverlaysExistAndAdded(false, false, false, false, null);
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -1128,13 +1240,11 @@ public class ScreenDecorationsTest extends SysuiTestCase {
|
||||
mScreenDecorations.start();
|
||||
|
||||
assertNotNull(mScreenDecorations.mScreenDecorHwcWindow);
|
||||
// mOverlays are inflated but the visibility should be GONE.
|
||||
assertNotNull(mScreenDecorations.mOverlays);
|
||||
final View topOverlay = mScreenDecorations.mOverlays[BOUNDS_POSITION_TOP].getRootView();
|
||||
final View botOverlay = mScreenDecorations.mOverlays[BOUNDS_POSITION_BOTTOM].getRootView();
|
||||
assertEquals(topOverlay.getVisibility(), View.INVISIBLE);
|
||||
assertEquals(botOverlay.getVisibility(), View.INVISIBLE);
|
||||
|
||||
// mOverlays are inflated but the visibility should be INVISIBLE.
|
||||
verifyOverlaysExistAndAdded(false, true, false, true, View.INVISIBLE);
|
||||
verify(mDotViewController, times(1)).initialize(any(), any(), any(), any());
|
||||
verify(mDotViewController, times(1)).setShowingListener(
|
||||
mScreenDecorations.mPrivacyDotShowingListener);
|
||||
}
|
||||
|
||||
@Test
|
||||
|
||||
Reference in New Issue
Block a user