Files
react-native/ReactAndroid/src/main/java/com/facebook/react/ReactActivity.java
T
Brent Kelly fc5cf54d6d Addressing various issues with the Appearance API (#28823) (#29106)
Summary:
This PR fixes a few issues with the Appearance API (as noted here https://github.com/facebook/react-native/issues/28823).

1. For the Appearance API to work correctly on Android you need to call `AppearanceModule.onConfigurationChanged` when the current Activity goes through a configuration change. This was being called in the RNTester app but not in `ReactActivity` so it meant the Appearance API wouldn't work for Android in newly generated RN projects (or ones upgraded to the latest version of RN).

2. The Appearance API wasn't working correctly for brownfield scenarios on Android. It's possible to force an app light or dark natively on Android by calling `AppCompatDelegate.setDefaultNightMode()`. The Appearance API wasn't picking up changes from this function because it was using the Application context instead of the current Activity context.

3. The Appearance API wasn't working correctly for brownfield scenarios on iOS. Just like on Android its possible to force an app light or dark natively by setting `window.overrideUserInterfaceStyle`. The Appearance API didn't work with this override because we were overwriting `_currentColorScheme` back to default as soon as we set it.

## Changelog

<!-- Help reviewers and the release process by writing your own changelog entry. For an example, see:
https://github.com/facebook/react-native/wiki/Changelog
-->

### Fixed

https://github.com/facebook/react-native/issues/28823

* [Android] [Fixed] - Appearance API now works on Android
* [Android] [Fixed] - Appearance API now works correctly when calling `AppCompatDelegate.setDefaultNightMode()`
* [iOS] [Fixed] - Appearance API now works correctly when setting `window.overrideUserInterfaceStyle`

Pull Request resolved: https://github.com/facebook/react-native/pull/29106

Test Plan: Ran RNTester on iOS and Android and verified the Appearance examples still worked [correctly.](url)

Reviewed By: hramos

Differential Revision: D31284331

Pulled By: sota000

fbshipit-source-id: 45bbe33983e506eb177d596d33ddf15f846708fd
2021-11-04 12:36:17 -07:00

142 lines
3.8 KiB
Java

/*
* Copyright (c) Facebook, Inc. and its affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
package com.facebook.react;
import android.content.Intent;
import android.content.res.Configuration;
import android.os.Bundle;
import android.view.KeyEvent;
import androidx.annotation.Nullable;
import androidx.appcompat.app.AppCompatActivity;
import com.facebook.react.modules.core.DefaultHardwareBackBtnHandler;
import com.facebook.react.modules.core.PermissionAwareActivity;
import com.facebook.react.modules.core.PermissionListener;
/** Base Activity for React Native applications. */
public abstract class ReactActivity extends AppCompatActivity
implements DefaultHardwareBackBtnHandler, PermissionAwareActivity {
private final ReactActivityDelegate mDelegate;
protected ReactActivity() {
mDelegate = createReactActivityDelegate();
}
/**
* Returns the name of the main component registered from JavaScript. This is used to schedule
* rendering of the component. e.g. "MoviesApp"
*/
protected @Nullable String getMainComponentName() {
return null;
}
/** Called at construction time, override if you have a custom delegate implementation. */
protected ReactActivityDelegate createReactActivityDelegate() {
return new ReactActivityDelegate(this, getMainComponentName());
}
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
mDelegate.onCreate(savedInstanceState);
}
@Override
protected void onPause() {
super.onPause();
mDelegate.onPause();
}
@Override
protected void onResume() {
super.onResume();
mDelegate.onResume();
}
@Override
protected void onDestroy() {
super.onDestroy();
mDelegate.onDestroy();
}
@Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
mDelegate.onActivityResult(requestCode, resultCode, data);
}
@Override
public boolean onKeyDown(int keyCode, KeyEvent event) {
return mDelegate.onKeyDown(keyCode, event) || super.onKeyDown(keyCode, event);
}
@Override
public boolean onKeyUp(int keyCode, KeyEvent event) {
return mDelegate.onKeyUp(keyCode, event) || super.onKeyUp(keyCode, event);
}
@Override
public boolean onKeyLongPress(int keyCode, KeyEvent event) {
return mDelegate.onKeyLongPress(keyCode, event) || super.onKeyLongPress(keyCode, event);
}
@Override
public void onBackPressed() {
if (!mDelegate.onBackPressed()) {
super.onBackPressed();
}
}
@Override
public void invokeDefaultOnBackPressed() {
super.onBackPressed();
}
@Override
public void onNewIntent(Intent intent) {
if (!mDelegate.onNewIntent(intent)) {
super.onNewIntent(intent);
}
}
@Override
public void requestPermissions(
String[] permissions, int requestCode, PermissionListener listener) {
mDelegate.requestPermissions(permissions, requestCode, listener);
}
@Override
public void onRequestPermissionsResult(
int requestCode, String[] permissions, int[] grantResults) {
mDelegate.onRequestPermissionsResult(requestCode, permissions, grantResults);
}
@Override
public void onWindowFocusChanged(boolean hasFocus) {
super.onWindowFocusChanged(hasFocus);
mDelegate.onWindowFocusChanged(hasFocus);
}
@Override
public void onConfigurationChanged(Configuration newConfig) {
super.onConfigurationChanged(newConfig);
mDelegate.onConfigurationChanged(newConfig);
}
protected final ReactNativeHost getReactNativeHost() {
return mDelegate.getReactNativeHost();
}
protected final ReactInstanceManager getReactInstanceManager() {
return mDelegate.getReactInstanceManager();
}
protected final void loadApp(String appKey) {
mDelegate.loadApp(appKey);
}
}