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

Set system bar appearance using WindowInsetsControllerCompat instead of the deprecated View#setSystemUiVisibility #29060

Merged
merged 1 commit into from
Oct 14, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion DEPS
Original file line number Diff line number Diff line change
Expand Up @@ -574,7 +574,7 @@ deps = {
'packages': [
{
'package': 'flutter/android/embedding_bundle',
'version': 'last_updated:2021-08-10T22:12:57-0700'
'version': 'last_updated:2021-10-08T14:22:08-0700'
}
],
'condition': 'download_android_deps',
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.annotation.VisibleForTesting;
import androidx.core.view.WindowInsetsControllerCompat;
import io.flutter.Log;
import io.flutter.embedding.engine.systemchannels.PlatformChannel;
import java.io.FileNotFoundException;
Expand Down Expand Up @@ -364,7 +365,8 @@ private void setSystemChromeSystemUIOverlayStyle(
PlatformChannel.SystemChromeStyle systemChromeStyle) {
Window window = activity.getWindow();
View view = window.getDecorView();
int flags = view.getSystemUiVisibility();
WindowInsetsControllerCompat windowInsetsControllerCompat =
new WindowInsetsControllerCompat(window, view);

// SYSTEM STATUS BAR -------------------------------------------------------------------
// You can't change the color of the system status bar until SDK 21, and you can't change the
Expand All @@ -377,11 +379,14 @@ private void setSystemChromeSystemUIOverlayStyle(
if (systemChromeStyle.statusBarIconBrightness != null) {
switch (systemChromeStyle.statusBarIconBrightness) {
case DARK:
// View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR
flags |= 0x2000;
// Dark status bar icon brightness.
// Light status bar appearance.
windowInsetsControllerCompat.setAppearanceLightStatusBars(true);
break;
case LIGHT:
flags &= ~0x2000;
// Light status bar icon brightness.
// Dark status bar appearance.
windowInsetsControllerCompat.setAppearanceLightStatusBars(false);
break;
}
}
Expand All @@ -408,11 +413,14 @@ private void setSystemChromeSystemUIOverlayStyle(
if (systemChromeStyle.systemNavigationBarIconBrightness != null) {
switch (systemChromeStyle.systemNavigationBarIconBrightness) {
case DARK:
// View.SYSTEM_UI_FLAG_LIGHT_NAVIGATION_BAR
flags |= 0x10;
// Dark navigation bar icon brightness.
// Light navigation bar appearance.
windowInsetsControllerCompat.setAppearanceLightNavigationBars(true);
break;
case LIGHT:
flags &= ~0x10;
// Light navigation bar icon brightness.
// Dark navigation bar appearance.
windowInsetsControllerCompat.setAppearanceLightNavigationBars(false);
break;
}
}
Expand All @@ -438,7 +446,6 @@ private void setSystemChromeSystemUIOverlayStyle(
systemChromeStyle.systemNavigationBarContrastEnforced);
}

view.setSystemUiVisibility(flags);
currentTheme = systemChromeStyle;
}

Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
package io.flutter.plugin.platform;

import static android.view.WindowInsetsController.APPEARANCE_LIGHT_NAVIGATION_BARS;
import static android.view.WindowInsetsController.APPEARANCE_LIGHT_STATUS_BARS;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNull;
Expand All @@ -20,6 +22,7 @@
import android.os.Build;
import android.view.View;
import android.view.Window;
import android.view.WindowInsetsController;
import androidx.activity.OnBackPressedCallback;
import androidx.fragment.app.FragmentActivity;
import io.flutter.embedding.engine.systemchannels.PlatformChannel;
Expand Down Expand Up @@ -216,6 +219,98 @@ public void setNavigationBarDividerColor() {
}
}

@Config(sdk = 30)
@Test
public void setNavigationBarIconBrightness() {
if (Build.VERSION.SDK_INT >= 30) {
View fakeDecorView = mock(View.class);
WindowInsetsController fakeWindowInsetsController = mock(WindowInsetsController.class);
Window fakeWindow = mock(Window.class);
when(fakeWindow.getDecorView()).thenReturn(fakeDecorView);
when(fakeWindow.getInsetsController()).thenReturn(fakeWindowInsetsController);
Activity fakeActivity = mock(Activity.class);
when(fakeActivity.getWindow()).thenReturn(fakeWindow);
PlatformChannel fakePlatformChannel = mock(PlatformChannel.class);
PlatformPlugin platformPlugin = new PlatformPlugin(fakeActivity, fakePlatformChannel);

SystemChromeStyle style =
new SystemChromeStyle(
null, // statusBarColor
null, // statusBarIconBrightness
null, // systemStatusBarContrastEnforced
null, // systemNavigationBarColor
Brightness.LIGHT, // systemNavigationBarIconBrightness
null, // systemNavigationBarDividerColor
null); // systemNavigationBarContrastEnforced

platformPlugin.mPlatformMessageHandler.setSystemUiOverlayStyle(style);

verify(fakeWindowInsetsController)
.setSystemBarsAppearance(0, APPEARANCE_LIGHT_NAVIGATION_BARS);

style =
new SystemChromeStyle(
null, // statusBarColor
null, // statusBarIconBrightness
null, // systemStatusBarContrastEnforced
null, // systemNavigationBarColor
Brightness.DARK, // systemNavigationBarIconBrightness
null, // systemNavigationBarDividerColor
null); // systemNavigationBarContrastEnforced

platformPlugin.mPlatformMessageHandler.setSystemUiOverlayStyle(style);

verify(fakeWindowInsetsController)
.setSystemBarsAppearance(
APPEARANCE_LIGHT_NAVIGATION_BARS, APPEARANCE_LIGHT_NAVIGATION_BARS);
}
}

@Config(sdk = 30)
@Test
public void setStatusBarIconBrightness() {
if (Build.VERSION.SDK_INT >= 30) {
View fakeDecorView = mock(View.class);
WindowInsetsController fakeWindowInsetsController = mock(WindowInsetsController.class);
Window fakeWindow = mock(Window.class);
when(fakeWindow.getDecorView()).thenReturn(fakeDecorView);
when(fakeWindow.getInsetsController()).thenReturn(fakeWindowInsetsController);
Activity fakeActivity = mock(Activity.class);
when(fakeActivity.getWindow()).thenReturn(fakeWindow);
PlatformChannel fakePlatformChannel = mock(PlatformChannel.class);
PlatformPlugin platformPlugin = new PlatformPlugin(fakeActivity, fakePlatformChannel);

SystemChromeStyle style =
new SystemChromeStyle(
null, // statusBarColor
Brightness.LIGHT, // statusBarIconBrightness
null, // systemStatusBarContrastEnforced
null, // systemNavigationBarColor
null, // systemNavigationBarIconBrightness
null, // systemNavigationBarDividerColor
null); // systemNavigationBarContrastEnforced

platformPlugin.mPlatformMessageHandler.setSystemUiOverlayStyle(style);

verify(fakeWindowInsetsController).setSystemBarsAppearance(0, APPEARANCE_LIGHT_STATUS_BARS);

style =
new SystemChromeStyle(
null, // statusBarColor
Brightness.DARK, // statusBarIconBrightness
null, // systemStatusBarContrastEnforced
null, // systemNavigationBarColor
null, // systemNavigationBarIconBrightness
null, // systemNavigationBarDividerColor
null); // systemNavigationBarContrastEnforced

platformPlugin.mPlatformMessageHandler.setSystemUiOverlayStyle(style);

verify(fakeWindowInsetsController)
.setSystemBarsAppearance(APPEARANCE_LIGHT_STATUS_BARS, APPEARANCE_LIGHT_STATUS_BARS);
}
}

@Config(sdk = 29)
@Test
public void setSystemUiMode() {
Expand Down
1 change: 1 addition & 0 deletions shell/platform/android/test_runner/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ android {
dependencies {
testImplementation files(project.property("flutter_jar"))
testImplementation "androidx.annotation:annotation:1.1.0"
testImplementation "androidx.core:core:1.6.0"
testImplementation "androidx.fragment:fragment:1.1.0"
testImplementation "androidx.lifecycle:lifecycle-runtime:2.2.0"
testImplementation "androidx.lifecycle:lifecycle-common-java8:2.2.0"
Expand Down
1 change: 1 addition & 0 deletions tools/cipd/android_embedding_bundle/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ android {

dependencies {
embedding "androidx.annotation:annotation:1.1.0"
embedding "androidx.core:core:1.6.0"
embedding "androidx.fragment:fragment:1.1.0"

def lifecycle_version = "2.2.0"
Expand Down