Skip to content
This repository was archived by the owner on Feb 25, 2025. It is now read-only.

Commit 1b12a37

Browse files
committed
Set system bar appearance using WindowInsetsControllerCompat instead of the deprecated View#setSystemUiVisibility
The deprecated APIs conflict with Android 12's `SplashScreenView#remove` behavior causing light status bar icon on light background.
1 parent 947d54d commit 1b12a37

File tree

5 files changed

+113
-9
lines changed

5 files changed

+113
-9
lines changed

DEPS

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -574,7 +574,7 @@ deps = {
574574
'packages': [
575575
{
576576
'package': 'flutter/android/embedding_bundle',
577-
'version': 'last_updated:2021-08-10T22:12:57-0700'
577+
'version': 'last_updated:2021-10-08T14:22:08-0700'
578578
}
579579
],
580580
'condition': 'download_android_deps',

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

Lines changed: 15 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020
import androidx.annotation.NonNull;
2121
import androidx.annotation.Nullable;
2222
import androidx.annotation.VisibleForTesting;
23+
import androidx.core.view.WindowInsetsControllerCompat;
2324
import io.flutter.Log;
2425
import io.flutter.embedding.engine.systemchannels.PlatformChannel;
2526
import java.io.FileNotFoundException;
@@ -364,7 +365,8 @@ private void setSystemChromeSystemUIOverlayStyle(
364365
PlatformChannel.SystemChromeStyle systemChromeStyle) {
365366
Window window = activity.getWindow();
366367
View view = window.getDecorView();
367-
int flags = view.getSystemUiVisibility();
368+
WindowInsetsControllerCompat windowInsetsControllerCompat =
369+
new WindowInsetsControllerCompat(window, view);
368370

369371
// SYSTEM STATUS BAR -------------------------------------------------------------------
370372
// You can't change the color of the system status bar until SDK 21, and you can't change the
@@ -377,11 +379,14 @@ private void setSystemChromeSystemUIOverlayStyle(
377379
if (systemChromeStyle.statusBarIconBrightness != null) {
378380
switch (systemChromeStyle.statusBarIconBrightness) {
379381
case DARK:
380-
// View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR
381-
flags |= 0x2000;
382+
// Dark status bar icon brightness.
383+
// Light status bar appearance.
384+
windowInsetsControllerCompat.setAppearanceLightStatusBars(true);
382385
break;
383386
case LIGHT:
384-
flags &= ~0x2000;
387+
// Light status bar icon brightness.
388+
// Dark status bar appearance.
389+
windowInsetsControllerCompat.setAppearanceLightStatusBars(false);
385390
break;
386391
}
387392
}
@@ -408,11 +413,14 @@ private void setSystemChromeSystemUIOverlayStyle(
408413
if (systemChromeStyle.systemNavigationBarIconBrightness != null) {
409414
switch (systemChromeStyle.systemNavigationBarIconBrightness) {
410415
case DARK:
411-
// View.SYSTEM_UI_FLAG_LIGHT_NAVIGATION_BAR
412-
flags |= 0x10;
416+
// Dark navigation bar icon brightness.
417+
// Light navigation bar appearance.
418+
windowInsetsControllerCompat.setAppearanceLightNavigationBars(true);
413419
break;
414420
case LIGHT:
415-
flags &= ~0x10;
421+
// Light navigation bar icon brightness.
422+
// Dark navigation bar appearance.
423+
windowInsetsControllerCompat.setAppearanceLightNavigationBars(false);
416424
break;
417425
}
418426
}
@@ -438,7 +446,6 @@ private void setSystemChromeSystemUIOverlayStyle(
438446
systemChromeStyle.systemNavigationBarContrastEnforced);
439447
}
440448

441-
view.setSystemUiVisibility(flags);
442449
currentTheme = systemChromeStyle;
443450
}
444451

shell/platform/android/test/io/flutter/plugin/platform/PlatformPluginTest.java

Lines changed: 95 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
package io.flutter.plugin.platform;
22

3+
import static android.view.WindowInsetsController.APPEARANCE_LIGHT_NAVIGATION_BARS;
4+
import static android.view.WindowInsetsController.APPEARANCE_LIGHT_STATUS_BARS;
35
import static org.junit.Assert.assertFalse;
46
import static org.junit.Assert.assertNotNull;
57
import static org.junit.Assert.assertNull;
@@ -20,6 +22,7 @@
2022
import android.os.Build;
2123
import android.view.View;
2224
import android.view.Window;
25+
import android.view.WindowInsetsController;
2326
import androidx.activity.OnBackPressedCallback;
2427
import androidx.fragment.app.FragmentActivity;
2528
import io.flutter.embedding.engine.systemchannels.PlatformChannel;
@@ -216,6 +219,98 @@ public void setNavigationBarDividerColor() {
216219
}
217220
}
218221

222+
@Config(sdk = 30)
223+
@Test
224+
public void setNavigationBarIconBrightness() {
225+
View fakeDecorView = mock(View.class);
226+
WindowInsetsController fakeWindowInsetsController = mock(WindowInsetsController.class);
227+
Window fakeWindow = mock(Window.class);
228+
when(fakeWindow.getDecorView()).thenReturn(fakeDecorView);
229+
when(fakeWindow.getInsetsController()).thenReturn(fakeWindowInsetsController);
230+
Activity fakeActivity = mock(Activity.class);
231+
when(fakeActivity.getWindow()).thenReturn(fakeWindow);
232+
PlatformChannel fakePlatformChannel = mock(PlatformChannel.class);
233+
PlatformPlugin platformPlugin = new PlatformPlugin(fakeActivity, fakePlatformChannel);
234+
235+
if (Build.VERSION.SDK_INT >= 30) {
236+
SystemChromeStyle style =
237+
new SystemChromeStyle(
238+
null, // statusBarColor
239+
Brightness.LIGHT, // statusBarIconBrightness
240+
null, // systemStatusBarContrastEnforced
241+
null, // systemNavigationBarColor
242+
null, // systemNavigationBarIconBrightness
243+
null, // systemNavigationBarDividerColor
244+
null); // systemNavigationBarContrastEnforced
245+
246+
platformPlugin.mPlatformMessageHandler.setSystemUiOverlayStyle(style);
247+
248+
verify(fakeWindowInsetsController)
249+
.setSystemBarsAppearance(0, APPEARANCE_LIGHT_NAVIGATION_BARS);
250+
251+
style =
252+
new SystemChromeStyle(
253+
null, // statusBarColor
254+
Brightness.DARK, // statusBarIconBrightness
255+
null, // systemStatusBarContrastEnforced
256+
null, // systemNavigationBarColor
257+
null, // systemNavigationBarIconBrightness
258+
null, // systemNavigationBarDividerColor
259+
null); // systemNavigationBarContrastEnforced
260+
261+
platformPlugin.mPlatformMessageHandler.setSystemUiOverlayStyle(style);
262+
263+
verify(fakeWindowInsetsController)
264+
.setSystemBarsAppearance(
265+
APPEARANCE_LIGHT_NAVIGATION_BARS, APPEARANCE_LIGHT_NAVIGATION_BARS);
266+
}
267+
}
268+
269+
@Config(sdk = 30)
270+
@Test
271+
public void setStatusBarIconBrightness() {
272+
View fakeDecorView = mock(View.class);
273+
WindowInsetsController fakeWindowInsetsController = mock(WindowInsetsController.class);
274+
Window fakeWindow = mock(Window.class);
275+
when(fakeWindow.getDecorView()).thenReturn(fakeDecorView);
276+
when(fakeWindow.getInsetsController()).thenReturn(fakeWindowInsetsController);
277+
Activity fakeActivity = mock(Activity.class);
278+
when(fakeActivity.getWindow()).thenReturn(fakeWindow);
279+
PlatformChannel fakePlatformChannel = mock(PlatformChannel.class);
280+
PlatformPlugin platformPlugin = new PlatformPlugin(fakeActivity, fakePlatformChannel);
281+
282+
if (Build.VERSION.SDK_INT >= 30) {
283+
SystemChromeStyle style =
284+
new SystemChromeStyle(
285+
null, // statusBarColor
286+
null, // statusBarIconBrightness
287+
null, // systemStatusBarContrastEnforced
288+
null, // systemNavigationBarColor
289+
Brightness.LIGHT, // systemNavigationBarIconBrightness
290+
null, // systemNavigationBarDividerColor
291+
null); // systemNavigationBarContrastEnforced
292+
293+
platformPlugin.mPlatformMessageHandler.setSystemUiOverlayStyle(style);
294+
295+
verify(fakeWindowInsetsController).setSystemBarsAppearance(0, APPEARANCE_LIGHT_STATUS_BARS);
296+
297+
style =
298+
new SystemChromeStyle(
299+
null, // statusBarColor
300+
null, // statusBarIconBrightness
301+
null, // systemStatusBarContrastEnforced
302+
null, // systemNavigationBarColor
303+
Brightness.DARK, // systemNavigationBarIconBrightness
304+
null, // systemNavigationBarDividerColor
305+
null); // systemNavigationBarContrastEnforced
306+
307+
platformPlugin.mPlatformMessageHandler.setSystemUiOverlayStyle(style);
308+
309+
verify(fakeWindowInsetsController)
310+
.setSystemBarsAppearance(APPEARANCE_LIGHT_STATUS_BARS, APPEARANCE_LIGHT_STATUS_BARS);
311+
}
312+
}
313+
219314
@Config(sdk = 29)
220315
@Test
221316
public void setSystemUiMode() {

shell/platform/android/test_runner/build.gradle

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@ android {
3737
dependencies {
3838
testImplementation files(project.property("flutter_jar"))
3939
testImplementation "androidx.annotation:annotation:1.1.0"
40+
testImplementation "androidx.core:core:1.6.0"
4041
testImplementation "androidx.fragment:fragment:1.1.0"
4142
testImplementation "androidx.lifecycle:lifecycle-runtime:2.2.0"
4243
testImplementation "androidx.lifecycle:lifecycle-common-java8:2.2.0"

tools/cipd/android_embedding_bundle/build.gradle

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@ android {
4141

4242
dependencies {
4343
embedding "androidx.annotation:annotation:1.1.0"
44+
embedding "androidx.core:core:1.6.0"
4445
embedding "androidx.fragment:fragment:1.1.0"
4546

4647
def lifecycle_version = "2.2.0"

0 commit comments

Comments
 (0)