Partially remove setSystemUiVisibility() usages (flutter/engine#31092)
This commit is contained in:
@@ -24,9 +24,9 @@ import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.view.Window;
|
||||
import android.view.WindowManager.LayoutParams;
|
||||
import androidx.core.view.WindowCompat;
|
||||
import io.flutter.Log;
|
||||
import io.flutter.plugin.common.PluginRegistry;
|
||||
import io.flutter.plugin.platform.PlatformPlugin;
|
||||
import io.flutter.util.Preconditions;
|
||||
import io.flutter.view.FlutterMain;
|
||||
import io.flutter.view.FlutterNativeView;
|
||||
@@ -141,7 +141,14 @@ public final class FlutterActivityDelegate
|
||||
Window window = activity.getWindow();
|
||||
window.addFlags(LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS);
|
||||
window.setStatusBarColor(0x40000000);
|
||||
window.getDecorView().setSystemUiVisibility(PlatformPlugin.DEFAULT_SYSTEM_UI);
|
||||
WindowCompat.setDecorFitsSystemWindows(window, false);
|
||||
if (Build.VERSION.SDK_INT < 30) {
|
||||
// This ensures that the navigation bar is not hidden for APIs < 30,
|
||||
// as dictated by the implementation of WindowCompat.
|
||||
View view = window.getDecorView();
|
||||
view.setSystemUiVisibility(
|
||||
view.getSystemUiVisibility() & ~View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION);
|
||||
}
|
||||
}
|
||||
|
||||
String[] args = getArgsFromIntent(activity.getIntent());
|
||||
|
||||
@@ -38,6 +38,7 @@ import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
import androidx.annotation.VisibleForTesting;
|
||||
import androidx.core.content.res.ResourcesCompat;
|
||||
import androidx.core.view.WindowCompat;
|
||||
import androidx.lifecycle.Lifecycle;
|
||||
import androidx.lifecycle.LifecycleOwner;
|
||||
import androidx.lifecycle.LifecycleRegistry;
|
||||
@@ -590,7 +591,14 @@ public class FlutterActivity extends Activity
|
||||
Window window = getWindow();
|
||||
window.addFlags(WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS);
|
||||
window.setStatusBarColor(0x40000000);
|
||||
window.getDecorView().setSystemUiVisibility(PlatformPlugin.DEFAULT_SYSTEM_UI);
|
||||
WindowCompat.setDecorFitsSystemWindows(window, false);
|
||||
if (Build.VERSION.SDK_INT < 30) {
|
||||
// This ensures that the navigation bar is not hidden for APIs < 30,
|
||||
// as dictated by the implementation of WindowCompat.
|
||||
View view = window.getDecorView();
|
||||
view.setSystemUiVisibility(
|
||||
view.getSystemUiVisibility() & ~View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -38,6 +38,7 @@ import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
import androidx.annotation.VisibleForTesting;
|
||||
import androidx.core.content.res.ResourcesCompat;
|
||||
import androidx.core.view.WindowCompat;
|
||||
import androidx.fragment.app.FragmentActivity;
|
||||
import androidx.fragment.app.FragmentManager;
|
||||
import io.flutter.Log;
|
||||
@@ -45,7 +46,6 @@ import io.flutter.embedding.android.FlutterActivityLaunchConfigs.BackgroundMode;
|
||||
import io.flutter.embedding.engine.FlutterEngine;
|
||||
import io.flutter.embedding.engine.FlutterShellArgs;
|
||||
import io.flutter.embedding.engine.plugins.util.GeneratedPluginRegister;
|
||||
import io.flutter.plugin.platform.PlatformPlugin;
|
||||
import io.flutter.util.ViewUtils;
|
||||
|
||||
/**
|
||||
@@ -495,7 +495,14 @@ public class FlutterFragmentActivity extends FragmentActivity
|
||||
Window window = getWindow();
|
||||
window.addFlags(WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS);
|
||||
window.setStatusBarColor(0x40000000);
|
||||
window.getDecorView().setSystemUiVisibility(PlatformPlugin.DEFAULT_SYSTEM_UI);
|
||||
WindowCompat.setDecorFitsSystemWindows(window, false);
|
||||
if (Build.VERSION.SDK_INT < 30) {
|
||||
// This ensures that the navigation bar is not hidden for APIs < 30,
|
||||
// as dictated by the implementation of WindowCompat.
|
||||
View view = window.getDecorView();
|
||||
view.setSystemUiVisibility(
|
||||
view.getSystemUiVisibility() & ~View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -20,6 +20,8 @@ import androidx.activity.OnBackPressedDispatcherOwner;
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
import androidx.annotation.VisibleForTesting;
|
||||
import androidx.core.view.WindowCompat;
|
||||
import androidx.core.view.WindowInsetsCompat;
|
||||
import androidx.core.view.WindowInsetsControllerCompat;
|
||||
import io.flutter.Log;
|
||||
import io.flutter.embedding.engine.systemchannels.PlatformChannel;
|
||||
@@ -28,14 +30,13 @@ import java.util.List;
|
||||
|
||||
/** Android implementation of the platform plugin. */
|
||||
public class PlatformPlugin {
|
||||
public static final int DEFAULT_SYSTEM_UI =
|
||||
View.SYSTEM_UI_FLAG_LAYOUT_STABLE | View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN;
|
||||
|
||||
private final Activity activity;
|
||||
private final PlatformChannel platformChannel;
|
||||
private final PlatformPluginDelegate platformPluginDelegate;
|
||||
private PlatformChannel.SystemChromeStyle currentTheme;
|
||||
private int mEnabledOverlays;
|
||||
private PlatformChannel.SystemUiMode currentSystemUiMode;
|
||||
private List<PlatformChannel.SystemUiOverlay> currentOverlays;
|
||||
private static final String TAG = "PlatformPlugin";
|
||||
|
||||
/**
|
||||
@@ -140,8 +141,6 @@ public class PlatformPlugin {
|
||||
this.platformChannel = platformChannel;
|
||||
this.platformChannel.setPlatformMessageHandler(mPlatformMessageHandler);
|
||||
this.platformPluginDelegate = delegate;
|
||||
|
||||
mEnabledOverlays = DEFAULT_SYSTEM_UI;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -238,17 +237,75 @@ public class PlatformPlugin {
|
||||
}
|
||||
|
||||
private void setSystemChromeEnabledSystemUIMode(PlatformChannel.SystemUiMode systemUiMode) {
|
||||
if (Build.VERSION.SDK_INT <= 19) {
|
||||
// As of API 30, the Android APIs for overlays/insets provides backwards compatibility back
|
||||
// through API 19. Since Flutter currently supports API 19, the legacy code is used for
|
||||
// that case.
|
||||
setSystemChromeEnabledSystemUIModeLegacy(systemUiMode);
|
||||
} else {
|
||||
Window window = activity.getWindow();
|
||||
View view = window.getDecorView();
|
||||
WindowInsetsControllerCompat windowInsetsControllerCompat =
|
||||
new WindowInsetsControllerCompat(window, view);
|
||||
|
||||
if (systemUiMode == PlatformChannel.SystemUiMode.LEAN_BACK) {
|
||||
// LEAN BACK
|
||||
// Available starting at SDK 16. Implemented for API 20+ here.
|
||||
// Should not show overlays, tap to reveal overlays, needs onChange callback
|
||||
// When the overlays come in on tap, the app does not receive the gesture and does not know
|
||||
// the system overlay has changed. The overlays cannot be dismissed, so adding the callback
|
||||
// support will allow users to restore the system ui and dismiss the overlays.
|
||||
// Not compatible with top/bottom overlays enabled.
|
||||
windowInsetsControllerCompat.setSystemBarsBehavior(
|
||||
WindowInsetsControllerCompat.BEHAVIOR_SHOW_BARS_BY_TOUCH);
|
||||
windowInsetsControllerCompat.hide(WindowInsetsCompat.Type.systemBars());
|
||||
WindowCompat.setDecorFitsSystemWindows(window, false);
|
||||
} else if (systemUiMode == PlatformChannel.SystemUiMode.IMMERSIVE) {
|
||||
// IMMERSIVE
|
||||
// Available starting at SDK 19. Implemented for API 20+ here.
|
||||
// Should not show overlays, swipe from edges to reveal overlays, needs onChange callback
|
||||
// When the overlays come in on swipe, the app does not receive the gesture and does not
|
||||
// know the system overlay has changed. The overlays cannot be dismissed, so adding callback
|
||||
// support will allow users to restore the system ui and dismiss the overlays.
|
||||
// Not compatible with top/bottom overlays enabled.
|
||||
windowInsetsControllerCompat.setSystemBarsBehavior(
|
||||
WindowInsetsControllerCompat.BEHAVIOR_SHOW_BARS_BY_SWIPE);
|
||||
windowInsetsControllerCompat.hide(WindowInsetsCompat.Type.systemBars());
|
||||
WindowCompat.setDecorFitsSystemWindows(window, false);
|
||||
} else if (systemUiMode == PlatformChannel.SystemUiMode.IMMERSIVE_STICKY) {
|
||||
// STICKY IMMERSIVE
|
||||
// Available starting at SDK 19. Implemented for API 20+ here.
|
||||
// Should not show overlays, swipe from edges to reveal overlays. The app will also receive
|
||||
// the swipe gesture. The overlays cannot be dismissed, so adding callback support will
|
||||
// allow users to restore the system ui and dismiss the overlays.
|
||||
// Not compatible with top/bottom overlays enabled.
|
||||
windowInsetsControllerCompat.setSystemBarsBehavior(
|
||||
WindowInsetsControllerCompat.BEHAVIOR_SHOW_TRANSIENT_BARS_BY_SWIPE);
|
||||
windowInsetsControllerCompat.hide(WindowInsetsCompat.Type.systemBars());
|
||||
WindowCompat.setDecorFitsSystemWindows(window, false);
|
||||
} else if (systemUiMode == PlatformChannel.SystemUiMode.EDGE_TO_EDGE
|
||||
&& Build.VERSION.SDK_INT >= 29) {
|
||||
// EDGE TO EDGE
|
||||
// Available starting at SDK 29. See issue for context:
|
||||
// https://github.com/flutter/flutter/issues/89774.
|
||||
// Will apply a translucent body scrim behind 2/3 button navigation bars
|
||||
// to ensure contrast with buttons on the nav and status bars, unless the contrast is not
|
||||
// enforced in the overlay styling.
|
||||
WindowCompat.setDecorFitsSystemWindows(window, false);
|
||||
} else {
|
||||
// When none of the conditions are matched, return without updating the system UI overlays.
|
||||
return;
|
||||
}
|
||||
}
|
||||
currentSystemUiMode = systemUiMode;
|
||||
}
|
||||
|
||||
private void setSystemChromeEnabledSystemUIModeLegacy(PlatformChannel.SystemUiMode systemUiMode) {
|
||||
int enabledOverlays;
|
||||
|
||||
if (systemUiMode == PlatformChannel.SystemUiMode.LEAN_BACK
|
||||
&& Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) {
|
||||
if (systemUiMode == PlatformChannel.SystemUiMode.LEAN_BACK) {
|
||||
// LEAN BACK
|
||||
// Available starting at SDK 16
|
||||
// Should not show overlays, tap to reveal overlays, needs onChange callback
|
||||
// When the overlays come in on tap, the app does not receive the gesture and does not know
|
||||
// the system overlay has changed. The overlays cannot be dismissed, so adding the callback
|
||||
// support will allow users to restore the system ui and dismiss the overlays.
|
||||
// Not compatible with top/bottom overlays enabled.
|
||||
// Available starting at SDK 16. Implemented for APIs 16-19 here.
|
||||
enabledOverlays =
|
||||
View.SYSTEM_UI_FLAG_LAYOUT_STABLE
|
||||
| View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION
|
||||
@@ -258,12 +315,8 @@ public class PlatformPlugin {
|
||||
} else if (systemUiMode == PlatformChannel.SystemUiMode.IMMERSIVE
|
||||
&& Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
|
||||
// IMMERSIVE
|
||||
// Available starting at 19
|
||||
// Should not show overlays, swipe from edges to reveal overlays, needs onChange callback
|
||||
// When the overlays come in on swipe, the app does not receive the gesture and does not know
|
||||
// the system overlay has changed. The overlays cannot be dismissed, so adding callback
|
||||
// support will allow users to restore the system ui and dismiss the overlays.
|
||||
// Not compatible with top/bottom overlays enabled.
|
||||
// Available starting at SDK 19. Implemented for API 19 here. Earlier versions will not be
|
||||
// affected by this.
|
||||
enabledOverlays =
|
||||
View.SYSTEM_UI_FLAG_IMMERSIVE
|
||||
| View.SYSTEM_UI_FLAG_LAYOUT_STABLE
|
||||
@@ -274,11 +327,8 @@ public class PlatformPlugin {
|
||||
} else if (systemUiMode == PlatformChannel.SystemUiMode.IMMERSIVE_STICKY
|
||||
&& Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
|
||||
// STICKY IMMERSIVE
|
||||
// Available starting at 19
|
||||
// Should not show overlays, swipe from edges to reveal overlays. The app will also receive
|
||||
// the swipe gesture. The overlays cannot be dismissed, so adding callback support will
|
||||
// allow users to restore the system ui and dismiss the overlays.
|
||||
// Not compatible with top/bottom overlays enabled.
|
||||
// Available starting at SDK 19. Implemented for API 19 here. Earlier versions will not be
|
||||
// affected by this.
|
||||
enabledOverlays =
|
||||
View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY
|
||||
| View.SYSTEM_UI_FLAG_LAYOUT_STABLE
|
||||
@@ -286,44 +336,69 @@ public class PlatformPlugin {
|
||||
| View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
|
||||
| View.SYSTEM_UI_FLAG_HIDE_NAVIGATION
|
||||
| View.SYSTEM_UI_FLAG_FULLSCREEN;
|
||||
} else if (systemUiMode == PlatformChannel.SystemUiMode.EDGE_TO_EDGE
|
||||
&& Build.VERSION.SDK_INT >= 29) {
|
||||
// EDGE TO EDGE
|
||||
// Available starting at 29
|
||||
// SDK 29 and up will apply a translucent body scrim behind 2/3 button navigation bars
|
||||
// to ensure contrast with buttons on the nav and status bars, unless the contrast is not
|
||||
// enforced in the overlay styling.
|
||||
enabledOverlays =
|
||||
View.SYSTEM_UI_FLAG_LAYOUT_STABLE
|
||||
| View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION
|
||||
| View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN;
|
||||
} else {
|
||||
// When none of the conditions are matched, return without updating the system UI overlays.
|
||||
return;
|
||||
}
|
||||
|
||||
mEnabledOverlays = enabledOverlays;
|
||||
updateSystemUiOverlays();
|
||||
activity.getWindow().getDecorView().setSystemUiVisibility(enabledOverlays);
|
||||
}
|
||||
|
||||
private void setSystemChromeEnabledSystemUIOverlays(
|
||||
List<PlatformChannel.SystemUiOverlay> overlaysToShow) {
|
||||
// Start by assuming we want to hide all system overlays (like an immersive
|
||||
// game).
|
||||
if (Build.VERSION.SDK_INT <= 19) {
|
||||
// As of API 30, the Android APIs for overlays/insets provides backwards compatibility back
|
||||
// through API 19. Since Flutter currently supports API 19, the legacy code is used
|
||||
// for that case.
|
||||
setSystemChromeEnabledSystemUIOverlaysLegacy(overlaysToShow);
|
||||
} else {
|
||||
Window window = activity.getWindow();
|
||||
View view = window.getDecorView();
|
||||
WindowInsetsControllerCompat windowInsetsControllerCompat =
|
||||
new WindowInsetsControllerCompat(window, view);
|
||||
|
||||
// Start by assuming we want to hide all system overlays (like an immersive
|
||||
// game).
|
||||
windowInsetsControllerCompat.hide(WindowInsetsCompat.Type.systemBars());
|
||||
WindowCompat.setDecorFitsSystemWindows(window, false);
|
||||
|
||||
// We apply sticky immersive mode if desired. Available starting at SDK 20.
|
||||
if (overlaysToShow.size() == 0) {
|
||||
currentSystemUiMode = PlatformChannel.SystemUiMode.IMMERSIVE_STICKY;
|
||||
windowInsetsControllerCompat.setSystemBarsBehavior(
|
||||
WindowInsetsControllerCompat.BEHAVIOR_SHOW_TRANSIENT_BARS_BY_SWIPE);
|
||||
}
|
||||
|
||||
// Re-add any desired system overlays.
|
||||
for (int i = 0; i < overlaysToShow.size(); ++i) {
|
||||
PlatformChannel.SystemUiOverlay overlayToShow = overlaysToShow.get(i);
|
||||
switch (overlayToShow) {
|
||||
case TOP_OVERLAYS:
|
||||
windowInsetsControllerCompat.show(WindowInsetsCompat.Type.statusBars());
|
||||
break;
|
||||
case BOTTOM_OVERLAYS:
|
||||
windowInsetsControllerCompat.show(WindowInsetsCompat.Type.navigationBars());
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
currentOverlays = overlaysToShow;
|
||||
}
|
||||
|
||||
private void setSystemChromeEnabledSystemUIOverlaysLegacy(
|
||||
List<PlatformChannel.SystemUiOverlay> overlaysToShow) {
|
||||
int enabledOverlays =
|
||||
DEFAULT_SYSTEM_UI
|
||||
View.SYSTEM_UI_FLAG_LAYOUT_STABLE
|
||||
| View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
|
||||
| View.SYSTEM_UI_FLAG_FULLSCREEN
|
||||
| View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION
|
||||
| View.SYSTEM_UI_FLAG_HIDE_NAVIGATION;
|
||||
|
||||
// The SYSTEM_UI_FLAG_IMMERSIVE_STICKY flag was introduced in API 19, so we
|
||||
// apply it
|
||||
// if desired, and if the current Android version is 19 or greater.
|
||||
// apply it if desired.
|
||||
if (overlaysToShow.size() == 0 && Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
|
||||
currentSystemUiMode = PlatformChannel.SystemUiMode.IMMERSIVE_STICKY;
|
||||
enabledOverlays |= View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY;
|
||||
}
|
||||
|
||||
// Re-add any desired system overlays.
|
||||
for (int i = 0; i < overlaysToShow.size(); ++i) {
|
||||
PlatformChannel.SystemUiOverlay overlayToShow = overlaysToShow.get(i);
|
||||
switch (overlayToShow) {
|
||||
@@ -336,9 +411,7 @@ public class PlatformPlugin {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
mEnabledOverlays = enabledOverlays;
|
||||
updateSystemUiOverlays();
|
||||
activity.getWindow().getDecorView().setSystemUiVisibility(enabledOverlays);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -350,9 +423,24 @@ public class PlatformPlugin {
|
||||
* PlatformPlugin}.
|
||||
*/
|
||||
public void updateSystemUiOverlays() {
|
||||
activity.getWindow().getDecorView().setSystemUiVisibility(mEnabledOverlays);
|
||||
if (currentTheme != null) {
|
||||
setSystemChromeSystemUIOverlayStyle(currentTheme);
|
||||
if (currentOverlays != null) {
|
||||
setSystemChromeEnabledSystemUIOverlays(currentOverlays);
|
||||
|
||||
if (currentOverlays.size() > 0) {
|
||||
if (currentSystemUiMode != null) {
|
||||
setSystemChromeEnabledSystemUIMode(currentSystemUiMode);
|
||||
} else {
|
||||
Window window = activity.getWindow();
|
||||
WindowCompat.setDecorFitsSystemWindows(window, false);
|
||||
if (Build.VERSION.SDK_INT < 30) {
|
||||
// This ensures that the navigation bar is not hidden for APIs < 30,
|
||||
// as dictated by the implementation of WindowCompat.
|
||||
View view = window.getDecorView();
|
||||
view.setSystemUiVisibility(
|
||||
view.getSystemUiVisibility() & ~View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -13,6 +13,7 @@ import static org.mockito.Mockito.times;
|
||||
import static org.mockito.Mockito.verify;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
import android.annotation.TargetApi;
|
||||
import android.app.Activity;
|
||||
import android.content.ClipData;
|
||||
import android.content.ClipboardManager;
|
||||
@@ -24,6 +25,8 @@ import android.view.View;
|
||||
import android.view.Window;
|
||||
import android.view.WindowInsetsController;
|
||||
import androidx.activity.OnBackPressedCallback;
|
||||
import androidx.core.view.WindowInsetsCompat;
|
||||
import androidx.core.view.WindowInsetsControllerCompat;
|
||||
import androidx.fragment.app.FragmentActivity;
|
||||
import androidx.test.ext.junit.runners.AndroidJUnit4;
|
||||
import io.flutter.embedding.engine.systemchannels.PlatformChannel;
|
||||
@@ -32,6 +35,8 @@ import io.flutter.embedding.engine.systemchannels.PlatformChannel.ClipboardConte
|
||||
import io.flutter.embedding.engine.systemchannels.PlatformChannel.SystemChromeStyle;
|
||||
import io.flutter.plugin.platform.PlatformPlugin.PlatformPluginDelegate;
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.concurrent.atomic.AtomicBoolean;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
@@ -313,7 +318,9 @@ public class PlatformPluginTest {
|
||||
|
||||
@Config(sdk = 29)
|
||||
@Test
|
||||
public void setSystemUiMode() {
|
||||
public void setSystemUiModeLegacy() {
|
||||
// This test reflects the behavior under the hood of the Android overlay/inset APIs used for API
|
||||
// 20-29 in the plugin.
|
||||
View fakeDecorView = mock(View.class);
|
||||
Window fakeWindow = mock(Window.class);
|
||||
when(fakeWindow.getDecorView()).thenReturn(fakeDecorView);
|
||||
@@ -325,46 +332,177 @@ public class PlatformPluginTest {
|
||||
if (Build.VERSION.SDK_INT >= 28) {
|
||||
platformPlugin.mPlatformMessageHandler.showSystemUiMode(
|
||||
PlatformChannel.SystemUiMode.LEAN_BACK);
|
||||
verify(fakeDecorView)
|
||||
.setSystemUiVisibility(
|
||||
View.SYSTEM_UI_FLAG_LAYOUT_STABLE
|
||||
| View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION
|
||||
| View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
|
||||
| View.SYSTEM_UI_FLAG_HIDE_NAVIGATION
|
||||
| View.SYSTEM_UI_FLAG_FULLSCREEN);
|
||||
|
||||
platformPlugin.mPlatformMessageHandler.showSystemUiMode(
|
||||
PlatformChannel.SystemUiMode.IMMERSIVE);
|
||||
verify(fakeDecorView)
|
||||
.setSystemUiVisibility(
|
||||
View.SYSTEM_UI_FLAG_IMMERSIVE
|
||||
| View.SYSTEM_UI_FLAG_LAYOUT_STABLE
|
||||
| View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION
|
||||
| View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
|
||||
| View.SYSTEM_UI_FLAG_HIDE_NAVIGATION
|
||||
| View.SYSTEM_UI_FLAG_FULLSCREEN);
|
||||
|
||||
platformPlugin.mPlatformMessageHandler.showSystemUiMode(
|
||||
PlatformChannel.SystemUiMode.IMMERSIVE_STICKY);
|
||||
verify(fakeDecorView)
|
||||
.setSystemUiVisibility(
|
||||
View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY
|
||||
| View.SYSTEM_UI_FLAG_LAYOUT_STABLE
|
||||
| View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION
|
||||
| View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
|
||||
| View.SYSTEM_UI_FLAG_HIDE_NAVIGATION
|
||||
| View.SYSTEM_UI_FLAG_FULLSCREEN);
|
||||
}
|
||||
|
||||
if (Build.VERSION.SDK_INT >= 29) {
|
||||
platformPlugin.mPlatformMessageHandler.showSystemUiMode(
|
||||
PlatformChannel.SystemUiMode.EDGE_TO_EDGE);
|
||||
verify(fakeDecorView).setSystemUiVisibility(View.SYSTEM_UI_FLAG_FULLSCREEN);
|
||||
verify(fakeDecorView).setSystemUiVisibility(View.SYSTEM_UI_FLAG_HIDE_NAVIGATION);
|
||||
verify(fakeDecorView)
|
||||
.setSystemUiVisibility(
|
||||
View.SYSTEM_UI_FLAG_LAYOUT_STABLE
|
||||
| View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION
|
||||
| View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN);
|
||||
|
||||
platformPlugin.mPlatformMessageHandler.showSystemUiMode(
|
||||
PlatformChannel.SystemUiMode.IMMERSIVE);
|
||||
verify(fakeDecorView).setSystemUiVisibility(View.SYSTEM_UI_FLAG_IMMERSIVE);
|
||||
verify(fakeDecorView, times(2)).setSystemUiVisibility(View.SYSTEM_UI_FLAG_FULLSCREEN);
|
||||
verify(fakeDecorView, times(2)).setSystemUiVisibility(View.SYSTEM_UI_FLAG_HIDE_NAVIGATION);
|
||||
verify(fakeDecorView, times(2))
|
||||
.setSystemUiVisibility(
|
||||
View.SYSTEM_UI_FLAG_LAYOUT_STABLE
|
||||
| View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION
|
||||
| View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN);
|
||||
|
||||
platformPlugin.mPlatformMessageHandler.showSystemUiMode(
|
||||
PlatformChannel.SystemUiMode.IMMERSIVE_STICKY);
|
||||
verify(fakeDecorView).setSystemUiVisibility(View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY);
|
||||
verify(fakeDecorView, times(3)).setSystemUiVisibility(View.SYSTEM_UI_FLAG_FULLSCREEN);
|
||||
verify(fakeDecorView, times(3)).setSystemUiVisibility(View.SYSTEM_UI_FLAG_HIDE_NAVIGATION);
|
||||
verify(fakeDecorView, times(3))
|
||||
.setSystemUiVisibility(
|
||||
View.SYSTEM_UI_FLAG_LAYOUT_STABLE
|
||||
| View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION
|
||||
| View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN);
|
||||
}
|
||||
|
||||
if (Build.VERSION.SDK_INT >= 29) {
|
||||
platformPlugin.mPlatformMessageHandler.showSystemUiMode(
|
||||
PlatformChannel.SystemUiMode.EDGE_TO_EDGE);
|
||||
verify(fakeDecorView, times(4))
|
||||
.setSystemUiVisibility(
|
||||
View.SYSTEM_UI_FLAG_LAYOUT_STABLE
|
||||
| View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION
|
||||
| View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN);
|
||||
}
|
||||
}
|
||||
|
||||
@TargetApi(30)
|
||||
@Test
|
||||
public void setSystemUiMode() {
|
||||
View fakeDecorView = mock(View.class);
|
||||
Window fakeWindow = mock(Window.class);
|
||||
when(fakeWindow.getDecorView()).thenReturn(fakeDecorView);
|
||||
Activity fakeActivity = mock(Activity.class);
|
||||
when(fakeActivity.getWindow()).thenReturn(fakeWindow);
|
||||
PlatformChannel fakePlatformChannel = mock(PlatformChannel.class);
|
||||
PlatformPlugin platformPlugin = new PlatformPlugin(fakeActivity, fakePlatformChannel);
|
||||
WindowInsetsController fakeWindowInsetsController = mock(WindowInsetsController.class);
|
||||
when(fakeWindow.getInsetsController()).thenReturn(fakeWindowInsetsController);
|
||||
|
||||
platformPlugin.mPlatformMessageHandler.showSystemUiMode(PlatformChannel.SystemUiMode.LEAN_BACK);
|
||||
|
||||
verify(fakeWindowInsetsController)
|
||||
.setSystemBarsBehavior(WindowInsetsControllerCompat.BEHAVIOR_SHOW_BARS_BY_TOUCH);
|
||||
verify(fakeWindowInsetsController).hide(WindowInsetsCompat.Type.systemBars());
|
||||
verify(fakeWindow).setDecorFitsSystemWindows(false);
|
||||
|
||||
platformPlugin.mPlatformMessageHandler.showSystemUiMode(PlatformChannel.SystemUiMode.IMMERSIVE);
|
||||
|
||||
verify(fakeWindowInsetsController)
|
||||
.setSystemBarsBehavior(WindowInsetsControllerCompat.BEHAVIOR_SHOW_BARS_BY_SWIPE);
|
||||
verify(fakeWindowInsetsController, times(2)).hide(WindowInsetsCompat.Type.systemBars());
|
||||
verify(fakeWindow, times(2)).setDecorFitsSystemWindows(false);
|
||||
|
||||
platformPlugin.mPlatformMessageHandler.showSystemUiMode(
|
||||
PlatformChannel.SystemUiMode.IMMERSIVE_STICKY);
|
||||
|
||||
verify(fakeWindowInsetsController)
|
||||
.setSystemBarsBehavior(WindowInsetsControllerCompat.BEHAVIOR_SHOW_TRANSIENT_BARS_BY_SWIPE);
|
||||
verify(fakeWindowInsetsController, times(3)).hide(WindowInsetsCompat.Type.systemBars());
|
||||
verify(fakeWindow, times(3)).setDecorFitsSystemWindows(false);
|
||||
|
||||
platformPlugin.mPlatformMessageHandler.showSystemUiMode(
|
||||
PlatformChannel.SystemUiMode.EDGE_TO_EDGE);
|
||||
|
||||
verify(fakeWindow, times(4)).setDecorFitsSystemWindows(false);
|
||||
}
|
||||
|
||||
@Config(sdk = 29)
|
||||
@Test
|
||||
public void showSystemOverlaysLegacy() {
|
||||
// This test reflects the behavior under the hood of the Android overlay/inset APIs used for API
|
||||
// 20-29 in the plugin.
|
||||
View fakeDecorView = mock(View.class);
|
||||
Window fakeWindow = mock(Window.class);
|
||||
when(fakeWindow.getDecorView()).thenReturn(fakeDecorView);
|
||||
int fakeSetFlags =
|
||||
View.SYSTEM_UI_FLAG_FULLSCREEN
|
||||
| View.SYSTEM_UI_FLAG_HIDE_NAVIGATION
|
||||
| View.SYSTEM_UI_FLAG_LAYOUT_STABLE
|
||||
| View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION
|
||||
| View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN;
|
||||
Activity fakeActivity = mock(Activity.class);
|
||||
when(fakeActivity.getWindow()).thenReturn(fakeWindow);
|
||||
PlatformChannel fakePlatformChannel = mock(PlatformChannel.class);
|
||||
PlatformPlugin platformPlugin = new PlatformPlugin(fakeActivity, fakePlatformChannel);
|
||||
|
||||
platformPlugin.mPlatformMessageHandler.showSystemOverlays(
|
||||
new ArrayList<PlatformChannel.SystemUiOverlay>());
|
||||
|
||||
verify(fakeDecorView).setSystemUiVisibility(View.SYSTEM_UI_FLAG_FULLSCREEN);
|
||||
verify(fakeDecorView).setSystemUiVisibility(View.SYSTEM_UI_FLAG_HIDE_NAVIGATION);
|
||||
verify(fakeDecorView)
|
||||
.setSystemUiVisibility(
|
||||
View.SYSTEM_UI_FLAG_LAYOUT_STABLE
|
||||
| View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION
|
||||
| View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN);
|
||||
|
||||
verify(fakeDecorView).setSystemUiVisibility(View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY);
|
||||
verify(fakeDecorView).setSystemUiVisibility(View.SYSTEM_UI_FLAG_FULLSCREEN);
|
||||
verify(fakeDecorView).setSystemUiVisibility(View.SYSTEM_UI_FLAG_HIDE_NAVIGATION);
|
||||
verify(fakeDecorView)
|
||||
.setSystemUiVisibility(
|
||||
View.SYSTEM_UI_FLAG_LAYOUT_STABLE
|
||||
| View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION
|
||||
| View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN);
|
||||
|
||||
when(fakeDecorView.getSystemUiVisibility()).thenReturn(fakeSetFlags);
|
||||
platformPlugin.mPlatformMessageHandler.showSystemOverlays(
|
||||
new ArrayList<PlatformChannel.SystemUiOverlay>(
|
||||
Arrays.asList(
|
||||
PlatformChannel.SystemUiOverlay.TOP_OVERLAYS,
|
||||
PlatformChannel.SystemUiOverlay.BOTTOM_OVERLAYS)));
|
||||
|
||||
verify(fakeDecorView).setSystemUiVisibility(View.SYSTEM_UI_FLAG_FULLSCREEN);
|
||||
verify(fakeDecorView).setSystemUiVisibility(View.SYSTEM_UI_FLAG_HIDE_NAVIGATION);
|
||||
verify(fakeDecorView)
|
||||
.setSystemUiVisibility(
|
||||
View.SYSTEM_UI_FLAG_LAYOUT_STABLE
|
||||
| View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION
|
||||
| View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN);
|
||||
|
||||
verify(fakeDecorView).setSystemUiVisibility(fakeSetFlags &= ~View.SYSTEM_UI_FLAG_FULLSCREEN);
|
||||
verify(fakeDecorView)
|
||||
.setSystemUiVisibility(fakeSetFlags &= ~View.SYSTEM_UI_FLAG_HIDE_NAVIGATION);
|
||||
}
|
||||
|
||||
@TargetApi(30)
|
||||
@Test
|
||||
public void showSystemOverlays() {
|
||||
View fakeDecorView = mock(View.class);
|
||||
Window fakeWindow = mock(Window.class);
|
||||
when(fakeWindow.getDecorView()).thenReturn(fakeDecorView);
|
||||
Activity fakeActivity = mock(Activity.class);
|
||||
when(fakeActivity.getWindow()).thenReturn(fakeWindow);
|
||||
PlatformChannel fakePlatformChannel = mock(PlatformChannel.class);
|
||||
PlatformPlugin platformPlugin = new PlatformPlugin(fakeActivity, fakePlatformChannel);
|
||||
WindowInsetsController fakeWindowInsetsController = mock(WindowInsetsController.class);
|
||||
when(fakeWindow.getInsetsController()).thenReturn(fakeWindowInsetsController);
|
||||
|
||||
platformPlugin.mPlatformMessageHandler.showSystemOverlays(
|
||||
new ArrayList<PlatformChannel.SystemUiOverlay>());
|
||||
|
||||
verify(fakeWindowInsetsController)
|
||||
.setSystemBarsBehavior(WindowInsetsControllerCompat.BEHAVIOR_SHOW_TRANSIENT_BARS_BY_SWIPE);
|
||||
verify(fakeWindowInsetsController).hide(WindowInsetsCompat.Type.systemBars());
|
||||
|
||||
platformPlugin.mPlatformMessageHandler.showSystemOverlays(
|
||||
new ArrayList<PlatformChannel.SystemUiOverlay>(
|
||||
Arrays.asList(
|
||||
PlatformChannel.SystemUiOverlay.TOP_OVERLAYS,
|
||||
PlatformChannel.SystemUiOverlay.BOTTOM_OVERLAYS)));
|
||||
|
||||
verify(fakeWindowInsetsController).show(WindowInsetsCompat.Type.statusBars());
|
||||
verify(fakeWindowInsetsController).show(WindowInsetsCompat.Type.navigationBars());
|
||||
}
|
||||
|
||||
@Config(sdk = 28)
|
||||
|
||||
Reference in New Issue
Block a user