Skip to content

Commit

Permalink
Fix an issue where the status bar colors would not match when opening…
Browse files Browse the repository at this point in the history
… modals (facebook#40979)

Summary:
The current ReactModalHostView implementation incorrectly applies system bar appearances by providing the wrong mask to the `setSystemBarsAppearance` method invocation. Per [this issue comment](facebook#34350 (comment)), jaydonlau correctly identified that when the status bar is set to `light-content` (light icons, dark background), the function is called with both a `0` appearance and `0` mask, which should instead be provided with the `APPEARANCE_LIGHT_STATUS_BARS` mask.

The first pass at this PR attempted to pull out the entire appearance from the activity, compare it against the dialog's appearance, and only use a mask of differing bits (see the `appearanceMask` variable). However, if the `android:windowLightStatusBar` attribute is ever set to true, this does not impact the appearance of the status bar but rather the system UI visibility. As a result, the derived mask from system bars appearance would be 0 since both the activity and dialog would have appearances of 0.

Rather than try and "future-proof" this implementation for other uses of system bar appearance, this change is directed only at updating the `APPEARANCE_LIGHT_STATUS_BARS` bit in the dialog's system bar appearance. The only other native code that touches status bars is the `StatusBarModule` and that only touches this flag.

This is a follow-up to facebook#34899.

## Changelog:

<!-- Help reviewers and the release process by writing your own changelog entry.

Pick one each for the category and type tags:

[ANDROID|GENERAL|IOS|INTERNAL] [BREAKING|ADDED|CHANGED|DEPRECATED|REMOVED|FIXED|SECURITY] - Message

For more details, see:
https://reactnative.dev/contributing/changelogs-in-pull-requests
-->

[ANDROID] [FIXED] - Fixed an issue where the status bar colors would not match when opening modals

Pull Request resolved: facebook#40979

Test Plan:
First test:
- Replace the `RNTesterAppShared` implementation with the implementation from [this Expo snack](https://snack.expo.dev/abbondanzo/status-bar-tester)
- Toggle the status bar to show dark icons, open the modal and ensure that dark icons are displayed
- Toggle the status bar to show light icons, open the modal and ensure that light icons are displayed

Second test:
- Set the `android:windowLightStatusBar` attribute to true in the `AppTheme`
- Follow the steps from the First test above, guaranteeing that status bar appearance overrides the theme

Reviewed By: NickGerleman

Differential Revision: D50329714

Pulled By: luluwu2032

fbshipit-source-id: 26ecaca05f8e00a52e13767e468b552ac167fc98
  • Loading branch information
Peter Abbondanzo authored and Othinn committed Jan 9, 2024
1 parent 860526a commit 1e53b77
Showing 1 changed file with 28 additions and 13 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
import android.view.ViewGroup;
import android.view.ViewStructure;
import android.view.Window;
import android.view.WindowInsetsController;
import android.view.WindowManager;
import android.view.accessibility.AccessibilityEvent;
import android.widget.FrameLayout;
Expand Down Expand Up @@ -328,19 +329,7 @@ public boolean onKey(DialogInterface dialog, int keyCode, KeyEvent event) {
}
if (currentActivity != null && !currentActivity.isFinishing()) {
mDialog.show();
if (context instanceof Activity) {
if (Build.VERSION.SDK_INT > Build.VERSION_CODES.R) {
int appearance =
((Activity) context).getWindow().getInsetsController().getSystemBarsAppearance();
mDialog.getWindow().getInsetsController().setSystemBarsAppearance(appearance, appearance);
} else {
mDialog
.getWindow()
.getDecorView()
.setSystemUiVisibility(
((Activity) context).getWindow().getDecorView().getSystemUiVisibility());
}
}
updateSystemAppearance();
mDialog.getWindow().clearFlags(WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE);
}
}
Expand Down Expand Up @@ -394,6 +383,32 @@ private void updateProperties() {
}
}

private void updateSystemAppearance() {
Activity currentActivity = getCurrentActivity();
if (currentActivity == null) {
return;
}
Assertions.assertNotNull(mDialog, "mDialog must exist when we call updateSystemAppearance");
// Modeled after the version check in StatusBarModule.setStyle
if (Build.VERSION.SDK_INT > Build.VERSION_CODES.R) {
int activityAppearance =
currentActivity.getWindow().getInsetsController().getSystemBarsAppearance();
int activityLightStatusBars =
activityAppearance & WindowInsetsController.APPEARANCE_LIGHT_STATUS_BARS;
mDialog
.getWindow()
.getInsetsController()
.setSystemBarsAppearance(
activityLightStatusBars, WindowInsetsController.APPEARANCE_LIGHT_STATUS_BARS);
} else {
mDialog
.getWindow()
.getDecorView()
.setSystemUiVisibility(
currentActivity.getWindow().getDecorView().getSystemUiVisibility());
}
}

@Nullable
public StateWrapper getStateWrapper() {
return mHostView.getStateWrapper();
Expand Down

0 comments on commit 1e53b77

Please sign in to comment.