Fix SurfaceView usage when status bar is transparent for a11y (#23457)

This commit is contained in:
Dan Field 2021-01-06 11:53:42 -08:00 committed by GitHub
parent 0419f1d46a
commit df27e691b3
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 38 additions and 0 deletions

View File

@ -6,6 +6,7 @@ package io.flutter.embedding.android;
import android.content.Context;
import android.graphics.PixelFormat;
import android.graphics.Region;
import android.util.AttributeSet;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
@ -135,6 +136,28 @@ public class FlutterSurfaceView extends SurfaceView implements RenderSurface {
setAlpha(0.0f);
}
// This is a work around for TalkBack.
// If Android decides that our layer is transparent because, e.g. the status-
// bar is transparent, TalkBack highlighting stops working.
// Explicitly telling Android this part of the region is not actually
// transparent makes TalkBack work again.
// See https://github.com/flutter/flutter/issues/73413 for context.
@Override
public boolean gatherTransparentRegion(Region region) {
if (getAlpha() < 1.0f) {
return false;
}
final int[] location = new int[2];
getLocationInWindow(location);
region.op(
location[0],
location[1],
location[0] + getRight() - getLeft(),
location[1] + getBottom() - getTop(),
Region.Op.DIFFERENCE);
return true;
}
@Nullable
@Override
public FlutterRenderer getAttachedRenderer() {

View File

@ -19,6 +19,7 @@ import android.content.res.Configuration;
import android.content.res.Resources;
import android.graphics.Canvas;
import android.graphics.Insets;
import android.graphics.Region;
import android.media.Image;
import android.media.Image.Plane;
import android.media.ImageReader;
@ -795,6 +796,20 @@ public class FlutterViewTest {
verify(mockImage, times(2)).close();
}
@Test
public void flutterSurfaceView_GathersTransparentRegion() {
final Region mockRegion = mock(Region.class);
final FlutterSurfaceView surfaceView = new FlutterSurfaceView(RuntimeEnvironment.application);
surfaceView.setAlpha(0.0f);
assertFalse(surfaceView.gatherTransparentRegion(mockRegion));
verify(mockRegion, times(0)).op(anyInt(), anyInt(), anyInt(), anyInt(), any());
surfaceView.setAlpha(1.0f);
assertTrue(surfaceView.gatherTransparentRegion(mockRegion));
verify(mockRegion, times(1)).op(0, 0, 0, 0, Region.Op.DIFFERENCE);
}
/*
* A custom shadow that reports fullscreen flag for system UI visibility
*/