Skip to content

Commit 90cd956

Browse files
author
Emmanuel Garcia
authored
Revert: Partially remove setSystemUiVisibility() usages (flutter#32007)
1 parent 2e1e32a commit 90cd956

5 files changed

Lines changed: 71 additions & 362 deletions

File tree

shell/platform/android/io/flutter/app/FlutterActivityDelegate.java

Lines changed: 2 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -24,9 +24,9 @@
2424
import android.view.ViewGroup;
2525
import android.view.Window;
2626
import android.view.WindowManager.LayoutParams;
27-
import androidx.core.view.WindowCompat;
2827
import io.flutter.Log;
2928
import io.flutter.plugin.common.PluginRegistry;
29+
import io.flutter.plugin.platform.PlatformPlugin;
3030
import io.flutter.util.Preconditions;
3131
import io.flutter.view.FlutterMain;
3232
import io.flutter.view.FlutterNativeView;
@@ -141,14 +141,7 @@ public void onCreate(Bundle savedInstanceState) {
141141
Window window = activity.getWindow();
142142
window.addFlags(LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS);
143143
window.setStatusBarColor(0x40000000);
144-
WindowCompat.setDecorFitsSystemWindows(window, false);
145-
if (Build.VERSION.SDK_INT < 30) {
146-
// This ensures that the navigation bar is not hidden for APIs < 30,
147-
// as dictated by the implementation of WindowCompat.
148-
View view = window.getDecorView();
149-
view.setSystemUiVisibility(
150-
view.getSystemUiVisibility() & ~View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION);
151-
}
144+
window.getDecorView().setSystemUiVisibility(PlatformPlugin.DEFAULT_SYSTEM_UI);
152145
}
153146

154147
String[] args = getArgsFromIntent(activity.getIntent());

shell/platform/android/io/flutter/embedding/android/FlutterActivity.java

Lines changed: 1 addition & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,6 @@
3838
import androidx.annotation.Nullable;
3939
import androidx.annotation.VisibleForTesting;
4040
import androidx.core.content.res.ResourcesCompat;
41-
import androidx.core.view.WindowCompat;
4241
import androidx.lifecycle.Lifecycle;
4342
import androidx.lifecycle.LifecycleOwner;
4443
import androidx.lifecycle.LifecycleRegistry;
@@ -591,14 +590,7 @@ private void configureStatusBarForFullscreenFlutterExperience() {
591590
Window window = getWindow();
592591
window.addFlags(WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS);
593592
window.setStatusBarColor(0x40000000);
594-
WindowCompat.setDecorFitsSystemWindows(window, false);
595-
if (Build.VERSION.SDK_INT < 30) {
596-
// This ensures that the navigation bar is not hidden for APIs < 30,
597-
// as dictated by the implementation of WindowCompat.
598-
View view = window.getDecorView();
599-
view.setSystemUiVisibility(
600-
view.getSystemUiVisibility() & ~View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION);
601-
}
593+
window.getDecorView().setSystemUiVisibility(PlatformPlugin.DEFAULT_SYSTEM_UI);
602594
}
603595
}
604596

shell/platform/android/io/flutter/embedding/android/FlutterFragmentActivity.java

Lines changed: 2 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -38,14 +38,14 @@
3838
import androidx.annotation.Nullable;
3939
import androidx.annotation.VisibleForTesting;
4040
import androidx.core.content.res.ResourcesCompat;
41-
import androidx.core.view.WindowCompat;
4241
import androidx.fragment.app.FragmentActivity;
4342
import androidx.fragment.app.FragmentManager;
4443
import io.flutter.Log;
4544
import io.flutter.embedding.android.FlutterActivityLaunchConfigs.BackgroundMode;
4645
import io.flutter.embedding.engine.FlutterEngine;
4746
import io.flutter.embedding.engine.FlutterShellArgs;
4847
import io.flutter.embedding.engine.plugins.util.GeneratedPluginRegister;
48+
import io.flutter.plugin.platform.PlatformPlugin;
4949
import io.flutter.util.ViewUtils;
5050

5151
/**
@@ -495,14 +495,7 @@ private void configureStatusBarForFullscreenFlutterExperience() {
495495
Window window = getWindow();
496496
window.addFlags(WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS);
497497
window.setStatusBarColor(0x40000000);
498-
WindowCompat.setDecorFitsSystemWindows(window, false);
499-
if (Build.VERSION.SDK_INT < 30) {
500-
// This ensures that the navigation bar is not hidden for APIs < 30,
501-
// as dictated by the implementation of WindowCompat.
502-
View view = window.getDecorView();
503-
view.setSystemUiVisibility(
504-
view.getSystemUiVisibility() & ~View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION);
505-
}
498+
window.getDecorView().setSystemUiVisibility(PlatformPlugin.DEFAULT_SYSTEM_UI);
506499
}
507500
}
508501

shell/platform/android/io/flutter/plugin/platform/PlatformPlugin.java

Lines changed: 49 additions & 141 deletions
Original file line numberDiff line numberDiff line change
@@ -20,8 +20,6 @@
2020
import androidx.annotation.NonNull;
2121
import androidx.annotation.Nullable;
2222
import androidx.annotation.VisibleForTesting;
23-
import androidx.core.view.WindowCompat;
24-
import androidx.core.view.WindowInsetsCompat;
2523
import androidx.core.view.WindowInsetsControllerCompat;
2624
import io.flutter.Log;
2725
import io.flutter.embedding.engine.systemchannels.PlatformChannel;
@@ -30,13 +28,14 @@
3028

3129
/** Android implementation of the platform plugin. */
3230
public class PlatformPlugin {
31+
public static final int DEFAULT_SYSTEM_UI =
32+
View.SYSTEM_UI_FLAG_LAYOUT_STABLE | View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN;
3333

3434
private final Activity activity;
3535
private final PlatformChannel platformChannel;
3636
private final PlatformPluginDelegate platformPluginDelegate;
3737
private PlatformChannel.SystemChromeStyle currentTheme;
38-
private PlatformChannel.SystemUiMode currentSystemUiMode;
39-
private List<PlatformChannel.SystemUiOverlay> currentOverlays;
38+
private int mEnabledOverlays;
4039
private static final String TAG = "PlatformPlugin";
4140

4241
/**
@@ -143,6 +142,8 @@ public PlatformPlugin(
143142
this.platformChannel = platformChannel;
144143
this.platformChannel.setPlatformMessageHandler(mPlatformMessageHandler);
145144
this.platformPluginDelegate = delegate;
145+
146+
mEnabledOverlays = DEFAULT_SYSTEM_UI;
146147
}
147148

148149
/**
@@ -240,75 +241,17 @@ public void onSystemUiVisibilityChange(int visibility) {
240241
}
241242

242243
private void setSystemChromeEnabledSystemUIMode(PlatformChannel.SystemUiMode systemUiMode) {
243-
if (Build.VERSION.SDK_INT <= 19) {
244-
// As of API 30, the Android APIs for overlays/insets provides backwards compatibility back
245-
// through API 19. Since Flutter currently supports API 19, the legacy code is used for
246-
// that case.
247-
setSystemChromeEnabledSystemUIModeLegacy(systemUiMode);
248-
} else {
249-
Window window = activity.getWindow();
250-
View view = window.getDecorView();
251-
WindowInsetsControllerCompat windowInsetsControllerCompat =
252-
new WindowInsetsControllerCompat(window, view);
253-
254-
if (systemUiMode == PlatformChannel.SystemUiMode.LEAN_BACK) {
255-
// LEAN BACK
256-
// Available starting at SDK 16. Implemented for API 20+ here.
257-
// Should not show overlays, tap to reveal overlays, needs onChange callback
258-
// When the overlays come in on tap, the app does not receive the gesture and does not know
259-
// the system overlay has changed. The overlays cannot be dismissed, so adding the callback
260-
// support will allow users to restore the system ui and dismiss the overlays.
261-
// Not compatible with top/bottom overlays enabled.
262-
windowInsetsControllerCompat.setSystemBarsBehavior(
263-
WindowInsetsControllerCompat.BEHAVIOR_SHOW_BARS_BY_TOUCH);
264-
windowInsetsControllerCompat.hide(WindowInsetsCompat.Type.systemBars());
265-
WindowCompat.setDecorFitsSystemWindows(window, false);
266-
} else if (systemUiMode == PlatformChannel.SystemUiMode.IMMERSIVE) {
267-
// IMMERSIVE
268-
// Available starting at SDK 19. Implemented for API 20+ here.
269-
// Should not show overlays, swipe from edges to reveal overlays, needs onChange callback
270-
// When the overlays come in on swipe, the app does not receive the gesture and does not
271-
// know the system overlay has changed. The overlays cannot be dismissed, so adding callback
272-
// support will allow users to restore the system ui and dismiss the overlays.
273-
// Not compatible with top/bottom overlays enabled.
274-
windowInsetsControllerCompat.setSystemBarsBehavior(
275-
WindowInsetsControllerCompat.BEHAVIOR_SHOW_BARS_BY_SWIPE);
276-
windowInsetsControllerCompat.hide(WindowInsetsCompat.Type.systemBars());
277-
WindowCompat.setDecorFitsSystemWindows(window, false);
278-
} else if (systemUiMode == PlatformChannel.SystemUiMode.IMMERSIVE_STICKY) {
279-
// STICKY IMMERSIVE
280-
// Available starting at SDK 19. Implemented for API 20+ here.
281-
// Should not show overlays, swipe from edges to reveal overlays. The app will also receive
282-
// the swipe gesture. The overlays cannot be dismissed, so adding callback support will
283-
// allow users to restore the system ui and dismiss the overlays.
284-
// Not compatible with top/bottom overlays enabled.
285-
windowInsetsControllerCompat.setSystemBarsBehavior(
286-
WindowInsetsControllerCompat.BEHAVIOR_SHOW_TRANSIENT_BARS_BY_SWIPE);
287-
windowInsetsControllerCompat.hide(WindowInsetsCompat.Type.systemBars());
288-
WindowCompat.setDecorFitsSystemWindows(window, false);
289-
} else if (systemUiMode == PlatformChannel.SystemUiMode.EDGE_TO_EDGE
290-
&& Build.VERSION.SDK_INT >= 29) {
291-
// EDGE TO EDGE
292-
// Available starting at SDK 29. See issue for context:
293-
// https://github.com/flutter/flutter/issues/89774.
294-
// Will apply a translucent body scrim behind 2/3 button navigation bars
295-
// to ensure contrast with buttons on the nav and status bars, unless the contrast is not
296-
// enforced in the overlay styling.
297-
WindowCompat.setDecorFitsSystemWindows(window, false);
298-
} else {
299-
// When none of the conditions are matched, return without updating the system UI overlays.
300-
return;
301-
}
302-
}
303-
currentSystemUiMode = systemUiMode;
304-
}
305-
306-
private void setSystemChromeEnabledSystemUIModeLegacy(PlatformChannel.SystemUiMode systemUiMode) {
307244
int enabledOverlays;
308245

309-
if (systemUiMode == PlatformChannel.SystemUiMode.LEAN_BACK) {
246+
if (systemUiMode == PlatformChannel.SystemUiMode.LEAN_BACK
247+
&& Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) {
310248
// LEAN BACK
311-
// Available starting at SDK 16. Implemented for APIs 16-19 here.
249+
// Available starting at SDK 16
250+
// Should not show overlays, tap to reveal overlays, needs onChange callback
251+
// When the overlays come in on tap, the app does not receive the gesture and does not know
252+
// the system overlay has changed. The overlays cannot be dismissed, so adding the callback
253+
// support will allow users to restore the system ui and dismiss the overlays.
254+
// Not compatible with top/bottom overlays enabled.
312255
enabledOverlays =
313256
View.SYSTEM_UI_FLAG_LAYOUT_STABLE
314257
| View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION
@@ -318,8 +261,12 @@ private void setSystemChromeEnabledSystemUIModeLegacy(PlatformChannel.SystemUiMo
318261
} else if (systemUiMode == PlatformChannel.SystemUiMode.IMMERSIVE
319262
&& Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
320263
// IMMERSIVE
321-
// Available starting at SDK 19. Implemented for API 19 here. Earlier versions will not be
322-
// affected by this.
264+
// Available starting at 19
265+
// Should not show overlays, swipe from edges to reveal overlays, needs onChange callback
266+
// When the overlays come in on swipe, the app does not receive the gesture and does not know
267+
// the system overlay has changed. The overlays cannot be dismissed, so adding callback
268+
// support will allow users to restore the system ui and dismiss the overlays.
269+
// Not compatible with top/bottom overlays enabled.
323270
enabledOverlays =
324271
View.SYSTEM_UI_FLAG_IMMERSIVE
325272
| View.SYSTEM_UI_FLAG_LAYOUT_STABLE
@@ -330,78 +277,56 @@ private void setSystemChromeEnabledSystemUIModeLegacy(PlatformChannel.SystemUiMo
330277
} else if (systemUiMode == PlatformChannel.SystemUiMode.IMMERSIVE_STICKY
331278
&& Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
332279
// STICKY IMMERSIVE
333-
// Available starting at SDK 19. Implemented for API 19 here. Earlier versions will not be
334-
// affected by this.
280+
// Available starting at 19
281+
// Should not show overlays, swipe from edges to reveal overlays. The app will also receive
282+
// the swipe gesture. The overlays cannot be dismissed, so adding callback support will
283+
// allow users to restore the system ui and dismiss the overlays.
284+
// Not compatible with top/bottom overlays enabled.
335285
enabledOverlays =
336286
View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY
337287
| View.SYSTEM_UI_FLAG_LAYOUT_STABLE
338288
| View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION
339289
| View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
340290
| View.SYSTEM_UI_FLAG_HIDE_NAVIGATION
341291
| View.SYSTEM_UI_FLAG_FULLSCREEN;
292+
} else if (systemUiMode == PlatformChannel.SystemUiMode.EDGE_TO_EDGE
293+
&& Build.VERSION.SDK_INT >= 29) {
294+
// EDGE TO EDGE
295+
// Available starting at 29
296+
// SDK 29 and up will apply a translucent body scrim behind 2/3 button navigation bars
297+
// to ensure contrast with buttons on the nav and status bars, unless the contrast is not
298+
// enforced in the overlay styling.
299+
enabledOverlays =
300+
View.SYSTEM_UI_FLAG_LAYOUT_STABLE
301+
| View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION
302+
| View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN;
342303
} else {
304+
// When none of the conditions are matched, return without updating the system UI overlays.
343305
return;
344306
}
345-
activity.getWindow().getDecorView().setSystemUiVisibility(enabledOverlays);
346-
}
347-
348-
private void setSystemChromeEnabledSystemUIOverlays(
349-
List<PlatformChannel.SystemUiOverlay> overlaysToShow) {
350-
if (Build.VERSION.SDK_INT <= 19) {
351-
// As of API 30, the Android APIs for overlays/insets provides backwards compatibility back
352-
// through API 19. Since Flutter currently supports API 19, the legacy code is used
353-
// for that case.
354-
setSystemChromeEnabledSystemUIOverlaysLegacy(overlaysToShow);
355-
} else {
356-
Window window = activity.getWindow();
357-
View view = window.getDecorView();
358-
WindowInsetsControllerCompat windowInsetsControllerCompat =
359-
new WindowInsetsControllerCompat(window, view);
360-
361-
// Start by assuming we want to hide all system overlays (like an immersive
362-
// game).
363-
windowInsetsControllerCompat.hide(WindowInsetsCompat.Type.systemBars());
364-
WindowCompat.setDecorFitsSystemWindows(window, false);
365-
366-
// We apply sticky immersive mode if desired. Available starting at SDK 20.
367-
if (overlaysToShow.size() == 0) {
368-
currentSystemUiMode = PlatformChannel.SystemUiMode.IMMERSIVE_STICKY;
369-
windowInsetsControllerCompat.setSystemBarsBehavior(
370-
WindowInsetsControllerCompat.BEHAVIOR_SHOW_TRANSIENT_BARS_BY_SWIPE);
371-
}
372307

373-
// Re-add any desired system overlays.
374-
for (int i = 0; i < overlaysToShow.size(); ++i) {
375-
PlatformChannel.SystemUiOverlay overlayToShow = overlaysToShow.get(i);
376-
switch (overlayToShow) {
377-
case TOP_OVERLAYS:
378-
windowInsetsControllerCompat.show(WindowInsetsCompat.Type.statusBars());
379-
break;
380-
case BOTTOM_OVERLAYS:
381-
windowInsetsControllerCompat.show(WindowInsetsCompat.Type.navigationBars());
382-
break;
383-
}
384-
}
385-
}
386-
currentOverlays = overlaysToShow;
308+
mEnabledOverlays = enabledOverlays;
309+
updateSystemUiOverlays();
387310
}
388311

389-
private void setSystemChromeEnabledSystemUIOverlaysLegacy(
312+
private void setSystemChromeEnabledSystemUIOverlays(
390313
List<PlatformChannel.SystemUiOverlay> overlaysToShow) {
314+
// Start by assuming we want to hide all system overlays (like an immersive
315+
// game).
391316
int enabledOverlays =
392-
View.SYSTEM_UI_FLAG_LAYOUT_STABLE
393-
| View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
317+
DEFAULT_SYSTEM_UI
394318
| View.SYSTEM_UI_FLAG_FULLSCREEN
395319
| View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION
396320
| View.SYSTEM_UI_FLAG_HIDE_NAVIGATION;
397321

398322
// The SYSTEM_UI_FLAG_IMMERSIVE_STICKY flag was introduced in API 19, so we
399-
// apply it if desired.
323+
// apply it
324+
// if desired, and if the current Android version is 19 or greater.
400325
if (overlaysToShow.size() == 0 && Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
401-
currentSystemUiMode = PlatformChannel.SystemUiMode.IMMERSIVE_STICKY;
402326
enabledOverlays |= View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY;
403327
}
404328

329+
// Re-add any desired system overlays.
405330
for (int i = 0; i < overlaysToShow.size(); ++i) {
406331
PlatformChannel.SystemUiOverlay overlayToShow = overlaysToShow.get(i);
407332
switch (overlayToShow) {
@@ -414,7 +339,9 @@ private void setSystemChromeEnabledSystemUIOverlaysLegacy(
414339
break;
415340
}
416341
}
417-
activity.getWindow().getDecorView().setSystemUiVisibility(enabledOverlays);
342+
343+
mEnabledOverlays = enabledOverlays;
344+
updateSystemUiOverlays();
418345
}
419346

420347
/**
@@ -426,26 +353,7 @@ private void setSystemChromeEnabledSystemUIOverlaysLegacy(
426353
* PlatformPlugin}.
427354
*/
428355
public void updateSystemUiOverlays() {
429-
if (currentOverlays != null) {
430-
setSystemChromeEnabledSystemUIOverlays(currentOverlays);
431-
432-
if (currentOverlays.size() > 0) {
433-
if (currentSystemUiMode != null) {
434-
setSystemChromeEnabledSystemUIMode(currentSystemUiMode);
435-
} else {
436-
Window window = activity.getWindow();
437-
WindowCompat.setDecorFitsSystemWindows(window, false);
438-
if (Build.VERSION.SDK_INT < 30) {
439-
// This ensures that the navigation bar is not hidden for APIs < 30,
440-
// as dictated by the implementation of WindowCompat.
441-
View view = window.getDecorView();
442-
view.setSystemUiVisibility(
443-
view.getSystemUiVisibility() & ~View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION);
444-
}
445-
}
446-
}
447-
}
448-
356+
activity.getWindow().getDecorView().setSystemUiVisibility(mEnabledOverlays);
449357
if (currentTheme != null) {
450358
setSystemChromeSystemUIOverlayStyle(currentTheme);
451359
}

0 commit comments

Comments
 (0)