//xplat/js/react-native-github/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/modules/appstate:appstateAndroid (#43938)

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

Changelog: [Internal]

Reviewed By: cortinico

Differential Revision: D55726807

fbshipit-source-id: 7338ee8949c05e192c47c6c06e999600dfad07a9
This commit is contained in:
Andrew Datsenko
2024-04-11 05:25:47 -07:00
committed by Facebook GitHub Bot
parent b530371b7f
commit 88c7391485
3 changed files with 103 additions and 121 deletions
@@ -2992,9 +2992,11 @@ public abstract interface class com/facebook/react/modules/appregistry/AppRegist
public abstract fun unmountApplicationComponentAtRootTag (I)V
}
public class com/facebook/react/modules/appstate/AppStateModule : com/facebook/fbreact/specs/NativeAppStateSpec, com/facebook/react/bridge/LifecycleEventListener, com/facebook/react/bridge/WindowFocusChangeListener {
public final class com/facebook/react/modules/appstate/AppStateModule : com/facebook/fbreact/specs/NativeAppStateSpec, com/facebook/react/bridge/LifecycleEventListener, com/facebook/react/bridge/WindowFocusChangeListener {
public static final field APP_STATE_ACTIVE Ljava/lang/String;
public static final field APP_STATE_BACKGROUND Ljava/lang/String;
public static final field Companion Lcom/facebook/react/modules/appstate/AppStateModule$Companion;
public static final field NAME Ljava/lang/String;
public fun <init> (Lcom/facebook/react/bridge/ReactApplicationContext;)V
public fun addListener (Ljava/lang/String;)V
public fun getCurrentAppState (Lcom/facebook/react/bridge/Callback;Lcom/facebook/react/bridge/Callback;)V
@@ -3007,6 +3009,9 @@ public class com/facebook/react/modules/appstate/AppStateModule : com/facebook/f
public fun removeListeners (D)V
}
public final class com/facebook/react/modules/appstate/AppStateModule$Companion {
}
public class com/facebook/react/modules/blob/BlobModule : com/facebook/fbreact/specs/NativeBlobModuleSpec {
public fun <init> (Lcom/facebook/react/bridge/ReactApplicationContext;)V
public fun addNetworkingHandler ()V
@@ -1,120 +0,0 @@
/*
* Copyright (c) Meta Platforms, Inc. and 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.modules.appstate;
import com.facebook.fbreact.specs.NativeAppStateSpec;
import com.facebook.react.bridge.Arguments;
import com.facebook.react.bridge.Callback;
import com.facebook.react.bridge.LifecycleEventListener;
import com.facebook.react.bridge.ReactApplicationContext;
import com.facebook.react.bridge.WindowFocusChangeListener;
import com.facebook.react.bridge.WritableMap;
import com.facebook.react.common.LifecycleState;
import com.facebook.react.module.annotations.ReactModule;
import java.util.HashMap;
import java.util.Map;
import javax.annotation.Nullable;
@ReactModule(name = NativeAppStateSpec.NAME)
public class AppStateModule extends NativeAppStateSpec
implements LifecycleEventListener, WindowFocusChangeListener {
public static final String APP_STATE_ACTIVE = "active";
public static final String APP_STATE_BACKGROUND = "background";
private static final String INITIAL_STATE = "initialAppState";
private String mAppState;
public AppStateModule(ReactApplicationContext reactContext) {
super(reactContext);
reactContext.addLifecycleEventListener(this);
reactContext.addWindowFocusChangeListener(this);
mAppState =
(reactContext.getLifecycleState() == LifecycleState.RESUMED
? APP_STATE_ACTIVE
: APP_STATE_BACKGROUND);
}
@Override
public Map<String, Object> getTypedExportedConstants() {
HashMap<String, Object> constants = new HashMap<>();
constants.put(INITIAL_STATE, mAppState);
return constants;
}
@Override
public void getCurrentAppState(Callback success, Callback error) {
success.invoke(createAppStateEventMap());
}
@Override
public void onHostResume() {
mAppState = APP_STATE_ACTIVE;
sendAppStateChangeEvent();
}
@Override
public void onHostPause() {
mAppState = APP_STATE_BACKGROUND;
sendAppStateChangeEvent();
}
@Override
public void onHostDestroy() {
// do not set state to destroyed, do not send an event. By the current implementation, the
// catalyst instance is going to be immediately dropped, and all JS calls with it.
}
@Override
public void onWindowFocusChange(boolean hasFocus) {
sendEvent("appStateFocusChange", hasFocus);
}
private WritableMap createAppStateEventMap() {
WritableMap appState = Arguments.createMap();
appState.putString("app_state", mAppState);
return appState;
}
private void sendEvent(String eventName, @Nullable Object data) {
ReactApplicationContext reactApplicationContext = getReactApplicationContext();
if (reactApplicationContext == null) {
return;
}
// We don't gain anything interesting from logging here, and it's an extremely common
// race condition for an AppState event to be triggered as the Catalyst instance is being
// set up or torn down. So, just fail silently here.
if (!reactApplicationContext.hasActiveReactInstance()) {
return;
}
reactApplicationContext.emitDeviceEvent(eventName, data);
}
private void sendAppStateChangeEvent() {
sendEvent("appStateDidChange", createAppStateEventMap());
}
@Override
public void addListener(String eventName) {
// iOS only
}
@Override
public void removeListeners(double count) {
// iOS only
}
@Override
public void invalidate() {
super.invalidate();
getReactApplicationContext().removeLifecycleEventListener(this);
}
}
@@ -0,0 +1,97 @@
/*
* Copyright (c) Meta Platforms, Inc. and 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.modules.appstate
import com.facebook.fbreact.specs.NativeAppStateSpec
import com.facebook.react.bridge.Arguments
import com.facebook.react.bridge.Callback
import com.facebook.react.bridge.LifecycleEventListener
import com.facebook.react.bridge.ReactApplicationContext
import com.facebook.react.bridge.WindowFocusChangeListener
import com.facebook.react.bridge.WritableMap
import com.facebook.react.common.LifecycleState
import com.facebook.react.module.annotations.ReactModule
@ReactModule(name = NativeAppStateSpec.NAME)
public class AppStateModule(reactContext: ReactApplicationContext) :
NativeAppStateSpec(reactContext), LifecycleEventListener, WindowFocusChangeListener {
private var appState: String
init {
reactContext.addLifecycleEventListener(this)
reactContext.addWindowFocusChangeListener(this)
appState =
if (reactContext.lifecycleState === LifecycleState.RESUMED) APP_STATE_ACTIVE
else APP_STATE_BACKGROUND
}
public override fun getTypedExportedConstants(): Map<String, Any> =
mapOf(INITIAL_STATE to appState)
public override fun getCurrentAppState(success: Callback, error: Callback?) {
success.invoke(createAppStateEventMap())
}
public override fun onHostResume() {
appState = APP_STATE_ACTIVE
sendAppStateChangeEvent()
}
public override fun onHostPause() {
appState = APP_STATE_BACKGROUND
sendAppStateChangeEvent()
}
public override fun onHostDestroy() {
// do not set state to destroyed, do not send an event. By the current implementation, the
// catalyst instance is going to be immediately dropped, and all JS calls with it.
}
public override fun onWindowFocusChange(hasFocus: Boolean) {
sendEvent("appStateFocusChange", hasFocus)
}
private fun createAppStateEventMap(): WritableMap =
Arguments.createMap().apply { putString("app_state", appState) }
private fun sendEvent(eventName: String, data: Any?) {
val reactApplicationContext = getReactApplicationContext() ?: return
// We don't gain anything interesting from logging here, and it's an extremely common
// race condition for an AppState event to be triggered as the Catalyst instance is being
// set up or torn down. So, just fail silently here.
if (!reactApplicationContext.hasActiveReactInstance()) {
return
}
reactApplicationContext.emitDeviceEvent(eventName, data)
}
private fun sendAppStateChangeEvent() {
sendEvent("appStateDidChange", createAppStateEventMap())
}
public override fun addListener(eventName: String?) {
// iOS only
}
public override fun removeListeners(count: Double) {
// iOS only
}
public override fun invalidate() {
super.invalidate()
getReactApplicationContext().removeLifecycleEventListener(this)
}
public companion object {
public const val NAME: String = NativeAppStateSpec.NAME
public const val APP_STATE_ACTIVE: String = "active"
public const val APP_STATE_BACKGROUND: String = "background"
private const val INITIAL_STATE: String = "initialAppState"
}
}